@takazudo/zudo-doc 4.2.1 → 4.4.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 (164) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +3 -3
  3. package/bin/zudo-doc.mjs +54 -13
  4. package/dist/auto-logo/index.d.ts +18 -0
  5. package/dist/auto-logo/index.js +33 -0
  6. package/dist/auto-logo/shapes.d.ts +32 -0
  7. package/dist/auto-logo/shapes.js +183 -0
  8. package/dist/auto-logo/standalone.d.ts +7 -0
  9. package/dist/auto-logo/standalone.js +35 -0
  10. package/dist/color-scheme-utils.d.ts +4 -3
  11. package/dist/color-scheme-utils.js +1 -1
  12. package/dist/config/component-tokens.js +2 -2
  13. package/dist/config.d.ts +23 -1
  14. package/dist/config.js +3 -0
  15. package/dist/content.css +4 -3
  16. package/dist/doc-content-header/index.js +1 -1
  17. package/dist/doc-history/index.js +1 -1
  18. package/dist/doc-history-area/index.d.ts +1 -0
  19. package/dist/doc-history-area/index.js +3 -0
  20. package/dist/doc-page-shell/index.js +1 -1
  21. package/dist/doc-pager/index.js +2 -2
  22. package/dist/eject-logo/config-parse.d.ts +25 -0
  23. package/dist/eject-logo/config-parse.js +68 -0
  24. package/dist/eject-logo/config-rewriter.d.ts +22 -0
  25. package/dist/eject-logo/config-rewriter.js +68 -0
  26. package/dist/eject-logo/eject.d.ts +18 -0
  27. package/dist/eject-logo/eject.js +66 -0
  28. package/dist/eject-logo/index.d.ts +4 -0
  29. package/dist/eject-logo/index.js +16 -0
  30. package/dist/eject-logo/site-name.d.ts +21 -0
  31. package/dist/eject-logo/site-name.js +31 -0
  32. package/dist/features.css +8 -29
  33. package/dist/header/header.js +14 -6
  34. package/dist/header/nav-class-tokens.d.ts +12 -0
  35. package/dist/header/nav-class-tokens.js +80 -0
  36. package/dist/header/nav-overflow-script.js +33 -16
  37. package/dist/home-page/index.d.ts +34 -5
  38. package/dist/home-page/index.js +95 -38
  39. package/dist/home-page/prepare-home-data.d.ts +9 -0
  40. package/dist/home-page/prepare-home-data.js +10 -3
  41. package/dist/html-preview-wrapper/highlight-runtime.d.ts +40 -0
  42. package/dist/html-preview-wrapper/highlight-runtime.js +58 -0
  43. package/dist/html-preview-wrapper/highlighted-code.d.ts +3 -2
  44. package/dist/html-preview-wrapper/highlighted-code.js +11 -30
  45. package/dist/i18n-defaults/index.js +3 -0
  46. package/dist/metainfo/doc-metainfo.js +35 -22
  47. package/dist/plugins/doc-history.js +6 -2
  48. package/dist/plugins/internal/doc-history/index.d.ts +2 -0
  49. package/dist/plugins/internal/doc-history/index.js +5 -0
  50. package/dist/plugins/internal/doc-history/pre-build.d.ts +2 -0
  51. package/dist/plugins/internal/doc-history/pre-build.js +3 -0
  52. package/dist/preset.d.ts +1 -0
  53. package/dist/preset.js +2 -1
  54. package/dist/routes/index.js +13 -3
  55. package/dist/routes/locale-index.js +12 -2
  56. package/dist/safelist.css +1 -1
  57. package/dist/settings.d.ts +15 -0
  58. package/dist/sidebar-tree-island/index.js +3 -3
  59. package/dist/theme-cli/config-scanner.js +47 -0
  60. package/dist/theme-packs/academia/fonts/CourierPrime-400-latin.woff2 +0 -0
  61. package/dist/theme-packs/academia/fonts/CourierPrime-700-latin.woff2 +0 -0
  62. package/dist/theme-packs/academia/fonts/OFL.txt +94 -0
  63. package/dist/theme-packs/academia/fonts/SourceSerif4-italic-latin.woff2 +0 -0
  64. package/dist/theme-packs/academia/fonts/SourceSerif4-latin.woff2 +0 -0
  65. package/dist/theme-packs/academia/meta.json +37 -0
  66. package/dist/theme-packs/academia/pack.css +505 -0
  67. package/dist/theme-packs/bauhaus/fonts/ArchivoBlack-latin.woff2 +0 -0
  68. package/dist/theme-packs/bauhaus/fonts/Jost-latin.woff2 +0 -0
  69. package/dist/theme-packs/bauhaus/fonts/OFL.txt +95 -0
  70. package/dist/theme-packs/bauhaus/fonts/SpaceMono-400-latin.woff2 +0 -0
  71. package/dist/theme-packs/bauhaus/fonts/SpaceMono-700-latin.woff2 +0 -0
  72. package/dist/theme-packs/bauhaus/meta.json +38 -0
  73. package/dist/theme-packs/bauhaus/pack.css +614 -0
  74. package/dist/theme-packs/blueprint/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  75. package/dist/theme-packs/blueprint/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  76. package/dist/theme-packs/blueprint/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  77. package/dist/theme-packs/blueprint/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  78. package/dist/theme-packs/blueprint/fonts/Inter-latin-ext.woff2 +0 -0
  79. package/dist/theme-packs/blueprint/fonts/Inter-latin.woff2 +0 -0
  80. package/dist/theme-packs/blueprint/fonts/JosefinSans-latin.woff2 +0 -0
  81. package/dist/theme-packs/blueprint/fonts/OFL.txt +95 -0
  82. package/dist/theme-packs/blueprint/meta.json +38 -0
  83. package/dist/theme-packs/blueprint/pack.css +577 -0
  84. package/dist/theme-packs/botanica/fonts/CormorantGaramond-latin.woff2 +0 -0
  85. package/dist/theme-packs/botanica/fonts/CourierPrime-400-latin-ext.woff2 +0 -0
  86. package/dist/theme-packs/botanica/fonts/CourierPrime-400-latin.woff2 +0 -0
  87. package/dist/theme-packs/botanica/fonts/CourierPrime-700-latin-ext.woff2 +0 -0
  88. package/dist/theme-packs/botanica/fonts/CourierPrime-700-latin.woff2 +0 -0
  89. package/dist/theme-packs/botanica/fonts/CrimsonPro-latin-italic.woff2 +0 -0
  90. package/dist/theme-packs/botanica/fonts/CrimsonPro-latin.woff2 +0 -0
  91. package/dist/theme-packs/botanica/fonts/OFL.txt +95 -0
  92. package/dist/theme-packs/botanica/meta.json +38 -0
  93. package/dist/theme-packs/botanica/pack.css +546 -0
  94. package/dist/theme-packs/brutalist/meta.json +1 -1
  95. package/dist/theme-packs/brutalist/pack.css +10 -9
  96. package/dist/theme-packs/eink/fonts/CourierPrime-400-latin-ext.woff2 +0 -0
  97. package/dist/theme-packs/eink/fonts/CourierPrime-400-latin.woff2 +0 -0
  98. package/dist/theme-packs/eink/fonts/CourierPrime-700-latin-ext.woff2 +0 -0
  99. package/dist/theme-packs/eink/fonts/CourierPrime-700-latin.woff2 +0 -0
  100. package/dist/theme-packs/eink/fonts/EBGaramond-latin-italic.woff2 +0 -0
  101. package/dist/theme-packs/eink/fonts/EBGaramond-latin.woff2 +0 -0
  102. package/dist/theme-packs/eink/fonts/OFL.txt +94 -0
  103. package/dist/theme-packs/eink/meta.json +37 -0
  104. package/dist/theme-packs/eink/pack.css +490 -0
  105. package/dist/theme-packs/foundry/meta.json +1 -1
  106. package/dist/theme-packs/foundry/pack.css +2 -2
  107. package/dist/theme-packs/hearth/meta.json +1 -1
  108. package/dist/theme-packs/hearth/pack.css +15 -4
  109. package/dist/theme-packs/nocturne/pack.css +4 -0
  110. package/dist/theme-packs/observatory/meta.json +1 -1
  111. package/dist/theme-packs/observatory/pack.css +4 -1
  112. package/dist/theme-packs/onyx/pack.css +6 -0
  113. package/dist/theme-packs/phosphor/pack.css +4 -0
  114. package/dist/theme-packs/riso/fonts/ArchivoBlack-latin.woff2 +0 -0
  115. package/dist/theme-packs/riso/fonts/OFL.txt +95 -0
  116. package/dist/theme-packs/riso/fonts/SpaceGrotesk-latin.woff2 +0 -0
  117. package/dist/theme-packs/riso/fonts/SpaceMono-400-italic-latin.woff2 +0 -0
  118. package/dist/theme-packs/riso/fonts/SpaceMono-400-latin.woff2 +0 -0
  119. package/dist/theme-packs/riso/fonts/SpaceMono-700-latin.woff2 +0 -0
  120. package/dist/theme-packs/riso/meta.json +38 -0
  121. package/dist/theme-packs/riso/pack.css +602 -0
  122. package/dist/theme-packs/sakura/fonts/MPlus1Code-400-latin.woff2 +0 -0
  123. package/dist/theme-packs/sakura/fonts/MPlus1Code-500-latin.woff2 +0 -0
  124. package/dist/theme-packs/sakura/fonts/Nunito-latin.woff2 +0 -0
  125. package/dist/theme-packs/sakura/fonts/OFL.txt +95 -0
  126. package/dist/theme-packs/sakura/fonts/ShipporiMincho-600-latin.woff2 +0 -0
  127. package/dist/theme-packs/sakura/fonts/ShipporiMincho-700-latin.woff2 +0 -0
  128. package/dist/theme-packs/sakura/meta.json +38 -0
  129. package/dist/theme-packs/sakura/pack.css +473 -0
  130. package/dist/theme-packs/scandi/fonts/Manrope-latin.woff2 +0 -0
  131. package/dist/theme-packs/scandi/fonts/OFL.txt +94 -0
  132. package/dist/theme-packs/scandi/fonts/SplineSansMono-latin.woff2 +0 -0
  133. package/dist/theme-packs/scandi/meta.json +37 -0
  134. package/dist/theme-packs/scandi/pack.css +370 -0
  135. package/dist/theme-packs/sumi/meta.json +1 -1
  136. package/dist/theme-packs/sumi/pack.css +4 -1
  137. package/dist/theme-packs/swissgrid/pack.css +4 -0
  138. package/dist/theme-packs/tidepool/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
  139. package/dist/theme-packs/tidepool/fonts/JetBrainsMono-latin.woff2 +0 -0
  140. package/dist/theme-packs/tidepool/fonts/OFL.txt +94 -0
  141. package/dist/theme-packs/tidepool/fonts/SpaceGrotesk-latin.woff2 +0 -0
  142. package/dist/theme-packs/tidepool/meta.json +37 -0
  143. package/dist/theme-packs/tidepool/pack.css +425 -0
  144. package/dist/theme-packs/timberline/fonts/Fraunces-italic-latin.woff2 +0 -0
  145. package/dist/theme-packs/timberline/fonts/Fraunces-latin.woff2 +0 -0
  146. package/dist/theme-packs/timberline/fonts/JetBrainsMono-latin.woff2 +0 -0
  147. package/dist/theme-packs/timberline/fonts/OFL.txt +95 -0
  148. package/dist/theme-packs/timberline/fonts/SourceSans3-italic-latin.woff2 +0 -0
  149. package/dist/theme-packs/timberline/fonts/SourceSans3-latin.woff2 +0 -0
  150. package/dist/theme-packs/timberline/meta.json +38 -0
  151. package/dist/theme-packs/timberline/pack.css +509 -0
  152. package/dist/theme-packs/washi/meta.json +1 -1
  153. package/dist/theme-packs/washi/pack.css +6 -26
  154. package/dist/theme-packs-registry/validator.js +24 -1
  155. package/dist/theme.css +1 -1
  156. package/eject/doc-history/index.tsx +1 -1
  157. package/eject/doc-pager/index.tsx +2 -2
  158. package/eject/header/header.tsx +16 -8
  159. package/eject/header/nav-class-tokens.ts +115 -0
  160. package/eject/header/nav-overflow-script.ts +49 -16
  161. package/eject/sidebar-tree-island/index.tsx +4 -4
  162. package/package.json +16 -13
  163. package/routes-src/index.tsx +10 -3
  164. package/routes-src/locale-index.tsx +9 -2
