create-zudo-doc 0.1.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.
Files changed (212) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +146 -0
  3. package/bin/create-zudo-doc.js +2 -0
  4. package/dist/api.d.ts +20 -0
  5. package/dist/api.js +13 -0
  6. package/dist/claude-md-gen.d.ts +2 -0
  7. package/dist/claude-md-gen.js +113 -0
  8. package/dist/cli.d.ts +39 -0
  9. package/dist/cli.js +157 -0
  10. package/dist/compose.d.ts +95 -0
  11. package/dist/compose.js +206 -0
  12. package/dist/constants.d.ts +20 -0
  13. package/dist/constants.js +224 -0
  14. package/dist/features/body-foot-util.d.ts +10 -0
  15. package/dist/features/body-foot-util.js +12 -0
  16. package/dist/features/claude-resources.d.ts +2 -0
  17. package/dist/features/claude-resources.js +6 -0
  18. package/dist/features/design-token-panel.d.ts +14 -0
  19. package/dist/features/design-token-panel.js +27 -0
  20. package/dist/features/doc-history.d.ts +9 -0
  21. package/dist/features/doc-history.js +11 -0
  22. package/dist/features/doc-tags.d.ts +19 -0
  23. package/dist/features/doc-tags.js +33 -0
  24. package/dist/features/footer-taglist.d.ts +14 -0
  25. package/dist/features/footer-taglist.js +17 -0
  26. package/dist/features/footer.d.ts +8 -0
  27. package/dist/features/footer.js +10 -0
  28. package/dist/features/i18n.d.ts +22 -0
  29. package/dist/features/i18n.js +41 -0
  30. package/dist/features/image-enlarge.d.ts +11 -0
  31. package/dist/features/image-enlarge.js +13 -0
  32. package/dist/features/index.d.ts +15 -0
  33. package/dist/features/index.js +53 -0
  34. package/dist/features/llms-txt.d.ts +11 -0
  35. package/dist/features/llms-txt.js +13 -0
  36. package/dist/features/search.d.ts +9 -0
  37. package/dist/features/search.js +11 -0
  38. package/dist/features/sidebar-resizer.d.ts +14 -0
  39. package/dist/features/sidebar-resizer.js +16 -0
  40. package/dist/features/sidebar-toggle.d.ts +13 -0
  41. package/dist/features/sidebar-toggle.js +15 -0
  42. package/dist/features/tag-governance.d.ts +14 -0
  43. package/dist/features/tag-governance.js +16 -0
  44. package/dist/features/tauri-dev.d.ts +2 -0
  45. package/dist/features/tauri-dev.js +25 -0
  46. package/dist/features/tauri.d.ts +11 -0
  47. package/dist/features/tauri.js +52 -0
  48. package/dist/features/versioning.d.ts +27 -0
  49. package/dist/features/versioning.js +43 -0
  50. package/dist/index.d.ts +1 -0
  51. package/dist/index.js +150 -0
  52. package/dist/preset.d.ts +37 -0
  53. package/dist/preset.js +156 -0
  54. package/dist/prompts.d.ts +32 -0
  55. package/dist/prompts.js +248 -0
  56. package/dist/scaffold.d.ts +4 -0
  57. package/dist/scaffold.js +344 -0
  58. package/dist/settings-gen.d.ts +2 -0
  59. package/dist/settings-gen.js +237 -0
  60. package/dist/utils.d.ts +8 -0
  61. package/dist/utils.js +34 -0
  62. package/dist/zfb-config-gen.d.ts +19 -0
  63. package/dist/zfb-config-gen.js +222 -0
  64. package/package.json +65 -0
  65. package/templates/base/.htmlvalidate.json +5 -0
  66. package/templates/base/.zfb/doc-history-meta.json +1 -0
  67. package/templates/base/pages/404.tsx +55 -0
  68. package/templates/base/pages/_data.ts +179 -0
  69. package/templates/base/pages/_mdx-components.ts +249 -0
  70. package/templates/base/pages/docs/[...slug].tsx +448 -0
  71. package/templates/base/pages/index.tsx +158 -0
  72. package/templates/base/pages/lib/_body-end-islands.tsx +201 -0
  73. package/templates/base/pages/lib/_category-nav.tsx +148 -0
  74. package/templates/base/pages/lib/_category-tree-nav.tsx +104 -0
  75. package/templates/base/pages/lib/_compose-meta-title.ts +29 -0
  76. package/templates/base/pages/lib/_details.tsx +30 -0
  77. package/templates/base/pages/lib/_doc-history-area.tsx +178 -0
  78. package/templates/base/pages/lib/_doc-metainfo-area.tsx +100 -0
  79. package/templates/base/pages/lib/_doc-tags-area.tsx +89 -0
  80. package/templates/base/pages/lib/_extract-headings.ts +81 -0
  81. package/templates/base/pages/lib/_footer-with-defaults.tsx +234 -0
  82. package/templates/base/pages/lib/_frontmatter-preview-data.ts +53 -0
  83. package/templates/base/pages/lib/_head-with-defaults.tsx +113 -0
  84. package/templates/base/pages/lib/_header-with-defaults.tsx +386 -0
  85. package/templates/base/pages/lib/_inline-version-switcher.tsx +84 -0
  86. package/templates/base/pages/lib/_math-block.tsx +63 -0
  87. package/templates/base/pages/lib/_nav-source-docs.ts +68 -0
  88. package/templates/base/pages/lib/_preset-generator.tsx +81 -0
  89. package/templates/base/pages/lib/_search-widget-script.ts +388 -0
  90. package/templates/base/pages/lib/_search-widget.tsx +196 -0
  91. package/templates/base/pages/lib/_sidebar-with-defaults.tsx +176 -0
  92. package/templates/base/pages/lib/_site-tree-nav.tsx +128 -0
  93. package/templates/base/pages/lib/locale-merge.ts +58 -0
  94. package/templates/base/pages/lib/route-enumerators.ts +302 -0
  95. package/templates/base/pages/sitemap.xml.tsx +51 -0
  96. package/templates/base/plugins/connect-adapter.mjs +144 -0
  97. package/templates/base/plugins/copy-public-plugin.mjs +50 -0
  98. package/templates/base/plugins/search-index-plugin.mjs +54 -0
  99. package/templates/base/scripts/run-b4push.sh +102 -0
  100. package/templates/base/src/components/ai-chat-modal.tsx +15 -0
  101. package/templates/base/src/components/client-router-bootstrap.tsx +14 -0
  102. package/templates/base/src/components/content/component-map.ts +25 -0
  103. package/templates/base/src/components/content/content-blockquote.tsx +16 -0
  104. package/templates/base/src/components/content/content-code.tsx +117 -0
  105. package/templates/base/src/components/content/content-link.tsx +83 -0
  106. package/templates/base/src/components/content/content-ol.tsx +19 -0
  107. package/templates/base/src/components/content/content-paragraph.tsx +10 -0
  108. package/templates/base/src/components/content/content-strong.tsx +16 -0
  109. package/templates/base/src/components/content/content-table.tsx +18 -0
  110. package/templates/base/src/components/content/content-ul.tsx +18 -0
  111. package/templates/base/src/components/content/heading-h2.tsx +26 -0
  112. package/templates/base/src/components/content/heading-h3.tsx +26 -0
  113. package/templates/base/src/components/content/heading-h4.tsx +26 -0
  114. package/templates/base/src/components/design-token-panel-bootstrap.tsx +15 -0
  115. package/templates/base/src/components/desktop-sidebar-toggle.tsx +15 -0
  116. package/templates/base/src/components/doc-history.tsx +18 -0
  117. package/templates/base/src/components/html-preview/highlighted-code.tsx +74 -0
  118. package/templates/base/src/components/html-preview/html-preview.tsx +108 -0
  119. package/templates/base/src/components/html-preview/preflight.ts +112 -0
  120. package/templates/base/src/components/html-preview/preview-base.tsx +159 -0
  121. package/templates/base/src/components/image-enlarge.tsx +19 -0
  122. package/templates/base/src/components/mobile-toc.tsx +94 -0
  123. package/templates/base/src/components/preset-generator.tsx +14 -0
  124. package/templates/base/src/components/sidebar-toggle.tsx +98 -0
  125. package/templates/base/src/components/sidebar-tree.tsx +543 -0
  126. package/templates/base/src/components/site-tree-nav.tsx +233 -0
  127. package/templates/base/src/components/theme-toggle.tsx +93 -0
  128. package/templates/base/src/components/toc.tsx +63 -0
  129. package/templates/base/src/components/tree-nav-shared.tsx +71 -0
  130. package/templates/base/src/config/color-scheme-utils.ts +182 -0
  131. package/templates/base/src/config/color-schemes.ts +128 -0
  132. package/templates/base/src/config/frontmatter-preview-defaults.ts +24 -0
  133. package/templates/base/src/config/frontmatter-preview-renderers.tsx +46 -0
  134. package/templates/base/src/config/i18n.ts +225 -0
  135. package/templates/base/src/config/settings-types.ts +162 -0
  136. package/templates/base/src/config/sidebars.ts +66 -0
  137. package/templates/base/src/config/tag-vocabulary-types.ts +39 -0
  138. package/templates/base/src/config/tag-vocabulary.ts +20 -0
  139. package/templates/base/src/hooks/use-active-heading.ts +133 -0
  140. package/templates/base/src/plugins/docs-source-map.ts +103 -0
  141. package/templates/base/src/plugins/hast-utils.ts +10 -0
  142. package/templates/base/src/plugins/rehype-code-title.ts +50 -0
  143. package/templates/base/src/plugins/rehype-heading-links.ts +53 -0
  144. package/templates/base/src/plugins/rehype-image-enlarge.ts +113 -0
  145. package/templates/base/src/plugins/rehype-mermaid.ts +41 -0
  146. package/templates/base/src/plugins/rehype-strip-md-extension.ts +58 -0
  147. package/templates/base/src/plugins/remark-admonitions.ts +99 -0
  148. package/templates/base/src/plugins/remark-resolve-markdown-links.ts +127 -0
  149. package/templates/base/src/plugins/url-utils.ts +4 -0
  150. package/templates/base/src/styles/global.css +1066 -0
  151. package/templates/base/src/types/docs-entry.ts +39 -0
  152. package/templates/base/src/types/heading.ts +5 -0
  153. package/templates/base/src/types/locale.ts +10 -0
  154. package/templates/base/src/utils/base.ts +139 -0
  155. package/templates/base/src/utils/content-files.ts +106 -0
  156. package/templates/base/src/utils/dedent.ts +24 -0
  157. package/templates/base/src/utils/docs.ts +335 -0
  158. package/templates/base/src/utils/git-info.ts +70 -0
  159. package/templates/base/src/utils/github.ts +19 -0
  160. package/templates/base/src/utils/header-right-items.ts +38 -0
  161. package/templates/base/src/utils/nav-scope.ts +63 -0
  162. package/templates/base/src/utils/sidebar.ts +104 -0
  163. package/templates/base/src/utils/slug.ts +10 -0
  164. package/templates/base/src/utils/smart-break.tsx +126 -0
  165. package/templates/base/src/utils/tags.ts +126 -0
  166. package/templates/base/tsconfig.json +36 -0
  167. package/templates/features/bodyFootUtil/files/src/utils/github.ts +19 -0
  168. package/templates/features/claudeResources/files/plugins/claude-resources-plugin.mjs +137 -0
  169. package/templates/features/claudeResources/files/src/integrations/claude-resources/__tests__/escape-for-mdx.test.ts +34 -0
  170. package/templates/features/claudeResources/files/src/integrations/claude-resources/__tests__/generate.test.ts +376 -0
  171. package/templates/features/claudeResources/files/src/integrations/claude-resources/escape-for-mdx.ts +93 -0
  172. package/templates/features/claudeResources/files/src/integrations/claude-resources/generate.ts +586 -0
  173. package/templates/features/designTokenPanel/files/src/components/design-token-panel-bootstrap.tsx +15 -0
  174. package/templates/features/designTokenPanel/files/src/config/design-token-panel-config.ts +99 -0
  175. package/templates/features/designTokenPanel/files/src/config/design-tokens-manifest.ts +177 -0
  176. package/templates/features/designTokenPanel/files/src/lib/design-token-panel-bootstrap.ts +50 -0
  177. package/templates/features/docHistory/files/plugins/doc-history-plugin.mjs +99 -0
  178. package/templates/features/docHistory/files/src/components/doc-history.tsx +598 -0
  179. package/templates/features/docHistory/files/src/types/doc-history.ts +23 -0
  180. package/templates/features/docHistory/files/src/utils/doc-history.ts +180 -0
  181. package/templates/features/docTags/files/pages/[locale]/docs/tags/[tag].tsx +116 -0
  182. package/templates/features/docTags/files/pages/[locale]/docs/tags/index.tsx +99 -0
  183. package/templates/features/docTags/files/pages/docs/tags/[tag].tsx +101 -0
  184. package/templates/features/docTags/files/pages/docs/tags/index.tsx +86 -0
  185. package/templates/features/i18n/files/pages/[locale]/docs/[...slug].tsx +467 -0
  186. package/templates/features/i18n/files/pages/[locale]/index.tsx +213 -0
  187. package/templates/features/imageEnlarge/files/src/components/image-enlarge.tsx +248 -0
  188. package/templates/features/llmsTxt/files/plugins/llms-txt-plugin.mjs +74 -0
  189. package/templates/features/sidebarResizer/files/src/scripts/sidebar-resizer.ts +185 -0
  190. package/templates/features/sidebarToggle/files/src/components/desktop-sidebar-toggle.tsx +126 -0
  191. package/templates/features/tagGovernance/files/scripts/tags-audit.ts +576 -0
  192. package/templates/features/tagGovernance/files/scripts/tags-suggest.ts +428 -0
  193. package/templates/features/tauri/files/src/components/find-bar.tsx +122 -0
  194. package/templates/features/tauri/files/src/components/find-in-page-init.tsx +53 -0
  195. package/templates/features/tauri/files/src/utils/find-in-page.ts +175 -0
  196. package/templates/features/tauri/files/src-tauri/Cargo.toml +14 -0
  197. package/templates/features/tauri/files/src-tauri/build.rs +3 -0
  198. package/templates/features/tauri/files/src-tauri/capabilities/default.json +11 -0
  199. package/templates/features/tauri/files/src-tauri/src/main.rs +250 -0
  200. package/templates/features/tauri/files/src-tauri/tauri.conf.json +25 -0
  201. package/templates/features/tauriDev/files/src-tauri-dev/Cargo.toml +15 -0
  202. package/templates/features/tauriDev/files/src-tauri-dev/build.rs +3 -0
  203. package/templates/features/tauriDev/files/src-tauri-dev/capabilities/default.json +7 -0
  204. package/templates/features/tauriDev/files/src-tauri-dev/frontend/index.html +187 -0
  205. package/templates/features/tauriDev/files/src-tauri-dev/icons/icon.png +0 -0
  206. package/templates/features/tauriDev/files/src-tauri-dev/src/main.rs +995 -0
  207. package/templates/features/tauriDev/files/src-tauri-dev/tauri.conf.json +22 -0
  208. package/templates/features/tauriDev/files/src-tauri-dev/test-launch.sh +65 -0
  209. package/templates/features/versioning/files/pages/[locale]/docs/versions.tsx +100 -0
  210. package/templates/features/versioning/files/pages/docs/versions.tsx +78 -0
  211. package/templates/features/versioning/files/pages/v/[version]/docs/[...slug].tsx +451 -0
  212. package/templates/features/versioning/files/pages/v/[version]/ja/docs/[...slug].tsx +490 -0
