Skip to content

Commit d7ad7aa

Browse files
committed
Hardcoded components, theme, and page-scripts packages are now plugins.
1 parent 028e88f commit d7ad7aa

55 files changed

Lines changed: 1527 additions & 587 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/pull_request_template.md‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
## Change
1+
## Summary
22

3-
Describe the problem and resulting behavior. Link a related issue if applicable.
3+
Summarize the change.
44

5-
## Validation
5+
## Changes
6+
7+
Describe the changes.
68

7-
Describe the checks you ran and include screenshots for visible UI changes.
9+
## Validation
810

9-
- [ ] Relevant tests and documentation updated.
10-
- [ ] CI passes.
11-
- [ ] Required generated assets regenerated manually, if applicable.
11+
Describe the validation.

‎frontend/purestack.studio/guides/extending/plugins.mdx‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,33 @@ yarn purestack serve --content ./content
8989

9090
The badge appears on the page. Change its `tone` in `plugins/site.ts` while the server runs: the site rebuilds and the page reloads. `build` and `publish` load the same config, so the published site gets the same badge.
9191

92+
## Standard plugins
93+
94+
PureStack includes three plugins automatically in `build`, `serve`, and `publish`:
95+
96+
| Package | Factory | Provides |
97+
| --- | --- | --- |
98+
| `@purestack/ts-components` | `componentsPlugin()` | Standard components, icons, and component styles |
99+
| `@purestack/ts-theme` | `themePlugin()` | The `doc` and `splash` templates, generated theme CSS, and theme switching |
100+
| `@purestack/ts-page-scripts` | `pageScriptsPlugin()` | Auth hint, consent and analytics, menus, navigation, code copying, search, and TOC runtimes |
101+
102+
The stylesheet provider initializes before component factories, then all config hooks run in plugin order. Names do not affect initialization. Components belong to each build, so hooks can override them through `context.components`. The theme and page runtime plugins supply head templates that run before the selected page template, preserving its ability to inspect or change the completed head. The lifecycle hook set is unchanged.
103+
104+
To choose the standard integrations yourself, disable the automatic set and list the plugins you want. The factories are exported from `purestack`, `@purestack/ts-ssg`, and their individual packages:
105+
106+
```ts
107+
import { componentsPlugin, defineConfig, themePlugin } from 'purestack'
108+
109+
export default defineConfig({
110+
defaultPlugins: false,
111+
plugins: [themePlugin(), componentsPlugin()],
112+
})
113+
```
114+
115+
This keeps the layouts and components while omitting the page runtimes. Theme switching belongs to the theme plugin; component-specific Tabs and Modal embeds still follow the page's `embed` settings. Without the theme plugin, another plugin must supply your page templates and any CSS output you need.
116+
117+
An explicitly listed standard plugin replaces the automatic instance by name and keeps its initialization position. You can also use `createDefaultPlugins()` to obtain the complete set. In programmatic builds, use `options.defaultPlugins` alongside `options.plugins`.
118+
92119
## How the config loads
93120

94121
- **Where it lives.** The CLI looks for `purestack.config.ts` in the folder passed to `--content`. It must default-export `defineConfig({ plugins: [...] })`.
@@ -496,9 +523,12 @@ Every field except `name` is optional.
496523
| Field | Type |
497524
| --- | --- |
498525
| `name` | `string`, unique among the site's plugins |
526+
| `defaults` | `boolean`; makes component and template contributions overridable defaults without changing initialization order |
499527
| `skins` | Skins by name, each `{ create(): ThemeSkinPair }` |
500528
| `components` | `(config) => ({ [name]: component })` |
501529
| `templates` | Templates by name, each `(input) => TSNode<'html'>` |
530+
| `head` | `(input) => TSNode<'head'>`, or a promise; composes head markup before the page template |
531+
| `styles` | `(config) => SiteStyles`; one stylesheet provider, initialized before component factories |
502532
| `markdown` | `{ remarkPlugins?: PluggableList, rehypePlugins?: PluggableList }` |
503533
| `pages` | `({ config, files }) => { path, source }[]`, or a promise of them; `source` is the text, or a function that returns it |
504534
| `hooks` | Any of the hooks above |

