@tenphi/cookbook 0.18.1 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/components.d.ts +2 -2
- package/dist/components.js +1 -1
- package/dist/content.d.ts +1 -1
- package/dist/content.js +1 -1
- package/dist/eslint-plugin.d.ts +1 -1
- package/dist/eslint-plugin.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/styling.d.ts +1 -1
- package/dist/styling.js +1 -1
- package/docs/architecture.md +14 -10
- package/docs/comparison.md +129 -0
- package/docs/configuration.md +8 -22
- package/docs/content-sources.md +1 -1
- package/docs/customization-rules.md +2 -2
- package/docs/getting-started.md +1 -1
- package/docs/index.md +9 -8
- package/docs/migration.md +33 -2
- package/docs/plugins.md +65 -86
- package/docs/theme-and-components.md +40 -34
- package/docs/troubleshooting.md +7 -9
- package/package.json +4 -4
- package/docs/starlight-comparison.md +0 -124
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ See [Theme and components](./docs/theme-and-components.md) for all named
|
|
|
43
43
|
sub-elements and the custom component flow.
|
|
44
44
|
|
|
45
45
|
Without configuration, a root `README.md` becomes `/` and
|
|
46
|
-
`docs/**/*.{md,mdx}` supplies the remaining pages. Cookbook includes
|
|
46
|
+
`docs/**/*.{md,mdx}` supplies the remaining pages. Cookbook includes its Astro renderer,
|
|
47
47
|
generates only static output, and derives its URL base from Astro. Adding other
|
|
48
48
|
Astro content collections does not require a Cookbook collection adapter.
|
|
49
49
|
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { resolveDocsTheme } from "@tenphi/
|
|
2
|
+
import { resolveDocsTheme } from "@tenphi/renderer";
|
|
3
3
|
import { createDocsGraph, formatDiagnostics, materializePackage, normalizeDocsConfig, readDocsLock, reconcileDocsLock, resolveDocsProject, validateBuiltDocs, validateProjectAssets, writeDocsLock } from "@tenphi/docs";
|
|
4
4
|
import { cp, mkdir } from "node:fs/promises";
|
|
5
5
|
import { dirname, resolve } from "node:path";
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["import { cp, mkdir } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { parseArgs } from \"node:util\";\nimport {\n createDocsGraph,\n formatDiagnostics,\n materializePackage,\n normalizeDocsConfig,\n readDocsLock,\n reconcileDocsLock,\n resolveDocsProject,\n writeDocsLock,\n validateProjectAssets,\n validateBuiltDocs,\n type DocsDiagnostic,\n type DocsProject,\n} from \"@tenphi/docs\";\nimport { resolveDocsTheme } from \"@tenphi/starlight\";\n\nlet jsonOutput = process.argv.slice(2).includes(\"--json\");\n\ntry {\n const { positionals, values } = parseArgs({\n allowPositionals: true,\n options: {\n json: { type: \"boolean\", default: false },\n root: { type: \"string\" },\n config: { type: \"string\" },\n out: { type: \"string\" },\n url: { type: \"string\" },\n \"public-dir\": { type: \"string\" },\n \"dry-run\": { type: \"boolean\", default: false },\n help: { type: \"boolean\", short: \"h\", default: false },\n },\n });\n jsonOutput = values.json;\n if (values.help || positionals.length === 0) {\n printHelp();\n } else {\n const command = positionals[0];\n if (![\"doctor\", \"update\", \"check-build\"].includes(command!)) {\n throw new Error(`Unknown command: ${command ?? \"\"}.`);\n }\n if (command !== \"update\" && (positionals.length > 1 || values[\"dry-run\"])) {\n throw new Error(\n `${command} does not accept package selectors or --dry-run.`,\n );\n }\n if (command !== \"check-build\" && (values.out || values.url))\n throw new Error(\"--out and --url are only supported by check-build.\");\n if (values[\"public-dir\"] && command !== \"doctor\")\n throw new Error(\"--public-dir is only supported by doctor.\");\n const project = await resolveDocsProject({\n root: resolve(values.root ?? process.cwd()),\n ...(values.config ? { configFile: values.config } : {}),\n });\n if (command === \"doctor\")\n await doctor(\n project,\n values.json,\n values[\"public-dir\"]\n ? resolve(values.root ?? process.cwd(), values[\"public-dir\"])\n : resolve(values.root ?? process.cwd(), \"public\"),\n );\n else if (command === \"check-build\") {\n const graph = await createDocsGraph(project);\n const report = await validateBuiltDocs({\n directory: resolve(values.root ?? process.cwd(), values.out ?? \"dist\"),\n graph,\n ...(values.url ? { deployedUrl: values.url } : {}),\n });\n report.diagnostics.unshift(...graph.diagnostics);\n report.ok = !report.diagnostics.some((d) => d.severity === \"error\");\n if (values.json) console.log(JSON.stringify(report, null, 2));\n else {\n if (report.diagnostics.length)\n console.log(formatDiagnostics(report.diagnostics));\n console.log(\n `${report.ok ? \"Passed\" : \"Failed\"} ${report.scope} checks: ${report.pages} pages, ${report.assets} assets${report.checkedUrls ? `, ${report.checkedUrls} deployed URLs` : \"\"}.`,\n );\n }\n if (!report.ok) process.exitCode = 1;\n } else\n await update(\n project,\n positionals.slice(1),\n values.json,\n values[\"dry-run\"],\n );\n }\n} catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const diagnostics: DocsDiagnostic[] =\n error && typeof error === \"object\" && \"diagnostics\" in error\n ? (error.diagnostics as DocsDiagnostic[])\n : [{ code: \"COOKBOOK_CLI_ERROR\", severity: \"error\", message }];\n if (jsonOutput) {\n console.log(\n JSON.stringify({ ok: false, pages: 0, assets: 0, diagnostics }, null, 2),\n );\n } else {\n console.error(formatDiagnostics(diagnostics));\n }\n process.exitCode = 1;\n}\n\nasync function doctor(\n project: DocsProject,\n json: boolean,\n publicDirectory?: string,\n): Promise<void> {\n const theme = resolveDocsTheme(project.config.theme);\n const graph = await createDocsGraph(project);\n const diagnostics = [\n ...graph.diagnostics,\n ...theme.diagnostics,\n ...(await validateProjectAssets(project, graph, publicDirectory)),\n ];\n const hasErrors = diagnostics.some(\n (diagnostic) => diagnostic.severity === \"error\",\n );\n if (json) {\n console.log(\n JSON.stringify(\n {\n ok: !hasErrors,\n scope: \"preflight\",\n buildVerified: false,\n pages: graph.entries.length,\n assets: graph.assets.length,\n diagnostics,\n },\n null,\n 2,\n ),\n );\n } else if (diagnostics.length > 0) {\n console.log(formatDiagnostics(diagnostics));\n } else {\n console.log(\n `Preflight passed: ${graph.entries.length} pages, ${graph.assets.length} content assets. MDX compilation, remote fonts, and deployment are not checked. Run astro build and cookbook check-build.`,\n );\n }\n if (hasErrors) process.exitCode = 1;\n}\n\nasync function update(\n project: DocsProject,\n packages: string[],\n json: boolean,\n dryRun: boolean,\n): Promise<void> {\n const existing = await readDocsLock(project.root);\n const next = await reconcileDocsLock(project.config, existing, { packages });\n const changes = next.sources.map((source) => ({\n requested: source.requested,\n from:\n existing?.sources.find(\n (current) => current.requested === source.requested,\n )?.resolved ?? null,\n to: source.resolved,\n }));\n const removed =\n existing?.sources\n .filter(\n (source) =>\n !next.sources.some(\n (current) => current.requested === source.requested,\n ),\n )\n .map((source) => source.requested) ?? [];\n if (!dryRun) {\n const build = normalizeDocsConfig(project.config).build;\n for (const source of next.sources) {\n if (!source.vendored) continue;\n const current = existing?.sources.find(\n (entry) => entry.requested === source.requested,\n );\n if (\n current?.vendored === source.vendored &&\n current.integrity === source.integrity\n )\n continue;\n const { vendored, ...remote } = source;\n const artifact = await materializePackage(remote, build, project.root);\n const destination = resolve(project.root, vendored);\n await mkdir(dirname(destination), { recursive: true });\n await cp(artifact, destination, { recursive: true });\n }\n await writeDocsLock(project.root, next);\n }\n if (json) {\n console.log(\n JSON.stringify(\n {\n ok: true,\n pages: 0,\n assets: 0,\n diagnostics: [],\n dryRun,\n changes,\n removed,\n lock: next,\n },\n null,\n 2,\n ),\n );\n } else {\n for (const change of changes)\n console.log(\n `${change.requested}: ${change.from ?? \"(new)\"} -> ${change.to}`,\n );\n for (const source of removed) console.log(`Removed ${source}`);\n console.log(\n dryRun\n ? \"Dry run: cookbook.lock.json is unchanged.\"\n : \"Updated cookbook.lock.json.\",\n );\n }\n}\n\nfunction printHelp(): never {\n console.log(\n `Usage: cookbook <command> [options]\\n\\nCommands:\\n doctor Check configuration, content graph, theme, and local files\\n check-build Inspect production output and optionally deployed URLs\\n update [packages] Reconcile configured package sources and their lock\\n\\nOptions:\\n --root <directory>\\n --config <path>\\n --public-dir <directory> Local public assets for doctor (default: public)\\n --out <directory> Built output (default: dist)\\n --url <base-url> Also check a deployed site\\n --dry-run Preview an update without writing files\\n --json\\n -h, --help`,\n );\n process.exit(0);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["import { cp, mkdir } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { parseArgs } from \"node:util\";\nimport {\n createDocsGraph,\n formatDiagnostics,\n materializePackage,\n normalizeDocsConfig,\n readDocsLock,\n reconcileDocsLock,\n resolveDocsProject,\n writeDocsLock,\n validateProjectAssets,\n validateBuiltDocs,\n type DocsDiagnostic,\n type DocsProject,\n} from \"@tenphi/docs\";\nimport { resolveDocsTheme } from \"@tenphi/renderer\";\n\nlet jsonOutput = process.argv.slice(2).includes(\"--json\");\n\ntry {\n const { positionals, values } = parseArgs({\n allowPositionals: true,\n options: {\n json: { type: \"boolean\", default: false },\n root: { type: \"string\" },\n config: { type: \"string\" },\n out: { type: \"string\" },\n url: { type: \"string\" },\n \"public-dir\": { type: \"string\" },\n \"dry-run\": { type: \"boolean\", default: false },\n help: { type: \"boolean\", short: \"h\", default: false },\n },\n });\n jsonOutput = values.json;\n if (values.help || positionals.length === 0) {\n printHelp();\n } else {\n const command = positionals[0];\n if (![\"doctor\", \"update\", \"check-build\"].includes(command!)) {\n throw new Error(`Unknown command: ${command ?? \"\"}.`);\n }\n if (command !== \"update\" && (positionals.length > 1 || values[\"dry-run\"])) {\n throw new Error(\n `${command} does not accept package selectors or --dry-run.`,\n );\n }\n if (command !== \"check-build\" && (values.out || values.url))\n throw new Error(\"--out and --url are only supported by check-build.\");\n if (values[\"public-dir\"] && command !== \"doctor\")\n throw new Error(\"--public-dir is only supported by doctor.\");\n const project = await resolveDocsProject({\n root: resolve(values.root ?? process.cwd()),\n ...(values.config ? { configFile: values.config } : {}),\n });\n if (command === \"doctor\")\n await doctor(\n project,\n values.json,\n values[\"public-dir\"]\n ? resolve(values.root ?? process.cwd(), values[\"public-dir\"])\n : resolve(values.root ?? process.cwd(), \"public\"),\n );\n else if (command === \"check-build\") {\n const graph = await createDocsGraph(project);\n const report = await validateBuiltDocs({\n directory: resolve(values.root ?? process.cwd(), values.out ?? \"dist\"),\n graph,\n ...(values.url ? { deployedUrl: values.url } : {}),\n });\n report.diagnostics.unshift(...graph.diagnostics);\n report.ok = !report.diagnostics.some((d) => d.severity === \"error\");\n if (values.json) console.log(JSON.stringify(report, null, 2));\n else {\n if (report.diagnostics.length)\n console.log(formatDiagnostics(report.diagnostics));\n console.log(\n `${report.ok ? \"Passed\" : \"Failed\"} ${report.scope} checks: ${report.pages} pages, ${report.assets} assets${report.checkedUrls ? `, ${report.checkedUrls} deployed URLs` : \"\"}.`,\n );\n }\n if (!report.ok) process.exitCode = 1;\n } else\n await update(\n project,\n positionals.slice(1),\n values.json,\n values[\"dry-run\"],\n );\n }\n} catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const diagnostics: DocsDiagnostic[] =\n error && typeof error === \"object\" && \"diagnostics\" in error\n ? (error.diagnostics as DocsDiagnostic[])\n : [{ code: \"COOKBOOK_CLI_ERROR\", severity: \"error\", message }];\n if (jsonOutput) {\n console.log(\n JSON.stringify({ ok: false, pages: 0, assets: 0, diagnostics }, null, 2),\n );\n } else {\n console.error(formatDiagnostics(diagnostics));\n }\n process.exitCode = 1;\n}\n\nasync function doctor(\n project: DocsProject,\n json: boolean,\n publicDirectory?: string,\n): Promise<void> {\n const theme = resolveDocsTheme(project.config.theme);\n const graph = await createDocsGraph(project);\n const diagnostics = [\n ...graph.diagnostics,\n ...theme.diagnostics,\n ...(await validateProjectAssets(project, graph, publicDirectory)),\n ];\n const hasErrors = diagnostics.some(\n (diagnostic) => diagnostic.severity === \"error\",\n );\n if (json) {\n console.log(\n JSON.stringify(\n {\n ok: !hasErrors,\n scope: \"preflight\",\n buildVerified: false,\n pages: graph.entries.length,\n assets: graph.assets.length,\n diagnostics,\n },\n null,\n 2,\n ),\n );\n } else if (diagnostics.length > 0) {\n console.log(formatDiagnostics(diagnostics));\n } else {\n console.log(\n `Preflight passed: ${graph.entries.length} pages, ${graph.assets.length} content assets. MDX compilation, remote fonts, and deployment are not checked. Run astro build and cookbook check-build.`,\n );\n }\n if (hasErrors) process.exitCode = 1;\n}\n\nasync function update(\n project: DocsProject,\n packages: string[],\n json: boolean,\n dryRun: boolean,\n): Promise<void> {\n const existing = await readDocsLock(project.root);\n const next = await reconcileDocsLock(project.config, existing, { packages });\n const changes = next.sources.map((source) => ({\n requested: source.requested,\n from:\n existing?.sources.find(\n (current) => current.requested === source.requested,\n )?.resolved ?? null,\n to: source.resolved,\n }));\n const removed =\n existing?.sources\n .filter(\n (source) =>\n !next.sources.some(\n (current) => current.requested === source.requested,\n ),\n )\n .map((source) => source.requested) ?? [];\n if (!dryRun) {\n const build = normalizeDocsConfig(project.config).build;\n for (const source of next.sources) {\n if (!source.vendored) continue;\n const current = existing?.sources.find(\n (entry) => entry.requested === source.requested,\n );\n if (\n current?.vendored === source.vendored &&\n current.integrity === source.integrity\n )\n continue;\n const { vendored, ...remote } = source;\n const artifact = await materializePackage(remote, build, project.root);\n const destination = resolve(project.root, vendored);\n await mkdir(dirname(destination), { recursive: true });\n await cp(artifact, destination, { recursive: true });\n }\n await writeDocsLock(project.root, next);\n }\n if (json) {\n console.log(\n JSON.stringify(\n {\n ok: true,\n pages: 0,\n assets: 0,\n diagnostics: [],\n dryRun,\n changes,\n removed,\n lock: next,\n },\n null,\n 2,\n ),\n );\n } else {\n for (const change of changes)\n console.log(\n `${change.requested}: ${change.from ?? \"(new)\"} -> ${change.to}`,\n );\n for (const source of removed) console.log(`Removed ${source}`);\n console.log(\n dryRun\n ? \"Dry run: cookbook.lock.json is unchanged.\"\n : \"Updated cookbook.lock.json.\",\n );\n }\n}\n\nfunction printHelp(): never {\n console.log(\n `Usage: cookbook <command> [options]\\n\\nCommands:\\n doctor Check configuration, content graph, theme, and local files\\n check-build Inspect production output and optionally deployed URLs\\n update [packages] Reconcile configured package sources and their lock\\n\\nOptions:\\n --root <directory>\\n --config <path>\\n --public-dir <directory> Local public assets for doctor (default: public)\\n --out <directory> Built output (default: dist)\\n --url <base-url> Also check a deployed site\\n --dry-run Preview an update without writing files\\n --json\\n -h, --help`,\n );\n process.exit(0);\n}\n"],"mappings":"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"}
|
package/dist/components.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
import { Callout, Card, CodeGroup, Logo, Preview, Steps, Tab, Tabs } from "@tenphi/
|
|
3
|
-
export type * from "@tenphi/
|
|
2
|
+
import { Callout, Card, CodeGroup, Logo, Preview, Steps, Tab, Tabs } from "@tenphi/renderer/components";
|
|
3
|
+
export type * from "@tenphi/renderer/components";
|
|
4
4
|
export { Callout, Card, CodeGroup, Logo, Preview, Steps, Tab, Tabs };
|
package/dist/components.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Callout, Card, CodeGroup, Logo, Preview, Steps, Tab, Tabs } from "@tenphi/
|
|
2
|
+
import { Callout, Card, CodeGroup, Logo, Preview, Steps, Tab, Tabs } from "@tenphi/renderer/components";
|
|
3
3
|
export { Callout, Card, CodeGroup, Logo, Preview, Steps, Tab, Tabs };
|
package/dist/content.d.ts
CHANGED
package/dist/content.js
CHANGED
package/dist/eslint-plugin.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import eslint_plugin_default, { ResolvedConfig, StyleFunctionConfig, TastyValidationConfig, createValidationConfig, recommended, strict, validationConfig } from "@tenphi/
|
|
2
|
+
import eslint_plugin_default, { ResolvedConfig, StyleFunctionConfig, TastyValidationConfig, createValidationConfig, recommended, strict, validationConfig } from "@tenphi/renderer/eslint-plugin";
|
|
3
3
|
export { type ResolvedConfig, type StyleFunctionConfig, type TastyValidationConfig, createValidationConfig, eslint_plugin_default as default, recommended, strict, validationConfig };
|
package/dist/eslint-plugin.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import eslint_plugin_default, { createValidationConfig, recommended, strict, validationConfig } from "@tenphi/
|
|
2
|
+
import eslint_plugin_default, { createValidationConfig, recommended, strict, validationConfig } from "@tenphi/renderer/eslint-plugin";
|
|
3
3
|
export { createValidationConfig, eslint_plugin_default as default, recommended, strict, validationConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
import
|
|
2
|
+
import renderer_default, { CookbookOptions, DEFAULT_THEME_TOKENS, DEFAULT_TYPOGRAPHY_PRESETS } from "@tenphi/renderer";
|
|
3
3
|
import { BrandConfig, BrandDeclaration, BreadcrumbItem, BuildConfig, COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, COOKBOOK_PALETTE_NAMES, ComponentStyleConfig, ComponentStyles, ComponentStylesConfig, ComponentsConfig, ContentConfig, CookbookComponentName, CookbookComponentStyles, CookbookComponentSubElementName, DocsAsset, DocsConfig, DocsDiagnostic, DocsEntry, DocsFrontmatter, DocsGraph, DocsRoute, DocsSource, EditLinkConfig, FontLoadingConfig, HeadConfig, LocaleConfig, MarkdownConfig, NavigationConfig, NavigationItem, NavigationPlacement, NavigationTab, PageSeoConfig, SearchConfig, SiteConfig, SiteIconConfig, SiteLogoConfig, SiteSeoConfig, SiteVersion, SocialImage, TableOfContentsConfig, ThemeConfig, ThemeFont, ThemeFontFile, ThemeFonts, ThemePaletteColor, ThemePaletteConfig, ThemeTokenValue, ThemeTokens, TypographyPreset, TypographyPresets, defineDocsConfig, mergeDocsConfig } from "@tenphi/docs";
|
|
4
|
-
export { type BrandConfig, type BrandDeclaration, type BreadcrumbItem, type BuildConfig, COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, COOKBOOK_PALETTE_NAMES, type ComponentStyleConfig, type ComponentStyles, type ComponentStylesConfig, type ComponentsConfig, type ContentConfig, type CookbookComponentName, type CookbookComponentStyles, type CookbookComponentSubElementName, type CookbookOptions, DEFAULT_THEME_TOKENS, DEFAULT_TYPOGRAPHY_PRESETS, type DocsAsset, type DocsConfig, type DocsDiagnostic, type DocsEntry, type DocsFrontmatter, type DocsGraph, type DocsRoute, type DocsSource, type EditLinkConfig, type FontLoadingConfig, type HeadConfig, type LocaleConfig, type MarkdownConfig, type NavigationConfig, type NavigationItem, type NavigationPlacement, type NavigationTab, type PageSeoConfig, type SearchConfig, type SiteConfig, type SiteIconConfig, type SiteLogoConfig, type SiteSeoConfig, type SiteVersion, type SocialImage, type TableOfContentsConfig, type ThemeConfig, type ThemeFont, type ThemeFontFile, type ThemeFonts, type ThemePaletteColor, type ThemePaletteConfig, type ThemeTokenValue, type ThemeTokens, type TypographyPreset, type TypographyPresets,
|
|
4
|
+
export { type BrandConfig, type BrandDeclaration, type BreadcrumbItem, type BuildConfig, COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, COOKBOOK_PALETTE_NAMES, type ComponentStyleConfig, type ComponentStyles, type ComponentStylesConfig, type ComponentsConfig, type ContentConfig, type CookbookComponentName, type CookbookComponentStyles, type CookbookComponentSubElementName, type CookbookOptions, DEFAULT_THEME_TOKENS, DEFAULT_TYPOGRAPHY_PRESETS, type DocsAsset, type DocsConfig, type DocsDiagnostic, type DocsEntry, type DocsFrontmatter, type DocsGraph, type DocsRoute, type DocsSource, type EditLinkConfig, type FontLoadingConfig, type HeadConfig, type LocaleConfig, type MarkdownConfig, type NavigationConfig, type NavigationItem, type NavigationPlacement, type NavigationTab, type PageSeoConfig, type SearchConfig, type SiteConfig, type SiteIconConfig, type SiteLogoConfig, type SiteSeoConfig, type SiteVersion, type SocialImage, type TableOfContentsConfig, type ThemeConfig, type ThemeFont, type ThemeFontFile, type ThemeFonts, type ThemePaletteColor, type ThemePaletteConfig, type ThemeTokenValue, type ThemeTokens, type TypographyPreset, type TypographyPresets, renderer_default as default, defineDocsConfig, mergeDocsConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import renderer_default, { DEFAULT_THEME_TOKENS, DEFAULT_TYPOGRAPHY_PRESETS } from "@tenphi/renderer";
|
|
3
3
|
import { COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, COOKBOOK_PALETTE_NAMES, defineDocsConfig, mergeDocsConfig } from "@tenphi/docs";
|
|
4
|
-
export { COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, COOKBOOK_PALETTE_NAMES, DEFAULT_THEME_TOKENS, DEFAULT_TYPOGRAPHY_PRESETS,
|
|
4
|
+
export { COOKBOOK_COMPONENT_NAMES, COOKBOOK_COMPONENT_SUB_ELEMENTS, COOKBOOK_PALETTE_NAMES, DEFAULT_THEME_TOKENS, DEFAULT_TYPOGRAPHY_PRESETS, renderer_default as default, defineDocsConfig, mergeDocsConfig };
|
package/dist/styling.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import { Styles, defineComponent, mergeStyles, resolveComponentStyles, tasty, useGlobalStyles } from "@tenphi/
|
|
2
|
+
import { Styles, defineComponent, mergeStyles, resolveComponentStyles, tasty, useGlobalStyles } from "@tenphi/renderer/styling";
|
|
3
3
|
export { type Styles, defineComponent, mergeStyles, resolveComponentStyles, tasty, useGlobalStyles };
|
package/dist/styling.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { defineComponent, mergeStyles, resolveComponentStyles, tasty, useGlobalStyles } from "@tenphi/
|
|
2
|
+
import { defineComponent, mergeStyles, resolveComponentStyles, tasty, useGlobalStyles } from "@tenphi/renderer/styling";
|
|
3
3
|
export { defineComponent, mergeStyles, resolveComponentStyles, tasty, useGlobalStyles };
|
package/docs/architecture.md
CHANGED
|
@@ -8,17 +8,21 @@ sidebar:
|
|
|
8
8
|
Cookbook keeps content concerns separate from rendering so another renderer
|
|
9
9
|
can consume the same validated graph in the future.
|
|
10
10
|
|
|
11
|
+
Cookbook's early documentation experience was inspired by
|
|
12
|
+
[Astro Starlight](https://starlight.astro.build/). Its current renderer is
|
|
13
|
+
maintained in this repository.
|
|
14
|
+
|
|
11
15
|
## Packages
|
|
12
16
|
|
|
13
|
-
| Package | Responsibility
|
|
14
|
-
| ------------------------- |
|
|
15
|
-
| `@tenphi/create-cookbook` | Inspect an npm artifact and scaffold a reproducible documentation project
|
|
16
|
-
| `@tenphi/cookbook` | Provide the memorable Astro integration, public config exports, and CLI
|
|
17
|
-
| `@tenphi/docs` | Discover sources, resolve packages, build the content graph, transform Markdown, and report diagnostics
|
|
18
|
-
| `@tenphi/
|
|
17
|
+
| Package | Responsibility |
|
|
18
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
19
|
+
| `@tenphi/create-cookbook` | Inspect an npm artifact and scaffold a reproducible documentation project |
|
|
20
|
+
| `@tenphi/cookbook` | Provide the memorable Astro integration, public config exports, and CLI |
|
|
21
|
+
| `@tenphi/docs` | Discover sources, resolve packages, build the content graph, transform Markdown, and report diagnostics |
|
|
22
|
+
| `@tenphi/renderer` | Render the graph with Astro and provide the Tasty/Glaze theme, components, search, and static assets |
|
|
19
23
|
|
|
20
24
|
The `@tenphi/cookbook` default export represents the complete product. Consumers do
|
|
21
|
-
not compose
|
|
25
|
+
not compose renderer internals themselves.
|
|
22
26
|
|
|
23
27
|
## Build pipeline
|
|
24
28
|
|
|
@@ -28,7 +32,7 @@ not compose Starlight or renderer internals themselves.
|
|
|
28
32
|
4. Parse Markdown and collect headings, links, and assets.
|
|
29
33
|
5. Rewrite internal references through the completed route graph.
|
|
30
34
|
6. Reject unsafe paths and report strict diagnostics.
|
|
31
|
-
7. Render static pages through Astro and
|
|
35
|
+
7. Render static pages through Astro and Cookbook components.
|
|
32
36
|
8. Copy content-hashed assets and build the local Pagefind index.
|
|
33
37
|
|
|
34
38
|
Source documents are read-only throughout this process. The transformed body
|
|
@@ -44,7 +48,7 @@ Theme resolution has three deliberately separate layers:
|
|
|
44
48
|
2. The Glaze values, design tokens, typography presets, states, and units are
|
|
45
49
|
registered directly with Tasty.
|
|
46
50
|
3. Cookbook components use `tasty()` and the Tasty selector bridge styles DOM
|
|
47
|
-
owned by Astro,
|
|
51
|
+
owned by Astro, Pagefind, and rendered Markdown.
|
|
48
52
|
|
|
49
53
|
The palette owns color relationships. Components never choose raw light/dark
|
|
50
54
|
colors, and shape tokens never contain palette logic. This keeps a palette
|
|
@@ -78,7 +82,7 @@ for (const route of graph.routes) {
|
|
|
78
82
|
```
|
|
79
83
|
|
|
80
84
|
The graph exposes normalized entries, routes, assets, and structured
|
|
81
|
-
diagnostics without importing
|
|
85
|
+
diagnostics without importing the renderer.
|
|
82
86
|
|
|
83
87
|
## Reference app
|
|
84
88
|
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Compare documentation tools
|
|
3
|
+
description: Choose between Cookbook, documentation site builders, hosted docs, and generated API or component references.
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 2
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Two choices shape a documentation site: **how closely it should follow your
|
|
9
|
+
product's design system** and **where its content comes from**. Cookbook was
|
|
10
|
+
built for both. Its theme is configurable down to named component parts, and
|
|
11
|
+
its content can come from existing repository files or a published npm package.
|
|
12
|
+
Turning Markdown into pages is only one part of that workflow.
|
|
13
|
+
|
|
14
|
+
The comparisons below describe each tool's documented starting workflow, not
|
|
15
|
+
every integration its users could build. They are a selection of established
|
|
16
|
+
options, not a popularity ranking or an exhaustive list.
|
|
17
|
+
|
|
18
|
+
## Why choose Cookbook for customization?
|
|
19
|
+
|
|
20
|
+
Cookbook treats appearance as a supported configuration surface rather than a
|
|
21
|
+
set of selectors to override after rendering:
|
|
22
|
+
|
|
23
|
+
- Set one `theme.brand` color or define semantic `theme.palette` roles. Glaze
|
|
24
|
+
resolves them for light, dark, normal, and high-contrast modes, with contrast
|
|
25
|
+
targets and diagnostics.
|
|
26
|
+
- Configure shared `theme.tokens`, font roles, typography `theme.presets`, and
|
|
27
|
+
responsive `theme.states` once. Components consume those roles consistently.
|
|
28
|
+
- Change a built-in component through a **partial**
|
|
29
|
+
`theme.styles.<ComponentName>` Tasty object. Cookbook merges it into the full
|
|
30
|
+
base style before extracting CSS. Its [named component parts](./theme-and-components.md#style-customization)
|
|
31
|
+
are published so a header title, search field, or sidebar item can be changed
|
|
32
|
+
without copying an entire component.
|
|
33
|
+
- Add a styled component with `defineComponent()` or replace markup and behavior
|
|
34
|
+
through an Astro component override when the supported anatomy is not enough.
|
|
35
|
+
Tasty and Glaze run during the build; the browser receives static CSS, not
|
|
36
|
+
their styling runtimes.
|
|
37
|
+
|
|
38
|
+
For example, this changes the brand, a shared radius, heading typography, and
|
|
39
|
+
one part of the header while keeping the other default component styles:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { defineDocsConfig } from "@tenphi/cookbook/config";
|
|
43
|
+
|
|
44
|
+
export default defineDocsConfig({
|
|
45
|
+
theme: {
|
|
46
|
+
brand: { from: "#315efb" },
|
|
47
|
+
tokens: { $radius: "10px" },
|
|
48
|
+
presets: { heading: { fontWeight: 650 } },
|
|
49
|
+
styles: { Header: { SiteTitle: { preset: "h4 / strong" } } },
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This style contract is specific to Cookbook's Tasty and Glaze system. Structural
|
|
55
|
+
changes still require an Astro override. Read the [customization rules](./customization-rules.md)
|
|
56
|
+
and [theme reference](./theme-and-components.md) for the supported names and
|
|
57
|
+
the full design-system API.
|
|
58
|
+
|
|
59
|
+
## Start with the material you have
|
|
60
|
+
|
|
61
|
+
- **A repository `README.md` and `docs/` tree:** Start with
|
|
62
|
+
[Cookbook](./getting-started.md), [Starlight](https://starlight.astro.build/getting-started/),
|
|
63
|
+
[VitePress](https://vitepress.dev/guide/getting-started), or another site
|
|
64
|
+
builder. Choose the framework and editing workflow you prefer; Cookbook can
|
|
65
|
+
read the existing files in place.
|
|
66
|
+
- **Markdown inside a published npm package:**
|
|
67
|
+
[Cookbook's package source](./content-sources.md#npm-package-sources) reads
|
|
68
|
+
the published artifact, pins its version and integrity, and builds without
|
|
69
|
+
installing that package.
|
|
70
|
+
- **TypeScript exports and code comments:** [TypeDoc](https://typedoc.org/index.html)
|
|
71
|
+
generates reference pages from the code model and can use package entry
|
|
72
|
+
points.
|
|
73
|
+
- **UI components and their stories:** [Storybook Autodocs](https://storybook.js.org/docs/writing-docs)
|
|
74
|
+
documents components alongside rendered stories.
|
|
75
|
+
- **An OpenAPI specification:** Choose [Cookbook's static reference](./content-sources.md#openapi-references)
|
|
76
|
+
or a tool with an [interactive API playground](https://mintlify.com/docs/api-playground/overview)
|
|
77
|
+
if readers need to make requests from the docs.
|
|
78
|
+
|
|
79
|
+
## Compare complete documentation sites
|
|
80
|
+
|
|
81
|
+
All of these tools support visual customization. Their default content and
|
|
82
|
+
styling contracts differ:
|
|
83
|
+
|
|
84
|
+
| Tool and usual source | Documented customization path |
|
|
85
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| **Cookbook** — Astro site reading repository paths, locked npm artifacts, or local OpenAPI. | Semantic Glaze palette, Tasty tokens and presets, partial named component styles, and Astro overrides; extracted static CSS. |
|
|
87
|
+
| [**Starlight**](https://starlight.astro.build/guides/pages/) — Astro docs collection with [plugins](https://starlight.astro.build/reference/plugins/). | [CSS variables, custom CSS or Tailwind](https://starlight.astro.build/guides/css-and-tailwind/), themes, and component overrides. |
|
|
88
|
+
| [**Docusaurus**](https://docusaurus.io/docs/docs-introduction) — React/MDX docs with [version snapshots](https://docusaurus.io/docs/versioning). | [Infima variables and custom CSS](https://docusaurus.io/docs/styling-layout), plus [swizzled React components](https://docusaurus.io/docs/swizzling). |
|
|
89
|
+
| [**VitePress**](https://vitepress.dev/guide/what-is-vitepress) — Markdown site with Vue components. | [Theme config, CSS variables, Vue layout slots, or a custom theme](https://vitepress.dev/guide/extending-default-theme). |
|
|
90
|
+
| [**Nextra**](https://nextra.site/docs) — Next.js/React site with Markdown and MDX. | [Next.js CSS](https://nextra.site/docs/guide/custom-css) or a [custom React theme](https://nextra.site/docs/custom-theme). |
|
|
91
|
+
| [**Material for MkDocs**](https://squidfunk.github.io/mkdocs-material/getting-started/) — Python/MkDocs site with Markdown. | [Palette settings and CSS variables](https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/), [extra CSS and template overrides](https://squidfunk.github.io/mkdocs-material/customization/). |
|
|
92
|
+
| [**Mintlify**](https://mintlify.com/docs/quickstart) — Managed MDX and OpenAPI site with Git-connected deployment and a web editor. | [Prebuilt themes](https://mintlify.com/docs/themes), configuration for colors and fonts, and visual editing. |
|
|
93
|
+
|
|
94
|
+
The table compares documented approaches, not a ceiling on what each tool can
|
|
95
|
+
do. Choose the styling model you want to maintain. Cookbook's model is useful
|
|
96
|
+
when brand, typography, semantic colors, and component anatomy must move
|
|
97
|
+
together across the whole site. Starlight, Docusaurus, VitePress, Nextra, and
|
|
98
|
+
Material for MkDocs provide their own routes to theme or component changes;
|
|
99
|
+
Mintlify provides a managed editing and hosting workflow. Cookbook requires an
|
|
100
|
+
Astro build and a host for its static output. Starlight plugins target its own
|
|
101
|
+
APIs and do not run in Cookbook; see [Cookbook extensions](./plugins.md).
|
|
102
|
+
|
|
103
|
+
## When the package _is_ the source
|
|
104
|
+
|
|
105
|
+
“Package to website” can mean two different jobs:
|
|
106
|
+
|
|
107
|
+
1. **Publish the prose included in an npm release.** Cookbook reads the actual
|
|
108
|
+
tarball's selected `README.md` and Markdown files. Package MDX requires an
|
|
109
|
+
explicit trust opt-in before its code can run. `cookbook update`
|
|
110
|
+
records the requested specifier, resolved version, and integrity in
|
|
111
|
+
`cookbook.lock.json`; a production build uses that lock. This is useful when
|
|
112
|
+
the docs site should describe exactly what package consumers received. See
|
|
113
|
+
[package sources](./content-sources.md#npm-package-sources) and the
|
|
114
|
+
[package quick start](./getting-started.md#document-a-published-npm-package).
|
|
115
|
+
2. **Generate reference pages from source code.** [TypeDoc](https://typedoc.org/index.html)
|
|
116
|
+
reads TypeScript exports and comments, including entry points discovered
|
|
117
|
+
from `package.json`, and emits an HTML or JSON reference. It is the direct
|
|
118
|
+
choice when exported types and signatures are the documentation.
|
|
119
|
+
|
|
120
|
+
For a component library, [Storybook](https://storybook.js.org/docs/writing-docs)
|
|
121
|
+
is a separate option when the main experience should be runnable component
|
|
122
|
+
examples. TypeDoc or Storybook can complement a guide site; link to their output
|
|
123
|
+
from Cookbook navigation when each serves a different reader need.
|
|
124
|
+
|
|
125
|
+
Cookbook does not extract API signatures from TypeScript or provide an
|
|
126
|
+
interactive OpenAPI client. Its strengths are design system customization,
|
|
127
|
+
source-aware prose, validated links and assets, and a reproducible npm artifact
|
|
128
|
+
input. See [content sources](./content-sources.md) and
|
|
129
|
+
[theme and components](./theme-and-components.md) for the supported scope.
|
package/docs/configuration.md
CHANGED
|
@@ -185,13 +185,10 @@ path, not a generated content-collection path. Set `editUrl: false` or
|
|
|
185
185
|
sources show a timestamp only when their materialized file has Git history or
|
|
186
186
|
the page supplies one explicitly.
|
|
187
187
|
|
|
188
|
-
These settings
|
|
189
|
-
|
|
190
|
-
and
|
|
191
|
-
[`lastUpdated`](https://starlight.astro.build/reference/configuration/#lastupdated)
|
|
192
|
-
configuration while preserving Cookbook's original source paths.
|
|
188
|
+
These settings use Cookbook's original source paths when constructing links and
|
|
189
|
+
timestamps.
|
|
193
190
|
|
|
194
|
-
Cookbook also accepts
|
|
191
|
+
Cookbook also accepts page presentation frontmatter:
|
|
195
192
|
|
|
196
193
|
```yaml
|
|
197
194
|
tableOfContents:
|
|
@@ -227,7 +224,7 @@ discoverable on the next build. A draft URL is public; this is not access contro
|
|
|
227
224
|
|
|
228
225
|
## Languages
|
|
229
226
|
|
|
230
|
-
|
|
227
|
+
Configure Cookbook's multilingual routing and language picker:
|
|
231
228
|
|
|
232
229
|
```ts
|
|
233
230
|
locales: {
|
|
@@ -483,19 +480,9 @@ Configure renderer-level Markdown options such as custom remark or rehype
|
|
|
483
480
|
plugins and Shiki languages through Astro's top-level `markdown` configuration.
|
|
484
481
|
Cookbook preserves those settings while adding its own build-time transforms.
|
|
485
482
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
import myStarlightPlugin from "./plugins/my-starlight-plugin.js";
|
|
490
|
-
|
|
491
|
-
export default defineConfig({
|
|
492
|
-
integrations: [cookbook({ plugins: [myStarlightPlugin()] })],
|
|
493
|
-
});
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
Cookbook preserves custom metadata for route middleware and supports custom schemas.
|
|
497
|
-
See the [plugin compatibility guide](./plugins.md) for the tested ecosystem matrix,
|
|
498
|
-
content query API, Tasty adapters, and collection/style limitations.
|
|
483
|
+
Cookbook preserves custom metadata and supports custom schemas. See
|
|
484
|
+
[extending Cookbook](./plugins.md) for Astro Markdown plugins, native GitHub
|
|
485
|
+
alerts, the content query API, and styling limits.
|
|
499
486
|
|
|
500
487
|
Cookbook renders fenced `mermaid` blocks as responsive, theme-aware SVG during
|
|
501
488
|
the static build. Flowcharts, state, sequence, class, and entity-relationship
|
|
@@ -624,8 +611,7 @@ a 120ms slide transition; customize these through `theme.styles.Sidebar`.
|
|
|
624
611
|
### Translate Cookbook controls
|
|
625
612
|
|
|
626
613
|
Cookbook includes English and French interface messages. Other languages use
|
|
627
|
-
English for missing
|
|
628
|
-
translations. Override messages by language code; regional codes fall back to the
|
|
614
|
+
English for missing messages. Override messages by language code; regional codes fall back to the
|
|
629
615
|
base language and then English:
|
|
630
616
|
|
|
631
617
|
```ts
|
package/docs/content-sources.md
CHANGED
|
@@ -170,7 +170,7 @@ Package Markdown is untrusted by default. Raw HTML is sanitized to safe
|
|
|
170
170
|
elements, HTML-capable frontmatter is stripped, custom `head` entries are discarded,
|
|
171
171
|
unsafe URL protocols are rejected, and MDX cannot execute. Set `trust: "mdx"`
|
|
172
172
|
only after reviewing the exact locked artifact; doing so allows its build-time
|
|
173
|
-
code to run. Trusted MDX is compiled by
|
|
173
|
+
code to run. Trusted MDX is compiled by Astro, including relative component
|
|
174
174
|
imports from the source file's directory. Package-provided indexes, include
|
|
175
175
|
patterns, exclude patterns, and every discovered file are confined to the
|
|
176
176
|
extracted artifact root.
|
|
@@ -45,7 +45,7 @@ import { defineDocsConfig } from "@tenphi/cookbook/config";
|
|
|
45
45
|
export default defineDocsConfig({
|
|
46
46
|
theme: {
|
|
47
47
|
styles: {
|
|
48
|
-
|
|
48
|
+
Header: { SiteTitle: { preset: "h4 / strong" } },
|
|
49
49
|
},
|
|
50
50
|
},
|
|
51
51
|
});
|
|
@@ -68,7 +68,7 @@ integration or calling upstream `configure()` is unnecessary. Shared settings
|
|
|
68
68
|
belong in `docs.config.ts`.
|
|
69
69
|
|
|
70
70
|
* Express styles with Tasty. Do not add CSS files, CSS modules, Astro `<style>`
|
|
71
|
-
blocks, inline `style` attributes, or imported
|
|
71
|
+
blocks, inline `style` attributes, or imported component styles to customize
|
|
72
72
|
the documentation interface. The isolated content of `Preview` is a separate
|
|
73
73
|
demonstration surface.
|
|
74
74
|
* Model descendants and pseudo-elements as named sub-elements inside the
|
package/docs/getting-started.md
CHANGED
|
@@ -67,7 +67,7 @@ import cookbook from "@tenphi/cookbook";
|
|
|
67
67
|
export default defineConfig({ integrations: [cookbook()] });
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
Cookbook includes
|
|
70
|
+
Cookbook includes its Astro renderer and discovers `docs.config.ts` automatically.
|
|
71
71
|
With no documentation configuration, it uses README/docs conventions.
|
|
72
72
|
|
|
73
73
|
## Configure the site
|
package/docs/index.md
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Cookbook
|
|
3
|
-
description: Build a
|
|
3
|
+
description: Build a customizable static documentation site from the Markdown your project already owns.
|
|
4
4
|
template: splash
|
|
5
5
|
hero:
|
|
6
6
|
title: Documentation that stays with the code.
|
|
7
|
-
tagline: Turn repository Markdown or a locked npm package into
|
|
7
|
+
tagline: Turn repository Markdown or a locked npm package into an Astro docs site that fits your design system—without creating a second source of truth.
|
|
8
8
|
image:
|
|
9
9
|
html: '<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 64 64" aria-hidden="true"><rect width="64" height="64" rx="14" fill="currentColor"/><path fill="#fff" d="M14.8 16c6.7.2 12.3 2 16.7 5.4v28.4c-4.4-3.1-10-4.7-16.6-4.9a3 3 0 0 1-2.9-3V19a3 3 0 0 1 2.8-3Z"/><path fill="#fff" d="M49.2 16c-6.7.2-12.3 2-16.7 5.4v28.4c4.4-3.1 10-4.7 16.6-4.9a3 3 0 0 0 2.9-3V19a3 3 0 0 0-2.8-3Z"/></svg>'
|
|
10
10
|
actions:
|
|
11
11
|
- text: Get started
|
|
12
12
|
link: /getting-started/
|
|
13
13
|
variant: primary
|
|
14
|
-
- text:
|
|
15
|
-
link: /
|
|
14
|
+
- text: Compare tools
|
|
15
|
+
link: /comparison/
|
|
16
16
|
variant: secondary
|
|
17
17
|
sidebar:
|
|
18
18
|
order: 1
|
|
@@ -20,7 +20,7 @@ sidebar:
|
|
|
20
20
|
## Keep documentation close to its source
|
|
21
21
|
|
|
22
22
|
Cookbook combines [Astro](https://astro.build) and
|
|
23
|
-
|
|
23
|
+
an Astro renderer with repository-aware content,
|
|
24
24
|
strict validation, local Pagefind search, and a theme powered by
|
|
25
25
|
[Tasty](./upstream/tasty/README.md) and [Glaze](./upstream/glaze/README.md).
|
|
26
26
|
|
|
@@ -42,8 +42,8 @@ for GitHub Pages or any static host.
|
|
|
42
42
|
|
|
43
43
|
### Styling that fits your product
|
|
44
44
|
|
|
45
|
-
Glaze turns a brand and semantic palette into light, dark, and high-contrast
|
|
46
|
-
colors with contrast targets. Tasty applies those color roles alongside shared
|
|
45
|
+
[Glaze](./upstream/glaze/README.md) turns a brand and semantic palette into light, dark, and high-contrast
|
|
46
|
+
colors with contrast targets. [Tasty](./upstream/tasty/README.md) applies those color roles alongside shared
|
|
47
47
|
tokens and typography presets, so the docs can follow your design system.
|
|
48
48
|
State maps keep hover, focus, and responsive values beside the styles they
|
|
49
49
|
change. Partial `theme.styles` overrides merge before CSS extraction, letting
|
|
@@ -57,11 +57,12 @@ states, and named component styles.
|
|
|
57
57
|
| I want to… | Start here | Then read |
|
|
58
58
|
| ------------------------------------ | --------------------------------------- | --------------------------------------------------------------------- |
|
|
59
59
|
| Start a site | [Getting started](./getting-started.md) | [Validate and deploy](./deployment.md) |
|
|
60
|
+
| Choose a documentation tool | [Compare tools](./comparison.md) | [Getting started](./getting-started.md) |
|
|
60
61
|
| Have an agent set it up | [AI agent workflow](./ai-agents.md) | [Customization rules](./customization-rules.md) |
|
|
61
62
|
| Bring existing Markdown or an API | [Content sources](./content-sources.md) | [Working examples](./examples.md) |
|
|
62
63
|
| Write pages and interactive examples | [Authoring](./authoring.mdx) | [Mobile contents and hero images](./authoring.mdx#on-page-navigation) |
|
|
63
64
|
| Change brand, fonts, or logo | [Configuration recipes](./recipes.md) | [Theme reference](./theme-and-components.md) |
|
|
64
|
-
| Add a
|
|
65
|
+
| Add a Markdown extension | [Extend Cookbook](./plugins.md) | [Architecture](./architecture.md) |
|
|
65
66
|
| Publish for people and agents | [Deployment](./deployment.md) | [Publishing metadata](./publishing.md) |
|
|
66
67
|
| Update or fix an existing site | [Upgrade Cookbook](./migration.md) | [Troubleshooting](./troubleshooting.md) |
|
|
67
68
|
|
package/docs/migration.md
CHANGED
|
@@ -38,9 +38,40 @@ upgrade the site's Cookbook runtime or package-manager dependencies. Commit the
|
|
|
38
38
|
documentation lock separately when intentionally updating imported content.
|
|
39
39
|
Local Markdown needs no lock update.
|
|
40
40
|
|
|
41
|
+
## 0.18.x to 0.19
|
|
42
|
+
|
|
43
|
+
Cookbook now renders documentation with its own Astro components. The public
|
|
44
|
+
`@tenphi/cookbook` integration remains the normal entry point. Projects that
|
|
45
|
+
import the renderer package directly should replace `@tenphi/starlight` with
|
|
46
|
+
`@tenphi/renderer`.
|
|
47
|
+
|
|
48
|
+
The page and theme contracts remain familiar, but component overrides now read
|
|
49
|
+
`Astro.locals.cookbookRoute`. Replace uses of `Astro.locals.starlightRoute` in
|
|
50
|
+
your own overrides. The named style surfaces `StarlightHeader` and
|
|
51
|
+
`StarlightAside` become `Header` and `MarkdownAlert`; the unused Starlight card,
|
|
52
|
+
link-card, badge, and steps bridges are removed. Cookbook's `Card`, `Callout`,
|
|
53
|
+
and `Steps` components remain available.
|
|
54
|
+
|
|
55
|
+
Renderer class names now use Cookbook-owned names. Update any custom CSS or
|
|
56
|
+
scripts that target generated markup, and prefer the named `theme.styles`
|
|
57
|
+
surfaces in the [theme reference](./theme-and-components.md).
|
|
58
|
+
|
|
59
|
+
The `plugins` integration option no longer forwards Starlight hooks. Move
|
|
60
|
+
content transforms to Astro's `markdown` configuration and use
|
|
61
|
+
`frontmatterSchema` for custom page metadata. GitHub alert blockquotes render
|
|
62
|
+
directly in Markdown and MDX, so `starlight-github-alerts` is no longer needed.
|
|
63
|
+
Use `cookbook doctor` and `cookbook check-build` instead of plugins that inspect
|
|
64
|
+
Starlight's content collection or physical docs files. See
|
|
65
|
+
[extending Cookbook](./plugins.md) for examples.
|
|
66
|
+
|
|
67
|
+
Build and preview each site after updating its package manifest. Check custom
|
|
68
|
+
component overrides, locale navigation, search, and Tasty style names before
|
|
69
|
+
deploying. Cookbook-saved appearance choices remain. Older Starlight-only
|
|
70
|
+
choices are ignored; visitors who relied on one can select their scheme again.
|
|
71
|
+
|
|
41
72
|
## 0.17.x to 0.18
|
|
42
73
|
|
|
43
|
-
These changes
|
|
74
|
+
These changes were introduced in 0.18:
|
|
44
75
|
|
|
45
76
|
- **Google fonts:** family-name shorthand loads preset weights and italics and
|
|
46
77
|
self-hosts the files. The initial build requires network access. Preserve the
|
|
@@ -63,7 +94,7 @@ These changes are included in the next minor release:
|
|
|
63
94
|
- **Plugins:** custom metadata is available to route middleware and through
|
|
64
95
|
Cookbook's content API. Plugins that need Astro's synthetic content files or
|
|
65
96
|
inject their own CSS require adaptation. See the tested
|
|
66
|
-
[
|
|
97
|
+
[extension guide](./plugins.md).
|
|
67
98
|
- **Styles:** rendered inline styles are rejected. Move custom styling to Tasty
|
|
68
99
|
and registered theme style trees. Keep these components server-rendered;
|
|
69
100
|
browser scripts and `client:*` islands cannot import Cookbook styling, Tasty,
|
package/docs/plugins.md
CHANGED
|
@@ -1,120 +1,99 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
2
|
+
title: Extend Cookbook
|
|
3
|
+
description: Add Markdown transforms, validate custom metadata, and query the content graph.
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 7
|
|
3
6
|
---
|
|
4
7
|
|
|
5
|
-
Cookbook
|
|
8
|
+
Cookbook renders with Astro and accepts Astro Markdown integrations. Configure
|
|
9
|
+
remark and rehype plugins in `astro.config.ts`; Cookbook adds its own transforms
|
|
10
|
+
to the same processor. Extensions that emit CSS must be adapted to Tasty because
|
|
11
|
+
the finished site ships only Tasty-generated styles.
|
|
6
12
|
|
|
7
|
-
```
|
|
8
|
-
import
|
|
9
|
-
import githubAlerts from "starlight-github-alerts";
|
|
13
|
+
```ts
|
|
14
|
+
import { defineConfig } from "astro/config";
|
|
10
15
|
import { unified } from "@astrojs/markdown-remark";
|
|
16
|
+
import cookbook from "@tenphi/cookbook";
|
|
17
|
+
import myRemarkPlugin from "./plugins/my-remark-plugin.js";
|
|
11
18
|
|
|
12
|
-
export default {
|
|
13
|
-
markdown: { processor: unified() },
|
|
14
|
-
integrations: [cookbook(
|
|
15
|
-
};
|
|
19
|
+
export default defineConfig({
|
|
20
|
+
markdown: { processor: unified({ remarkPlugins: [myRemarkPlugin] }) },
|
|
21
|
+
integrations: [cookbook()],
|
|
22
|
+
});
|
|
16
23
|
```
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
plugins' peer dependency ranges when upgrading. See [configuration](./configuration.md)
|
|
20
|
-
for Astro Markdown hooks and [customization](./theme-and-components.md) for styling.
|
|
25
|
+
## GitHub alerts
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
Cookbook renders GitHub alert blockquotes in Markdown and MDX without an extra
|
|
28
|
+
plugin. `NOTE`, `TIP`, `IMPORTANT`, `WARNING`, and `CAUTION` map to the semantic
|
|
29
|
+
note, tip, caution, and danger surfaces. For example:
|
|
23
30
|
|
|
24
|
-
The
|
|
25
|
-
pinned Astro and Starlight versions. Compatibility with other versions is not implied.
|
|
31
|
+
The default Astro integration is sufficient for alert rendering:
|
|
26
32
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
| `starlight-github-alerts` | 0.4.0 | With `unified()`, Markdown and MDX alert syntax uses Cookbook's Tasty `StarlightAside` adapter. |
|
|
30
|
-
| `starlight-links-validator` | 0.26.0 | Incompatible with mounted sources: error reporting assumes physical `src/content/docs` files. Cookbook rejects it with a diagnostic. |
|
|
31
|
-
| Route middleware and `i18n:setup` | Starlight 0.42.4 | Custom metadata, body, file path, and translations survive in real consumer builds with locales and a base path. |
|
|
32
|
-
| Plugins requiring `astro:content`'s `docs` collection | — | Cookbook's renderer uses its own graph. Adapt to the content API below; no native collection is populated automatically. |
|
|
33
|
-
| Plugins supplying CSS, styled Astro components, or Expressive Code | — | Require an adapter built with Tasty. The build rejects incompatible output. |
|
|
34
|
-
|
|
35
|
-
GitHub Alerts 0.4.0 assumes an older Sätteri plugin structure and silently skips
|
|
36
|
-
alerts with Starlight 0.42.4's default processor. Cookbook rejects that combination
|
|
37
|
-
with a configuration hint. Use `unified()` as above, or Starlight's native
|
|
38
|
-
`:::note` / `:::tip` directives with the default processor.
|
|
33
|
+
```js cookbook-verify=github-alerts
|
|
34
|
+
import cookbook from "@tenphi/cookbook";
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
and `FirstContent`. Styles merge into the full owned tree; the plugin's stylesheet
|
|
43
|
-
is unnecessary. All supported appearance modes use the Glaze palette.
|
|
36
|
+
export default { integrations: [cookbook()] };
|
|
37
|
+
```
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
but fails while reporting broken links because it tries to read synthesized
|
|
47
|
-
`src/content/docs` paths. Its middleware also cannot add previously absent links
|
|
48
|
-
to its validation store. Use Cookbook's doctor and built-output checks for mounted
|
|
49
|
-
sources. Plugins that depend on native collection IDs or mutate routing after
|
|
50
|
-
graph creation need a Cookbook-specific adapter.
|
|
39
|
+
Write the alert in a Markdown or MDX page:
|
|
51
40
|
|
|
52
|
-
|
|
41
|
+
```md
|
|
42
|
+
> [!TIP]
|
|
43
|
+
> Keep source documentation next to the code it describes.
|
|
44
|
+
```
|
|
53
45
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
only if your site does not use custom metadata.
|
|
46
|
+
Customize the result through `theme.styles.MarkdownAlert`. Its named
|
|
47
|
+
sub-elements are `Note`, `Tip`, `Caution`, `Danger`, `Title`, and
|
|
48
|
+
`FirstContent`.
|
|
58
49
|
|
|
59
|
-
|
|
50
|
+
## Custom frontmatter
|
|
60
51
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
52
|
+
Unknown frontmatter fields can be preserved as JSON metadata. Set
|
|
53
|
+
`content.frontmatter: "preserve"`, then validate or add custom fields with
|
|
54
|
+
`frontmatterSchema`:
|
|
64
55
|
|
|
65
|
-
|
|
56
|
+
```ts
|
|
57
|
+
export default defineConfig({
|
|
66
58
|
integrations: [
|
|
67
59
|
cookbook({
|
|
68
|
-
frontmatterSchema:
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
frontmatterSchema: {
|
|
61
|
+
parse(metadata) {
|
|
62
|
+
return { ...metadata, owner: metadata.owner ?? "maintainers" };
|
|
63
|
+
},
|
|
64
|
+
},
|
|
71
65
|
}),
|
|
72
66
|
],
|
|
73
|
-
};
|
|
67
|
+
});
|
|
74
68
|
```
|
|
75
69
|
|
|
76
|
-
The schema receives
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
and `aliases` belong in source frontmatter and cannot be set by this schema.
|
|
80
|
-
A schema cannot change routing or discovery after the graph is built.
|
|
70
|
+
The schema receives only custom metadata. It cannot change route, title, draft,
|
|
71
|
+
or other reserved page fields. Returned values must be JSON-safe because the
|
|
72
|
+
renderer passes them through a build-time virtual module.
|
|
81
73
|
|
|
82
|
-
|
|
83
|
-
and the actual source location in `entry.filePath`. Presentation changes made by
|
|
84
|
-
middleware do not update the graph, sitemap, or agent text. Put shared publishing
|
|
85
|
-
metadata in source configuration so every output agrees.
|
|
74
|
+
## Read the content graph
|
|
86
75
|
|
|
87
|
-
|
|
76
|
+
Server-rendered Astro components can query the validated graph:
|
|
88
77
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
```js
|
|
78
|
+
```ts
|
|
92
79
|
import {
|
|
93
80
|
getCookbookCollection,
|
|
94
81
|
getCookbookEntry,
|
|
95
82
|
} from "@tenphi/cookbook/content";
|
|
96
83
|
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
const page = getCookbookEntry("/guide");
|
|
84
|
+
const visiblePages = getCookbookCollection();
|
|
85
|
+
const guide = getCookbookEntry("/guide");
|
|
100
86
|
```
|
|
101
87
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
-
|
|
113
|
-
|
|
114
|
-
- **Inline styles or external stylesheet in built output:** replace that visual
|
|
115
|
-
component with owned markup styled through `tasty()` and registered
|
|
116
|
-
`theme.styles` anatomy. See [customization rules](./customization-rules.md).
|
|
117
|
-
- **Empty `getCollection("docs")`:** use the Cookbook content API above. Cookbook
|
|
118
|
-
does not create a second, potentially conflicting Starlight content collection.
|
|
119
|
-
- **Missing custom field:** keep `content.frontmatter` at its default `"preserve"`,
|
|
120
|
-
validate its shape, and read it after the Cookbook route bridge has run.
|
|
88
|
+
Queries return snapshots. Drafts are omitted from the collection by default;
|
|
89
|
+
`getCookbookEntry()` can retrieve one by its exact route. The same API is
|
|
90
|
+
available at `@tenphi/renderer/content` for renderer-only projects.
|
|
91
|
+
|
|
92
|
+
Component overrides receive page data from `Astro.locals.cookbookRoute`,
|
|
93
|
+
including the current entry, locale, navigation, table of contents, and head
|
|
94
|
+
tags. See [theme and components](./theme-and-components.md) for Tasty styling
|
|
95
|
+
and [configuration](./configuration.md) for structural overrides.
|
|
96
|
+
|
|
97
|
+
Use Astro's Markdown plugin APIs for content transforms, and Cookbook's graph
|
|
98
|
+
and built-output checks for link validation. Extensions tied to another
|
|
99
|
+
renderer need an adapter built against Cookbook's APIs.
|
|
@@ -125,13 +125,13 @@ Cookbook keeps literal surface seeds desaturated in the dark scheme so a nearly
|
|
|
125
125
|
white tint does not become vivid dark chrome when its tone is inverted.
|
|
126
126
|
|
|
127
127
|
Components consume semantic colors consistently: `surface`, `header`, `surface-2`,
|
|
128
|
-
`surface-3`, `text`, `heading`, `text-soft`, `border`, `border-strong`, `accent-text`,
|
|
128
|
+
`surface-3`, `text`, `heading`, `text-soft`, `sidebar-text`, `border`, `border-strong`, `accent-text`,
|
|
129
129
|
`accent-surface`, `accent-surface-text`, `logo-surface`, `logo-mark`, and `focus`.
|
|
130
130
|
Tasty components can use these as `#surface`, `#text`, `#border`, and so on; the Astro shell consumes the
|
|
131
131
|
same resolved values. Glaze also generates hover and pressed states, subtle
|
|
132
132
|
accent fills, overlays, shadows, and the orange, green, blue, purple, and red
|
|
133
|
-
roles used by
|
|
134
|
-
|
|
133
|
+
roles used by Cookbook content components. No browser color mixes or
|
|
134
|
+
upstream fallback palette values participate in the rendered theme. Surface
|
|
135
135
|
elevation uses Glaze's contrast-uniform tone axis: `surface-2` advances two tone
|
|
136
136
|
steps and `surface-3` advances four from the base surface, with proportionally
|
|
137
137
|
wider steps in high-contrast mode. Their saturation also steps down to 75% and
|
|
@@ -145,7 +145,7 @@ change border tone, not that restrained saturation relationship.
|
|
|
145
145
|
The Appearance button in the desktop and mobile header opens one panel with
|
|
146
146
|
Color scheme and Contrast sections. Color scheme offers Light, Dark, and Auto;
|
|
147
147
|
Contrast offers Normal, High, and Auto. Each preference is independent, and
|
|
148
|
-
|
|
148
|
+
selections are saved in the browser. The panel supports keyboard navigation,
|
|
149
149
|
Escape, and outside-click dismissal. The popover fades and scales vertically
|
|
150
150
|
from 96% to 100% over 120ms using native entry and exit transitions. Reduced
|
|
151
151
|
motion disables the transition. Customize these states with
|
|
@@ -159,9 +159,14 @@ Interactive controls step up exactly one surface level: a control on `surface`
|
|
|
159
159
|
uses `surface-2`, while a control on `surface-2` uses `surface-3`. Hover and
|
|
160
160
|
pressed states build on that elevated surface without changing the border.
|
|
161
161
|
Inputs stay on their surrounding surface so their border remains the visual
|
|
162
|
-
boundary.
|
|
163
|
-
paired `accent-surface-text
|
|
164
|
-
|
|
162
|
+
boundary. Primary buttons and selected navigation use the fixed-mode
|
|
163
|
+
`accent-surface` and its paired light `accent-surface-text`. The brand fill
|
|
164
|
+
keeps its polarity in dark mode while Glaze adjusts it to preserve label
|
|
165
|
+
contrast.
|
|
166
|
+
|
|
167
|
+
Page navigation keeps Next first in the keyboard order. It appears above
|
|
168
|
+
Previous on narrow screens; wider layouts show Previous at the start and Next
|
|
169
|
+
at the end.
|
|
165
170
|
|
|
166
171
|
## Design tokens
|
|
167
172
|
|
|
@@ -326,6 +331,10 @@ headings use a medium `610` weight and progressively gentle negative tracking.
|
|
|
326
331
|
The separate `720` heading bold weight keeps emphasized heading text distinct.
|
|
327
332
|
Navigation uses a lighter `450` weight with `580` for the current sidebar page,
|
|
328
333
|
while smaller group labels establish hierarchy without oversized bold text.
|
|
334
|
+
Inactive sidebar links use `sidebar-text`, a slightly softer blend of `text-soft`
|
|
335
|
+
and the surface. In high-contrast mode it matches `text-soft`. Set
|
|
336
|
+
`theme.palette['sidebar-text']` to adjust that color without changing other
|
|
337
|
+
secondary text, or `theme.styles.Sidebar.Control` to customize the control.
|
|
329
338
|
Top-level sidebar groups are always-visible section headings with their direct
|
|
330
339
|
links aligned beneath them. Deeper groups expand on click or keyboard activation;
|
|
331
340
|
the current group and its ancestors start open. Groups can have a parent-page
|
|
@@ -352,10 +361,9 @@ are useful when building a theme editor or presenting a reset action.
|
|
|
352
361
|
## Style customization
|
|
353
362
|
|
|
354
363
|
Cookbook-owned interface elements are direct `tasty()` components. Supported
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
override.
|
|
364
|
+
Cookbook components and generated Markdown surfaces use Tasty style trees.
|
|
365
|
+
Customize them by name under `theme.styles`; the configuration is resolved
|
|
366
|
+
before CSS generation, so this is not a selector-based CSS override.
|
|
359
367
|
|
|
360
368
|
> **Direct styles, without a specificity battle.** Cookbook merges your partial
|
|
361
369
|
> style object with the component's base styles before Tasty extracts CSS. The
|
|
@@ -368,13 +376,13 @@ below to find its exact anatomy:
|
|
|
368
376
|
|
|
369
377
|
| Page area | Style names to inspect |
|
|
370
378
|
| ----------------------------- | ------------------------------------------------------------------------------------ |
|
|
371
|
-
| Header, title, and navigation | `HeaderFrame`, `
|
|
379
|
+
| Header, title, and navigation | `HeaderFrame`, `Header`, `SiteLogo`, `HeaderLinks`, `TopNavigation` |
|
|
372
380
|
| Sidebar and mobile menu | `Sidebar`, `MobileMenuToggle`, `MobileNavigationTabs`, `MobileMenuFooter` |
|
|
373
381
|
| Article text and headings | `Markdown`, `MarkdownHeading`, `Heading`, `MainContent` |
|
|
374
382
|
| Code and diagrams | `MarkdownCodeBlock`, `MarkdownInlineCode`, `SyntaxHighlight`, `CodeGroup`, `Mermaid` |
|
|
375
383
|
| Search | `SearchButton`, `Search`, `SearchResults` |
|
|
376
384
|
| Table of contents | `TableOfContents`, `MobileTableOfContents`, `TableOfContentsLayout` |
|
|
377
|
-
| Cards, notes, and tabs | `Card`, `
|
|
385
|
+
| Cards, notes, and tabs | `Card`, `Callout`, `MarkdownAlert`, `Tabs` |
|
|
378
386
|
| Footer and page controls | `Footer`, `Pagination`, `PageActions`, `ThemeSelect` |
|
|
379
387
|
|
|
380
388
|
For example, this changes a typography role and one named element without
|
|
@@ -455,7 +463,7 @@ sub-elements:
|
|
|
455
463
|
| `MobileTableOfContents` | `Summary`, `List`, `NestedList`, `Item`, `Link`, `HoverLink`, `Focus` |
|
|
456
464
|
| `PageActions` | `Control`, `Hover`, `Focus`, `Pending`, `Status` |
|
|
457
465
|
| `Footer` | `Meta`, `LoneMetaItem`, `MetaLink`, `HoverMetaLink`, `Credit`, `CreditLink`, `HoverCreditLink` |
|
|
458
|
-
| `Hero` | `Visual`, `Stack`, `Copy`, `Title`, `Tagline`, `Actions`, `Action`, `HoverAction`, `PrimaryAction`, `SecondaryAction`, `MinimalAction`, `ActionIcon`
|
|
466
|
+
| `Hero` | `Visual`, `DarkVisual`, `LightVisual`, `Stack`, `Copy`, `Title`, `Tagline`, `Actions`, `Action`, `HoverAction`, `PrimaryAction`, `SecondaryAction`, `MinimalAction`, `ActionIcon` |
|
|
459
467
|
| `LanguageSelect` | `Label`, `HoverLabel`, `LabelIcon`, `Select`, `Caret`, `Option` |
|
|
460
468
|
| `Logo` | `Svg`, `Mark` |
|
|
461
469
|
| `SiteLogo` | `Image`, `Light`, `Dark` |
|
|
@@ -473,7 +481,7 @@ sub-elements:
|
|
|
473
481
|
| `Preview` | `Caption`, `Stage`, `Frame`, `Code`, `Summary`, `Pre` |
|
|
474
482
|
| `Sidebar` | `Backdrop`, `OpenBackdrop`, `MobileHeading`, `HomeLink`, `HomeLogo`, `HomeLabel`, `Close`, `HoverClose`, `CloseIcon`, `CurrentLink`, `OpenPane`, `EnteredPane`, `Content`, `Tree`, `List`, `Item`, `TopLevelSpacing`, `GroupSpacing`, `NestedItem`, `SectionHeading`, `Control`, `Summary`, `GroupLabel`, `GroupLabelText`, `Link`, `LinkLabel`, `InteractiveControl`, `SummaryMarker`, `Caret`, `ExpandedCaret`, `LinkedSummary`, `GroupLink`, `LinkedSectionHeading`, `SectionLink`, `Badge`, `TopLevelLink` |
|
|
475
483
|
| `SocialIcons` | `Link`, `HoverLink`, `Icon` |
|
|
476
|
-
| `
|
|
484
|
+
| `Header` | `Primary`, `TitleAndSearch`, `Title`, `LogoLink`, `Logo`, `SiteTitle`, `Search`, `SearchElement`, `Tools`, `ToolItem`, `Social`, `MobileTheme` |
|
|
477
485
|
| `TableOfContentsLayout` | `WithMobile`, `Content` |
|
|
478
486
|
| `SearchButton` | `PendingShortcut`, `Label`, `Shortcut`, `Hover`, `Active`, `NativeIcon`, `Icon` |
|
|
479
487
|
| `Layout` | `Islands`, `LockedPage`, `Light`, `Auto` |
|
|
@@ -486,20 +494,16 @@ sub-elements:
|
|
|
486
494
|
| `TableOfContents` | `Heading`, `List`, `Item`, `Link`, `LinkLabel`, `HoverLink`, `CurrentLink` |
|
|
487
495
|
| `ThemeSelect` | `Trigger`, `HoverTrigger`, `ActiveTrigger`, `Icon`, `Panel`, `OpenPanel`, `Section`, `SectionSpacing`, `SectionLabel`, `Option`, `HoverOption`, `CheckedOption`, `FocusedOption`, `Input`, `OptionIcon`, `Checkmark`, `SelectedCheckmark` |
|
|
488
496
|
| `TopNavigation` | `Scrollbar`, `Link`, `HoverLink`, `CurrentLink`, `ActiveIndicator` |
|
|
489
|
-
| `Document` | `All`, `Body`, `Control`, `Pointer`, `ResponsiveWidth`, `ResponsiveHeight`, `Hidden`, `DesktopBlock`, `DesktopFlex`, `ScreenReaderOnly`, `Strong`, `Link`, `NarrowBlock`, `MobileBlock`, `Code`, `FocusRing`, `CurrentLink`, `SearchOpen`
|
|
497
|
+
| `Document` | `All`, `Body`, `Control`, `Pointer`, `ResponsiveWidth`, `ResponsiveHeight`, `Hidden`, `PrintHidden`, `DesktopBlock`, `DesktopFlex`, `ScreenReaderOnly`, `Strong`, `Link`, `NarrowBlock`, `MobileBlock`, `Code`, `FocusRing`, `CurrentLink`, `SearchOpen` |
|
|
490
498
|
| `MainPane` | `WithSidebars` |
|
|
491
499
|
| `MainContent` | `ContentSpacing`, `Container`, `Panel`, `FirstPanel`, `BodyPanel` |
|
|
492
500
|
| `Banner` | `Link` |
|
|
493
501
|
| `SkipLink` | `Focus` |
|
|
494
502
|
| `Search` | `Status`, `Dialog`, `CloseIcon`, `OpenDialog`, `Backdrop`, `Frame`, `Container`, `Close`, `HoverClose`, `ActiveClose` |
|
|
495
|
-
| `Pagination` | `Link`, `NextLink`, `NextIcon`, `NextLabel`, `HoverLink`, `ActiveLink`, `Title`, `LoneNextLink`, `
|
|
503
|
+
| `Pagination` | `Link`, `PreviousLink`, `NextLink`, `NextIcon`, `NextLabel`, `HoverLink`, `ActiveLink`, `Title`, `LoneNextLink`, `Icon`, `PreviousIconRtl`, `NextIconRtl` |
|
|
496
504
|
| `Markdown` | `Block`, `BlockSpacing`, `HeadingSpacing`, `List`, `CompactItem`, `ListItem`, `DefinitionTerm`, `DefinitionDescription`, `Link`, `HoverLink`, `Quote`, `Rule`, `Details`, `HoverDetails`, `Summary`, `OpenSummary`, `SummaryMarker`, `SummaryIcon`, `OpenSummaryIcon`, `Code` |
|
|
497
505
|
| `MermaidSource` | None |
|
|
498
|
-
| `
|
|
499
|
-
| `StarlightCard` | `Title` |
|
|
500
|
-
| `StarlightLinkCard` | `Hover`, `Stack`, `Link`, `LinkOverlay`, `DescriptionAndIcon` |
|
|
501
|
-
| `StarlightBadge` | None |
|
|
502
|
-
| `StarlightSteps` | `Item`, `Counter`, `Connector` |
|
|
506
|
+
| `MarkdownAlert` | `Note`, `Tip`, `Caution`, `Danger`, `Title`, `FirstContent` |
|
|
503
507
|
| `SyntaxHighlight` | `Scroll`, `Wrap`, `Marker`, `Comment`, `Punctuation`, `Keyword`, `String`, `Token`, `Property`, `Number`, `Function`, `Value`, `Operator`, `Text`, `Bg`, `Inserted`, `Deleted`, `Italic`, `Strong`, `Underline` |
|
|
504
508
|
| `SearchResults` | `Form`, `Input`, `Clear`, `Results`, `Result`, `ResultLink`, `SearchIcon`, `ClearIcon`, `SuppressedClear`, `Message`, `List`, `Title`, `Excerpt`, `NestedResult`, `Match`, `More`, `HoverMore` |
|
|
505
509
|
|
|
@@ -599,7 +603,7 @@ source.
|
|
|
599
603
|
Import styling tools from `@tenphi/cookbook/styling`. They use the same Tasty
|
|
600
604
|
runtime as Cookbook, with its semantic colors, typography presets, units, and
|
|
601
605
|
responsive states. The renderer package also exposes them from
|
|
602
|
-
`@tenphi/
|
|
606
|
+
`@tenphi/renderer/styling`.
|
|
603
607
|
|
|
604
608
|
| Export | Purpose |
|
|
605
609
|
| ------------------------ | ---------------------------------------------------------------------------------- |
|
|
@@ -665,6 +669,7 @@ separately for square artwork; the default Cookbook icon set remains in place
|
|
|
665
669
|
until changed. `Logo` remains available as the standalone Cookbook book mark.
|
|
666
670
|
|
|
667
671
|
The built-in mark uses `theme.palette["logo-surface"]` and `theme.palette["logo-mark"]`.
|
|
672
|
+
The default homepage hero artwork also uses `logo-surface` for its brand fill.
|
|
668
673
|
Both default to Glaze `mode: "fixed"`: the brand background and light book keep
|
|
669
674
|
their polarity in dark mode while respecting Glaze's tone boundaries and
|
|
670
675
|
high-contrast settings. The mark-to-background contrast floor is 3:1 normally
|
|
@@ -690,7 +695,7 @@ theme: {
|
|
|
690
695
|
Custom image assets keep their authored colors; use `light`/`dark` files when
|
|
691
696
|
you want distinct artwork. Header and drawer home links center logos with the
|
|
692
697
|
site title regardless of their aspect ratio. Use `theme.styles.SiteLogo` for
|
|
693
|
-
image size and `theme.styles.
|
|
698
|
+
image size and `theme.styles.Header.SiteTitle` / `Sidebar.HomeLink`
|
|
694
699
|
for typography; they do not need baseline offsets for a different preset.
|
|
695
700
|
|
|
696
701
|
### Advanced site title markup
|
|
@@ -738,7 +743,7 @@ Then create `docs/components/SiteTitle.astro`, using an SVG whose paths use
|
|
|
738
743
|
import ProjectLogo from "../../public/logo.svg";
|
|
739
744
|
import { SiteTitleRoot } from "./site-title.js";
|
|
740
745
|
|
|
741
|
-
const { siteTitle, siteTitleHref } = Astro.locals.
|
|
746
|
+
const { siteTitle, siteTitleHref } = Astro.locals.cookbookRoute;
|
|
742
747
|
---
|
|
743
748
|
|
|
744
749
|
<SiteTitleRoot href={siteTitleHref}>
|
|
@@ -817,7 +822,7 @@ components using the compatibility bridge described above.
|
|
|
817
822
|
|
|
818
823
|
`@tenphi/cookbook/eslint-plugin` re-exports the Tasty ESLint plugin together with
|
|
819
824
|
Cookbook's `validationConfig`. The renderer offers the same exports from
|
|
820
|
-
`@tenphi/
|
|
825
|
+
`@tenphi/renderer/eslint-plugin`. Keep style definitions in `.ts` or `.tsx`
|
|
821
826
|
modules, as in the site title example above, to lint them with either ESLint or
|
|
822
827
|
oxlint.
|
|
823
828
|
|
|
@@ -829,7 +834,7 @@ export default {
|
|
|
829
834
|
};
|
|
830
835
|
```
|
|
831
836
|
|
|
832
|
-
Renderer-only consumers can use `extends: "@tenphi/
|
|
837
|
+
Renderer-only consumers can use `extends: "@tenphi/renderer"` instead.
|
|
833
838
|
The preset registers both Cookbook styling import paths, its built-in tokens,
|
|
834
839
|
units, responsive states, and typography presets. It also describes
|
|
835
840
|
`defineComponent`, `resolveComponentStyles`, and `mergeStyles`, so their inline
|
|
@@ -927,7 +932,7 @@ output.
|
|
|
927
932
|
The header uses `#header`, generated from `theme.palette.header` (or the page
|
|
928
933
|
surface) at 70% opacity in all four appearance modes, with a 16px backdrop blur.
|
|
929
934
|
Customize the outer bar with `theme.styles.HeaderFrame`, its contents with
|
|
930
|
-
`
|
|
935
|
+
`Header`, and header buttons with `HeaderLinks` and `SearchButton`.
|
|
931
936
|
|
|
932
937
|
Below 50rem, page navigation moves into a header row and opens a left drawer.
|
|
933
938
|
`MobileMenuToggle.Section` and `Page` style its breadcrumb labels. The drawer
|
|
@@ -1108,7 +1113,7 @@ directly to Tasty `#name` tokens. `COOKBOOK_PALETTE_NAMES`, exported from
|
|
|
1108
1113
|
| Area | Roles |
|
|
1109
1114
|
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1110
1115
|
| Surfaces | `surface`, `header`, `overlay`, `surface-2`, `surface-3`, `surface-2-hover`, `surface-2-pressed`, `surface-3-hover`, `surface-3-pressed` |
|
|
1111
|
-
| Reading | `text`, `heading`, `text-soft` (alias `textSoft`), `text-muted`
|
|
1116
|
+
| Reading | `text`, `heading`, `text-soft` (alias `textSoft`), `text-muted`, `sidebar-text` |
|
|
1112
1117
|
| Brand and focus | `accent-text`, `accent-surface`, `accent-surface-text`, `accent-surface-subtle`, `accent-surface-2-subtle`, `logo-surface`, `logo-mark`, `focus` |
|
|
1113
1118
|
| Borders and effects | `border`, `border-strong`, `shadow`, `clear` |
|
|
1114
1119
|
| Status | `info`, `success`, `warning`, `danger`, each with `-text` and `-surface` variants |
|
|
@@ -1134,9 +1139,10 @@ backgrounds, typography, or layout.
|
|
|
1134
1139
|
A `DOCS_SEMANTIC_CONTRAST_UNMET` or `DOCS_BRAND_CONTRAST_UNMET` error names the
|
|
1135
1140
|
pair, mode, and required target. Adjust that pair's `theme.palette` declarations:
|
|
1136
1141
|
use an absolute tone for reading text, reduce saturation when needed, and keep
|
|
1137
|
-
`autoFlip` enabled when the solver needs to cross its base.
|
|
1138
|
-
|
|
1139
|
-
|
|
1142
|
+
`autoFlip` enabled when the solver needs to cross its base. Cookbook's default
|
|
1143
|
+
fixed brand fill is anchored to a light label and darkens when needed to meet
|
|
1144
|
+
contrast, including for orange, yellow, and pale brands. A custom fixed
|
|
1145
|
+
middle-tone fill can make its label's contrast impossible.
|
|
1140
1146
|
Focus uses a WCAG 3:1 floor (4.5:1 in high contrast) against the surface ramp.
|
|
1141
1147
|
|
|
1142
1148
|
Keep contrast requirements when adjusting colors. Extreme custom tone windows,
|
|
@@ -1165,8 +1171,8 @@ theme: {
|
|
|
1165
1171
|
and accessibility utilities. `MainPane` and `MainContent` own the content
|
|
1166
1172
|
layout. `Markdown` owns prose, lists, links, quotations, and disclosure
|
|
1167
1173
|
anatomy. `Search` owns the dialog; `SearchResults` owns the Pagefind UI.
|
|
1168
|
-
|
|
1169
|
-
|
|
1174
|
+
`MarkdownAlert` styles rendered alert blockquotes; `Card`, `Callout`, and
|
|
1175
|
+
`Steps` style Cookbook components.
|
|
1170
1176
|
|
|
1171
1177
|
Custom components created with `defineComponent()` receive `theme.customStyles`
|
|
1172
1178
|
overrides during server rendering. Units, recipes, states, and presets are
|
package/docs/troubleshooting.md
CHANGED
|
@@ -49,15 +49,13 @@ contrast. Browser checks complement the numeric diagnostics.
|
|
|
49
49
|
|
|
50
50
|
## Incompatible plugins
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
For your own plugin, read custom frontmatter through route middleware or the
|
|
60
|
-
server-only `@tenphi/cookbook/content` API. If a schema rejects data, check that
|
|
52
|
+
Cookbook owns content routing and all rendered styles. Plugins that assume a
|
|
53
|
+
different docs collection or inject CSS cannot run in the renderer. GitHub
|
|
54
|
+
alerts are supported directly; use Cookbook's graph and built-output checks
|
|
55
|
+
for links. See [extending Cookbook](./plugins.md) for Astro Markdown plugins.
|
|
56
|
+
|
|
57
|
+
Read custom frontmatter through the server-only `@tenphi/cookbook/content` API
|
|
58
|
+
or `Astro.locals.cookbookRoute` in a component override. If a schema rejects data, check that
|
|
61
59
|
custom fields do not replace reserved Cookbook frontmatter and that parsed
|
|
62
60
|
values are JSON-safe. A plugin's successful registration is not proof that its
|
|
63
61
|
rendered output works.
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tenphi/cookbook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Repository-native static documentation for Astro",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"astro-integration",
|
|
8
8
|
"astro",
|
|
9
9
|
"documentation",
|
|
10
|
-
"
|
|
10
|
+
"documentation",
|
|
11
11
|
"static-site"
|
|
12
12
|
],
|
|
13
13
|
"bin": {
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"author": "Andrey Yamanov",
|
|
69
69
|
"license": "MIT",
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@tenphi/docs": "0.
|
|
72
|
-
"@tenphi/
|
|
71
|
+
"@tenphi/docs": "0.19.0",
|
|
72
|
+
"@tenphi/renderer": "0.19.0"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"astro": "^7.3.2"
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Cookbook and Starlight
|
|
3
|
-
description: Understand which Starlight authoring conventions Cookbook preserves and where its repository and theme model differs.
|
|
4
|
-
sidebar:
|
|
5
|
-
order: 5
|
|
6
|
-
---
|
|
7
|
-
Cookbook uses [Astro Starlight](https://starlight.astro.build/) as its
|
|
8
|
-
documentation shell. It keeps familiar page-authoring conventions while adding
|
|
9
|
-
repository and npm content sources, stricter validation, and a Tasty/Glaze
|
|
10
|
-
theme model.
|
|
11
|
-
|
|
12
|
-
## Cookbook or Starlight?
|
|
13
|
-
|
|
14
|
-
Start with the place where the documentation must live. Starlight is a strong
|
|
15
|
-
choice when an Astro site owns its content. Cookbook is designed for projects
|
|
16
|
-
where the repository Markdown—or the documentation actually published in an
|
|
17
|
-
npm package—must remain the source of truth.
|
|
18
|
-
|
|
19
|
-
| Concern | Starlight | Cookbook |
|
|
20
|
-
| ----------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
21
|
-
| Starting point | Add Starlight to an Astro project and author its documentation content collection. | Add one integration to an Astro project, or generate a complete site directly from a published npm package. |
|
|
22
|
-
| Content ownership | The documentation site conventionally owns its Markdown under `src/content/docs/`. | Reads `README.md`, repository `docs/` trees, files outside the Astro app, and selected files from npm artifacts without copying or rewriting them. |
|
|
23
|
-
| Reproducible releases | Follows the dependencies and content committed with the site. | Can lock an npm package to its exact resolved version and integrity, then rebuild from the files users actually receive. |
|
|
24
|
-
| Build guarantees | Provides Starlight's content schema and Astro build pipeline. | Adds strict checks for duplicate routes, broken links, missing assets, unsafe paths, and invalid navigation with source-aware diagnostics. |
|
|
25
|
-
| Design system | Supports CSS variables, custom CSS, and component overrides. | Exposes the full [Tasty styling DSL](./upstream/tasty/docs/dsl.md) through configuration, with Glaze-generated semantic colors and named style trees for Cookbook and shell surfaces. |
|
|
26
|
-
| Familiar authoring | Defines the Starlight page, navigation, i18n, and frontmatter conventions. | Preserves those conventions—including splash pages, locales, edit links, and last-updated metadata—while resolving them against each original source. |
|
|
27
|
-
| Structural escape hatch | Replaces Starlight components when markup or behavior must change. | Supports Astro component overrides for structural changes; visual changes normally stay in typed `theme` configuration. |
|
|
28
|
-
|
|
29
|
-
Choose Starlight when the documentation site is the natural home for the
|
|
30
|
-
content and its CSS-oriented customization model fits the project. Choose
|
|
31
|
-
Cookbook when documentation must stay beside the code, match a published
|
|
32
|
-
package, fail strictly when references drift, or expose a reusable design
|
|
33
|
-
system entirely through configuration.
|
|
34
|
-
|
|
35
|
-
## Customize with Tasty's DSL
|
|
36
|
-
|
|
37
|
-
Cookbook customization is not limited to replacing token values. Every entry
|
|
38
|
-
under `theme.styles` is a partial Tasty style object that Cookbook merges into
|
|
39
|
-
the component's base style tree. That gives configuration access to the same
|
|
40
|
-
responsive values, state maps, calculations, semantic tokens, typography
|
|
41
|
-
presets, and named sub-elements used by Cookbook itself:
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
export default defineDocsConfig({
|
|
45
|
-
theme: {
|
|
46
|
-
states: {
|
|
47
|
-
"@touch": "@media(pointer: coarse)",
|
|
48
|
-
},
|
|
49
|
-
styles: {
|
|
50
|
-
MarkdownCodeBlock: {
|
|
51
|
-
Pre: {
|
|
52
|
-
padding: {
|
|
53
|
-
"": "2x 4x",
|
|
54
|
-
"@mobile": "1.5x 3x",
|
|
55
|
-
},
|
|
56
|
-
radius: "$card-radius",
|
|
57
|
-
},
|
|
58
|
-
CopyButton: {
|
|
59
|
-
inlineSize: {
|
|
60
|
-
"": "2rem",
|
|
61
|
-
"@touch": "2.5rem",
|
|
62
|
-
},
|
|
63
|
-
scale: {
|
|
64
|
-
"": "1",
|
|
65
|
-
":active": "0.94",
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
The user supplies only overrides; the merge happens inside Cookbook. See
|
|
75
|
-
[Theme and components](./theme-and-components.md#style-customization) for the
|
|
76
|
-
complete component and sub-element inventory, and the
|
|
77
|
-
[Tasty documentation](./upstream/tasty/docs/README.md) for the DSL's properties and
|
|
78
|
-
conditional syntax. Structural Astro overrides remain available when a change
|
|
79
|
-
requires different markup or behavior rather than styling.
|
|
80
|
-
|
|
81
|
-
## Configure the shared capabilities
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
export default defineDocsConfig({
|
|
85
|
-
editLink: {
|
|
86
|
-
baseUrl: "https://github.com/example/project/edit/main/",
|
|
87
|
-
},
|
|
88
|
-
lastUpdated: true,
|
|
89
|
-
locales: {
|
|
90
|
-
root: { label: "English", lang: "en" },
|
|
91
|
-
fr: { label: "Français", lang: "fr" },
|
|
92
|
-
},
|
|
93
|
-
defaultLocale: "root",
|
|
94
|
-
});
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
The keys deliberately match Starlight so an existing Starlight author does not
|
|
98
|
-
need to relearn page metadata or i18n. Cookbook resolves edit and Git metadata
|
|
99
|
-
before handing each page to Starlight because its source may live in a root
|
|
100
|
-
`docs/` directory, outside the Astro app, or inside a locked npm artifact.
|
|
101
|
-
|
|
102
|
-
## Create a splash page
|
|
103
|
-
|
|
104
|
-
```yaml
|
|
105
|
-
---
|
|
106
|
-
title: Example
|
|
107
|
-
template: splash
|
|
108
|
-
hero:
|
|
109
|
-
title: Build something clear.
|
|
110
|
-
tagline: A short explanation of the value your project provides.
|
|
111
|
-
actions:
|
|
112
|
-
- text: Get started
|
|
113
|
-
link: /getting-started/
|
|
114
|
-
variant: primary
|
|
115
|
-
- text: View API
|
|
116
|
-
link: /reference/
|
|
117
|
-
variant: secondary
|
|
118
|
-
---
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Use `template: doc` (the default) for conventional reference pages. See
|
|
122
|
-
Starlight's [page guide](https://starlight.astro.build/guides/pages/) for the
|
|
123
|
-
authoring model Cookbook builds on, then use [Theme and
|
|
124
|
-
components](./theme-and-components.md) for Cookbook-specific styling.
|