diff --git a/src/demo/editor/headerBase.tsx b/src/demo/editor/headerBase.tsx
new file mode 100644
index 000000000..446a9d435
--- /dev/null
+++ b/src/demo/editor/headerBase.tsx
@@ -0,0 +1,11 @@
+import React from 'react'
+
+export const HeaderBase = (): JSX.Element => {
+ return (
+
+
+
+ Thema
+
+ )
+}
diff --git a/src/demo/editor/index.tsx b/src/demo/editor/index.tsx
index d1a200f89..778d7e213 100644
--- a/src/demo/editor/index.tsx
+++ b/src/demo/editor/index.tsx
@@ -12,7 +12,7 @@ export const ThemeEditor = (): JSX.Element => {
- Current Theme
+ Theme
{
-
- Themes are designed to be customizable, if you’d like to make extensive
- changes you can extend a theme, or make one from scratch.{' '}
- Read the documentation{' '}
- to learn how.
-
-
Customize
diff --git a/src/demo/gallery.tsx b/src/demo/gallery.tsx
new file mode 100644
index 000000000..a098761c7
--- /dev/null
+++ b/src/demo/gallery.tsx
@@ -0,0 +1,9 @@
+/**
+ * Header for gallery page
+ */
+
+import React from 'react'
+import ReactDOM from 'react-dom'
+import { HeaderBase } from './editor/headerBase'
+
+ReactDOM.render(, document.getElementById('header'))
diff --git a/src/demo/styles.css b/src/demo/styles.css
index 55e883e9e..9d9bf1014 100644
--- a/src/demo/styles.css
+++ b/src/demo/styles.css
@@ -13,11 +13,14 @@ html {
}
body {
- display: flex;
- flex-wrap: wrap;
height: 100%;
margin: 0;
padding: 3rem 0 0;
+
+ &.editor {
+ display: flex;
+ flex-wrap: wrap;
+ }
}
body > * {
@@ -65,6 +68,11 @@ header {
color: var(--color-neutral-700);
}
+ a:link,
+ a:visited {
+ text-decoration: none;
+ }
+
img {
height: 2rem;
}
@@ -99,6 +107,81 @@ main {
background-color: var(--color-neutral-100);
}
+:--root > :--List > :--ListItem {
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.035), 0 0 40px rgba(0, 0, 0, 0.07);
+ overflow: hidden;
+ transition: box-shadow 200ms ease-out;
+ padding-bottom: var(--spacer-sm);
+
+ &:hover {
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.045), 0 0 40px rgba(0, 0, 0, 0.17);
+ }
+}
+
+/* Gallery page */
+
+:--root > :--List > :--ListItem > :--CreativeWork {
+ :--title {
+ display: none;
+ }
+
+ :--Heading {
+ font-size: var(--font-size-h1);
+ color: var(--color-key);
+ order: -1;
+ margin-top: var(--spacer-md);
+ margin-bottom: var(--spacer-md);
+ text-transform: capitalize;
+ }
+
+ & > a[href^='/editor?'] {
+ order: -1;
+ display: block;
+ border-bottom: 1px solid var(--color-neutral-400);
+ margin-bottom: var(--spacer-md);
+ }
+
+ & > :--Organization {
+ display: none;
+ }
+
+ & > :--Paragraph:last-of-type > a {
+ background-color: var(--color-neutral-300);
+ border-radius: 4px;
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.035), 0 0 40px rgba(0, 0, 0, 0.07);
+ border: 1px solid var(--color-neutral-400);
+ font-size: 12px;
+ font-weight: bold;
+ letter-spacing: 1px;
+ padding: 0.25rem 0.5rem;
+ text-decoration: none;
+ text-transform: uppercase;
+ transition: color 200ms ease-out, background-color 200ms ease-out,
+ border-color 200ms ease-out;
+
+ &:hover {
+ background-color: var(--color-neutral-400);
+ }
+
+ &::after {
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' stroke='#363636' stroke-width='2.5' fill='none' stroke-linecap='round' stroke-linejoin='round' class='css-i6dzq1'%3E%3Cpolyline points='9 18 15 12 9 6'%3E%3C/polyline%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-size: contain;
+ color: red;
+ content: '';
+ display: inline-block;
+ height: 16px;
+ transition: transform 125ms ease-out;
+ vertical-align: middle;
+ width: 14px;
+ }
+
+ &:hover::after {
+ transform: translateX(0.25rem);
+ }
+ }
+}
+
iframe {
background-color: white;
border: 1px solid var(--color-neutral-300);
@@ -145,10 +228,11 @@ menu p {
#contribute:link,
#sidebar > a.button,
#sidebar > button {
- background-color: #1d64f3;
+ background-color: var(--color-neutral-400);
border-radius: 2px;
- border: none;
- color: white;
+ border: 1px solid var(--color-neutral-500);
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.035), 0 0 40px rgba(0, 0, 0, 0.07);
+ color: var(--color-key);
font-weight: bold;
letter-spacing: 1px;
margin: 1rem 0;
@@ -161,6 +245,7 @@ menu p {
#contribute:hover,
#sidebar > a.button:hover,
#sidebar > button:hover {
+ color: white;
background-color: #164ebf;
}
@@ -182,8 +267,8 @@ menu p {
width: 100%;
}
-h2,
-h3 {
+#sidebar h2,
+#sidebar h3 {
font-size: 12px;
font-weight: bold;
color: var(--color-neutral-700);
@@ -192,7 +277,7 @@ h3 {
position: relative;
}
-h3::after {
+#sidebar h3::after {
content: '';
position: absolute;
-webkit-transform: translateY(-50%);
@@ -202,7 +287,7 @@ h3::after {
}
hr,
-h3::after {
+#sidebar h3::after {
background-color: var(--color-neutral-500);
border: none;
height: 1px;
@@ -240,17 +325,12 @@ h3::after {
}
#themeVariables label.modified {
- color: #066860;
cursor: help;
font-style: italic;
font-weight: bold;
padding: 1px 0;
}
-#themeVariables label.modified::after {
- content: '*';
-}
-
#themeVariables .labelWrapper button {
background-color: var(--color-neutral-100);
border: 1px solid var(--color-neutral-400);
diff --git a/src/galleryTemplate.ejs b/src/galleryTemplate.ejs
new file mode 100644
index 000000000..13ca3586f
--- /dev/null
+++ b/src/galleryTemplate.ejs
@@ -0,0 +1,16 @@
+
+
+
+ Stencila Thema
+
+
+
+
+
+
+
+
+ <%= require("./gallery.ejs")() %>
+
+
+
diff --git a/src/scripts/gallery.ts b/src/scripts/gallery.ts
index 544e77044..51d59efe1 100644
--- a/src/scripts/gallery.ts
+++ b/src/scripts/gallery.ts
@@ -1,29 +1,31 @@
/**
- * A script to generate `../docs/gallery.html`
*
* Run using `npm run docs:gallery`. Noting that this
* uses built themes in `docs/themes` so `npm run docs:app`
* needs to be done first.
*/
-import { read, write, dump, shutdown } from '@stencila/encoda'
+import { dump, read, shutdown, write } from '@stencila/encoda'
import {
Article,
article,
CreativeWork,
creativeWork,
+ heading,
imageObject,
link,
list,
listItem,
- organization
+ organization,
+ paragraph
} from '@stencila/schema'
import { tmpdir } from 'os'
import path from 'path'
-import { themes } from '../themes'
+import { themes } from '../themes/index'
const themesDir = path.join(__dirname, '..', 'themes')
const examplesDir = path.join(__dirname, '..', 'examples')
+const srcDir = path.join(__dirname, '..')
const docsDir = path.join(__dirname, '..', '..', 'docs')
const stencila = organization({
@@ -52,7 +54,11 @@ async function generateGallery(): Promise {
Object.keys(themes).map(
async (theme): Promise<[string, CreativeWork]> => [
theme,
- await generateSummary(theme, `?theme=${theme}`, example as Article)
+ await generateSummary(
+ theme,
+ `/editor?theme=${theme}`,
+ example as Article
+ )
]
)
)
@@ -64,7 +70,7 @@ async function generateGallery(): Promise {
{}
)
- await write(summaries, path.join(docsDir, 'themes.json'))
+ await write(summaries, path.join(srcDir, 'themes.json'))
const gallery = article({
title: 'Thema Gallery',
@@ -72,6 +78,21 @@ async function generateGallery(): Promise {
publisher: stencila,
datePublished: new Date().toISOString(),
content: [
+ paragraph({
+ content: [
+ 'Thema provides semantic themes for use with ',
+ link({
+ target: 'https://github.com/stencila/encoda/',
+ content: ['Stencila’s Encoda']
+ }),
+ '. Themes are designed to be customizable, or you can ',
+ link({
+ target: 'https://github.com/stencila/thema/',
+ content: ['make one from scratch']
+ }),
+ '.'
+ ]
+ }),
list({
items: Object.entries(summaries).map(([theme, summary]) => {
return listItem({
@@ -85,9 +106,10 @@ async function generateGallery(): Promise {
]
})
- await write(gallery, path.join(docsDir, 'gallery.html'), {
- isStandalone: true,
- theme: path.join(docsDir, 'themes', 'galleria')
+ await write(gallery, path.join(srcDir, 'gallery.ejs'), {
+ isStandalone: false,
+ format: 'html',
+ theme: path.join(srcDir, 'themes', 'galleria')
})
await shutdown()
@@ -113,6 +135,7 @@ async function generateSummary(
// Generate a screenshot using the local build of the theme
const screenshot = path.join(tmpdir(), 'screenshots', `${theme}.png`)
+
await write(example, screenshot, {
theme: path.join(docsDir, 'themes', theme),
size: { height: 500, width: 800 }
@@ -124,13 +147,22 @@ async function generateSummary(
publisher,
// New content includes the screenshot
content: [
- ...content,
link({
target: url,
content: [imageObject({ contentUrl: screenshot })]
+ }),
+ heading({ depth: 3, content: [theme] }),
+ ...content,
+ paragraph({
+ content: [
+ link({
+ target: url,
+ content: ['View demo & customize']
+ })
+ ]
})
],
- // If their is not a description in the YAML meta data of the
+ // If there is not a description in the YAML meta data of the
// README, then make it the plain text version of the original content
description:
description !== undefined ? description : await dump(content, 'txt'),
diff --git a/src/template.html b/src/template.html
index 106522199..8e956d704 100644
--- a/src/template.html
+++ b/src/template.html
@@ -6,7 +6,7 @@
-
+