dev: Initial playground re-design (#218)

Improve the landing page for playground items.
This commit is contained in:
Cole Lawrence 2022-06-17 15:23:35 -04:00 committed by GitHub
parent df692427ca
commit 16e255fd57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 365 additions and 43 deletions

1
REMOVEME.md Normal file
View file

@ -0,0 +1 @@
file for testing commit

View file

@ -1,29 +0,0 @@
import React from 'react'
export const Home = ({groups}: {groups: {[groupName: string]: string[]}}) => (
<ul>
{Object.entries(groups).map(([groupName, modules]) => (
<li key={`li-${groupName}`}>
<span>{groupName}</span>
<Group
key={`group-${groupName}`}
groupName={groupName}
modules={modules}
/>
</li>
))}
</ul>
)
const Group = (props: {groupName: string; modules: string[]}) => {
const {groupName, modules} = props
return (
<ul>
{modules.map((moduleName) => (
<li key={`li-${moduleName}`}>
<a href={`/${groupName}/${moduleName}`}>{moduleName}</a>
</li>
))}
</ul>
)
}

View file

@ -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(/<body>[\s\S]*<\/body>/, `<body>${homeHtml}</body>`),
index
.replace(/<\/head>/, `${homeHtml.head}<\/head>`)
.replace(/<body>/, `<body>${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>/,
`<script src="${path.join(
'/',
path.relative(buildDir, outDir),
'index.js',
)}"></script></body>`,
),
'utf-8',
),

View file