‎frontend/purestack.studio/siteConfig.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "../../packages/ts-ssg/schema/siteConfig.schema.json",
2+
"$schema": "https://raw.githubusercontent.com/PureStackStudio/PureStack/refs/heads/main/packages/ts-ssg/schema/siteConfig.schema.json",
33
"siteTitle": "PureStack",
44
"favicon": "tabler:stack-2",
55
"style": {

‎packages/ts-common/src/index.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type {
1111
PageFrontmatter,
1212
ParsedFrontmatterSource,
1313
} from './frontmatter-types'
14+
export { isTocEnabled } from './isTocEnabled'
1415
export type {
1516
ClassicLogoConfig,
1617
LogoAppearance,
@@ -32,6 +33,7 @@ export type {
3233
PageNavigationLinks,
3334
} from './navMenu-types'
3435
export type {
36+
PageHeadTemplate,
3537
PageInfo,
3638
PageTemplate,
3739
PageTemplateInput,
@@ -62,6 +64,7 @@ export type {
6264
SiteStyleConfig,
6365
SiteStyleConfigInput,
6466
} from './site-config-types'
67+
export type { SiteStyles, WriteStylesResult } from './site-styles'
6568
export type {
6669
PageContext,
6770
PageOutlineItem,
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type { PageFrontmatter, PageOutlineItem } from '@purestack/ts-common'
1+
import type { PageFrontmatter } from './frontmatter-types'
2+
import type { PageOutlineItem } from './ts-ssg-context'
23

34
export function isTocEnabled(
45
frontmatter: PageFrontmatter,

‎packages/ts-common/src/page-template-types.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,8 @@ export type PageTemplate = (
3939
) => TSNode<'html'> | Promise<TSNode<'html'>>
4040

4141
export type PageTemplateMap = Record<string, PageTemplate>
42+
43+
/** Composes head markup before the page template receives it. */
44+
export type PageHeadTemplate = (
45+
input: PageTemplateInput,
46+
) => TSNode<'head'> | Promise<TSNode<'head'>>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { ThemeStylesheetLink } from '@purestack/ts-style'
2+
3+
export interface WriteStylesResult {
4+
revision: number
5+
outPath: string
6+
outputs: string[]
7+
signature: string
8+
}
9+
10+
/** A plugin's stylesheet output, initialized before component factories. */
11+
export interface SiteStyles {
12+
readonly revision: number
13+
links(cacheKey?: string): ThemeStylesheetLink[]
14+
write(input: {
15+
outDir: string
16+
cacheKey?: string
17+
}): Promise<WriteStylesResult>
18+
}

‎packages/ts-components/README.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,16 @@ by the static site generator and available to custom renderers.
88
`registerStyles()` adds its styles to PureStack's theme builder. Individual
99
component definitions and style registration functions are also exported when
1010
you need a smaller selection.
11+
12+
`componentsPlugin()` integrates these components, SVG icons, and their styles
13+
as default contributions scoped to each build. It is enabled by default by
14+
`@purestack/ts-ssg` and can also be imported from this package:
15+
16+
```ts
17+
import { componentsPlugin } from '@purestack/ts-components'
18+
```
19+
20+
Extension component factories and config hooks can override standard components
21+
through `context.components` and register styles. When choosing plugins explicitly with `defaultPlugins: false`,
22+
include `@purestack/ts-theme` to emit CSS, or supply your own style writer through
23+
`context.styles`.

‎packages/ts-components/package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"@purestack/ts-css": "workspace:^",
5555
"@purestack/ts-page-scripts": "workspace:^",
5656
"@purestack/ts-style": "workspace:^",
57+
"@purestack/ts-svg-icons": "workspace:^",
5758
"@purestack/ts-util": "workspace:^",
5859
"regor": "^1.7.5"
5960
},

‎packages/ts-components/src/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export type {
1515
TsSsgTabsApi,
1616
} from '@purestack/ts-page-scripts'
1717
export { defineComponents } from './defineComponents'
18+
export { componentsPlugin } from './plugin'
1819
export { registerStyles } from './registerStyles'
1920
export type { AlertBox } from './standard/alertBox/alertBox'
2021
export { defineAlertComponents } from './standard/alertBox/alertBox'

0 commit comments

Comments
 (0)