Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ yarn frontend
```

Open **http://127.0.0.1:4700**. The content watcher updates MDX and browser
TypeScript; the process watcher reloads changes to the runner, components, and theme.
TypeScript, and reloads the Studio plugin when it, a component, or the theme
changes; the process watcher restarts the server when PureStack's own sources change.

```sh
yarn frontend:build
Expand All @@ -23,14 +24,15 @@ yarn frontend:publish
- `frontend:publish` creates a clean, minified production artifact in
`frontend/out/purestack.studio/web`. This is a local build, not a deployment.
- Serve the production folder as a static website at `https://purestack.studio`.
- Use the site runner rather than invoking the generic CLI directly: the runner
registers the `studio` skin, composition components, template, and typed styles.
- Each command runs the `purestack` CLI. It loads `purestack.studio/purestack.config.ts`,
whose plugin registers the `studio` skin, composition components, template, and typed styles.

## Source map

| File | Purpose |
| --- | --- |
| `studio.ts` | Build/dev entry point and semantic HTML document template |
| `studioPlugin.ts` | The Studio plugin: skin, components, templates, styles, and generated previews |
| `purestack.studio/purestack.config.ts` | Adds the Studio plugin, so the CLI builds and serves the site |
| `demoStyle.ts` | Typed CSS for the real Style API workbench preview |
| `purestack.studio/index.mdx` | Landing page, source examples, and static component previews |
| `purestack.studio/header.mdx`, `footer.mdx` | Shared navigation and footer |
Expand Down
11 changes: 6 additions & 5 deletions frontend/docs/siteGuide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,9 @@ export async function writeSiteGuidePreviews(site: SiteConfig) {
index,
),
}))
const cards = samples
.map((sample) => {
const body = renderApp(sample.template, {
const cells = await Promise.all(
samples.map(async (sample) => {
const body = await renderApp(sample.template, {
components: defineComponents(getSvgIcon),
context: contextFor(site, sample),
})
Expand All @@ -332,8 +332,9 @@ export async function writeSiteGuidePreviews(site: SiteConfig) {
const isolated =
name === 'TopBar' || name === 'SignIn' || sample.signedIn
return `<section class="component-appearance-cell site-guide-sample"><code>${escapeAttribute(sample.label)}</code>${isolated ? `<iframe title="${escapeAttribute(sample.label)}" style="height:160px" srcdoc="${escapeAttribute(documentFor(site, inner, sample.signedIn))}"></iframe>` : body}</section>`
})
.join('')
}),
)
const cards = cells.join('')
const targets =
name === 'PageToc'
? '<section id="guide-intro"><h3>Introduction</h3><p>Outline links have real targets in this document.</p></section><section id="guide-detail"><h3>Details</h3><p>Nested entries link to supporting content.</p></section>'
Expand Down
6 changes: 3 additions & 3 deletions frontend/purestack.studio/components/site/consent/consent.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const exampleTemplate = html`<SectionHeader
Reset this example
</Btn>`

function createConsentPreviewDocument(site: SiteConfig): string {
async function createConsentPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -139,7 +139,7 @@ function createConsentPreviewDocument(site: SiteConfig): string {
],
services: [],
}
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -169,7 +169,7 @@ export async function writeConsentPreview(site: SiteConfig) {
'consent',
'preview.html',
)
const documentHtml = createConsentPreviewDocument(site)
const documentHtml = await createConsentPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/purestack.studio/components/site/consent/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const exampleTemplate = html`<SectionHeader
Reset this example
</Btn>`

function createConsentPreviewDocument(site: SiteConfig): string {
async function createConsentPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -104,7 +104,7 @@ function createConsentPreviewDocument(site: SiteConfig): string {
],
services: [],
}
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -134,7 +134,7 @@ export async function writeConsentPreview(site: SiteConfig) {
'consent',
'preview.html',
)
const documentHtml = createConsentPreviewDocument(site)
const documentHtml = await createConsentPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ const navMenuPreviewTemplate = html`<iframe
></iframe>`
const exampleTemplate = html`<NavMenu />`

function createNavMenuPreviewDocument(site: SiteConfig): string {
async function createNavMenuPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -512,7 +512,7 @@ function createNavMenuPreviewDocument(site: SiteConfig): string {
},
],
}
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -543,7 +543,7 @@ export async function writeNavMenuPreview(site: SiteConfig) {
'nav-menu',
'preview.html',
)
const documentHtml = createNavMenuPreviewDocument(site)
const documentHtml = await createNavMenuPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/purestack.studio/components/site/nav-menu/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const navMenuPreviewTemplate = html`<iframe
></iframe>`
const exampleTemplate = html`<NavMenu />`

function createNavMenuPreviewDocument(site: SiteConfig): string {
async function createNavMenuPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -79,7 +79,7 @@ function createNavMenuPreviewDocument(site: SiteConfig): string {
},
],
}
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -110,7 +110,7 @@ export async function writeNavMenuPreview(site: SiteConfig) {
'nav-menu',
'preview.html',
)
const documentHtml = createNavMenuPreviewDocument(site)
const documentHtml = await createNavMenuPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const exampleTemplate = html`<PageToc title="Example contents" />
<p>Keep headings descriptive and ordered.</p>
</section>`

function createPageTocPreviewDocument(site: SiteConfig): string {
async function createPageTocPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -106,7 +106,7 @@ function createPageTocPreviewDocument(site: SiteConfig): string {
children: [{ id: 'preview-contract', title: 'Contract', depth: 3 }],
},
]
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -135,7 +135,7 @@ export async function writePageTocPreview(site: SiteConfig) {
'page-toc',
'preview.html',
)
const documentHtml = createPageTocPreviewDocument(site)
const documentHtml = await createPageTocPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/purestack.studio/components/site/page-toc/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const exampleTemplate = html`<PageToc title="Example contents" />
<p>Keep headings descriptive and ordered.</p>
</section>`

function createPageTocPreviewDocument(site: SiteConfig): string {
async function createPageTocPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -71,7 +71,7 @@ function createPageTocPreviewDocument(site: SiteConfig): string {
children: [{ id: 'preview-contract', title: 'Contract', depth: 3 }],
},
]
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -100,7 +100,7 @@ export async function writePageTocPreview(site: SiteConfig) {
'page-toc',
'preview.html',
)
const documentHtml = createPageTocPreviewDocument(site)
const documentHtml = await createPageTocPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
6 changes: 3 additions & 3 deletions frontend/purestack.studio/components/site/sign-in/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const exampleTemplate = html`<Flex align="center" justify="between">
preview does not sign you in.
</p>`

function createSignInPreviewDocument(site: SiteConfig): string {
async function createSignInPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -72,7 +72,7 @@ function createSignInPreviewDocument(site: SiteConfig): string {
recordRuntimeEmbed: () => {},
}
context.site.auth = { ...context.site.auth, enabled: true, signUp: false }
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -101,7 +101,7 @@ export async function writeSignInPreview(site: SiteConfig) {
'sign-in',
'preview.html',
)
const documentHtml = createSignInPreviewDocument(site)
const documentHtml = await createSignInPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
6 changes: 3 additions & 3 deletions frontend/purestack.studio/components/site/sign-in/sign-in.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const exampleTemplate = html`<Flex align="center" justify="between">
preview does not sign you in.
</p>`

function createSignInPreviewDocument(site: SiteConfig): string {
async function createSignInPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -107,7 +107,7 @@ function createSignInPreviewDocument(site: SiteConfig): string {
recordRuntimeEmbed: () => {},
}
context.site.auth = { ...context.site.auth, enabled: true, signUp: false }
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -136,7 +136,7 @@ export async function writeSignInPreview(site: SiteConfig) {
'sign-in',
'preview.html',
)
const documentHtml = createSignInPreviewDocument(site)
const documentHtml = await createSignInPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/purestack.studio/components/site/top-bar/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const exampleTemplate = html`<TopBar tone="neutral" variant="surface" />
changes this preview.
</p>`

function createTopBarPreviewDocument(site: SiteConfig): string {
async function createTopBarPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -58,7 +58,7 @@ function createTopBarPreviewDocument(site: SiteConfig): string {
recordRuntimeEmbed: () => {},
}
context.site.pagefind = { ...context.site.pagefind, enabled: false }
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -87,7 +87,7 @@ export async function writeTopBarPreview(site: SiteConfig) {
'top-bar',
'preview.html',
)
const documentHtml = createTopBarPreviewDocument(site)
const documentHtml = await createTopBarPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
6 changes: 3 additions & 3 deletions frontend/purestack.studio/components/site/top-bar/top-bar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const exampleTemplate = html`<TopBar tone="neutral" variant="surface" />
changes this preview.
</p>`

function createTopBarPreviewDocument(site: SiteConfig): string {
async function createTopBarPreviewDocument(site: SiteConfig): Promise<string> {
const context: TsSsgContext = {
site: { ...site },
pageInfo: {
Expand Down Expand Up @@ -100,7 +100,7 @@ function createTopBarPreviewDocument(site: SiteConfig): string {
recordRuntimeEmbed: () => {},
}
context.site.pagefind = { ...context.site.pagefind, enabled: false }
const body = renderApp(exampleTemplate, {
const body = await renderApp(exampleTemplate, {
components: defineComponents(getSvgIcon),
context,
})
Expand Down Expand Up @@ -129,7 +129,7 @@ export async function writeTopBarPreview(site: SiteConfig) {
'top-bar',
'preview.html',
)
const documentHtml = createTopBarPreviewDocument(site)
const documentHtml = await createTopBarPreviewDocument(site)
await fs.mkdir(path.dirname(output), { recursive: true })
await fs.writeFile(output, documentHtml, 'utf8')
}
Expand Down
3 changes: 2 additions & 1 deletion frontend/purestack.studio/guides/_nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"utility-css-classes.mdx",
"semantic-tones.mdx",
"icons.mdx",
"themes.mdx"
"themes.mdx",
"plugins.mdx"
],
"items": [
{
Expand Down
7 changes: 6 additions & 1 deletion frontend/purestack.studio/guides/index.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Guides
description: Learn how to build and style a PureStack site with the CLI, site configuration, links, VS Code extension, Regor, typography, utility classes, semantic tones, icons, and themes.
description: Learn how to build and style a PureStack site with the CLI, site configuration, links, VS Code extension, Regor, typography, utility classes, semantic tones, icons, themes, and plugins.
template: doc
layout:
showNav: true
Expand Down Expand Up @@ -67,6 +67,11 @@ These guides follow the path from a content folder to a finished interface. Star
<p>Start with a skin, tune light and dark palettes, and add theme-aware styles.</p>
<BtnLink href="/guides/themes/" tone="accent" variant="link">Style a site</BtnLink>
</Panel>
<Panel tone="neutral" bodyClass="p-3">
<h2 class="mt-0">Plugins</h2>
<p>Add your own skin, components, page templates, and build steps as named plugins.</p>
<BtnLink href="./plugins" tone="accent" variant="link">Extend a site</BtnLink>
</Panel>
</Grid>

## Explore the building blocks
Expand Down
Loading
Loading