@ -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 (
<section>
<SectionHeader>{groupName}</SectionHeader>
<ItemListContainer>
{modules.map((moduleName) => {
const href = `/${groupName}/${moduleName}`
return (
<ItemContainer key={`li-${moduleName}`}>
<ItemLink href={href}>
<PreviewContainer>
<iframe src={href} frameBorder="0" tabIndex={-1} />
</PreviewContainer>
<ItemDesc>
<h3>{moduleName}</h3>
<p>{href}</p>
</ItemDesc>
</ItemLink>
</ItemContainer>
)
})}
</ItemListContainer>
</section>
)
}
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;
`

View file

@ -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 (
<PlaygroundHeaderContainer>
<HeaderGroup>
<TheatreLogo />
{props.version && (
<PlaygroundHeaderVersion>
{props.version.displayText}
</PlaygroundHeaderVersion>
)}
</HeaderGroup>
<HeaderGroup>
{props.links.map((link) => (
<HeaderLink href={link.href} key={link.label} role="button">
{link.label}
</HeaderLink>
))}
</HeaderGroup>
</PlaygroundHeaderContainer>
)
}
const TheatreLogo = () => (
<svg
width="100"
height="25"
viewBox="0 0 100 25"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M97.9139 15.1557L93.3534 8.16702L93.3508 8.16288C92.6058 6.99457 92.2281 5.8335 92.2281 4.71175C92.2281 3.88544 92.4299 3.13727 92.7957 2.60433C93.2044 2.00879 93.7927 1.70714 94.544 1.70714C95.1235 1.70714 95.63 1.8722 96.0481 2.19713C96.4403 2.50189 96.7668 2.95203 97.0188 3.53516L97.0695 3.65364C97.0954 3.71366 97.1455 3.75971 97.2076 3.77989C97.2697 3.80007 97.3375 3.79283 97.3939 3.76023L97.5041 3.69555H97.5051L98.4556 3.13778L98.4572 3.13675L98.557 3.07776C98.6098 3.04672 98.6476 2.99601 98.6626 2.93703C98.6776 2.87804 98.6678 2.81544 98.6362 2.76318L98.5782 2.66797L98.5762 2.66487C97.7551 1.31029 96.3234 0.564697 94.544 0.564697C93.2515 0.564697 92.0842 1.00036 91.2564 1.79148C90.4264 2.58467 89.9696 3.70332 89.9696 4.94252C89.9696 6.51286 90.325 7.67755 91.2377 9.09733C91.2393 9.09992 91.2408 9.1025 91.2429 9.10509L95.7961 16.115L95.8008 16.1227C96.7564 17.5715 97.2211 18.8619 97.2211 20.0685C97.2211 21.0961 97.0022 21.955 96.5883 22.5521C96.1376 23.2025 95.4608 23.5326 94.5766 23.5326C93.6923 23.5326 92.969 23.1989 92.4749 22.5412C92.0195 21.9348 91.7686 21.0568 91.7686 20.068V19.2981C91.7686 19.1724 91.6667 19.0704 91.5409 19.0704H89.64C89.5142 19.0704 89.4123 19.1724 89.4123 19.2981V20.232C89.4123 22.7653 91.6325 24.675 94.5771 24.675C96.0409 24.675 97.2894 24.2104 98.1876 23.3308C99.0755 22.46 99.5453 21.2637 99.5453 19.8709C99.5453 18.3787 99.0118 16.8363 97.9149 15.1562L97.9139 15.1557Z" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M42.6037 23.9087L42.7273 24.0842C42.7765 24.154 42.7827 24.2451 42.7434 24.3206C42.704 24.3962 42.6264 24.4438 42.541 24.4438H39.8872C39.8112 24.4438 39.7403 24.406 39.6979 24.3429C39.656 24.2797 39.6477 24.1995 39.6767 24.1292L39.7413 23.9714C39.9447 23.4772 39.9385 23.1528 39.8541 22.7301C39.8532 22.7273 39.8527 22.7242 39.8522 22.7213L39.8521 22.7203L39.0175 18.1774H33.6493L33.1418 21.0128V21.0143L33.1252 21.107C33.1061 21.2156 33.0114 21.2948 32.9012 21.2948H32.2114C32.1437 21.2948 32.08 21.2653 32.0366 21.2136C31.9931 21.1618 31.975 21.0935 31.9869 21.0273L32.0107 20.8938L35.1607 3.04517C35.1612 3.04362 35.1617 3.04206 35.1617 3.04051C35.243 2.56811 35.2678 2.27371 35.2471 2.02535C35.2274 1.78941 35.1633 1.57417 35.0241 1.28183V1.28028L34.9475 1.11885C34.9139 1.04848 34.9191 0.965691 34.961 0.899463C35.0029 0.833234 35.0753 0.793393 35.1534 0.793393H36.8428C37.5548 0.793393 38.1896 1.34599 38.3252 2.08071C38.3262 2.08382 38.3267 2.08692 38.3273 2.09003L42.1328 22.5945C42.133 22.5953 42.1332 22.5961 42.1334 22.597C42.1339 22.5989 42.1344 22.601 42.1344 22.6028L42.1437 22.6592C42.2037 23.0245 42.272 23.4389 42.6016 23.9056L42.6037 23.9087ZM36.2902 3.49014L33.8713 17.0349H38.7945L36.2902 3.49014Z"
/>
<path d="M0.227661 0.793911H9.643C9.76873 0.793911 9.87066 0.895841 9.87066 1.02157V1.70921C9.87066 1.83494 9.76873 1.93687 9.643 1.93687H6.0651V22.6928C6.0651 22.9422 6.07286 23.1218 6.11115 23.3023C6.15099 23.4907 6.22705 23.6904 6.35743 23.9512L6.4397 24.1162C6.47489 24.1866 6.47075 24.2704 6.42935 24.3377C6.38796 24.4044 6.31449 24.4453 6.23584 24.4453H3.63585C3.55669 24.4453 3.48321 24.4044 3.44182 24.3372C3.40043 24.2699 3.39681 24.1861 3.43199 24.1152L3.51426 23.9501C3.64465 23.6899 3.72019 23.4902 3.76003 23.3023C3.79832 23.1212 3.80608 22.9417 3.80608 22.6923V1.93635H0.227661C0.10193 1.93635 0 1.83442 0 1.70869V1.02157C0 0.895841 0.10193 0.793911 0.227661 0.793911Z" />
<path d="M65.972 1.28856C66.1029 1.55037 66.179 1.75009 66.2183 1.93687C66.2566 2.11745 66.2644 2.29751 66.2644 2.54638V19.4921C66.2644 19.6179 66.3663 19.7198 66.492 19.7198H73.7415C73.8672 19.7198 73.9691 19.6179 73.9691 19.4921V18.8055C73.9691 18.6798 73.8672 18.5779 73.7415 18.5779H68.5229V9.05645H73.7415C73.8672 9.05645 73.9691 8.95452 73.9691 8.82879V8.14219C73.9691 8.01646 73.8672 7.91453 73.7415 7.91453H68.5229V1.93687H73.7415C73.8672 1.93687 73.9691 1.83494 73.9691 1.70921V1.02209C73.9691 0.896358 73.8672 0.794428 73.7415 0.794428H66.0936C66.0145 0.794428 65.9415 0.835304 65.8996 0.902567C65.8582 0.969831 65.8541 1.05365 65.8898 1.12402L65.972 1.28907V1.28856Z" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M74.7985 22.7648L75.0609 23.159L75.0603 23.1595L75.124 23.2558C75.1571 23.3065 75.1695 23.3686 75.1571 23.4281C75.1447 23.4876 75.1095 23.5398 75.0583 23.5729L74.9615 23.6356C74.961 23.6358 74.9604 23.6362 74.9597 23.6366L74.9589 23.6371C74.9585 23.6373 74.9582 23.6375 74.9579 23.6376C73.728 24.4344 72.2203 24.8385 70.4771 24.8385C68.5943 24.8385 67.1067 24.5074 65.7945 23.7965C64.5269 23.1099 63.3839 22.0419 62.1965 20.4359V20.4348C61.5859 19.6127 61.0851 18.8671 60.6432 18.2089L60.5169 18.0211C60.059 17.3397 59.6461 16.7369 59.2348 16.2588C58.8095 15.7652 58.408 15.4341 57.9728 15.2178C57.5154 14.9901 57.0074 14.8773 56.3823 14.8654V24.2171C56.3823 24.3429 56.2804 24.4448 56.1547 24.4448H54.352C54.2263 24.4448 54.1243 24.3429 54.1243 24.2171V2.54638C54.1243 2.29699 54.1166 2.11745 54.0783 1.93687C54.039 1.75009 53.9629 1.55037 53.832 1.28856L53.7497 1.1235C53.714 1.05313 53.7182 0.969313 53.7596 0.90205C53.8015 0.834786 53.8744 0.793911 53.9536 0.793911H56.9929C58.958 0.793911 60.594 1.44947 61.7241 2.68971C62.8448 3.92011 63.4372 5.69742 63.4372 7.82915C63.4372 11.019 61.9393 13.4539 59.464 14.4086C61.1699 15.2752 62.4759 16.9511 64.1559 19.2707L64.1606 19.2769C66.0993 21.9643 67.8709 23.6299 70.7079 23.6299C72.2498 23.6299 73.3307 23.3432 74.3225 22.6711H74.3236L74.4172 22.6075C74.4674 22.5733 74.5285 22.5609 74.5885 22.5723C74.648 22.5837 74.7008 22.6188 74.7344 22.669L74.7975 22.7632L74.7985 22.7648ZM56.5986 1.93687H56.3823V13.7214H56.5981C58.0701 13.7214 59.1965 13.1963 59.9468 12.1604C60.6768 11.1535 61.0468 9.78704 61.0468 7.82915C61.0468 5.87127 60.726 4.45201 60.0653 3.49066C59.3476 2.44497 58.2134 1.93687 56.5986 1.93687Z"
/>
<path d="M85.4277 0.793911H87.2314C87.3572 0.793911 87.4591 0.895841 87.4591 1.02157V19.7389C87.4591 21.1892 86.995 22.4202 86.1164 23.2987C85.2161 24.1985 83.9283 24.674 82.3926 24.674C80.6132 24.674 79.181 23.9284 78.3599 22.5738L78.2999 22.475C78.2683 22.4227 78.2585 22.3601 78.2735 22.3011C78.2885 22.2422 78.3263 22.1915 78.379 22.1604L78.4789 22.1014L78.481 22.1004L79.5417 21.4785C79.5981 21.4454 79.6658 21.4381 79.7279 21.4583C79.79 21.4785 79.8402 21.5245 79.8661 21.5845L79.9152 21.6989C79.9155 21.6997 79.9157 21.7003 79.916 21.701C79.9163 21.7016 79.9165 21.7022 79.9168 21.703C80.1693 22.2872 80.4963 22.7373 80.8875 23.0416C81.306 23.3665 81.8126 23.5316 82.3921 23.5316C83.4098 23.5316 84.1342 23.1373 84.6066 22.327C84.9947 21.6611 85.2001 20.7091 85.2001 19.5749V1.02157C85.2001 0.895841 85.302 0.793911 85.4277 0.793911Z" />
<path d="M35.5441 23.41H35.5436L35.2818 23.0493L35.2181 22.9608C35.1462 22.862 35.0091 22.8377 34.9072 22.9055L34.8187 22.9645L34.8166 22.966C34.472 23.1958 34.115 23.3023 33.6933 23.3023H26.4889V12.0098H31.9703C32.0961 12.0098 32.198 11.9079 32.198 11.7822V11.0951C32.198 10.9693 32.0961 10.8674 31.9703 10.8674H26.4889V1.93687H31.9703C32.0961 1.93687 32.198 1.83494 32.198 1.70921V1.02157C32.198 0.895841 32.0961 0.793911 31.9703 0.793911H24.0602C23.981 0.793911 23.908 0.834786 23.8661 0.90205C23.8242 0.969313 23.8206 1.05313 23.8563 1.1235L23.938 1.287V1.28856C24.0695 1.55037 24.1455 1.75009 24.1849 1.93635C24.2231 2.11745 24.2304 2.29751 24.2304 2.54638V24.2171C24.2304 24.3429 24.3323 24.4448 24.458 24.4448H33.8247C34.4808 24.4448 34.976 24.2756 35.4799 23.8798L35.5658 23.8115C35.6621 23.7359 35.6812 23.5973 35.6088 23.4984L35.5441 23.4094V23.41Z" />
<path d="M75.4334 23.2827C75.4334 22.5697 76.0134 21.9897 76.7264 21.9897C77.4399 21.9897 78.0199 22.5692 78.0199 23.2827C78.0199 23.9962 77.4394 24.5762 76.7264 24.5762C76.0134 24.5762 75.4334 23.9957 75.4334 23.2827Z" />
<path d="M21.4426 23.9501C21.3122 23.6899 21.2366 23.4896 21.1963 23.3023C21.158 23.1212 21.1507 22.9412 21.1507 22.6923V1.02157C21.1507 0.895841 21.0488 0.793911 20.9231 0.793911H19.1204C18.9947 0.793911 18.8928 0.895841 18.8928 1.02157V13.7214H13.4082V1.02157C13.4082 0.895841 13.3063 0.793911 13.1805 0.793911H11.3779C11.2521 0.793911 11.1502 0.895841 11.1502 1.02157V24.2171C11.1502 24.3429 11.2521 24.4448 11.3779 24.4448H13.1805C13.3063 24.4448 13.4082 24.3429 13.4082 24.2171V14.8644H18.8928V24.2171C18.8928 24.3429 18.9947 24.4448 19.1204 24.4448H21.3215C21.4007 24.4448 21.4736 24.4039 21.5155 24.3366C21.5569 24.2694 21.5611 24.1856 21.5253 24.1147L21.4431 23.9496L21.4426 23.9501Z" />
<path d="M42.8753 0.793911H52.2906C52.4164 0.793911 52.5183 0.895841 52.5183 1.02157V1.70921C52.5183 1.83494 52.4164 1.93687 52.2906 1.93687H48.7122V22.6923C48.7122 22.9412 48.72 23.1212 48.7583 23.3018C48.7981 23.4896 48.8742 23.6894 49.0046 23.9496L49.0056 23.9517L49.0868 24.1152C49.122 24.1856 49.1179 24.2694 49.0765 24.3366C49.0351 24.4034 48.9616 24.4443 48.883 24.4443H46.283C46.2038 24.4443 46.1303 24.4034 46.0889 24.3361C46.0475 24.2694 46.0439 24.1856 46.0791 24.1147L46.1614 23.9496C46.2918 23.6894 46.3678 23.4902 46.4071 23.3023C46.4454 23.1212 46.4532 22.9417 46.4532 22.6923V1.93635H42.8753C42.7496 1.93635 42.6476 1.83442 42.6476 1.70869V1.02157C42.6476 0.895841 42.7496 0.793911 42.8753 0.793911Z" />
</svg>
)

View file

@ -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[]}
}) => (
<StyleSheetManager disableVendorPrefixes>
<HomeContainer>
<PlaygroundHeader
version={{
displayText: version,
}}
links={[
{
label: 'Getting Started',
href: 'https://docs.theatrejs.com/getting-started/',
},
{
label: 'Docs',
href: 'https://docs.theatrejs.com/',
},
{
label: 'API',
href: 'https://docs.theatrejs.com/api/',
},
{
label: 'Github',
href: 'https://github.com/theatre-js/theatre',
},
]}
/>
<ContentContainer>
<PageTitleH1>Playground</PageTitleH1>
{Object.entries(groups).map(([groupName, modules]) => (
<ItemSectionWithPreviews
key={`group-${groupName}`}
groupName={groupName}
modules={modules}
/>
))}
</ContentContainer>
</HomeContainer>
</StyleSheetManager>
)

View file

@ -20,10 +20,7 @@
}
</style>
</head>
<body>
<div id="root"></div>
<script src="%ENTRYPOINT%"></script>
</body>
</html>