@takazudo/zudo-doc 3.2.0 → 3.3.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 +29 -0
- package/dist/chrome/derive.d.ts +7 -1
- package/dist/chrome/derive.js +13 -2
- package/dist/chrome-bindings.d.ts +159 -0
- package/dist/chrome-bindings.js +6 -0
- package/dist/color-scheme-utils.d.ts +1 -1
- package/dist/color-schemes-defaults/index.d.ts +23 -0
- package/dist/color-schemes-defaults/index.js +121 -0
- package/dist/config.d.ts +443 -0
- package/dist/config.js +116 -0
- package/dist/design-token-panel-bootstrap.d.ts +57 -7
- package/dist/design-token-panel-bootstrap.js +12 -0
- package/dist/design-token-panel-config/index.d.ts +49 -0
- package/dist/design-token-panel-config/index.js +214 -0
- package/dist/design-token-panel-config/manifest.d.ts +46 -0
- package/dist/design-token-panel-config/manifest.js +105 -0
- package/dist/directive-vocabulary-defaults/index.d.ts +16 -0
- package/dist/directive-vocabulary-defaults/index.js +12 -0
- package/dist/doc-body-end-islands/index.d.ts +30 -7
- package/dist/doc-body-end-islands/index.js +27 -0
- package/dist/docs-schema/index.d.ts +67 -0
- package/dist/docs-schema/index.js +47 -0
- package/dist/factory-context/index.d.ts +14 -0
- package/dist/features.css +10 -0
- package/dist/find-in-page/find-bar.d.ts +9 -0
- package/dist/find-in-page/find-bar.js +114 -0
- package/dist/find-in-page/find-in-page.d.ts +17 -0
- package/dist/find-in-page/find-in-page.js +131 -0
- package/dist/find-in-page/index.d.ts +11 -0
- package/dist/find-in-page/index.js +49 -0
- package/dist/frontmatter-preview-defaults/index.d.ts +16 -0
- package/dist/frontmatter-preview-defaults/index.js +25 -0
- package/dist/i18n-defaults/index.d.ts +22 -0
- package/dist/i18n-defaults/index.js +167 -0
- package/dist/plugins/routes.js +44 -20
- package/dist/preset.d.ts +9 -0
- package/dist/routes/_chrome.js +2 -1
- package/dist/safelist.css +1 -1
- package/dist/settings.d.ts +37 -0
- package/dist/theme.css +319 -0
- package/dist/z-index-defaults/index.d.ts +45 -0
- package/dist/z-index-defaults/index.js +34 -0
- package/package.json +50 -3
- package/routes-src/_chrome.tsx +30 -8
- package/routes-src/_virtual.d.ts +34 -2
- package/tsconfig.base.json +29 -0
- package/virtual-modules.d.ts +79 -0
- package/zfb-config-shim.d.ts +188 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@takazudo/zudo-doc/design-token-panel-config` — the PACKAGE-DEFAULT zdtp
|
|
3
|
+
* PanelConfig builder (#2658, epic Minimal Scaffold #2651, decision wave
|
|
4
|
+
* #2653 "Approach (a)").
|
|
5
|
+
*
|
|
6
|
+
* Ported from the showcase's `src/config/design-token-panel-config.ts` (441
|
|
7
|
+
* lines, ~90% mechanical derivation per the decision-wave audit) so
|
|
8
|
+
* `designTokenPanel: true` works with NO host config file: the Palette tab
|
|
9
|
+
* comes from `defaultColorSchemes`' shared `ramps`, the Color tab from
|
|
10
|
+
* `buildSemanticTierItems`, and Font/Spacing/Size from the manifest in
|
|
11
|
+
* `./manifest.js`. The hand-authored panel-identity constants
|
|
12
|
+
* (`storagePrefix`, `consoleNamespace`, `modalClassPrefix`, `schemaId`,
|
|
13
|
+
* `exportFilenameBase`) and the `FONT_ROLE_TO_SCALE` map are carried over
|
|
14
|
+
* verbatim — `storagePrefix: "zudo-doc-tweak"` in particular MUST NOT change
|
|
15
|
+
* (existing user-save carry-over guarantee, see `packages/zudo-doc/CLAUDE.md`
|
|
16
|
+
* and `src/CLAUDE.md`).
|
|
17
|
+
*
|
|
18
|
+
* A host that needs a fully custom panel (its own color schemes, its own
|
|
19
|
+
* token manifest) points `settings.designTokenPanelConfigModule` at a module
|
|
20
|
+
* exporting a named `buildDesignTokenPanelConfig` — see
|
|
21
|
+
* `../plugins/routes.ts` (`virtual:zudo-doc-design-token-panel-config`,
|
|
22
|
+
* mirrors the `chromeBindingsModule` contract). This module is what the
|
|
23
|
+
* routes plugin re-exports when NO override is configured.
|
|
24
|
+
*
|
|
25
|
+
* Unlike the showcase original, this builder does not resolve
|
|
26
|
+
* `settings.colorMode`/`settings.colorScheme` — the PACKAGE has no settings
|
|
27
|
+
* singleton to read (the preset's node-free eval-graph rule keeps this
|
|
28
|
+
* module out of the config eval graph too, so it must stay side-effect-free
|
|
29
|
+
* on import). It seeds the Color tab straight from `defaultColorSchemes`'
|
|
30
|
+
* "Default Light" / "Default Dark" entries for the requested `mode` — the
|
|
31
|
+
* exact pair `@takazudo/zudo-doc/theme.css` ships as the default scheme.
|
|
32
|
+
*/
|
|
33
|
+
import type { PanelConfig } from "@takazudo/zdtp";
|
|
34
|
+
type PanelMode = "light" | "dark";
|
|
35
|
+
/**
|
|
36
|
+
* Build the full PACKAGE-DEFAULT PanelConfig for a given color-scheme
|
|
37
|
+
* `mode`. Only the Color tab's semantic tier and `panelSettings.colorMode.
|
|
38
|
+
* defaultMode` vary by mode; the Palette/Font/Spacing/Size tabs are
|
|
39
|
+
* mode-independent. `@takazudo/zudo-doc/design-token-panel-bootstrap` calls
|
|
40
|
+
* this per mode on every `color-scheme-changed` toggle (destroy +
|
|
41
|
+
* reconfigure) — it is passed as the BUILDER, not a resolved config (#2610).
|
|
42
|
+
*
|
|
43
|
+
* `storagePrefix: "zudo-doc-tweak"` is the same value the showcase's own
|
|
44
|
+
* `design-token-panel-config.ts` has always used — keep it unchanged so a
|
|
45
|
+
* host migrating from an ejected config to this package default carries its
|
|
46
|
+
* existing user-saved tweaks over.
|
|
47
|
+
*/
|
|
48
|
+
export declare function buildDesignTokenPanelConfig(mode: PanelMode): PanelConfig;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { SPACING_TOKENS, FONT_TOKENS, SIZE_TOKENS } from "./manifest.js";
|
|
2
|
+
import { STATE_ROLES, buildSemanticTierItems } from "../color-scheme-utils.js";
|
|
3
|
+
import { defaultColorSchemes } from "../color-schemes-defaults/index.js";
|
|
4
|
+
const DEFAULT_SHIKI_THEME = "github-dark";
|
|
5
|
+
function schemeNameForMode(mode) {
|
|
6
|
+
return mode === "dark" ? "Default Dark" : "Default Light";
|
|
7
|
+
}
|
|
8
|
+
function schemeForMode(mode) {
|
|
9
|
+
const scheme = defaultColorSchemes[schemeNameForMode(mode)];
|
|
10
|
+
if (!scheme) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`zudo-doc: defaultColorSchemes is missing "${schemeNameForMode(mode)}" \u2014 this is a package bug.`
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
return scheme;
|
|
16
|
+
}
|
|
17
|
+
function toTierItem(t) {
|
|
18
|
+
let kind;
|
|
19
|
+
if (t.control === "select") {
|
|
20
|
+
kind = { kind: "select", options: t.options ?? [] };
|
|
21
|
+
} else if (t.control === "text") {
|
|
22
|
+
kind = { kind: "text" };
|
|
23
|
+
} else {
|
|
24
|
+
kind = {
|
|
25
|
+
kind: "length",
|
|
26
|
+
step: t.step,
|
|
27
|
+
unit: t.unit
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const item = {
|
|
31
|
+
id: t.id,
|
|
32
|
+
cssVar: t.cssVar,
|
|
33
|
+
label: t.label,
|
|
34
|
+
default: t.default,
|
|
35
|
+
type: kind
|
|
36
|
+
};
|
|
37
|
+
if (t.pill) item.pill = t.pill;
|
|
38
|
+
if (t.readonly) item.readonly = true;
|
|
39
|
+
return item;
|
|
40
|
+
}
|
|
41
|
+
function tierFromGroup(tokens, groupId, label) {
|
|
42
|
+
return {
|
|
43
|
+
id: groupId,
|
|
44
|
+
label,
|
|
45
|
+
items: tokens.filter((t) => t.group === groupId).map(toTierItem)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function buildRampTiers(mode) {
|
|
49
|
+
const { ramps } = schemeForMode(mode);
|
|
50
|
+
const baseTier = {
|
|
51
|
+
id: "base",
|
|
52
|
+
label: "Base",
|
|
53
|
+
items: ramps.base.map((color, i) => ({
|
|
54
|
+
id: `base-${i}`,
|
|
55
|
+
cssVar: `--palette-base-${i}`,
|
|
56
|
+
label: String(i),
|
|
57
|
+
default: color,
|
|
58
|
+
type: { kind: "color", format: "oklch" }
|
|
59
|
+
}))
|
|
60
|
+
};
|
|
61
|
+
const accentTier = {
|
|
62
|
+
id: "accent",
|
|
63
|
+
label: "Accent",
|
|
64
|
+
items: ramps.accent.map((color, i) => ({
|
|
65
|
+
id: `accent-${i}`,
|
|
66
|
+
cssVar: `--palette-accent-${i}`,
|
|
67
|
+
label: String(i),
|
|
68
|
+
default: color,
|
|
69
|
+
type: { kind: "color", format: "oklch" }
|
|
70
|
+
}))
|
|
71
|
+
};
|
|
72
|
+
const stateTier = {
|
|
73
|
+
id: "state",
|
|
74
|
+
label: "State",
|
|
75
|
+
items: STATE_ROLES.map((role) => ({
|
|
76
|
+
id: `state-${role}`,
|
|
77
|
+
cssVar: `--palette-state-${role}`,
|
|
78
|
+
label: role,
|
|
79
|
+
default: ramps.state[role],
|
|
80
|
+
type: { kind: "color", format: "oklch" }
|
|
81
|
+
}))
|
|
82
|
+
};
|
|
83
|
+
return [baseTier, accentTier, stateTier];
|
|
84
|
+
}
|
|
85
|
+
function buildPaletteTab(mode) {
|
|
86
|
+
return {
|
|
87
|
+
id: "palette",
|
|
88
|
+
label: "Palette",
|
|
89
|
+
tiers: buildRampTiers(mode)
|
|
90
|
+
// No colorExtras: a tab with multiple kind:'color' tiers MUST omit it so
|
|
91
|
+
// resolveColorClusterFromTab is not invoked and zdtp renders the ramps
|
|
92
|
+
// with its native curve editor (zdtp palette-tab contract).
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function buildSemanticTier(mode) {
|
|
96
|
+
return {
|
|
97
|
+
id: "semantic",
|
|
98
|
+
label: "Semantic",
|
|
99
|
+
semantic: true,
|
|
100
|
+
referencesRamps: [
|
|
101
|
+
{ tab: "palette", tier: "base" },
|
|
102
|
+
{ tab: "palette", tier: "accent" },
|
|
103
|
+
{ tab: "palette", tier: "state" }
|
|
104
|
+
],
|
|
105
|
+
items: buildSemanticTierItems(schemeForMode(mode))
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function buildColorExtras(mode) {
|
|
109
|
+
const lightScheme = schemeNameForMode("light");
|
|
110
|
+
const darkScheme = schemeNameForMode("dark");
|
|
111
|
+
return {
|
|
112
|
+
id: "zudo-doc",
|
|
113
|
+
label: "Zudo Doc",
|
|
114
|
+
baseRoles: {},
|
|
115
|
+
baseDefaults: {},
|
|
116
|
+
defaultShikiTheme: DEFAULT_SHIKI_THEME,
|
|
117
|
+
colorSchemes: {},
|
|
118
|
+
panelSettings: {
|
|
119
|
+
colorScheme: schemeNameForMode(mode),
|
|
120
|
+
colorMode: { defaultMode: mode, lightScheme, darkScheme }
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function buildColorTab(mode) {
|
|
125
|
+
return {
|
|
126
|
+
id: "color",
|
|
127
|
+
label: "Color",
|
|
128
|
+
tiers: [buildSemanticTier(mode)],
|
|
129
|
+
colorExtras: buildColorExtras(mode)
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const FONT_SCALE_TIER_ID = "font-scale";
|
|
133
|
+
const FONT_ROLE_TO_SCALE = {
|
|
134
|
+
"text-micro": "text-scale-2xs",
|
|
135
|
+
"text-caption": "text-scale-xs",
|
|
136
|
+
"text-small": "text-scale-sm",
|
|
137
|
+
"text-body": "text-scale-md",
|
|
138
|
+
"text-title": "text-scale-lg",
|
|
139
|
+
"text-heading": "text-scale-xl",
|
|
140
|
+
"text-display": "text-scale-2xl"
|
|
141
|
+
};
|
|
142
|
+
function buildFontRoleTier() {
|
|
143
|
+
const base = tierFromGroup(FONT_TOKENS, "font-size", "Font size");
|
|
144
|
+
return {
|
|
145
|
+
...base,
|
|
146
|
+
items: base.items.map((item) => {
|
|
147
|
+
const scaleId = FONT_ROLE_TO_SCALE[item.id];
|
|
148
|
+
return scaleId ? { ...item, default: scaleId } : item;
|
|
149
|
+
}),
|
|
150
|
+
referencesTier: FONT_SCALE_TIER_ID
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function buildFontTab() {
|
|
154
|
+
return {
|
|
155
|
+
id: "font",
|
|
156
|
+
label: "Font",
|
|
157
|
+
tiers: [
|
|
158
|
+
tierFromGroup(FONT_TOKENS, FONT_SCALE_TIER_ID, "Scale"),
|
|
159
|
+
buildFontRoleTier(),
|
|
160
|
+
tierFromGroup(FONT_TOKENS, "line-height", "Line height"),
|
|
161
|
+
tierFromGroup(FONT_TOKENS, "font-weight", "Font weight"),
|
|
162
|
+
tierFromGroup(FONT_TOKENS, "font-family", "Font family")
|
|
163
|
+
]
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function buildSpacingTab() {
|
|
167
|
+
return {
|
|
168
|
+
id: "spacing",
|
|
169
|
+
label: "Spacing",
|
|
170
|
+
tiers: [
|
|
171
|
+
tierFromGroup(SPACING_TOKENS, "hsp", "Horizontal spacing"),
|
|
172
|
+
tierFromGroup(SPACING_TOKENS, "vsp", "Vertical spacing"),
|
|
173
|
+
tierFromGroup(SPACING_TOKENS, "icon", "Icons"),
|
|
174
|
+
tierFromGroup(SPACING_TOKENS, "layout", "Layout")
|
|
175
|
+
]
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function buildSizeTab() {
|
|
179
|
+
return {
|
|
180
|
+
id: "size",
|
|
181
|
+
label: "Size",
|
|
182
|
+
tiers: [
|
|
183
|
+
tierFromGroup(SIZE_TOKENS, "radius", "Radius"),
|
|
184
|
+
tierFromGroup(SIZE_TOKENS, "transition", "Transition")
|
|
185
|
+
]
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function buildDesignTokenPanelConfig(mode) {
|
|
189
|
+
return {
|
|
190
|
+
storagePrefix: "zudo-doc-tweak",
|
|
191
|
+
consoleNamespace: "zudoDoc",
|
|
192
|
+
modalClassPrefix: "zudo-doc-design-token-panel-modal",
|
|
193
|
+
// DISPLAY-ONLY in zdtp 0.4.6: the panel's export hard-codes
|
|
194
|
+
// `zudo-design-tokens/v2` and auto-upgrades to `.../v3` when object leaves
|
|
195
|
+
// ({ref}/{literal}/per-mode) are present — which the semantic tier's ramp
|
|
196
|
+
// refs always are, so real exports carry v3. `schemaId` does NOT gate
|
|
197
|
+
// import, and (verified against the installed zdtp 0.4.6 bundle) zdtp's
|
|
198
|
+
// Import/Export modals do not read this field at all — their hint/error
|
|
199
|
+
// text is hardcoded to zdtp's own internal `SCHEMA_V1`/`SCHEMA_V2`/
|
|
200
|
+
// `SCHEMA_V3` constants (#498/#505), which are unrelated to this field.
|
|
201
|
+
// It is thus a purely descriptive config value with no runtime effect;
|
|
202
|
+
// set to v3 (a literal, not one of those constants) to match what real
|
|
203
|
+
// exports carry. Distinct from the host serde's `DESIGN_TOKEN_SCHEMA`
|
|
204
|
+
// (`zudo-doc-design-tokens/v3` — bumped from v2 in #2599 so a stale
|
|
205
|
+
// pre-5/3-minimize export resets instead of crashing on import), which
|
|
206
|
+
// governs a separate round-trip.
|
|
207
|
+
schemaId: "zudo-design-tokens/v3",
|
|
208
|
+
exportFilenameBase: "zudo-doc-design-tokens",
|
|
209
|
+
tabs: [buildPaletteTab(mode), buildColorTab(mode), buildFontTab(), buildSpacingTab(), buildSizeTab()]
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
export {
|
|
213
|
+
buildDesignTokenPanelConfig
|
|
214
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design-token manifest data arrays — the PACKAGE-DEFAULT source of truth for
|
|
3
|
+
* the spacing/font/size tabs of `buildDesignTokenPanelConfig` (#2658, epic
|
|
4
|
+
* Minimal Scaffold #2651).
|
|
5
|
+
*
|
|
6
|
+
* Ported verbatim from the showcase's `src/config/design-tokens-manifest.ts`
|
|
7
|
+
* (values mirror the defaults shipped by `@takazudo/zudo-doc/theme.css`,
|
|
8
|
+
* #2655) so `designTokenPanel: true` works with no host manifest file. A
|
|
9
|
+
* project that needs its own token set entirely ejects via
|
|
10
|
+
* `designTokenPanelConfigModule` (see `../plugins/routes.ts`), not by editing
|
|
11
|
+
* this file — this module stays the PACKAGE default.
|
|
12
|
+
*
|
|
13
|
+
* Type strategy: arrays are typed `readonly TokenDef[]`, matching the
|
|
14
|
+
* upstream zdtp `TokenDef` shape consumed by `../color-scheme-utils.js` and
|
|
15
|
+
* `./index.ts` (which partitions them into `TabConfig.tiers` by `group`).
|
|
16
|
+
*/
|
|
17
|
+
import type { TokenDef } from "@takazudo/zdtp";
|
|
18
|
+
/**
|
|
19
|
+
* Spacing tokens — mirrors every `--spacing-*` declaration shipped by
|
|
20
|
+
* `@takazudo/zudo-doc/theme.css`, plus the `--zd-sidebar-w` layout token.
|
|
21
|
+
* Read-only rows surface tokens whose value can't be expressed on a
|
|
22
|
+
* single-axis slider (`clamp()`, structural `0`).
|
|
23
|
+
*/
|
|
24
|
+
export declare const SPACING_TOKENS: readonly TokenDef[];
|
|
25
|
+
/**
|
|
26
|
+
* Font tokens — mirrors every font-related declaration shipped by
|
|
27
|
+
* `@takazudo/zudo-doc/theme.css`.
|
|
28
|
+
*
|
|
29
|
+
* Tier 2 semantic tokens (sizes, line-heights, weights, families) are exposed
|
|
30
|
+
* as primary tiers; Tier 1 abstract scale (`--text-scale-*`) lives in its own
|
|
31
|
+
* `font-scale` tier so designers who tweak the scale see the tokens that the
|
|
32
|
+
* semantic sizes resolve from.
|
|
33
|
+
*/
|
|
34
|
+
export declare const FONT_TOKENS: readonly TokenDef[];
|
|
35
|
+
/**
|
|
36
|
+
* Size tokens — mirrors every non-breakpoint size-category custom property
|
|
37
|
+
* shipped by `@takazudo/zudo-doc/theme.css`. Breakpoints (`--breakpoint-*`)
|
|
38
|
+
* are intentionally omitted — live-changing them causes layout thrash
|
|
39
|
+
* mid-drag and adds no real tweak value.
|
|
40
|
+
*
|
|
41
|
+
* Radius defaults use `px` (matches a 0-100 slider), even though
|
|
42
|
+
* `theme.css` expresses them in `rem` — the browser accepts both.
|
|
43
|
+
* `--radius-full` carries a `pill` toggle: its design default (`9999px`) is
|
|
44
|
+
* an intentional sentinel a 0-100 slider can't reach.
|
|
45
|
+
*/
|
|
46
|
+
export declare const SIZE_TOKENS: readonly TokenDef[];
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const FONT_WEIGHT_OPTIONS = [
|
|
2
|
+
"100",
|
|
3
|
+
"200",
|
|
4
|
+
"300",
|
|
5
|
+
"400",
|
|
6
|
+
"500",
|
|
7
|
+
"600",
|
|
8
|
+
"700",
|
|
9
|
+
"800",
|
|
10
|
+
"900"
|
|
11
|
+
];
|
|
12
|
+
const SPACING_TOKENS = [
|
|
13
|
+
// --- Horizontal spacing ---
|
|
14
|
+
{ id: "hsp-2xs", cssVar: "--spacing-hsp-2xs", label: "hsp-2xs", group: "hsp", default: "0.125rem", step: 0.025, unit: "rem" },
|
|
15
|
+
{ id: "hsp-xs", cssVar: "--spacing-hsp-xs", label: "hsp-xs", group: "hsp", default: "0.375rem", step: 0.025, unit: "rem" },
|
|
16
|
+
{ id: "hsp-sm", cssVar: "--spacing-hsp-sm", label: "hsp-sm", group: "hsp", default: "0.5rem", step: 0.025, unit: "rem" },
|
|
17
|
+
{ id: "hsp-md", cssVar: "--spacing-hsp-md", label: "hsp-md", group: "hsp", default: "0.75rem", step: 0.025, unit: "rem" },
|
|
18
|
+
{ id: "hsp-lg", cssVar: "--spacing-hsp-lg", label: "hsp-lg", group: "hsp", default: "1rem", step: 0.025, unit: "rem" },
|
|
19
|
+
{ id: "hsp-xl", cssVar: "--spacing-hsp-xl", label: "hsp-xl", group: "hsp", default: "1.5rem", step: 0.025, unit: "rem" },
|
|
20
|
+
{ id: "hsp-2xl", cssVar: "--spacing-hsp-2xl", label: "hsp-2xl", group: "hsp", default: "2rem", step: 0.025, unit: "rem" },
|
|
21
|
+
// --- Vertical spacing ---
|
|
22
|
+
{ id: "vsp-3xs", cssVar: "--spacing-vsp-3xs", label: "vsp-3xs", group: "vsp", default: "0.25rem", step: 0.025, unit: "rem" },
|
|
23
|
+
{ id: "vsp-2xs", cssVar: "--spacing-vsp-2xs", label: "vsp-2xs", group: "vsp", default: "0.4375rem", step: 0.025, unit: "rem" },
|
|
24
|
+
{ id: "vsp-xs", cssVar: "--spacing-vsp-xs", label: "vsp-xs", group: "vsp", default: "0.875rem", step: 0.025, unit: "rem" },
|
|
25
|
+
{ id: "vsp-sm", cssVar: "--spacing-vsp-sm", label: "vsp-sm", group: "vsp", default: "1.25rem", step: 0.025, unit: "rem" },
|
|
26
|
+
{ id: "vsp-md", cssVar: "--spacing-vsp-md", label: "vsp-md", group: "vsp", default: "1.5rem", step: 0.025, unit: "rem" },
|
|
27
|
+
{ id: "vsp-lg", cssVar: "--spacing-vsp-lg", label: "vsp-lg", group: "vsp", default: "1.75rem", step: 0.025, unit: "rem" },
|
|
28
|
+
{ id: "vsp-xl", cssVar: "--spacing-vsp-xl", label: "vsp-xl", group: "vsp", default: "2.5rem", step: 0.025, unit: "rem" },
|
|
29
|
+
{ id: "vsp-2xl", cssVar: "--spacing-vsp-2xl", label: "vsp-2xl", group: "vsp", default: "3.5rem", step: 0.025, unit: "rem" },
|
|
30
|
+
// --- Icons ---
|
|
31
|
+
{ id: "icon-xs", cssVar: "--spacing-icon-xs", label: "icon-xs", group: "icon", default: "0.75rem", step: 0.05, unit: "rem" },
|
|
32
|
+
{ id: "icon-sm", cssVar: "--spacing-icon-sm", label: "icon-sm", group: "icon", default: "1rem", step: 0.05, unit: "rem" },
|
|
33
|
+
{ id: "icon-md", cssVar: "--spacing-icon-md", label: "icon-md", group: "icon", default: "1.25rem", step: 0.05, unit: "rem" },
|
|
34
|
+
{ id: "icon-lg", cssVar: "--spacing-icon-lg", label: "icon-lg", group: "icon", default: "1.5rem", step: 0.05, unit: "rem" },
|
|
35
|
+
// --- Layout ---
|
|
36
|
+
{ id: "image-overlay-inset", cssVar: "--spacing-image-overlay-inset", label: "image-overlay-inset", group: "layout", default: "0.5rem", step: 0.05, unit: "rem" },
|
|
37
|
+
// Structural zero — surfaced as read-only so designers see it exists, but
|
|
38
|
+
// editing it would break every utility that relies on "0 is 0".
|
|
39
|
+
{ id: "spacing-0", cssVar: "--spacing-0", label: "spacing-0", group: "layout", default: "0", step: 1, unit: "", readonly: true },
|
|
40
|
+
// 1px hairline — also read-only by design.
|
|
41
|
+
{ id: "spacing-px", cssVar: "--spacing-px", label: "spacing-px", group: "layout", default: "1px", step: 1, unit: "px", readonly: true },
|
|
42
|
+
// Responsive clamp() expression — can't be expressed on a single slider.
|
|
43
|
+
{ id: "sidebar-w", cssVar: "--zd-sidebar-w", label: "sidebar-w", group: "layout", default: "clamp(14rem, 20vw, 22rem)", step: 1, unit: "", readonly: true }
|
|
44
|
+
];
|
|
45
|
+
const FONT_TOKENS = [
|
|
46
|
+
// --- Font sizes (Tier 2 semantic) ---
|
|
47
|
+
{ id: "text-micro", cssVar: "--text-micro", label: "text-micro", group: "font-size", default: "0.75rem", step: 0.05, unit: "rem" },
|
|
48
|
+
{ id: "text-caption", cssVar: "--text-caption", label: "text-caption", group: "font-size", default: "0.875rem", step: 0.05, unit: "rem" },
|
|
49
|
+
{ id: "text-small", cssVar: "--text-small", label: "text-small", group: "font-size", default: "1rem", step: 0.05, unit: "rem" },
|
|
50
|
+
{ id: "text-body", cssVar: "--text-body", label: "text-body", group: "font-size", default: "1.2rem", step: 0.05, unit: "rem" },
|
|
51
|
+
{ id: "text-title", cssVar: "--text-title", label: "text-title", group: "font-size", default: "1.4rem", step: 0.05, unit: "rem" },
|
|
52
|
+
{ id: "text-heading", cssVar: "--text-heading", label: "text-heading", group: "font-size", default: "3rem", step: 0.05, unit: "rem" },
|
|
53
|
+
{ id: "text-display", cssVar: "--text-display", label: "text-display", group: "font-size", default: "3.75rem", step: 0.05, unit: "rem" },
|
|
54
|
+
// --- Line heights (unitless) ---
|
|
55
|
+
{ id: "leading-tight", cssVar: "--leading-tight", label: "leading-tight", group: "line-height", default: "1.25", step: 0.05, unit: "" },
|
|
56
|
+
{ id: "leading-snug", cssVar: "--leading-snug", label: "leading-snug", group: "line-height", default: "1.375", step: 0.05, unit: "" },
|
|
57
|
+
{ id: "leading-normal", cssVar: "--leading-normal", label: "leading-normal", group: "line-height", default: "1.5", step: 0.05, unit: "" },
|
|
58
|
+
{ id: "leading-relaxed", cssVar: "--leading-relaxed", label: "leading-relaxed", group: "line-height", default: "1.625", step: 0.05, unit: "" },
|
|
59
|
+
// --- Font weights (select) ---
|
|
60
|
+
{ id: "font-weight-normal", cssVar: "--font-weight-normal", label: "font-weight-normal", group: "font-weight", default: "400", step: 1, unit: "", control: "select", options: FONT_WEIGHT_OPTIONS },
|
|
61
|
+
{ id: "font-weight-medium", cssVar: "--font-weight-medium", label: "font-weight-medium", group: "font-weight", default: "500", step: 1, unit: "", control: "select", options: FONT_WEIGHT_OPTIONS },
|
|
62
|
+
{ id: "font-weight-semibold", cssVar: "--font-weight-semibold", label: "font-weight-semibold", group: "font-weight", default: "600", step: 1, unit: "", control: "select", options: FONT_WEIGHT_OPTIONS },
|
|
63
|
+
{ id: "font-weight-bold", cssVar: "--font-weight-bold", label: "font-weight-bold", group: "font-weight", default: "700", step: 1, unit: "", control: "select", options: FONT_WEIGHT_OPTIONS },
|
|
64
|
+
// --- Font families (text input) ---
|
|
65
|
+
{ id: "font-sans", cssVar: "--font-sans", label: "font-sans", group: "font-family", default: "system-ui, sans-serif", step: 1, unit: "", control: "text" },
|
|
66
|
+
{ id: "font-mono", cssVar: "--font-mono", label: "font-mono", group: "font-family", default: "ui-monospace, monospace", step: 1, unit: "", control: "text" },
|
|
67
|
+
// --- Tier 1 abstract scale ---
|
|
68
|
+
{ id: "text-scale-2xs", cssVar: "--text-scale-2xs", label: "text-scale-2xs", group: "font-scale", default: "0.75rem", step: 0.05, unit: "rem" },
|
|
69
|
+
{ id: "text-scale-xs", cssVar: "--text-scale-xs", label: "text-scale-xs", group: "font-scale", default: "0.875rem", step: 0.05, unit: "rem" },
|
|
70
|
+
{ id: "text-scale-sm", cssVar: "--text-scale-sm", label: "text-scale-sm", group: "font-scale", default: "1rem", step: 0.05, unit: "rem" },
|
|
71
|
+
{ id: "text-scale-md", cssVar: "--text-scale-md", label: "text-scale-md", group: "font-scale", default: "1.2rem", step: 0.05, unit: "rem" },
|
|
72
|
+
{ id: "text-scale-lg", cssVar: "--text-scale-lg", label: "text-scale-lg", group: "font-scale", default: "1.4rem", step: 0.05, unit: "rem" },
|
|
73
|
+
{ id: "text-scale-xl", cssVar: "--text-scale-xl", label: "text-scale-xl", group: "font-scale", default: "3rem", step: 0.05, unit: "rem" },
|
|
74
|
+
{ id: "text-scale-2xl", cssVar: "--text-scale-2xl", label: "text-scale-2xl", group: "font-scale", default: "3.75rem", step: 0.05, unit: "rem" }
|
|
75
|
+
];
|
|
76
|
+
const SIZE_TOKENS = [
|
|
77
|
+
// --- Radius ---
|
|
78
|
+
{ id: "radius-DEFAULT", cssVar: "--radius-DEFAULT", label: "radius-DEFAULT", group: "radius", default: "4px", step: 1, unit: "px" },
|
|
79
|
+
{ id: "radius-lg", cssVar: "--radius-lg", label: "radius-lg", group: "radius", default: "8px", step: 1, unit: "px" },
|
|
80
|
+
{
|
|
81
|
+
id: "radius-full",
|
|
82
|
+
cssVar: "--radius-full",
|
|
83
|
+
label: "radius-full",
|
|
84
|
+
group: "radius",
|
|
85
|
+
default: "9999px",
|
|
86
|
+
step: 1,
|
|
87
|
+
unit: "px",
|
|
88
|
+
pill: { value: "9999px", customDefault: "16px" }
|
|
89
|
+
},
|
|
90
|
+
// --- Transitions ---
|
|
91
|
+
{
|
|
92
|
+
id: "default-transition-duration",
|
|
93
|
+
cssVar: "--default-transition-duration",
|
|
94
|
+
label: "default-transition-duration",
|
|
95
|
+
group: "transition",
|
|
96
|
+
default: "150ms",
|
|
97
|
+
step: 10,
|
|
98
|
+
unit: "ms"
|
|
99
|
+
}
|
|
100
|
+
];
|
|
101
|
+
export {
|
|
102
|
+
FONT_TOKENS,
|
|
103
|
+
SIZE_TOKENS,
|
|
104
|
+
SPACING_TOKENS
|
|
105
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default directive vocabulary — the canonical seven.
|
|
3
|
+
*
|
|
4
|
+
* Ported from the `directiveVocabulary` object that every
|
|
5
|
+
* `create-zudo-doc`-generated `zfb.config.ts` previously hardcoded inline
|
|
6
|
+
* (see `packages/create-zudo-doc/src/zfb-config-gen.ts`'s `generateZfbConfig`
|
|
7
|
+
* and this repo's own `zfb.config.ts`) into a package default (epic
|
|
8
|
+
* zudolab/zudo-doc#2651, S4 #2654).
|
|
9
|
+
*
|
|
10
|
+
* Keys are directive names; values are the JSX component names the markdown
|
|
11
|
+
* pipeline's `directives` feature resolves them to (registered in the host's
|
|
12
|
+
* `pages/_mdx-components.ts`). `details` routes to a collapsible, NOT an
|
|
13
|
+
* admonition — the other six are admonition variants.
|
|
14
|
+
*/
|
|
15
|
+
import type { DirectiveVocabulary } from "../preset.js";
|
|
16
|
+
export declare const defaultDirectiveVocabulary: DirectiveVocabulary;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/** @jsxRuntime automatic */
|
|
2
2
|
/** @jsxImportSource preact */
|
|
3
3
|
import type { JSX } from "preact";
|
|
4
|
-
|
|
4
|
+
import type { FactoryComponent } from "../factory-context/index.js";
|
|
5
|
+
/** The `settings` subset this factory reads — the four package-island flags.
|
|
5
6
|
* A structural subset so the host can pass its full `Settings` object. */
|
|
6
7
|
export interface BodyEndIslandsSettings {
|
|
7
8
|
aiAssistant: boolean;
|
|
@@ -14,10 +15,38 @@ export interface BodyEndIslandsSettings {
|
|
|
14
15
|
* `undefined` is treated as `false` (no overlay) at the mount site, preserving
|
|
15
16
|
* pre-#2482 behavior; internal callers always pass the full `Settings`. */
|
|
16
17
|
dynamicPageTransition?: boolean;
|
|
18
|
+
/** Gates the `DesignTokenPanelBootstrap` island mount (#2658). Optional for
|
|
19
|
+
* the same external-caller-compat reason as `dynamicPageTransition` above.
|
|
20
|
+
* `undefined` is treated as `false` (no panel island). Even when `true`,
|
|
21
|
+
* nothing mounts unless `deps.DesignTokenPanelBootstrap` was also supplied
|
|
22
|
+
* — see {@link BodyEndIslandsDeps}. */
|
|
23
|
+
designTokenPanel?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Gates the `FindInPageInit` island mount (zudolab/zudo-doc#2689). Optional
|
|
26
|
+
* for the same external-caller-compat reason as `dynamicPageTransition`/
|
|
27
|
+
* `designTokenPanel` above. `undefined` is treated as `false` (no island).
|
|
28
|
+
* Controls the PACKAGE-DEFAULT `BodyEndIslands` slot only — a host that
|
|
29
|
+
* overrides the `BodyEndIslands` chrome binding must mount `FindInPageInit`
|
|
30
|
+
* itself.
|
|
31
|
+
*/
|
|
32
|
+
findInPage?: boolean;
|
|
17
33
|
}
|
|
18
34
|
/** Dependencies injected by `_chrome.tsx` (carries the virtual-module settings). */
|
|
19
35
|
export interface BodyEndIslandsDeps {
|
|
20
36
|
settings: BodyEndIslandsSettings;
|
|
37
|
+
/**
|
|
38
|
+
* The real `DesignTokenPanelBootstrap` component (#2658) — see the module
|
|
39
|
+
* header note above for why it is NOT imported directly here.
|
|
40
|
+
* `chrome/derive.tsx`'s `deriveBodyEndIslands` supplies
|
|
41
|
+
* `@takazudo/zudo-doc/design-token-panel-bootstrap`'s
|
|
42
|
+
* `DesignTokenPanelBootstrap` as the default for every `createChrome`
|
|
43
|
+
* consumer (#2659 gate-2 fix), so chrome-derived callers always carry it.
|
|
44
|
+
* Omitted (a bare `createBodyEndIslands({ settings })` call outside the
|
|
45
|
+
* chrome path, as this factory's own unit tests do) means no panel island
|
|
46
|
+
* mounts even when `settings.designTokenPanel` is `true` — a safe no-op,
|
|
47
|
+
* not a crash.
|
|
48
|
+
*/
|
|
49
|
+
DesignTokenPanelBootstrap?: FactoryComponent;
|
|
21
50
|
}
|
|
22
51
|
/** Props for the produced `BodyEndIslands` component. */
|
|
23
52
|
export interface BodyEndIslandsProps {
|
|
@@ -30,10 +59,4 @@ export interface BodyEndIslandsProps {
|
|
|
30
59
|
*/
|
|
31
60
|
aiChatBodyLabel?: string;
|
|
32
61
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Build the package-default `BodyEndIslands` component bound to the host's
|
|
35
|
-
* serializable `settings` flags. The produced component matches the
|
|
36
|
-
* `createDocBodyEnd` `BodyEndIslands` slot contract
|
|
37
|
-
* (`(props: { basePath: string }) => JSX.Element`).
|
|
38
|
-
*/
|
|
39
62
|
export declare function createBodyEndIslands(deps: BodyEndIslandsDeps): (props: BodyEndIslandsProps) => JSX.Element;
|
|
@@ -3,10 +3,24 @@ import { Island } from "@takazudo/zfb";
|
|
|
3
3
|
import { AiChatModal } from "../ai-chat-modal/index.js";
|
|
4
4
|
import { ImageEnlarge, ImageEnlargeSsrFallback } from "../image-enlarge/index.js";
|
|
5
5
|
import { MermaidEnlarge, MermaidEnlargeSsrFallback } from "../mermaid-enlarge/index.js";
|
|
6
|
+
import { FindInPageInit } from "../find-in-page/index.js";
|
|
6
7
|
import { PageLoadingOverlay } from "../page-loading/index.js";
|
|
7
8
|
const DEFAULT_AI_CHAT_BODY_LABEL = "Ask a question about the documentation.";
|
|
9
|
+
const ZDTP_TOGGLE_SHIM_SRC = `(function(){
|
|
10
|
+
if(window.__zdtpToggleShimInstalled)return;
|
|
11
|
+
window.__zdtpToggleShimInstalled=true;
|
|
12
|
+
var pending=false;
|
|
13
|
+
function shim(){pending=true;}
|
|
14
|
+
window.addEventListener('toggle-design-token-panel',shim);
|
|
15
|
+
window.__zdtpReadyClicks=function(){
|
|
16
|
+
window.removeEventListener('toggle-design-token-panel',shim);
|
|
17
|
+
delete window.__zdtpReadyClicks;
|
|
18
|
+
if(pending){pending=false;window.dispatchEvent(new CustomEvent('toggle-design-token-panel'));}
|
|
19
|
+
};
|
|
20
|
+
})();`;
|
|
8
21
|
function createBodyEndIslands(deps) {
|
|
9
22
|
const { settings } = deps;
|
|
23
|
+
const DesignTokenPanelBootstrap = deps.DesignTokenPanelBootstrap;
|
|
10
24
|
function BodyEndIslands({
|
|
11
25
|
basePath,
|
|
12
26
|
aiChatBodyLabel = DEFAULT_AI_CHAT_BODY_LABEL
|
|
@@ -28,8 +42,21 @@ function createBodyEndIslands(deps) {
|
|
|
28
42
|
ssrFallback: /* @__PURE__ */ jsx(MermaidEnlargeSsrFallback, {}),
|
|
29
43
|
children: /* @__PURE__ */ jsx(MermaidEnlarge, {})
|
|
30
44
|
}) : null;
|
|
45
|
+
const designTokenPanelBootstrap = settings.designTokenPanel && DesignTokenPanelBootstrap ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
46
|
+
/* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: ZDTP_TOGGLE_SHIM_SRC } }),
|
|
47
|
+
Island({
|
|
48
|
+
when: "load",
|
|
49
|
+
children: /* @__PURE__ */ jsx(DesignTokenPanelBootstrap, {})
|
|
50
|
+
})
|
|
51
|
+
] }) : null;
|
|
52
|
+
const findInPageInit = settings.findInPage ? Island({
|
|
53
|
+
when: "load",
|
|
54
|
+
children: /* @__PURE__ */ jsx(FindInPageInit, {})
|
|
55
|
+
}) : null;
|
|
31
56
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
32
57
|
settings.dynamicPageTransition ? /* @__PURE__ */ jsx(PageLoadingOverlay, {}) : null,
|
|
58
|
+
designTokenPanelBootstrap,
|
|
59
|
+
findInPageInit,
|
|
33
60
|
aiAssistant,
|
|
34
61
|
imageEnlarge,
|
|
35
62
|
mermaidEnlarge
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default docs-frontmatter zod schema builder.
|
|
3
|
+
*
|
|
4
|
+
* Ported (and parameterized) from the `create-zudo-doc` base template's
|
|
5
|
+
* `src/config/docs-schema.ts` `buildDocsSchema` export (epic
|
|
6
|
+
* zudolab/zudo-doc#2651, S4 #2654).
|
|
7
|
+
*
|
|
8
|
+
* Unlike the template original — which read the host `settings` and
|
|
9
|
+
* `tag-vocabulary` singletons directly — this package default NEVER imports
|
|
10
|
+
* host singletons: governance mode and the vocabulary entries are passed in
|
|
11
|
+
* as `opts`. `zudoDoc()` (#2657) calls this with the project's merged
|
|
12
|
+
* governance config; a project may also override `buildDocsSchema` entirely
|
|
13
|
+
* via `ZudoDocConfig.buildDocsSchema`.
|
|
14
|
+
*/
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
import type { PresetTagVocabularyEntry } from "../preset.js";
|
|
17
|
+
export interface BuildDocsSchemaOptions {
|
|
18
|
+
tagGovernance?: "off" | "warn" | "strict";
|
|
19
|
+
tagVocabulary?: readonly PresetTagVocabularyEntry[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build the docs frontmatter zod schema.
|
|
23
|
+
*
|
|
24
|
+
* Returns a single `z.object(...).passthrough()` reused for every docs
|
|
25
|
+
* collection (default + per-locale + per-version + per-version-per-locale).
|
|
26
|
+
* The `tags` field is governance-aware: `buildTagsSchema()` returns a plain
|
|
27
|
+
* `z.array(z.string())` when governance is off (or `opts` is omitted), or a
|
|
28
|
+
* restricted `z.enum` when `opts.tagGovernance: "strict"` plus a non-empty
|
|
29
|
+
* `opts.tagVocabulary` is supplied.
|
|
30
|
+
*
|
|
31
|
+
* `.passthrough()` keeps custom frontmatter keys (e.g. `author`, `status`)
|
|
32
|
+
* available downstream — the frontmatter-preview UI relies on this to
|
|
33
|
+
* surface arbitrary keys without declaring each one here.
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildDocsSchema(opts?: BuildDocsSchemaOptions): z.ZodObject<{
|
|
36
|
+
title: z.ZodString;
|
|
37
|
+
description: z.ZodOptional<z.ZodString>;
|
|
38
|
+
category: z.ZodOptional<z.ZodString>;
|
|
39
|
+
sidebar_position: z.ZodOptional<z.ZodNumber>;
|
|
40
|
+
sidebar_label: z.ZodOptional<z.ZodString>;
|
|
41
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>> | z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
42
|
+
[x: string]: string;
|
|
43
|
+
}>>>;
|
|
44
|
+
search_exclude: z.ZodOptional<z.ZodBoolean>;
|
|
45
|
+
pagination_next: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
46
|
+
pagination_prev: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
47
|
+
draft: z.ZodOptional<z.ZodBoolean>;
|
|
48
|
+
unlisted: z.ZodOptional<z.ZodBoolean>;
|
|
49
|
+
hide_sidebar: z.ZodOptional<z.ZodBoolean>;
|
|
50
|
+
hide_toc: z.ZodOptional<z.ZodBoolean>;
|
|
51
|
+
wide: z.ZodOptional<z.ZodBoolean>;
|
|
52
|
+
doc_history: z.ZodOptional<z.ZodBoolean>;
|
|
53
|
+
standalone: z.ZodOptional<z.ZodBoolean>;
|
|
54
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
55
|
+
generated: z.ZodOptional<z.ZodBoolean>;
|
|
56
|
+
category_no_page: z.ZodOptional<z.ZodBoolean>;
|
|
57
|
+
category_sort_order: z.ZodOptional<z.ZodEnum<{
|
|
58
|
+
asc: "asc";
|
|
59
|
+
desc: "desc";
|
|
60
|
+
}>>;
|
|
61
|
+
}, z.core.$loose>;
|
|
62
|
+
/**
|
|
63
|
+
* TypeScript type inferred from the default docs frontmatter zod schema.
|
|
64
|
+
* A project overriding `buildDocsSchema` via `ZudoDocConfig` should derive
|
|
65
|
+
* its own `DocsData` type from its own builder instead of this one.
|
|
66
|
+
*/
|
|
67
|
+
export type DocsData = z.infer<ReturnType<typeof buildDocsSchema>>;
|