@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.
- package/CHANGELOG.md +43 -0
- package/README.md +3 -3
- package/bin/zudo-doc.mjs +54 -13
- package/dist/auto-logo/index.d.ts +18 -0
- package/dist/auto-logo/index.js +33 -0
- package/dist/auto-logo/shapes.d.ts +32 -0
- package/dist/auto-logo/shapes.js +183 -0
- package/dist/auto-logo/standalone.d.ts +7 -0
- package/dist/auto-logo/standalone.js +35 -0
- package/dist/color-scheme-utils.d.ts +4 -3
- package/dist/color-scheme-utils.js +1 -1
- package/dist/config/component-tokens.js +2 -2
- package/dist/config.d.ts +23 -1
- package/dist/config.js +3 -0
- package/dist/content.css +4 -3
- package/dist/doc-content-header/index.js +1 -1
- package/dist/doc-history/index.js +1 -1
- package/dist/doc-history-area/index.d.ts +1 -0
- package/dist/doc-history-area/index.js +3 -0
- package/dist/doc-page-shell/index.js +1 -1
- package/dist/doc-pager/index.js +2 -2
- package/dist/eject-logo/config-parse.d.ts +25 -0
- package/dist/eject-logo/config-parse.js +68 -0
- package/dist/eject-logo/config-rewriter.d.ts +22 -0
- package/dist/eject-logo/config-rewriter.js +68 -0
- package/dist/eject-logo/eject.d.ts +18 -0
- package/dist/eject-logo/eject.js +66 -0
- package/dist/eject-logo/index.d.ts +4 -0
- package/dist/eject-logo/index.js +16 -0
- package/dist/eject-logo/site-name.d.ts +21 -0
- package/dist/eject-logo/site-name.js +31 -0
- package/dist/features.css +8 -29
- package/dist/header/header.js +14 -6
- package/dist/header/nav-class-tokens.d.ts +12 -0
- package/dist/header/nav-class-tokens.js +80 -0
- package/dist/header/nav-overflow-script.js +33 -16
- package/dist/home-page/index.d.ts +34 -5
- package/dist/home-page/index.js +95 -38
- package/dist/home-page/prepare-home-data.d.ts +9 -0
- package/dist/home-page/prepare-home-data.js +10 -3
- package/dist/html-preview-wrapper/highlight-runtime.d.ts +40 -0
- package/dist/html-preview-wrapper/highlight-runtime.js +58 -0
- package/dist/html-preview-wrapper/highlighted-code.d.ts +3 -2
- package/dist/html-preview-wrapper/highlighted-code.js +11 -30
- package/dist/i18n-defaults/index.js +3 -0
- package/dist/metainfo/doc-metainfo.js +35 -22
- package/dist/plugins/doc-history.js +6 -2
- package/dist/plugins/internal/doc-history/index.d.ts +2 -0
- package/dist/plugins/internal/doc-history/index.js +5 -0
- package/dist/plugins/internal/doc-history/pre-build.d.ts +2 -0
- package/dist/plugins/internal/doc-history/pre-build.js +3 -0
- package/dist/preset.d.ts +1 -0
- package/dist/preset.js +2 -1
- package/dist/routes/index.js +13 -3
- package/dist/routes/locale-index.js +12 -2
- package/dist/safelist.css +1 -1
- package/dist/settings.d.ts +15 -0
- package/dist/sidebar-tree-island/index.js +3 -3
- package/dist/theme-cli/config-scanner.js +47 -0
- package/dist/theme-packs/academia/fonts/CourierPrime-400-latin.woff2 +0 -0
- package/dist/theme-packs/academia/fonts/CourierPrime-700-latin.woff2 +0 -0
- package/dist/theme-packs/academia/fonts/OFL.txt +94 -0
- package/dist/theme-packs/academia/fonts/SourceSerif4-italic-latin.woff2 +0 -0
- package/dist/theme-packs/academia/fonts/SourceSerif4-latin.woff2 +0 -0
- package/dist/theme-packs/academia/meta.json +37 -0
- package/dist/theme-packs/academia/pack.css +505 -0
- package/dist/theme-packs/bauhaus/fonts/ArchivoBlack-latin.woff2 +0 -0
- package/dist/theme-packs/bauhaus/fonts/Jost-latin.woff2 +0 -0
- package/dist/theme-packs/bauhaus/fonts/OFL.txt +95 -0
- package/dist/theme-packs/bauhaus/fonts/SpaceMono-400-latin.woff2 +0 -0
- package/dist/theme-packs/bauhaus/fonts/SpaceMono-700-latin.woff2 +0 -0
- package/dist/theme-packs/bauhaus/meta.json +38 -0
- package/dist/theme-packs/bauhaus/pack.css +614 -0
- package/dist/theme-packs/blueprint/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
- package/dist/theme-packs/blueprint/fonts/IBMPlexMono-400-latin.woff2 +0 -0
- package/dist/theme-packs/blueprint/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
- package/dist/theme-packs/blueprint/fonts/IBMPlexMono-500-latin.woff2 +0 -0
- package/dist/theme-packs/blueprint/fonts/Inter-latin-ext.woff2 +0 -0
- package/dist/theme-packs/blueprint/fonts/Inter-latin.woff2 +0 -0
- package/dist/theme-packs/blueprint/fonts/JosefinSans-latin.woff2 +0 -0
- package/dist/theme-packs/blueprint/fonts/OFL.txt +95 -0
- package/dist/theme-packs/blueprint/meta.json +38 -0
- package/dist/theme-packs/blueprint/pack.css +577 -0
- package/dist/theme-packs/botanica/fonts/CormorantGaramond-latin.woff2 +0 -0
- package/dist/theme-packs/botanica/fonts/CourierPrime-400-latin-ext.woff2 +0 -0
- package/dist/theme-packs/botanica/fonts/CourierPrime-400-latin.woff2 +0 -0
- package/dist/theme-packs/botanica/fonts/CourierPrime-700-latin-ext.woff2 +0 -0
- package/dist/theme-packs/botanica/fonts/CourierPrime-700-latin.woff2 +0 -0
- package/dist/theme-packs/botanica/fonts/CrimsonPro-latin-italic.woff2 +0 -0
- package/dist/theme-packs/botanica/fonts/CrimsonPro-latin.woff2 +0 -0
- package/dist/theme-packs/botanica/fonts/OFL.txt +95 -0
- package/dist/theme-packs/botanica/meta.json +38 -0
- package/dist/theme-packs/botanica/pack.css +546 -0
- package/dist/theme-packs/brutalist/meta.json +1 -1
- package/dist/theme-packs/brutalist/pack.css +10 -9
- package/dist/theme-packs/eink/fonts/CourierPrime-400-latin-ext.woff2 +0 -0
- package/dist/theme-packs/eink/fonts/CourierPrime-400-latin.woff2 +0 -0
- package/dist/theme-packs/eink/fonts/CourierPrime-700-latin-ext.woff2 +0 -0
- package/dist/theme-packs/eink/fonts/CourierPrime-700-latin.woff2 +0 -0
- package/dist/theme-packs/eink/fonts/EBGaramond-latin-italic.woff2 +0 -0
- package/dist/theme-packs/eink/fonts/EBGaramond-latin.woff2 +0 -0
- package/dist/theme-packs/eink/fonts/OFL.txt +94 -0
- package/dist/theme-packs/eink/meta.json +37 -0
- package/dist/theme-packs/eink/pack.css +490 -0
- package/dist/theme-packs/foundry/meta.json +1 -1
- package/dist/theme-packs/foundry/pack.css +2 -2
- package/dist/theme-packs/hearth/meta.json +1 -1
- package/dist/theme-packs/hearth/pack.css +15 -4
- package/dist/theme-packs/nocturne/pack.css +4 -0
- package/dist/theme-packs/observatory/meta.json +1 -1
- package/dist/theme-packs/observatory/pack.css +4 -1
- package/dist/theme-packs/onyx/pack.css +6 -0
- package/dist/theme-packs/phosphor/pack.css +4 -0
- package/dist/theme-packs/riso/fonts/ArchivoBlack-latin.woff2 +0 -0
- package/dist/theme-packs/riso/fonts/OFL.txt +95 -0
- package/dist/theme-packs/riso/fonts/SpaceGrotesk-latin.woff2 +0 -0
- package/dist/theme-packs/riso/fonts/SpaceMono-400-italic-latin.woff2 +0 -0
- package/dist/theme-packs/riso/fonts/SpaceMono-400-latin.woff2 +0 -0
- package/dist/theme-packs/riso/fonts/SpaceMono-700-latin.woff2 +0 -0
- package/dist/theme-packs/riso/meta.json +38 -0
- package/dist/theme-packs/riso/pack.css +602 -0
- package/dist/theme-packs/sakura/fonts/MPlus1Code-400-latin.woff2 +0 -0
- package/dist/theme-packs/sakura/fonts/MPlus1Code-500-latin.woff2 +0 -0
- package/dist/theme-packs/sakura/fonts/Nunito-latin.woff2 +0 -0
- package/dist/theme-packs/sakura/fonts/OFL.txt +95 -0
- package/dist/theme-packs/sakura/fonts/ShipporiMincho-600-latin.woff2 +0 -0
- package/dist/theme-packs/sakura/fonts/ShipporiMincho-700-latin.woff2 +0 -0
- package/dist/theme-packs/sakura/meta.json +38 -0
- package/dist/theme-packs/sakura/pack.css +473 -0
- package/dist/theme-packs/scandi/fonts/Manrope-latin.woff2 +0 -0
- package/dist/theme-packs/scandi/fonts/OFL.txt +94 -0
- package/dist/theme-packs/scandi/fonts/SplineSansMono-latin.woff2 +0 -0
- package/dist/theme-packs/scandi/meta.json +37 -0
- package/dist/theme-packs/scandi/pack.css +370 -0
- package/dist/theme-packs/sumi/meta.json +1 -1
- package/dist/theme-packs/sumi/pack.css +4 -1
- package/dist/theme-packs/swissgrid/pack.css +4 -0
- package/dist/theme-packs/tidepool/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
- package/dist/theme-packs/tidepool/fonts/JetBrainsMono-latin.woff2 +0 -0
- package/dist/theme-packs/tidepool/fonts/OFL.txt +94 -0
- package/dist/theme-packs/tidepool/fonts/SpaceGrotesk-latin.woff2 +0 -0
- package/dist/theme-packs/tidepool/meta.json +37 -0
- package/dist/theme-packs/tidepool/pack.css +425 -0
- package/dist/theme-packs/timberline/fonts/Fraunces-italic-latin.woff2 +0 -0
- package/dist/theme-packs/timberline/fonts/Fraunces-latin.woff2 +0 -0
- package/dist/theme-packs/timberline/fonts/JetBrainsMono-latin.woff2 +0 -0
- package/dist/theme-packs/timberline/fonts/OFL.txt +95 -0
- package/dist/theme-packs/timberline/fonts/SourceSans3-italic-latin.woff2 +0 -0
- package/dist/theme-packs/timberline/fonts/SourceSans3-latin.woff2 +0 -0
- package/dist/theme-packs/timberline/meta.json +38 -0
- package/dist/theme-packs/timberline/pack.css +509 -0
- package/dist/theme-packs/washi/meta.json +1 -1
- package/dist/theme-packs/washi/pack.css +6 -26
- package/dist/theme-packs-registry/validator.js +24 -1
- package/dist/theme.css +1 -1
- package/eject/doc-history/index.tsx +1 -1
- package/eject/doc-pager/index.tsx +2 -2
- package/eject/header/header.tsx +16 -8
- package/eject/header/nav-class-tokens.ts +115 -0
- package/eject/header/nav-overflow-script.ts +49 -16
- package/eject/sidebar-tree-island/index.tsx +4 -4
- package/package.json +16 -13
- package/routes-src/index.tsx +10 -3
- package/routes-src/locale-index.tsx +9 -2
package/eject/header/header.tsx
CHANGED
|
@@ -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
|
-
? "
|
|
458
|
-
: "
|
|
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 ? "
|
|
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 ? "
|
|
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
|
-
? "
|
|
518
|
-
: "
|
|
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(
|
|
93
|
-
a.classList.remove(
|
|
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(
|
|
97
|
-
a.classList.add(
|
|
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(
|
|
116
|
-
c.classList.remove(
|
|
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(
|
|
120
|
-
c.classList.add(
|
|
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(
|
|
127
|
-
else { svg.classList.add(
|
|
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 =
|
|
242
|
+
a.className = ${clsLiteral(NAV_MENU_PARENT)};
|
|
210
243
|
if (parentLink.getAttribute("aria-current") === "page") {
|
|
211
|
-
a.className +=
|
|
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
|
-
?
|
|
224
|
-
:
|
|
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 =
|
|
267
|
+
a2.className = ${clsLiteral(NAV_MENU_PLAIN)};
|
|
235
268
|
if (anchor.getAttribute("aria-current") === "page") {
|
|
236
|
-
a2.className +=
|
|
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.
|
|
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.
|
|
593
|
-
"@takazudo/zfb-md-wasm": "^0.1.0-next.
|
|
594
|
-
"@takazudo/zfb-runtime": "^0.1.0-next.
|
|
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.
|
|
634
|
-
"@takazudo/zfb-md-wasm": "0.1.0-next.
|
|
635
|
-
"@takazudo/zfb-runtime": "0.1.0-next.
|
|
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.
|
|
653
|
+
"@takazudo/zudo-doc-history-server": "4.4.0"
|
|
651
654
|
},
|
|
652
655
|
"scripts": {
|
|
653
656
|
"build": "tsup && tsc -p tsconfig.build.json",
|
package/routes-src/index.tsx
CHANGED
|
@@ -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
|
|
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
|
|
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
|
}
|