@@ -45,6 +45,14 @@ import {
45
45
  pathForMatch,
46
46
  } from "./nav-active.js";
47
47
  import { NAV_OVERFLOW_SCRIPT } from "./nav-overflow-script.js";
48
+ import {
49
+ NAV_CHEVRON_ACTIVE,
50
+ NAV_CHEVRON_INACTIVE,
51
+ NAV_CHILD_ACTIVE,
52
+ NAV_CHILD_INACTIVE,
53
+ NAV_TOP_ACTIVE,
54
+ NAV_TOP_INACTIVE,
55
+ } from "./nav-class-tokens.js";
48
56
  import { LANGUAGE_SWITCHER_INIT_SCRIPT } from "../i18n-version/language-switcher.js";
49
57
  import { VERSION_SWITCHER_REWIRE_SCRIPT } from "../i18n-version/version-switcher.js";
50
58
  import type {
@@ -349,7 +357,7 @@ export function Header(props: HeaderProps): JSX.Element {
349
357
  <div class="relative shrink-0" data-nav-more style="display:none">
350
358
  <button
351
359
  type="button"
352
- class="px-hsp-md py-vsp-2xs text-small font-medium text-muted hover:underline cursor-pointer"
360
+ class="px-hsp-md py-vsp-2xs text-small font-medium text-muted hover:text-accent hover:underline focus-visible:text-accent focus-visible:underline cursor-pointer"
353
361
  data-nav-more-toggle
354
362
  aria-expanded="false"
355
363
  >
@@ -454,15 +462,15 @@ function renderNavItem(
454
462
  class={[
455
463
  "flex items-center gap-x-hsp-xs px-hsp-md py-vsp-2xs text-small font-medium transition-colors",
456
464
  isActive
457
- ? "bg-fg text-bg"
458
- : "text-muted hover:underline focus:underline",
465
+ ? NAV_TOP_ACTIVE.join(" ")
466
+ : NAV_TOP_INACTIVE.join(" "),
459
467
  ].join(" ")}
460
468
  >
461
469
  {label}
462
470
  <svg
463
471
  class={[
464
472
  "h-[0.5rem] w-[0.5rem] shrink-0",
465
- isActive ? "text-bg" : "text-muted",
473
+ isActive ? NAV_CHEVRON_ACTIVE.join(" ") : NAV_CHEVRON_INACTIVE.join(" "),
466
474
  ].join(" ")}
467
475
  fill="none"
468
476
  viewBox="0 0 24 24"
@@ -492,8 +500,8 @@ function renderNavItem(
492
500
  href={childHref}
493
501
  data-active={childActive ? "" : undefined}
494
502
  class={[
495
- "block px-hsp-md py-vsp-2xs text-small hover:bg-accent/10 hover:underline",
496
- childActive ? "font-bold text-accent" : "text-fg",
503
+ "block px-hsp-md py-vsp-2xs text-small hover:bg-accent/10 hover:underline focus-visible:underline",
504
+ childActive ? NAV_CHILD_ACTIVE.join(" ") : NAV_CHILD_INACTIVE.join(" "),
497
505
  ].join(" ")}
498
506
  >
499
507
  {childLabel}
@@ -514,8 +522,8 @@ function renderNavItem(
514
522
  class={[
515
523
  "px-hsp-md py-vsp-2xs text-small font-medium transition-colors shrink-0",
516
524
  isActive
517
- ? "bg-fg text-bg"
518
- : "text-muted hover:underline focus:underline",
525
+ ? NAV_TOP_ACTIVE.join(" ")
526
+ : NAV_TOP_INACTIVE.join(" "),
519
527
  ].join(" ")}
520
528
  >
521
529
  {label}
@@ -0,0 +1,115 @@
1
+ // Single source of truth for the header desktop-nav class tokens that must
2
+ // stay in lockstep between the SSR markup (`header.tsx`) and the runtime
3
+ // rebuild/toggle script (`nav-overflow-script.ts`).
4
+ //
5
+ // WHY THIS MODULE EXISTS: the same class strings used to live, duplicated, in
6
+ // both files. `header.tsx` paints the active nav item on first render; the
7
+ // inline script re-paints it after SPA navigation and rebuilds the "···"
8
+ // overflow menu — so both files have to agree on the exact class lists. That
9
+ // duplicated knowledge drifted twice (zudolab/zudo-doc#3011 stale-class after
10
+ // navigation, #3016 divergence), each caught only by a throwaway script. Both
11
+ // files now derive their class strings from the arrays below, so the two can
12
+ // no longer silently diverge (guard: #3023).
13
+ //
14
+ // Tokens are ARRAYS, not whole strings, because the two consumers need
15
+ // different shapes: `header.tsx` joins them into `class={}` attributes, while
16
+ // the script both spreads them into `classList.add/remove(...)` calls and
17
+ // joins them into `className` assignments. Keeping them composable per-part
18
+ // also lets the overflow-menu recipes (which intentionally differ from the
19
+ // header-bar items in padding/weight/base) reuse the shared color tokens
20
+ // instead of re-typing them.
21
+
22
+ // ── Header-bar top-level item: active-state color toggle ─────────────────
23
+ // setTopActive() (script) ↔ the top-level <a> in renderNavItem() (SSR).
24
+ export const NAV_TOP_ACTIVE: readonly string[] = ["bg-fg", "text-bg"];
25
+ export const NAV_TOP_INACTIVE: readonly string[] = [
26
+ "text-muted",
27
+ "hover:text-accent",
28
+ "hover:underline",
29
+ "focus:underline",
30
+ "focus:text-accent",
31
+ ];
32
+
33
+ // ── Header-bar dropdown chevron SVG: active-state color toggle ───────────
34
+ // applyActiveNav() (script) ↔ the chevron <svg> in renderNavItem() (SSR).
35
+ export const NAV_CHEVRON_ACTIVE: readonly string[] = ["text-bg"];
36
+ export const NAV_CHEVRON_INACTIVE: readonly string[] = ["text-muted"];
37
+
38
+ // ── Header-bar dropdown child link: active-state color toggle ────────────
39
+ // applyActiveNav() (script) ↔ the child <a> in renderNavItem() (SSR). The
40
+ // static base (`block px-hsp-md ... focus-visible:underline`) stays inline in
41
+ // header.tsx — the script never rewrites it, so it can't drift across files.
42
+ export const NAV_CHILD_ACTIVE: readonly string[] = ["font-bold", "text-accent"];
43
+ export const NAV_CHILD_INACTIVE: readonly string[] = [
44
+ "text-fg",
45
+ "hover:text-accent",
46
+ "focus-visible:text-accent",
47
+ ];
48
+
49
+ // ── Overflow "···" menu row recipes ──────────────────────────────────────
50
+ // Assembled at runtime by update() in nav-overflow-script.ts. These are menu
51
+ // rows (indented, their own padding/weight), NOT header-bar items, so they
52
+ // intentionally differ from the toggle groups above. Co-located here so the
53
+ // whole header-nav class vocabulary has one home; the shared color tokens
54
+ // (e.g. NAV_CHILD_ACTIVE = "font-bold text-accent") are literally reused.
55
+ const MENU_ROW_BASE: readonly string[] = [
56
+ "block",
57
+ "px-hsp-md",
58
+ "py-vsp-2xs",
59
+ "text-small",
60
+ ];
61
+ const MENU_CHILD_BASE: readonly string[] = [
62
+ "block",
63
+ "pl-hsp-xl",
64
+ "pr-hsp-md",
65
+ "py-vsp-2xs",
66
+ "text-small",
67
+ ];
68
+ // Resting (inactive) interactive appearance shared by the parent + plain rows.
69
+ const MENU_ROW_RESTING: readonly string[] = [
70
+ "hover:bg-accent/10",
71
+ "hover:underline",
72
+ "focus-visible:underline",
73
+ "focus-visible:text-accent",
74
+ "text-fg",
75
+ "hover:text-accent",
76
+ ];
77
+
78
+ // Overflow bucket: promoted dropdown-parent link (bold label). Active rows
79
+ // additionally get NAV_MENU_PARENT_ACTIVE_SUFFIX appended.
80
+ export const NAV_MENU_PARENT: readonly string[] = [
81
+ ...MENU_ROW_BASE,
82
+ "font-bold",
83
+ ...MENU_ROW_RESTING,
84
+ ];
85
+ export const NAV_MENU_PARENT_ACTIVE_SUFFIX: readonly string[] = ["text-accent"];
86
+
87
+ // Overflow bucket: plain (non-dropdown) item link. Active rows additionally
88
+ // get NAV_MENU_PLAIN_ACTIVE_SUFFIX (= NAV_CHILD_ACTIVE) appended.
89
+ export const NAV_MENU_PLAIN: readonly string[] = [
90
+ ...MENU_ROW_BASE,
91
+ ...MENU_ROW_RESTING,
92
+ ];
93
+ export const NAV_MENU_PLAIN_ACTIVE_SUFFIX: readonly string[] = [
94
+ ...NAV_CHILD_ACTIVE,
95
+ ];
96
+
97
+ // Overflow bucket: indented dropdown-child link (active vs resting variants
98
+ // are whole strings — the resting variant interleaves menu affordances with
99
+ // the child color tokens, so it is spelled out rather than composed).
100
+ export const NAV_MENU_CHILD_ACTIVE: readonly string[] = [
101
+ ...MENU_CHILD_BASE,
102
+ ...NAV_CHILD_ACTIVE,
103
+ "hover:bg-accent/10",
104
+ "hover:underline",
105
+ "focus-visible:underline",
106
+ ];
107
+ export const NAV_MENU_CHILD_INACTIVE: readonly string[] = [
108
+ ...MENU_CHILD_BASE,
109
+ "text-fg",
110
+ "hover:bg-accent/10",
111
+ "hover:text-accent",
112
+ "hover:underline",
113
+ "focus-visible:underline",
114
+ "focus-visible:text-accent",
115
+ ];
@@ -31,6 +31,39 @@
31
31
  // script can be reviewed in isolation.
32
32
 
33
33
  import { AFTER_NAVIGATE_EVENT } from "../transitions/page-events.js";
34
+ import {
35
+ NAV_CHEVRON_ACTIVE,
36
+ NAV_CHEVRON_INACTIVE,
37
+ NAV_CHILD_ACTIVE,
38
+ NAV_CHILD_INACTIVE,
39
+ NAV_MENU_CHILD_ACTIVE,
40
+ NAV_MENU_CHILD_INACTIVE,
41
+ NAV_MENU_PARENT,
42
+ NAV_MENU_PARENT_ACTIVE_SUFFIX,
43
+ NAV_MENU_PLAIN,
44
+ NAV_MENU_PLAIN_ACTIVE_SUFFIX,
45
+ NAV_TOP_ACTIVE,
46
+ NAV_TOP_INACTIVE,
47
+ } from "./nav-class-tokens.js";
48
+
49
+ // The class lists spliced into the script below are the SSR ↔ runtime
50
+ // lockstep: they must match the strings header.tsx renders. Both files import
51
+ // them from ./nav-class-tokens so they cannot drift (zudolab/zudo-doc#3023).
52
+ // The script ships as plain text via dangerouslySetInnerHTML and cannot import
53
+ // the arrays at runtime, so these helpers splice the token lists into the
54
+ // script string at module-eval (build) time instead.
55
+
56
+ // -> `"bg-fg", "text-bg"` — argument list for a classList.add/remove(...) call.
57
+ const clsArgs = (tokens: readonly string[]): string =>
58
+ tokens.map((token) => JSON.stringify(token)).join(", ");
59
+
60
+ // -> `"bg-fg text-bg"` — a single class-string literal for `className = ...`.
61
+ const clsLiteral = (tokens: readonly string[]): string =>
62
+ JSON.stringify(tokens.join(" "));
63
+
64
+ // -> `" font-bold text-accent"` — leading-space append for `className += ...`.
65
+ const clsAppend = (tokens: readonly string[]): string =>
66
+ JSON.stringify(" " + tokens.join(" "));
34
67
 
35
68
  export const NAV_OVERFLOW_SCRIPT = `(function () {
36
69
  var cleanupNavOverflow = null;
@@ -89,12 +122,12 @@ export const NAV_OVERFLOW_SCRIPT = `(function () {
89
122
  function setTopActive(a, active) {
90
123
  if (!a) return;
91
124
  if (active) {
92
- a.classList.add("bg-fg", "text-bg");
93
- a.classList.remove("text-muted", "hover:underline", "focus:underline");
125
+ a.classList.add(${clsArgs(NAV_TOP_ACTIVE)});
126
+ a.classList.remove(${clsArgs(NAV_TOP_INACTIVE)});
94
127
  a.setAttribute("aria-current", "page");
95
128
  } else {
96
- a.classList.remove("bg-fg", "text-bg");
97
- a.classList.add("text-muted", "hover:underline", "focus:underline");
129
+ a.classList.remove(${clsArgs(NAV_TOP_ACTIVE)});
130
+ a.classList.add(${clsArgs(NAV_TOP_INACTIVE)});
98
131
  a.removeAttribute("aria-current");
99
132
  }
100
133
  }
@@ -112,19 +145,19 @@ export const NAV_OVERFLOW_SCRIPT = `(function () {
112
145
  if (childActive) {
113
146
  anyChild = true;
114
147
  c.setAttribute("data-active", "");
115
- c.classList.add("font-bold", "text-accent");
116
- c.classList.remove("text-fg");
148
+ c.classList.add(${clsArgs(NAV_CHILD_ACTIVE)});
149
+ c.classList.remove(${clsArgs(NAV_CHILD_INACTIVE)});
117
150
  } else {
118
151
  c.removeAttribute("data-active");
119
- c.classList.remove("font-bold", "text-accent");
120
- c.classList.add("text-fg");
152
+ c.classList.remove(${clsArgs(NAV_CHILD_ACTIVE)});
153
+ c.classList.add(${clsArgs(NAV_CHILD_INACTIVE)});
121
154
  }
122
155
  });
123
156
  topActive = parentMatch || anyChild;
124
157
  var svg = topA ? topA.querySelector("svg") : null;
125
158
  if (svg) {
126
- if (topActive) { svg.classList.add("text-bg"); svg.classList.remove("text-muted"); }
127
- else { svg.classList.add("text-muted"); svg.classList.remove("text-bg"); }
159
+ if (topActive) { svg.classList.add(${clsArgs(NAV_CHEVRON_ACTIVE)}); svg.classList.remove(${clsArgs(NAV_CHEVRON_INACTIVE)}); }
160
+ else { svg.classList.add(${clsArgs(NAV_CHEVRON_INACTIVE)}); svg.classList.remove(${clsArgs(NAV_CHEVRON_ACTIVE)}); }
128
161
  }
129
162
  } else {
130
163
  topActive = activePath !== "" && navPathname(topA) === activePath;
@@ -206,9 +239,9 @@ export const NAV_OVERFLOW_SCRIPT = `(function () {
206
239
  a.href = parentLink.href;
207
240
  var parentText = parentLink.textContent ? parentLink.textContent.trim().replace(/\\s+/g, " ") : "";
208
241
  a.textContent = parentText;
209
- a.className = "block px-hsp-md py-vsp-2xs text-small font-bold hover:bg-accent/10 hover:underline focus-visible:underline text-fg";
242
+ a.className = ${clsLiteral(NAV_MENU_PARENT)};
210
243
  if (parentLink.getAttribute("aria-current") === "page") {
211
- a.className += " text-accent";
244
+ a.className += ${clsAppend(NAV_MENU_PARENT_ACTIVE_SUFFIX)};
212
245
  }
213
246
  li.appendChild(a);
214
247
  moreMenu.appendChild(li);
@@ -220,8 +253,8 @@ export const NAV_OVERFLOW_SCRIPT = `(function () {
220
253
  a.textContent = child.textContent ? child.textContent.trim() : "";
221
254
  var isChildActive = child.hasAttribute("data-active");
222
255
  a.className = isChildActive
223
- ? "block pl-hsp-xl pr-hsp-md py-vsp-2xs text-small font-bold text-accent hover:bg-accent/10 hover:underline focus-visible:underline"
224
- : "block pl-hsp-xl pr-hsp-md py-vsp-2xs text-small text-muted hover:bg-accent/10 hover:text-fg hover:underline focus-visible:underline";
256
+ ? ${clsLiteral(NAV_MENU_CHILD_ACTIVE)}
257
+ : ${clsLiteral(NAV_MENU_CHILD_INACTIVE)};
225
258
  li.appendChild(a);
226
259
  moreMenu.appendChild(li);
227
260
  });
@@ -231,9 +264,9 @@ export const NAV_OVERFLOW_SCRIPT = `(function () {
231
264
  var a2 = document.createElement("a");
232
265
  a2.href = anchor.href;
233
266
  a2.textContent = anchor.textContent ? anchor.textContent.trim() : "";
234
- a2.className = "block px-hsp-md py-vsp-2xs text-small hover:bg-accent/10 hover:underline focus-visible:underline text-fg";
267
+ a2.className = ${clsLiteral(NAV_MENU_PLAIN)};
235
268
  if (anchor.getAttribute("aria-current") === "page") {
236
- a2.className += " font-bold text-accent";
269
+ a2.className += ${clsAppend(NAV_MENU_PLAIN_ACTIVE_SUFFIX)};
237
270
  }
238
271
  li2.appendChild(a2);
239
272
  moreMenu.appendChild(li2);
@@ -447,7 +447,7 @@ const CategoryNode = memo(function CategoryNode({
447
447
  <a
448
448
  href={node.href}
449
449
  aria-current={isActive ? "page" : undefined}
450
- className={`flex-1 flex items-start gap-hsp-xs py-vsp-xs hover:underline focus:underline break-words ${isActive ? "text-bg" : "text-fg"}`}
450
+ className={`flex-1 flex items-start gap-hsp-xs py-vsp-xs hover:underline focus:underline break-words ${isActive ? "text-bg" : "text-fg hover:text-accent focus:text-accent"}`}
451
451
  style={{ paddingLeft }}
452
452
  >
453
453
  {depth === 0 && (
@@ -471,7 +471,7 @@ const CategoryNode = memo(function CategoryNode({
471
471
  <button
472
472
  type="button"
473
473
  onClick={toggle}
474
- className={`flex w-full items-center gap-hsp-md text-left text-small font-semibold py-vsp-xs text-fg hover:underline focus:underline break-words`}
474
+ className={`flex w-full items-center gap-hsp-md text-left text-small font-semibold py-vsp-xs text-fg hover:text-accent hover:underline focus:underline focus:text-accent break-words`}
475
475
  style={{ paddingLeft }}
476
476
  aria-expanded={isExpanded}
477
477
  aria-label={isExpanded ? `Collapse ${node.label}` : `Expand ${node.label}`}
@@ -536,12 +536,12 @@ const LeafNode = memo(function LeafNode({
536
536
  data-nav-active={!isRoot && isActive ? "" : undefined}
537
537
  className={isRoot
538
538
  ? `flex items-start gap-hsp-xs py-[calc(var(--spacing-vsp-xs)+0.15rem)] pr-[4px] text-small font-semibold break-words ${
539
- isActive ? "bg-fg text-bg" : "text-fg hover:underline focus:underline"
539
+ isActive ? "bg-fg text-bg" : "text-fg hover:text-accent hover:underline focus:underline focus:text-accent"
540
540
  }`
541
541
  : `block py-vsp-2xs pr-[4px] text-small break-words ${
542
542
  isActive
543
543
  ? "bg-fg font-medium text-bg"
544
- : "text-muted hover:underline focus:underline"
544
+ : "text-muted hover:text-accent hover:underline focus:underline focus:text-accent"
545
545
  }`
546
546
  }
547
547
  style={{ paddingLeft }}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takazudo/zudo-doc",
3
- "version": "4.2.1",
3
+ "version": "4.4.0",
4
4
  "type": "module",
5
5
  "description": "zudo-doc framework primitives layer that sits on top of zfb's engine — sidebar, theme, TOC, breadcrumb, layouts, head injection, View Transitions, SSR-skip wrappers (per ADR-003).",
6
6
  "license": "MIT",
@@ -151,6 +151,10 @@
151
151
  "types": "./dist/preset.d.ts",
152
152
  "default": "./dist/preset.js"
153
153
  },
154
+ "./auto-logo": {
155
+ "types": "./dist/auto-logo/index.d.ts",
156
+ "default": "./dist/auto-logo/index.js"
157
+ },
154
158
  "./component-tokens": {
155
159
  "types": "./dist/config/component-tokens.d.ts",
156
160
  "default": "./dist/config/component-tokens.js"
@@ -567,6 +571,10 @@
567
571
  "./theme-cli": {
568
572
  "types": "./dist/theme-cli/index.d.ts",
569
573
  "default": "./dist/theme-cli/index.js"
574
+ },
575
+ "./eject-logo": {
576
+ "types": "./dist/eject-logo/index.d.ts",
577
+ "default": "./dist/eject-logo/index.js"
570
578
  }
571
579
  },
572
580
  "bin": {
@@ -589,14 +597,13 @@
589
597
  ],
590
598
  "peerDependencies": {
591
599
  "@takazudo/zdtp": "^0.4.9",
592
- "@takazudo/zfb": "^0.1.0-next.89",
593
- "@takazudo/zfb-md-wasm": "^0.1.0-next.89",
594
- "@takazudo/zfb-runtime": "^0.1.0-next.89",
600
+ "@takazudo/zfb": "^0.1.0-next.90",
601
+ "@takazudo/zfb-md-wasm": "^0.1.0-next.90",
602
+ "@takazudo/zfb-runtime": "^0.1.0-next.90",
595
603
  "@takazudo/zudo-doc-history-server": "^4.0.0",
596
604
  "diff": "^8.0.0",
597
605
  "katex": "^0.16.0",
598
606
  "preact": "^10.29.1",
599
- "shiki": "^4.0.2",
600
607
  "zod": "^4.3.6"
601
608
  },
602
609
  "peerDependenciesMeta": {
@@ -609,9 +616,6 @@
609
616
  "@takazudo/zfb-md-wasm": {
610
617
  "optional": true
611
618
  },
612
- "shiki": {
613
- "optional": true
614
- },
615
619
  "katex": {
616
620
  "optional": true
617
621
  },
@@ -630,9 +634,9 @@
630
634
  "tsx": "^4.21.0"
631
635
  },
632
636
  "devDependencies": {
633
- "@takazudo/zfb": "0.1.0-next.89",
634
- "@takazudo/zfb-md-wasm": "0.1.0-next.89",
635
- "@takazudo/zfb-runtime": "0.1.0-next.89",
637
+ "@takazudo/zfb": "0.1.0-next.90",
638
+ "@takazudo/zfb-md-wasm": "0.1.0-next.90",
639
+ "@takazudo/zfb-runtime": "0.1.0-next.90",
636
640
  "@types/fs-extra": "^11.0.4",
637
641
  "@types/minimist": "^1.2.5",
638
642
  "@types/node": "^25.3.5",
@@ -642,12 +646,11 @@
642
646
  "happy-dom": "^20.10.6",
643
647
  "preact": "^10.29.1",
644
648
  "preact-render-to-string": "^6.6.6",
645
- "shiki": "^4.0.2",
646
649
  "tsup": "^8.0.0",
647
650
  "typescript": "^5.0.0",
648
651
  "vitest": "^4.1.0",
649
652
  "zod": "^4.3.6",
650
- "@takazudo/zudo-doc-history-server": "4.2.1"
653
+ "@takazudo/zudo-doc-history-server": "4.4.0"
651
654
  },
652
655
  "scripts": {
653
656
  "build": "tsup && tsc -p tsconfig.build.json",
@@ -11,7 +11,7 @@
11
11
  // the result to the shared home body factory.
12
12
 
13
13
  import type { JSX } from "preact";
14
- import { defaultLocale, routeCtx } from "./_context.js";
14
+ import { defaultLocale, routeCtx, settings } from "./_context.js";
15
15
  import { prepareHomeData } from "@takazudo/zudo-doc/home-page";
16
16
  import { HomePageView } from "./_chrome.js";
17
17
 
@@ -20,9 +20,16 @@ export const frontmatter = { title: "Home" };
20
20
  export default function IndexPage(): JSX.Element {
21
21
  const locale = defaultLocale;
22
22
 
23
- const { tree, categoryOrder, tagCount } = prepareHomeData(routeCtx, locale);
23
+ const { tree, categoryOrder, tagCount, tags } = prepareHomeData(routeCtx, locale);
24
24
 
25
25
  return (
26
- <HomePageView locale={locale} tree={tree} categoryOrder={categoryOrder} tagCount={tagCount} />
26
+ <HomePageView
27
+ locale={locale}
28
+ tree={tree}
29
+ categoryOrder={categoryOrder}
30
+ tagCount={tagCount}
31
+ tags={tags}
32
+ wide={settings.home?.wide ?? false}
33
+ />
27
34
  );
28
35
  }
@@ -34,9 +34,16 @@ interface PageArgs {
34
34
  export default function LocaleIndexPage({ params }: PageArgs): JSX.Element {
35
35
  const locale = params.locale;
36
36
 
37
- const { tree, categoryOrder, tagCount } = prepareHomeData(routeCtx, locale);
37
+ const { tree, categoryOrder, tagCount, tags } = prepareHomeData(routeCtx, locale);
38
38
 
39
39
  return (
40
- <HomePageView locale={locale} tree={tree} categoryOrder={categoryOrder} tagCount={tagCount} />
40
+ <HomePageView
41
+ locale={locale}
42
+ tree={tree}
43
+ categoryOrder={categoryOrder}
44
+ tagCount={tagCount}
45
+ tags={tags}
46
+ wide={settings.home?.wide ?? false}
47
+ />
41
48
  );
42
49
  }