diff --git a/REMOVEME.md b/REMOVEME.md
new file mode 100644
index 0000000..f620022
--- /dev/null
+++ b/REMOVEME.md
@@ -0,0 +1 @@
+file for testing commit
diff --git a/packages/playground/devEnv/Home.tsx b/packages/playground/devEnv/Home.tsx
deleted file mode 100644
index e7b7c49..0000000
--- a/packages/playground/devEnv/Home.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import React from 'react'
-
-export const Home = ({groups}: {groups: {[groupName: string]: string[]}}) => (
-
- {Object.entries(groups).map(([groupName, modules]) => (
- -
- {groupName}
-
-
- ))}
-
-)
-
-const Group = (props: {groupName: string; modules: string[]}) => {
- const {groupName, modules} = props
- return (
-
- )
-}
diff --git a/packages/playground/devEnv/build.ts b/packages/playground/devEnv/build.ts
index 153d7b1..da2a9c3 100644
--- a/packages/playground/devEnv/build.ts
+++ b/packages/playground/devEnv/build.ts
@@ -7,7 +7,8 @@ import {definedGlobals} from '../../../theatre/devEnv/definedGlobals'
import {mapValues} from 'lodash-es'
import React from 'react'
import {renderToStaticMarkup} from 'react-dom/server'
-import {Home} from './Home'
+import {ServerStyleSheet} from 'styled-components'
+import {PlaygroundPage} from './home/PlaygroundPage'
import {timer} from './timer'
import {openForOS} from './openForOS'
import {tryMultiplePorts} from './tryMultiplePorts'
@@ -83,11 +84,31 @@ export async function start(options: {
)
// Render home page contents
- const homeHtml = renderToStaticMarkup(
- React.createElement(Home, {
- groups: mapValues(groups, (group) => Object.keys(group)),
- }),
- )
+
+ // Render home page contents
+ const homeHtml = (() => {
+ const sheet = new ServerStyleSheet()
+ try {
+ const html = renderToStaticMarkup(
+ sheet.collectStyles(
+ React.createElement(PlaygroundPage, {
+ groups: mapValues(groups, (group) => Object.keys(group)),
+ }),
+ ),
+ )
+ const styleTags = sheet.getStyleTags() // or sheet.getStyleElement();
+ sheet.seal()
+ return {
+ head: styleTags,
+ html,
+ }
+ } catch (error) {
+ // handle error
+ console.error(error)
+ sheet.seal()
+ process.exit(1)
+ }
+ })()
const _initialBuild = timer('esbuild initial playground entry point builds')
@@ -108,7 +129,12 @@ export async function start(options: {
'window.__IS_VISUAL_REGRESSION_TESTING': 'true',
},
banner: liveReload?.esbuildBanner,
- watch: liveReload?.esbuildWatch,
+ watch: liveReload?.esbuildWatch && {
+ onRebuild(error, result) {
+ esbuildWatchStop = result?.stop ?? esbuildWatchStop
+ liveReload?.esbuildWatch.onRebuild?.(error, result)
+ },
+ },
}
let esbuildWatchStop: undefined | (() => void)
@@ -128,17 +154,23 @@ export async function start(options: {
// Write home page
writeFile(
path.join(buildDir, 'index.html'),
- index.replace(/[\s\S]*<\/body>/, `${homeHtml}`),
+ index
+ .replace(/<\/head>/, `${homeHtml.head}<\/head>`)
+ .replace(//, `${homeHtml.html}`),
'utf-8',
),
// Write module pages
...outDirs.map((outDir) =>
writeFile(
path.join(outDir, 'index.html'),
- // Substitute %ENTRYPOINT% placeholder with the output file path
+ // Insert the script
index.replace(
- '%ENTRYPOINT%',
- path.join('/', path.relative(buildDir, outDir), 'index.js'),
+ /<\/body>/,
+ ``,
),
'utf-8',
),
diff --git a/packages/playground/devEnv/home/ItemSectionWithPreviews.tsx b/packages/playground/devEnv/home/ItemSectionWithPreviews.tsx
new file mode 100644
index 0000000..8460828
--- /dev/null
+++ b/packages/playground/devEnv/home/ItemSectionWithPreviews.tsx
@@ -0,0 +1,130 @@
+import React from 'react'
+import styled from 'styled-components'
+
+export const ItemSectionWithPreviews = (props: {
+ groupName: string
+ modules: string[]
+}) => {
+ let {groupName, modules} = props
+ return (
+
+ {groupName}
+
+ {modules.map((moduleName) => {
+ const href = `/${groupName}/${moduleName}`
+ return (
+
+
+
+
+
+
+ {moduleName}
+ {href}
+
+
+
+ )
+ })}
+
+
+ )
+}
+
+const SectionHeader = styled.h3`
+ font-family: 'Inter', sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 19px;
+
+ text-transform: capitalize;
+
+ /* White/White50 */
+ color: rgba(255, 255, 255, 0.5);
+`
+
+const ItemDesc = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ padding: 8px 12px;
+ gap: 4px;
+
+ & > h3 {
+ margin: 0;
+
+ font-family: 'Inter', sans-serif;
+ font-style: normal;
+ font-weight: 600;
+ font-size: 15px;
+ line-height: 18px;
+
+ /* White/White80 */
+ color: rgba(255, 255, 255, 0.8);
+ }
+
+ & > p {
+ margin: 0;
+ font-weight: 400;
+ font-size: 13px;
+ line-height: 16px;
+ /* identical to box height, or 123% */
+ /* White/White60 */
+ color: rgba(255, 255, 255, 0.6);
+ }
+`
+
+const ItemContainer = styled.div`
+ /* display: inline-flex; */
+`
+
+const ItemListContainer = styled.div`
+ display: flex;
+ gap: 1rem;
+ flex-wrap: wrap;
+
+ margin-bottom: 2rem;
+`
+
+const PreviewContainer = styled.div`
+ --previewHeight: 450px;
+ --previewWidth: 800px;
+ --previewScale: 0.3;
+ position: relative;
+ overflow: hidden;
+ height: calc(var(--previewHeight) * var(--previewScale));
+ width: calc(var(--previewWidth) * var(--previewScale));
+
+ /* Neutral/Neutral800 */
+ background: rgba(33, 35, 39, 0.9);
+
+ &::after {
+ content: '';
+ position: absolute;
+ display: block;
+ z-index: 1;
+ top: 0;
+ left: 0;
+ height: calc(var(--previewHeight) * var(--previewScale));
+ width: calc(var(--previewWidth) * var(--previewScale));
+ }
+
+ iframe {
+ /* don't want original size of iframe affecting layout */
+ position: absolute;
+ transform-origin: top left;
+ transform: scale(var(--previewScale));
+ height: var(--previewHeight);
+ width: var(--previewWidth);
+ }
+`
+const ItemLink = styled.a`
+ border: 1px solid rgba(255, 255, 255, 0.08);
+ border-radius: 4px;
+ text-decoration: none;
+ overflow: hidden;
+
+ display: flex;
+ flex-direction: column;
+`
diff --git a/packages/playground/devEnv/home/PlaygroundHeader.tsx b/packages/playground/devEnv/home/PlaygroundHeader.tsx
new file mode 100644
index 0000000..3b1fcef
--- /dev/null
+++ b/packages/playground/devEnv/home/PlaygroundHeader.tsx
@@ -0,0 +1,124 @@
+import React from 'react'
+import styled from 'styled-components'
+
+const PlaygroundHeaderContainer = styled.div`
+ /* Auto layout */
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ flex-wrap: wrap;
+
+ padding: 1rem;
+
+ /* White/White8 */
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
+`
+const PlaygroundHeaderVersion = styled.div`
+ padding: 6px 16px;
+
+ background: rgba(34, 103, 99, 0.38);
+ border-radius: 30px;
+
+ font-family: 'Source Code Pro', 'Monaco', monospace;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 13px;
+ line-height: 17px;
+
+ /* Teal/Teal300 */
+ color: #64c4bf;
+`
+
+const HeaderGroup = styled.div`
+ /* Auto layout */
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+
+ gap: 12px;
+`
+
+const HeaderLink = styled.a`
+ font-family: 'Inter', sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 1;
+
+ text-decoration: none;
+ display: inline-flex;
+ padding: 0.5rem;
+
+ /* identical to box height, or 169% */
+
+ /* White/White100 */
+ color: #ffffff;
+
+ transition: color 0.2s ease-in;
+
+ &:hover,
+ &:focus {
+ /* Teal/Teal300 */
+ color: #64c4bf;
+ }
+`
+
+export function PlaygroundHeader(props: {
+ version?: {
+ displayText: string
+ linkHref?: string
+ }
+ links: {
+ label: string
+ href: string
+ }[]
+}) {
+ return (
+
+
+
+ {props.version && (
+
+ {props.version.displayText}
+
+ )}
+
+
+ {props.links.map((link) => (
+
+ {link.label}
+
+ ))}
+
+
+ )
+}
+
+const TheatreLogo = () => (
+
+)
diff --git a/packages/playground/devEnv/home/PlaygroundPage.tsx b/packages/playground/devEnv/home/PlaygroundPage.tsx
new file mode 100644
index 0000000..82f9ed1
--- /dev/null
+++ b/packages/playground/devEnv/home/PlaygroundPage.tsx
@@ -0,0 +1,67 @@
+import React from 'react'
+import styled, {StyleSheetManager} from 'styled-components'
+import {ItemSectionWithPreviews} from './ItemSectionWithPreviews'
+import {PlaygroundHeader} from './PlaygroundHeader'
+
+const HomeContainer = styled.div`
+ position: fixed;
+ inset: 0;
+ background: #1b1c1e;
+`
+const ContentContainer = styled.div`
+ padding: 0 5rem;
+
+ @media screen and (max-width: 920px) {
+ padding: 0 2rem;
+ }
+`
+
+const version = require('../../../../theatre/studio/package.json').version
+
+const PageTitleH1 = styled.h1`
+ padding: 1rem 0;
+`
+
+export const PlaygroundPage = ({
+ groups,
+}: {
+ groups: {[groupName: string]: string[]}
+}) => (
+
+
+
+
+ Playground
+ {Object.entries(groups).map(([groupName, modules]) => (
+
+ ))}
+
+
+
+)
diff --git a/packages/playground/devEnv/index.html b/packages/playground/devEnv/index.html
index 26c1d45..26f56ac 100644
--- a/packages/playground/devEnv/index.html
+++ b/packages/playground/devEnv/index.html
@@ -20,10 +20,7 @@
}
-
-
-