@@ -0,0 +1,128 @@
1
+ /** A color reference: palette index (number) or direct color value (string) */
2
+ export type ColorRef = number | string;
3
+
4
+ export interface ColorScheme {
5
+ background: ColorRef;
6
+ foreground: ColorRef;
7
+ cursor: ColorRef;
8
+ selectionBg: ColorRef;
9
+ selectionFg: ColorRef;
10
+ palette: [
11
+ string, string, string, string, string, string, string, string,
12
+ string, string, string, string, string, string, string, string,
13
+ ];
14
+ /** Optional semantic overrides — when omitted, defaults are used:
15
+ * surface=p0, muted=p8, accent=p5, accentHover=p14
16
+ * codeBg=p10, codeFg=p11, success=p2, danger=p1, warning=p3, info=p4
17
+ * Each field accepts a palette index (number) or a direct color value (string). */
18
+ semantic?: {
19
+ surface?: ColorRef;
20
+ muted?: ColorRef;
21
+ accent?: ColorRef;
22
+ accentHover?: ColorRef;
23
+ codeBg?: ColorRef;
24
+ codeFg?: ColorRef;
25
+ success?: ColorRef;
26
+ danger?: ColorRef;
27
+ warning?: ColorRef;
28
+ info?: ColorRef;
29
+ mermaidNodeBg?: ColorRef;
30
+ mermaidText?: ColorRef;
31
+ mermaidLine?: ColorRef;
32
+ mermaidLabelBg?: ColorRef;
33
+ mermaidNoteBg?: ColorRef;
34
+ chatUserBg?: ColorRef;
35
+ chatUserText?: ColorRef;
36
+ chatAssistantBg?: ColorRef;
37
+ chatAssistantText?: ColorRef;
38
+ /** UI chrome over user images — enlarge/close overlay buttons */
39
+ imageOverlayBg?: ColorRef;
40
+ imageOverlayFg?: ColorRef;
41
+ /** <mark> highlight for matched keywords in search results */
42
+ matchedKeywordBg?: ColorRef;
43
+ matchedKeywordFg?: ColorRef;
44
+ };
45
+ }
46
+
47
+ /**
48
+ * Standard palette index convention (all schemes should follow this):
49
+ *
50
+ * | Index | Role | Description |
51
+ * |-------|-------------------|------------------------------------------|
52
+ * | p0 | Dark surface | Deepest surface (code blocks, mermaid) |
53
+ * | p1 | Danger | Red family — errors, destructive actions |
54
+ * | p2 | Success | Green family — confirmations, tips |
55
+ * | p3 | Warning | Yellow/amber — caution messages |
56
+ * | p4 | Info | Blue family — informational highlights |
57
+ * | p5 | Accent | Primary interactive color (links, CTA) |
58
+ * | p6 | Neutral | Slate/cyan — borders, secondary elements |
59
+ * | p7 | Secondary neutral | Gray or muted accent |
60
+ * | p8 | Muted | Gray — borders, secondary text, comments |
61
+ * | p9 | Background | Page background |
62
+ * | p10 | Surface | Elevated surface (panels, sidebars) |
63
+ * | p11 | Text primary | Main body text |
64
+ * | p12 | Accent variant | Brighter or alternate accent |
65
+ * | p13 | Decorative | Purple/lavender — non-semantic decoration |
66
+ * | p14 | Accent hover | Hover state for interactive elements |
67
+ * | p15 | Text secondary | Secondary text or muted foreground |
68
+ */
69
+ export const colorSchemes: Record<string, ColorScheme> = {
70
+ "Default Light": {
71
+ background: 9,
72
+ foreground: 11,
73
+ cursor: 6,
74
+ selectionBg: 11,
75
+ selectionFg: 10,
76
+ palette: [
77
+ "#303030", "#dd3131", "#266538", "#a83838", // p0-3: dark surface, danger, success, warning
78
+ "#3277c8", "#a35e0f", "#90a1b9", "#7a5218", // p4-7: info, accent, neutral, secondary
79
+ "#6b6b6b", "#e2ddda", "#ece9e9", "#303030", // p8-11: muted, background, surface, text
80
+ "#5b99dc", "#b89ee7", "#8590a0", "#654516", // p12-15: accent variant, decorative, hover, muted foreground
81
+ ],
82
+ semantic: {
83
+ surface: 10,
84
+ muted: 8,
85
+ accent: 5,
86
+ accentHover: 14,
87
+ codeBg: 10,
88
+ codeFg: 11,
89
+ success: 2,
90
+ danger: 1,
91
+ warning: 3,
92
+ info: 4,
93
+ imageOverlayBg: 11,
94
+ imageOverlayFg: 10,
95
+ matchedKeywordBg: "#fff59d",
96
+ matchedKeywordFg: "#000000",
97
+ },
98
+ },
99
+ "Default Dark": {
100
+ background: 9,
101
+ foreground: 15,
102
+ cursor: 6,
103
+ selectionBg: 10,
104
+ selectionFg: 11,
105
+ palette: [
106
+ "#1c1c1c", "#da6871", "#93bb77", "#dfbb77", // p0-3: dark surface, danger, success, warning
107
+ "#5caae9", "#c074d6", "#90a1b9", "#a0a0a0", // p4-7: info, accent, neutral, secondary
108
+ "#888888", "#181818", "#383838", "#e0e0e0", // p8-11: muted, background, surface, text
109
+ "#d69a66", "#c074d6", "#a7c0e3", "#b8b8b8", // p12-15: accent variant, decorative, hover, text secondary
110
+ ],
111
+ semantic: {
112
+ surface: 0,
113
+ muted: 8,
114
+ accent: 12,
115
+ accentHover: 14,
116
+ codeBg: 10,
117
+ codeFg: 11,
118
+ success: 2,
119
+ danger: 1,
120
+ warning: 3,
121
+ info: 4,
122
+ imageOverlayBg: 0,
123
+ imageOverlayFg: 11,
124
+ matchedKeywordBg: "#fff59d",
125
+ matchedKeywordFg: "#000000",
126
+ },
127
+ },
128
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Schema-managed frontmatter keys that are handled by the framework and
3
+ * should be hidden from the frontmatter preview by default.
4
+ * These correspond to every field defined in the docsSchema in src/content.config.ts.
5
+ */
6
+ export const DEFAULT_FRONTMATTER_IGNORE_KEYS: string[] = [
7
+ "title",
8
+ "description",
9
+ "category",
10
+ "sidebar_position",
11
+ "sidebar_label",
12
+ "tags",
13
+ "search_exclude",
14
+ "pagination_next",
15
+ "pagination_prev",
16
+ "draft",
17
+ "unlisted",
18
+ "hide_sidebar",
19
+ "hide_toc",
20
+ "doc_history",
21
+ "standalone",
22
+ "slug",
23
+ "generated",
24
+ ];
@@ -0,0 +1,46 @@
1
+ import type {
2
+ FrontmatterCellRenderer,
3
+ FrontmatterCellRendererProps,
4
+ } from "@takazudo/zudo-doc/metainfo";
5
+
6
+ /**
7
+ * Props passed to every custom frontmatter renderer component.
8
+ *
9
+ * Lookup rule: `frontmatterRenderers[key]` is checked after the ignore-list
10
+ * filter and after null/undefined skipping, so renderers only receive defined
11
+ * values and are never invoked for ignored keys.
12
+ *
13
+ * Ignore-list precedence: if a key appears in `settings.frontmatterPreview.ignoreKeys`
14
+ * (or the default ignore list), the row is suppressed entirely — even if a renderer
15
+ * is registered for that key. To reveal a framework-managed key with a custom
16
+ * renderer, first remove the key from the ignore list in settings.
17
+ *
18
+ * Fallback behavior: if no renderer is registered for a key, the built-in
19
+ * `renderValue()` path is used (string/number/boolean as text, other types as
20
+ * JSON in a `<code>` element).
21
+ *
22
+ * Null/undefined skipping: values of `null` or `undefined` are filtered out
23
+ * before renderer lookup. Renderers can assume `value` is defined.
24
+ */
25
+ // Re-export the canonical props type from the package so project code has a
26
+ // single import path. The locale field is typed as string (the package uses
27
+ // string rather than the project-specific Locale union to avoid a circular
28
+ // dependency); the runtime values are identical.
29
+ export type { FrontmatterCellRendererProps as FrontmatterRendererProps };
30
+
31
+ /**
32
+ * Per-key custom renderer map for the frontmatter-preview component.
33
+ *
34
+ * Add entries here to override how specific frontmatter fields are displayed.
35
+ * Keys must match frontmatter field names exactly (case-sensitive).
36
+ *
37
+ * Each renderer is a function `(props: FrontmatterCellRendererProps) => ComponentChildren`.
38
+ * Return `null` or `undefined` to fall through to the built-in `renderValue()`
39
+ * plain-text path.
40
+ *
41
+ * Example (add a renderer for a `status` field):
42
+ * ```tsx
43
+ * status: ({ value }) => <strong>{String(value)}</strong>,
44
+ * ```
45
+ */
46
+ export const frontmatterRenderers: Record<string, FrontmatterCellRenderer> = {};
@@ -0,0 +1,225 @@
1
+ import { settings } from "./settings";
2
+
3
+ // Collection name string used by zfb's content engine (`getCollection(...)`).
4
+ // Kept as a structural string-literal alias so callers don't have to redeclare
5
+ // it; it's a structural type so the underlying engine is interchangeable.
6
+ type CollectionKey = string;
7
+
8
+ /** Default locale code, served from docsDir. */
9
+ export const defaultLocale = settings.defaultLocale;
10
+
11
+ /** All supported locale codes, derived from settings. */
12
+ export const locales = [
13
+ defaultLocale,
14
+ ...(Object.keys(settings.locales) as Array<keyof typeof settings.locales>),
15
+ ] as const;
16
+ export type Locale = (typeof locales)[number];
17
+
18
+ type LocaleKey = keyof typeof settings.locales;
19
+
20
+ /** Safely look up a locale in settings.locales. */
21
+ function getLocaleConfig(locale: string) {
22
+ return (settings.locales as Record<string, (typeof settings.locales)[LocaleKey]>)[locale];
23
+ }
24
+
25
+ /** Get the content directory for a locale. */
26
+ export function getContentDir(locale: Locale | string): string {
27
+ if (locale === defaultLocale) return settings.docsDir;
28
+ return getLocaleConfig(locale)?.dir ?? settings.docsDir;
29
+ }
30
+
31
+ /**
32
+ * Get the Astro content collection name for a locale.
33
+ * Returns a CollectionKey so it can be passed directly to getCollection().
34
+ * The cast is safe because collections are dynamically created in content.config.ts
35
+ * for every locale in settings.locales.
36
+ */
37
+ export function getCollectionName(locale: Locale | string): CollectionKey {
38
+ if (locale === defaultLocale) return "docs";
39
+ return `docs-${locale}` as CollectionKey;
40
+ }
41
+
42
+ /** Get the display label for a locale. */
43
+ export function getLocaleLabel(locale: Locale | string): string {
44
+ if (locale === defaultLocale) return defaultLocale.toUpperCase();
45
+ return getLocaleConfig(locale)?.label ?? locale.toUpperCase();
46
+ }
47
+
48
+ /** Detect locale from a URL pathname (after base stripping). */
49
+ export function detectLocaleFromPath(path: string): Locale {
50
+ for (const code of Object.keys(settings.locales)) {
51
+ if (path.startsWith(`/${code}/`) || path === `/${code}`) {
52
+ return code as Locale;
53
+ }
54
+ }
55
+ return defaultLocale;
56
+ }
57
+
58
+ /** UI string translations */
59
+ const translations: Record<string, Record<string, string>> = {
60
+ en: {
61
+ "nav.gettingStarted": "Getting Started",
62
+ "nav.learn": "Learn",
63
+ "nav.guides": "Guides",
64
+ "nav.components": "Components",
65
+ "nav.reference": "Reference",
66
+ "nav.claude": "Claude",
67
+ "nav.changelog": "Changelog",
68
+ "nav.develop": "Develop",
69
+ "nav.previous": "Previous",
70
+ "nav.next": "Next",
71
+ "nav.overview": "Overview",
72
+ "toc.title": "On this page",
73
+ "docs.browseAll": "Browse all documentation sections.",
74
+ "search.label": "Search",
75
+ "search.resultCount": "{count} results",
76
+ "code.copy": "Copy code",
77
+ "code.copied": "Copied!",
78
+ "code.wrapToggle": "Toggle word wrap",
79
+ "doc.editPage": "Edit this page",
80
+ "doc.viewSource": "View source on GitHub",
81
+ "header.github": "GitHub repository",
82
+ "doc.tags": "Tags",
83
+ "doc.taggedWith": "Pages tagged with",
84
+ "doc.allTags": "All Tags",
85
+ "doc.created": "Created",
86
+ "doc.updated": "Updated",
87
+ "doc.noTags": "No tags found.",
88
+ "doc.pageCount": "{count} pages",
89
+ "doc.pageCountSingle": "{count} page",
90
+ "nav.backToMenu": "Back to main menu",
91
+ "doc.fallbackNotice":
92
+ "This page has not been translated yet and is shown in the original language.",
93
+ "frontmatter.preview.title": "Frontmatter",
94
+ "frontmatter.preview.keyCol": "Key",
95
+ "frontmatter.preview.valueCol": "Value",
96
+ "version.latest": "Latest",
97
+ "version.switcher.label": "Version",
98
+ "version.banner.unmaintained":
99
+ "You are viewing documentation for an older version.",
100
+ "version.banner.unreleased":
101
+ "You are viewing unreleased documentation.",
102
+ "version.banner.latestLink": "View the latest version",
103
+ "version.switcher.unavailable": "Not available in this version",
104
+ "version.switcher.allVersions": "All versions",
105
+ "version.page.title": "Documentation Versions",
106
+ "version.page.latest.title": "Latest Version (Current)",
107
+ "version.page.latest.description":
108
+ "The most up-to-date documentation for the latest stable release.",
109
+ "version.page.latest.link": "View latest docs",
110
+ "version.page.past.title": "Past Versions",
111
+ "version.page.past.description":
112
+ "Documentation for previously released versions.",
113
+ "version.page.unmaintained": "Unmaintained",
114
+ "version.page.unreleased": "Unreleased",
115
+ "version.page.status": "Status",
116
+ "version.page.docs": "Docs",
117
+ },
118
+ ja: {
119
+ "nav.gettingStarted": "はじめに",
120
+ "nav.learn": "学ぶ",
121
+ "nav.guides": "ガイド",
122
+ "nav.components": "コンポーネント",
123
+ "nav.reference": "リファレンス",
124
+ "nav.claude": "Claude",
125
+ "nav.changelog": "変更履歴",
126
+ "nav.develop": "開発",
127
+ "nav.previous": "前へ",
128
+ "nav.next": "次へ",
129
+ "nav.overview": "概要",
130
+ "toc.title": "目次",
131
+ "docs.browseAll": "すべてのドキュメントセクションを閲覧",
132
+ "search.label": "検索",
133
+ "search.resultCount": "{count} 件",
134
+ "code.copy": "コードをコピー",
135
+ "code.copied": "コピーしました!",
136
+ "code.wrapToggle": "折り返し切替",
137
+ "doc.editPage": "このページを編集",
138
+ "doc.viewSource": "GitHub でソースを見る",
139
+ "header.github": "GitHub リポジトリ",
140
+ "doc.tags": "タグ",
141
+ "doc.taggedWith": "タグ付きページ",
142
+ "doc.allTags": "すべてのタグ",
143
+ "doc.created": "作成",
144
+ "doc.updated": "更新",
145
+ "doc.noTags": "タグが見つかりません。",
146
+ "doc.pageCount": "{count}ページ",
147
+ "doc.pageCountSingle": "{count}ページ",
148
+ "nav.backToMenu": "メインメニューに戻る",
149
+ "doc.fallbackNotice":
150
+ "このページはまだ翻訳されていません。原文のまま表示しています。",
151
+ "frontmatter.preview.title": "フロントマター",
152
+ "frontmatter.preview.keyCol": "キー",
153
+ "frontmatter.preview.valueCol": "値",
154
+ "version.latest": "最新",
155
+ "version.switcher.label": "バージョン",
156
+ "version.banner.unmaintained":
157
+ "これは旧バージョンのドキュメントです。",
158
+ "version.banner.unreleased":
159
+ "これは未リリースのドキュメントです。",
160
+ "version.banner.latestLink": "最新バージョンを見る",
161
+ "version.switcher.unavailable": "このバージョンでは利用できません",
162
+ "version.switcher.allVersions": "すべてのバージョン",
163
+ "version.page.title": "ドキュメントバージョン",
164
+ "version.page.latest.title": "最新バージョン(現在)",
165
+ "version.page.latest.description":
166
+ "最新の安定版リリースのドキュメントです。",
167
+ "version.page.latest.link": "最新ドキュメントを見る",
168
+ "version.page.past.title": "過去のバージョン",
169
+ "version.page.past.description":
170
+ "以前にリリースされたバージョンのドキュメントです。",
171
+ "version.page.unmaintained": "メンテナンス終了",
172
+ "version.page.unreleased": "未リリース",
173
+ "version.page.status": "ステータス",
174
+ "version.page.docs": "ドキュメント",
175
+ },
176
+ de: {
177
+ "nav.gettingStarted": "Erste Schritte",
178
+ "nav.learn": "Lernen",
179
+ "nav.guides": "Anleitungen",
180
+ "nav.components": "Komponenten",
181
+ "nav.reference": "Referenz",
182
+ "nav.claude": "Claude",
183
+ "nav.changelog": "Changelog",
184
+ "nav.develop": "Entwicklung",
185
+ "nav.previous": "Zurück",
186
+ "nav.next": "Weiter",
187
+ "nav.overview": "Überblick",
188
+ "toc.title": "Auf dieser Seite",
189
+ "docs.browseAll": "Alle Dokumentationsabschnitte durchsuchen.",
190
+ "search.label": "Suche",
191
+ "search.resultCount": "{count} Ergebnisse",
192
+ "code.copy": "Code kopieren",
193
+ "code.copied": "Kopiert!",
194
+ "code.wrapToggle": "Zeilenumbruch umschalten",
195
+ "nav.backToMenu": "Zurück zum Hauptmenü",
196
+ "doc.editPage": "Diese Seite bearbeiten",
197
+ "doc.viewSource": "Quellcode auf GitHub ansehen",
198
+ "header.github": "GitHub-Repository",
199
+ "doc.tags": "Tags",
200
+ "doc.taggedWith": "Seiten mit Tag",
201
+ "doc.allTags": "Alle Tags",
202
+ "doc.created": "Erstellt",
203
+ "doc.updated": "Aktualisiert",
204
+ "doc.noTags": "Keine Tags gefunden.",
205
+ "doc.pageCount": "{count} Seiten",
206
+ "doc.pageCountSingle": "{count} Seite",
207
+ "doc.fallbackNotice":
208
+ "Diese Seite wurde noch nicht übersetzt und wird in der Originalsprache angezeigt.",
209
+ "frontmatter.preview.title": "Frontmatter",
210
+ "frontmatter.preview.keyCol": "Schlüssel",
211
+ "frontmatter.preview.valueCol": "Wert",
212
+ "version.latest": "Neueste",
213
+ "version.switcher.label": "Version",
214
+ "version.banner.unmaintained":
215
+ "Sie sehen die Dokumentation einer älteren Version.",
216
+ "version.banner.unreleased":
217
+ "Sie sehen unveröffentlichte Dokumentation.",
218
+ "version.banner.latestLink": "Neueste Version anzeigen",
219
+ },
220
+ };
221
+
222
+ /** Get a translated UI string */
223
+ export function t(key: string, locale: Locale | string = defaultLocale): string {
224
+ return translations[locale]?.[key] ?? translations[defaultLocale]?.[key] ?? key;
225
+ }
@@ -0,0 +1,162 @@
1
+ export interface HeaderNavChildItem {
2
+ label: string;
3
+ labelKey?: string;
4
+ path: string;
5
+ categoryMatch?: string;
6
+ }
7
+
8
+ export interface HeaderNavItem extends HeaderNavChildItem {
9
+ children?: HeaderNavChildItem[];
10
+ }
11
+
12
+ export type HeaderRightComponentName =
13
+ | "theme-toggle"
14
+ | "language-switcher"
15
+ | "version-switcher"
16
+ | "github-link"
17
+ | "search";
18
+
19
+ export type HeaderRightTriggerName = "design-token-panel" | "ai-chat";
20
+
21
+ export interface HeaderRightComponentItem {
22
+ type: "component";
23
+ component: HeaderRightComponentName;
24
+ }
25
+
26
+ export interface HeaderRightTriggerItem {
27
+ type: "trigger";
28
+ trigger: HeaderRightTriggerName;
29
+ }
30
+
31
+ export interface HeaderRightLinkItem {
32
+ type: "link";
33
+ href: string;
34
+ label?: string;
35
+ ariaLabel?: string;
36
+ icon?: "github";
37
+ }
38
+
39
+ export interface HeaderRightHtmlItem {
40
+ type: "html";
41
+ html: string;
42
+ }
43
+
44
+ export type HeaderRightItem =
45
+ | HeaderRightComponentItem
46
+ | HeaderRightTriggerItem
47
+ | HeaderRightLinkItem
48
+ | HeaderRightHtmlItem;
49
+
50
+ export interface BodyFootUtilAreaConfig {
51
+ docHistory?: boolean;
52
+ viewSourceLink?: boolean;
53
+ }
54
+
55
+ export interface ColorModeConfig {
56
+ defaultMode: "light" | "dark";
57
+ lightScheme: string;
58
+ darkScheme: string;
59
+ respectPrefersColorScheme: boolean;
60
+ }
61
+
62
+ export interface LocaleConfig {
63
+ label: string;
64
+ dir: string;
65
+ }
66
+
67
+ export interface FooterLinkItem {
68
+ label: string;
69
+ href: string;
70
+ locales?: Record<string, { label: string }>;
71
+ }
72
+
73
+ export interface FooterLinkColumn {
74
+ title: string;
75
+ items: FooterLinkItem[];
76
+ locales?: Record<string, { title: string }>;
77
+ }
78
+
79
+ /**
80
+ * Per-locale overrides for the footer taglist labels.
81
+ *
82
+ * `title` — overrides `taglist.title` on this locale.
83
+ * `groupTitles` — per-group title overrides keyed by vocabulary `group`.
84
+ */
85
+ export interface FooterTaglistLocaleConfig {
86
+ title?: string;
87
+ groupTitles?: Record<string, string>;
88
+ }
89
+
90
+ /**
91
+ * Opt-in footer tag index.
92
+ *
93
+ * Renders one or more columns of tag links inside the existing footer grid.
94
+ * Off by default: when `enabled: false` (or the field is omitted entirely),
95
+ * the footer renders unchanged.
96
+ *
97
+ * - `groupBy: "group"` — one column per vocabulary `group`, in the order the
98
+ * groups first appear in `tag-vocabulary.ts`. Each column's title comes from
99
+ * `groupTitles[group]`, falling back to a capitalised version of the group
100
+ * name.
101
+ * - `groupBy: "flat"` — a single column titled `title` listing every tag
102
+ * alphabetically. This is also the fallback used when the vocabulary is
103
+ * inactive (`tagVocabulary: false` or `tagGovernance: "off"`).
104
+ */
105
+ export interface FooterTaglistConfig {
106
+ enabled: boolean;
107
+ /** Column title used in flat mode (and as fallback for ungrouped tags). */
108
+ title?: string;
109
+ /** Default `"group"` when the vocabulary is active, otherwise forced to `"flat"`. */
110
+ groupBy?: "group" | "flat";
111
+ /** English (default-locale) group titles, e.g. `{ type: "By type" }`. */
112
+ groupTitles?: Record<string, string>;
113
+ /** Locale-specific overrides for `title` and `groupTitles`. */
114
+ locales?: Record<string, FooterTaglistLocaleConfig>;
115
+ }
116
+
117
+ export interface FooterConfig {
118
+ links: FooterLinkColumn[];
119
+ /** Copyright text displayed at the bottom of the footer. HTML is supported. */
120
+ copyright?: string;
121
+ /** Opt-in footer tag index. Off by default. */
122
+ taglist?: FooterTaglistConfig;
123
+ }
124
+
125
+ export interface HtmlPreviewConfig {
126
+ /** Raw HTML injected into <head> (links, meta, fonts) */
127
+ head?: string;
128
+ /** CSS injected as <style> after preflight */
129
+ css?: string;
130
+ /** JS injected as <script> before </body> */
131
+ js?: string;
132
+ }
133
+
134
+ export interface FrontmatterPreviewConfig {
135
+ /**
136
+ * Completely replaces the default ignore list.
137
+ * When set, `extraIgnoreKeys` is ignored.
138
+ */
139
+ ignoreKeys?: string[];
140
+ /**
141
+ * Additional keys to ignore on top of the defaults.
142
+ * Has no effect when `ignoreKeys` is also set.
143
+ */
144
+ extraIgnoreKeys?: string[];
145
+ }
146
+
147
+ export type TagPlacement = "after-title" | "before-pager";
148
+
149
+ export type { TagGovernanceMode, TagVocabularyEntry } from "./tag-vocabulary-types";
150
+
151
+ export interface VersionConfig {
152
+ /** Version identifier, used in URL path (e.g., "1.0", "v1") */
153
+ slug: string;
154
+ /** Display label (e.g., "1.0.0", "Version 1") */
155
+ label: string;
156
+ /** Content directory for this version's English docs */
157
+ docsDir: string;
158
+ /** Per-locale content directories for this version */
159
+ locales?: Record<string, { dir: string }>;
160
+ /** Banner text shown on versioned pages (e.g., "unmaintained", "unreleased") */
161
+ banner?: "unmaintained" | "unreleased" | false;
162
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Sidebar configuration file.
3
+ *
4
+ * Items can be:
5
+ * - "autogenerated" — auto-scan a directory (default behavior)
6
+ * - doc references with optional overrides
7
+ * - external links
8
+ * - category groupings
9
+ *
10
+ * If this file exports an empty object or the key for a section is not found,
11
+ * the sidebar falls back to filesystem-based auto-generation.
12
+ */
13
+
14
+ export interface SidebarLink {
15
+ type: "link";
16
+ label: string;
17
+ href: string;
18
+ }
19
+
20
+ export interface SidebarDoc {
21
+ type: "doc";
22
+ id: string; // doc slug, e.g. "getting-started/introduction"
23
+ label?: string; // override the doc's title in sidebar
24
+ }
25
+
26
+ export interface SidebarCategory {
27
+ type: "category";
28
+ label: string;
29
+ items: SidebarItem[];
30
+ collapsed?: boolean;
31
+ sortOrder?: "asc" | "desc";
32
+ }
33
+
34
+ export interface SidebarAutogenerated {
35
+ type: "autogenerated";
36
+ dirName?: string; // subdirectory to scan (optional)
37
+ }
38
+
39
+ export type SidebarItem =
40
+ | SidebarDoc
41
+ | SidebarLink
42
+ | SidebarCategory
43
+ | SidebarAutogenerated
44
+ | string;
45
+
46
+ // String shorthand: "getting-started/introduction" is equivalent to
47
+ // { type: "doc", id: "getting-started/introduction" }
48
+
49
+ export interface SidebarsConfig {
50
+ [sectionKey: string]: SidebarItem[] | undefined;
51
+ }
52
+
53
+ /**
54
+ * Sidebar configuration.
55
+ * Keys correspond to headerNav categoryMatch values.
56
+ * If a section has no config here, it uses auto-generated filesystem sidebar.
57
+ */
58
+ const sidebars: SidebarsConfig = {
59
+ // Example:
60
+ // "!": [
61
+ // { type: "autogenerated" },
62
+ // { type: "link", label: "GitHub", href: "https://github.com/..." },
63
+ // ],
64
+ };
65
+
66
+ export default sidebars;