@takazudo/zudo-doc 8.0.0 → 8.1.1
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 +40 -0
- package/README.md +2 -2
- package/dist/asset-index-page/body.js +9 -9
- package/dist/compiled.css +15 -8
- package/dist/config-assertions/index.d.ts +13 -0
- package/dist/config-assertions/index.js +25 -0
- package/dist/config.d.ts +12 -1
- package/dist/config.js +2 -0
- package/dist/diff-loader.d.ts +3 -0
- package/dist/diff-loader.js +13 -0
- package/dist/doc-history/index.js +6 -5
- package/dist/doclayout/doc-layout.js +5 -1
- package/dist/features.css +24 -0
- package/dist/header/header.d.ts +9 -0
- package/dist/header/header.js +21 -2
- package/dist/header-with-defaults/index.d.ts +3 -1
- package/dist/header-with-defaults/index.js +1 -0
- package/dist/home-page/index.js +1 -1
- package/dist/katex-loader.d.ts +3 -0
- package/dist/katex-loader.js +12 -0
- package/dist/math-block/index.js +4 -9
- package/dist/md-utils/index.d.ts +8 -2
- package/dist/md-utils/index.js +10 -3
- package/dist/nav-indexing/note-tray-index-parts/card-list.js +25 -21
- package/dist/nav-indexing/note-tray-index-parts/date-line.d.ts +3 -1
- package/dist/nav-indexing/note-tray-index-parts/date-line.js +17 -10
- package/dist/nav-indexing/note-tray-index-parts/index-list.js +4 -3
- package/dist/plugins/diff-loader.d.ts +4 -0
- package/dist/plugins/diff-loader.js +13 -0
- package/dist/plugins/katex-loader.d.ts +4 -0
- package/dist/plugins/katex-loader.js +13 -0
- package/dist/preset.d.ts +6 -2
- package/dist/preset.js +14 -1
- package/dist/settings-defaults.js +1 -0
- package/dist/settings.d.ts +21 -0
- package/dist/sidebar-tree-island/index.js +2 -6
- package/dist/site-tree-nav-island/index.js +11 -8
- package/dist/theme-packs/brutalist/pack.css +2 -2
- package/dist/transitions/persisted-focus-settle-bootstrap.d.ts +2 -0
- package/dist/transitions/persisted-focus-settle-bootstrap.js +22 -0
- package/dist/tree-nav-shared/index.d.ts +2 -0
- package/dist/tree-nav-shared/index.js +8 -1
- package/dist/wind.json +0 -2
- package/eject/doc-history/index.tsx +13 -9
- package/eject/header/header.tsx +40 -0
- package/eject/sidebar-tree-island/index.tsx +2 -8
- package/eject/site-tree-nav-island/index.tsx +15 -8
- package/package.json +24 -8
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,46 @@ The format is based on Keep a Changelog, and release notes are generated from th
|
|
|
8
8
|
|
|
9
9
|
No unreleased changes.
|
|
10
10
|
|
|
11
|
+
## [8.1.1] - 2026-10-26
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
- Search-index bodies, llms.txt descriptions and agent-export fallback descriptions now read as plain prose.
|
|
16
|
+
- Inline code keeps its text and only the backticks are dropped. Before, `` `pnpm approve-builds` `` was deleted, leaving fragments like "by default ()".
|
|
17
|
+
- Whole-line directive fences are removed and their label or title text is kept. This covers `:::warning[Title]`, `:::note Title`, `:::name{attrs}`, nested `::::` and bare closing `:::`. (9d0bffb5, 64cae6a6)
|
|
18
|
+
- Sites that don't use math and don't install the optional `katex` peer no longer get a Rolldown `UNRESOLVED_IMPORT 'katex'` warning on every build.
|
|
19
|
+
- math-block now loads KaTeX through the package-owned `@takazudo/zudo-doc/katex-loader` subpath. With `math` off, the preset replaces that subpath with a stub.
|
|
20
|
+
- Bare `katex` imports in your own code are untouched.
|
|
21
|
+
- `` now requires `math: true`, as already documented. With `math` off it reports the missing-katex error even when `katex` happens to be installed. (82c24ea5, 64cae6a6)
|
|
22
|
+
- Sites with `docHistory` off that don't install the optional `diff` peer no longer get an `UNRESOLVED_IMPORT 'diff'` warning.
|
|
23
|
+
- The doc-history Compare view loads `diff` through the package-owned `@takazudo/zudo-doc/diff-loader` subpath. With `docHistory` off, the preset replaces that subpath with a stub.
|
|
24
|
+
- The dates-only mode (`docHistoryUi: false`) keeps the real loader. (6e6434ca)
|
|
25
|
+
- Some row descendants now follow their own row's hover and focus-visible accent, while keeping their resting colors and the inverted current-item style. This covers:
|
|
26
|
+
- numbered index ranks
|
|
27
|
+
- linked note-tray dates (index, compact and wide card stamps)
|
|
28
|
+
- sidebar tray and site-tree note-tray ranks and dates
|
|
29
|
+
- asset-tree folder and file icons, names and metadata (4c271316, 0efa5cbf)
|
|
30
|
+
|
|
31
|
+
### Other Changes
|
|
32
|
+
|
|
33
|
+
- Requires zfb 5.1.3: the `@takazudo/zfb`, `zfb-runtime` and `zfb-md-wasm` peer floors move from `^5.1.2` to `^5.1.3`. zfb 5.1.3 rebuilds the native engine and WASM binaries; the JavaScript API is unchanged. Update the zfb family (and `zfb-adapter-cloudflare` when used) to 5.1.3 together with this release. (62648582)
|
|
34
|
+
|
|
35
|
+
## [8.1.0] - 2026-10-25
|
|
36
|
+
|
|
37
|
+
### Features
|
|
38
|
+
|
|
39
|
+
- Add the opt-in `headerBrand` setting (`false | { icon: string }`, default `false`): a decorative square icon painted with the text colour (CSS mask) before the site name in the header. `/`-prefixed paths receive the site `base` once, other URLs are used as-is, and an empty or missing `icon` (or `true`) throws at config resolution. The site name stays the link's accessible name, long names still ellipsize, and theme-pack leading emblems are hidden while an icon is set. (fb3358ca)
|
|
40
|
+
- Add a `data-zd-site-name` attribute to the home hero `<h1>` as a styling hook for the site name. (fb3358ca)
|
|
41
|
+
|
|
42
|
+
### Bug Fixes
|
|
43
|
+
|
|
44
|
+
- With dynamic page transitions enabled, navigating from a footer link (or any focused link in persisted chrome) now finishes at the top of the destination page on current Chromium builds instead of staying near the footer. A package-owned inline head script settles the browser's queued focus reveal after the persisted DOM move and before the router applies its top, hash or history scroll. Focus, persistence, transitions and scroll restoration are unchanged. Sites that pin inline-script hashes in a Content Security Policy need to add the new script's hash. (524a440f)
|
|
45
|
+
- In `SiteTreeNav`, labels now always start a small gap after the end of their dashed branch. On wide viewports the double-width homepage branches used to run into the label text. (3e6e720f)
|
|
46
|
+
|
|
47
|
+
### Other Changes
|
|
48
|
+
|
|
49
|
+
- Requires zfb 5.1.2: the `@takazudo/zfb`, `zfb-runtime` and `zfb-md-wasm` peer floors move from `^5.0.1` to `^5.1.2`. zfb 5.1.0 adds an islands build guard: the build now fails if an emitted islands chunk imports the islands entry, because that import would 404 in production. zfb 5.1.1 is a fix release for Windows hosts (bare-package subpath aliases and `pnpm.cmd` spawning) and for projects built from a symlinked path. zfb 5.1.2 ships rebuilt native engine and WASM binaries with no change to the JavaScript API. Chunking is otherwise unchanged. Upgrade the zfb family (and `zfb-adapter-cloudflare` when used) to 5.1.2 together with this release. (6eef9416, 44d7684b)
|
|
50
|
+
|
|
11
51
|
## [8.0.0] - 2026-10-24
|
|
12
52
|
|
|
13
53
|
### Breaking Changes
|
package/README.md
CHANGED
|
@@ -109,7 +109,7 @@ If your project renders **semi-trusted or user-submitted** HTML in a preview, ov
|
|
|
109
109
|
|
|
110
110
|
**6.0.0** is the coordinated major release of `@takazudo/zudo-doc`,
|
|
111
111
|
`@takazudo/zudo-doc-history-server` and `create-zudo-doc`. The current workspace
|
|
112
|
-
targets the published **zfb 5.
|
|
112
|
+
targets the published **zfb 5.1.3** family (peer floor **^5.1.3**).
|
|
113
113
|
[Upstream #4097](https://github.com/Takazudo/zudo-front-builder/issues/4097) is
|
|
114
114
|
resolved; its strict published 4.3.1 consumer control passed 3/3 with no skips or
|
|
115
115
|
retries in the [source-bound verification](../../docs/findings/zfb-4.3.1/verification.md).
|
|
@@ -126,7 +126,7 @@ are feature-dependent. Package defaults for `agentExport`, `mcp`, and `llmsTxt`
|
|
|
126
126
|
are all `false`. The create-zudo-doc initializer enables `llmsTxt` by default;
|
|
127
127
|
agent export and MCP remain opt-in.
|
|
128
128
|
|
|
129
|
-
For the panel, the installed **zdtp 0.8.
|
|
129
|
+
For the panel, the installed **zdtp 0.8.7** manifest carries **Preact ^10.29.1** as
|
|
130
130
|
its own dependency (it was a peer through 0.8.5) and exports `./styles.css` (also `./styles`) to `dist/zdtp.css`. Its internal
|
|
131
131
|
Tailwind browser dependency and Preact subtree are isolated from host JSX.
|
|
132
132
|
Install `@takazudo/zdtp` and import `@takazudo/zdtp/styles.css` when enabling it.
|
|
@@ -48,15 +48,15 @@ function iconFor(asset) {
|
|
|
48
48
|
function AssetTree({ node, base, routePrefix, locale, fileCountLabel, fileCountSingleLabel, linesLabel, root = false }) {
|
|
49
49
|
return /* @__PURE__ */ jsxs("ul", { "data-zd-asset-tree": root ? true : void 0, children: [
|
|
50
50
|
node.dirs.map((dir) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("details", { open: true, children: [
|
|
51
|
-
/* @__PURE__ */ jsxs("summary", { class: "flex cursor-pointer items-center gap-hsp-xs rounded px-hsp-sm py-vsp-3xs text-small hover:bg-accent/10 focus-visible:bg-accent/10", children: [
|
|
52
|
-
/* @__PURE__ */ jsx(ChevronRight, { class: "h-icon-xs w-icon-xs shrink-0 text-muted transition-transform" }),
|
|
53
|
-
/* @__PURE__ */ jsx(Folder, { class: "h-icon-sm w-icon-sm shrink-0 text-muted" }),
|
|
54
|
-
/* @__PURE__ */ jsx(FolderOpen, { class: "h-icon-sm w-icon-sm shrink-0 text-muted" }),
|
|
55
|
-
/* @__PURE__ */ jsxs("span", { class: "min-w-0 truncate font-mono text-fg", children: [
|
|
51
|
+
/* @__PURE__ */ jsxs("summary", { class: "group flex cursor-pointer items-center gap-hsp-xs rounded px-hsp-sm py-vsp-3xs text-small hover:bg-accent/10 focus-visible:bg-accent/10", children: [
|
|
52
|
+
/* @__PURE__ */ jsx(ChevronRight, { class: "h-icon-xs w-icon-xs shrink-0 text-muted transition-transform group-hover:text-accent group-focus-visible:text-accent" }),
|
|
53
|
+
/* @__PURE__ */ jsx(Folder, { class: "h-icon-sm w-icon-sm shrink-0 text-muted group-hover:text-accent group-focus-visible:text-accent" }),
|
|
54
|
+
/* @__PURE__ */ jsx(FolderOpen, { class: "h-icon-sm w-icon-sm shrink-0 text-muted group-hover:text-accent group-focus-visible:text-accent" }),
|
|
55
|
+
/* @__PURE__ */ jsxs("span", { class: "min-w-0 truncate font-mono text-fg group-hover:text-accent group-focus-visible:text-accent", children: [
|
|
56
56
|
dir.name,
|
|
57
57
|
"/"
|
|
58
58
|
] }),
|
|
59
|
-
/* @__PURE__ */ jsxs("span", { class: "ml-auto hidden whitespace-nowrap pl-hsp-lg text-caption text-muted sm:block", children: [
|
|
59
|
+
/* @__PURE__ */ jsxs("span", { class: "ml-auto hidden whitespace-nowrap pl-hsp-lg text-caption text-muted sm:block group-hover:text-accent group-focus-visible:text-accent", children: [
|
|
60
60
|
countLabel(dir.fileCount, fileCountLabel, fileCountSingleLabel),
|
|
61
61
|
" \xB7 ",
|
|
62
62
|
formatAssetBytes(dir.bytes)
|
|
@@ -68,10 +68,10 @@ function AssetTree({ node, base, routePrefix, locale, fileCountLabel, fileCountS
|
|
|
68
68
|
const Icon = iconFor(asset);
|
|
69
69
|
const facet = facetLabel(asset, asset.lines !== void 0 ? linesLabel.replace("{count}", String(asset.lines)) : void 0);
|
|
70
70
|
const meta = [kindLabel(asset), facet, formatAssetBytes(asset.bytes)].filter(Boolean).join(" \xB7 ");
|
|
71
|
-
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("a", { href: assetViewerHref({ base, routePrefix, path: asset.path, locale }), title: asset.name, class: "flex min-w-0 items-center gap-hsp-xs rounded px-hsp-sm py-vsp-3xs text-small text-fg hover:bg-accent/10 hover:text-accent hover:underline focus-visible:bg-accent/10 focus-visible:text-accent focus-visible:underline", children: [
|
|
72
|
-
/* @__PURE__ */ jsx(Icon, { class: "h-icon-sm w-icon-sm shrink-0 text-muted" }),
|
|
71
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("a", { href: assetViewerHref({ base, routePrefix, path: asset.path, locale }), title: asset.name, class: "group flex min-w-0 items-center gap-hsp-xs rounded px-hsp-sm py-vsp-3xs text-small text-fg hover:bg-accent/10 hover:text-accent hover:underline focus-visible:bg-accent/10 focus-visible:text-accent focus-visible:underline", children: [
|
|
72
|
+
/* @__PURE__ */ jsx(Icon, { class: "h-icon-sm w-icon-sm shrink-0 text-muted group-hover:text-accent group-focus-visible:text-accent" }),
|
|
73
73
|
/* @__PURE__ */ jsx("span", { class: "min-w-0 truncate font-mono", children: basename(asset.path) }),
|
|
74
|
-
/* @__PURE__ */ jsx("span", { class: "ml-auto hidden whitespace-nowrap pl-hsp-lg text-caption text-muted sm:block", children: meta })
|
|
74
|
+
/* @__PURE__ */ jsx("span", { class: "ml-auto hidden whitespace-nowrap pl-hsp-lg text-caption text-muted sm:block group-hover:text-accent group-focus-visible:text-accent", children: meta })
|
|
75
75
|
] }) });
|
|
76
76
|
})
|
|
77
77
|
] });
|
package/dist/compiled.css
CHANGED
|
@@ -1864,6 +1864,21 @@ nav[data-zd-toc], div[data-zd-mobile-toc] {
|
|
|
1864
1864
|
font-family: var(--zdc-toc-font, var(--zdc-chrome-font, var(--font-sans)));
|
|
1865
1865
|
}
|
|
1866
1866
|
|
|
1867
|
+
[data-header-brand-icon] {
|
|
1868
|
+
display: inline-block;
|
|
1869
|
+
width: 1.1em;
|
|
1870
|
+
height: 1.1em;
|
|
1871
|
+
vertical-align: -.2em;
|
|
1872
|
+
margin-inline-end: var(--spacing-hsp-sm);
|
|
1873
|
+
background-color: currentColor;
|
|
1874
|
+
-webkit-mask: var(--zd-header-brand-icon) center/contain no-repeat;
|
|
1875
|
+
mask: var(--zd-header-brand-icon) center/contain no-repeat;
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
html[data-theme-pack] [data-header-logo][data-header-brand]:before {
|
|
1879
|
+
content: none;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1867
1882
|
button[data-zd-pending] {
|
|
1868
1883
|
opacity: .7;
|
|
1869
1884
|
pointer-events: none;
|
|
@@ -3593,11 +3608,6 @@ site-search [data-search-results] > :is([data-search-placeholder], p) {
|
|
|
3593
3608
|
color: var(--zw-color-bg);
|
|
3594
3609
|
}
|
|
3595
3610
|
}
|
|
3596
|
-
@media (hover: hover) {
|
|
3597
|
-
:where(.group:hover) .group-hover\:text-fg {
|
|
3598
|
-
color: var(--zw-color-fg);
|
|
3599
|
-
}
|
|
3600
|
-
}
|
|
3601
3611
|
@media (hover: hover) {
|
|
3602
3612
|
:where(.group:hover) .group-hover\:bg-fg {
|
|
3603
3613
|
background-color: var(--zw-color-fg);
|
|
@@ -3609,9 +3619,6 @@ site-search [data-search-results] > :is([data-search-placeholder], p) {
|
|
|
3609
3619
|
:where(.group:focus-visible) .group-focus-visible\:text-accent {
|
|
3610
3620
|
color: var(--zw-color-accent);
|
|
3611
3621
|
}
|
|
3612
|
-
:where(.group:focus-visible) .group-focus-visible\:text-fg {
|
|
3613
|
-
color: var(--zw-color-fg);
|
|
3614
|
-
}
|
|
3615
3622
|
@media (hover: hover) {
|
|
3616
3623
|
:where(.peer:hover) ~ .peer-hover\:text-accent {
|
|
3617
3624
|
color: var(--zw-color-accent);
|
|
@@ -55,6 +55,19 @@ export interface EmptyStringFaviconOrLogoSubject {
|
|
|
55
55
|
* object is not an empty string).
|
|
56
56
|
*/
|
|
57
57
|
export declare function assertNoEmptyStringFaviconOrLogo(settings: EmptyStringFaviconOrLogoSubject): void;
|
|
58
|
+
/** Structural subset of `Settings` {@link assertValidHeaderBrand} reads. */
|
|
59
|
+
export interface HeaderBrandSubject {
|
|
60
|
+
headerBrand?: unknown;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validate `headerBrand`: `undefined`, `false`, or `{ icon: <non-empty string> }`.
|
|
64
|
+
*
|
|
65
|
+
* The value is typed `false | HeaderBrandConfig`, but JavaScript callers and
|
|
66
|
+
* casted values can still pass `true`, a bare string, an array, or an object
|
|
67
|
+
* whose `icon` is missing/empty — each of which would render a broken mask in
|
|
68
|
+
* every page header. Fail loudly at config resolution, naming the field.
|
|
69
|
+
*/
|
|
70
|
+
export declare function assertValidHeaderBrand(settings: HeaderBrandSubject): void;
|
|
58
71
|
/** Structural subset of `Settings` the zdtp-bundling helpers read. */
|
|
59
72
|
export interface ZdtpBundlingSubject {
|
|
60
73
|
designTokenPanel?: boolean;
|
|
@@ -32,6 +32,30 @@ function assertNoEmptyStringFaviconOrLogo(settings) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
function assertValidHeaderBrand(settings) {
|
|
36
|
+
const value = settings.headerBrand;
|
|
37
|
+
if (value === void 0 || value === false) return;
|
|
38
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
39
|
+
throw new TypeError(
|
|
40
|
+
`Invalid headerBrand ${describeValue(value)}: pass false (or omit it) for no icon, or an object { icon: "/img/icon.svg" }.`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
const icon = value.icon;
|
|
44
|
+
if (typeof icon !== "string" || icon === "") {
|
|
45
|
+
throw new TypeError(
|
|
46
|
+
`Invalid headerBrand.icon ${describeValue(icon)}: must be a non-empty string (a "/"-prefixed path, a data: URL, or an absolute URL).`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function describeValue(value) {
|
|
51
|
+
if (value === void 0) return "undefined";
|
|
52
|
+
if (Array.isArray(value)) return "(array)";
|
|
53
|
+
try {
|
|
54
|
+
return JSON.stringify(value) ?? String(value);
|
|
55
|
+
} catch {
|
|
56
|
+
return String(value);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
35
59
|
function resolvesBundleZdtp(settings) {
|
|
36
60
|
return settings.bundleZdtp ?? settings.designTokenPanel === true;
|
|
37
61
|
}
|
|
@@ -92,6 +116,7 @@ function warnAmbiguousDropdownCategoryMatch(headerNav, logger = console) {
|
|
|
92
116
|
export {
|
|
93
117
|
assertAgentDocsConsistent,
|
|
94
118
|
assertNoEmptyStringFaviconOrLogo,
|
|
119
|
+
assertValidHeaderBrand,
|
|
95
120
|
assertValidSearchMaxBodyLength,
|
|
96
121
|
assertZdtpBundlingConsistent,
|
|
97
122
|
resolvesBundleZdtp,
|
package/dist/config.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ import type { ZfbConfig, BundleConfig, WindConfig } from "@takazudo/zfb/config";
|
|
|
70
70
|
import type { ZodType } from "zod";
|
|
71
71
|
import type { DirectiveVocabulary, PresetTranslations, PresetTagVocabularyEntry } from "./preset.js";
|
|
72
72
|
import type { ColorScheme } from "./color-scheme-utils.js";
|
|
73
|
-
import type { Settings, ColorModeConfig, LocaleConfig, MetaTagsConfig, SiteHeadConfig, TagPlacement, TagGovernanceMode, VersionConfig, FooterConfig, HeaderNavItem, HeaderRightItem, HomeConfig, AssetViewerIndexingConfig, FrontmatterPreviewConfig, BodyFootUtilAreaConfig, HtmlPreviewConfig, FaviconConfig, DateFormatSetting } from "./settings.js";
|
|
73
|
+
import type { Settings, ColorModeConfig, LocaleConfig, MetaTagsConfig, SiteHeadConfig, TagPlacement, TagGovernanceMode, VersionConfig, FooterConfig, HeaderNavItem, HeaderRightItem, HomeConfig, AssetViewerIndexingConfig, FrontmatterPreviewConfig, BodyFootUtilAreaConfig, HtmlPreviewConfig, FaviconConfig, HeaderBrandConfig, DateFormatSetting } from "./settings.js";
|
|
74
74
|
/** The `settings.claudeResources` block (or `false` when disabled). */
|
|
75
75
|
type ClaudeResourcesConfig = {
|
|
76
76
|
claudeDir: string;
|
|
@@ -132,6 +132,17 @@ export interface ZudoDocConfig {
|
|
|
132
132
|
* @default undefined
|
|
133
133
|
*/
|
|
134
134
|
favicon?: string | FaviconConfig | false;
|
|
135
|
+
/**
|
|
136
|
+
* Header brand icon rendered before the site name in the header logo
|
|
137
|
+
* anchor, as a decorative `currentColor` CSS mask (`aria-hidden`; the
|
|
138
|
+
* anchor's accessible name stays `siteName`). `false` renders the site name
|
|
139
|
+
* alone. A `HeaderBrandConfig` (`{ icon }`) paints `icon`: a value starting
|
|
140
|
+
* with `/` is prefixed with `base`, anything else (`data:`, `https://…`) is
|
|
141
|
+
* used verbatim. `true`, arrays, other non-objects, and a missing,
|
|
142
|
+
* non-string or empty `icon` throw a `TypeError` at config resolution.
|
|
143
|
+
* @default false
|
|
144
|
+
*/
|
|
145
|
+
headerBrand?: false | HeaderBrandConfig;
|
|
135
146
|
/**
|
|
136
147
|
* Public URL sub-path prefix mounted in front of every absolute asset URL
|
|
137
148
|
* (e.g. `"/pj/my-site/"`). `"/"` = root-mounted.
|
package/dist/config.js
CHANGED
|
@@ -6,6 +6,7 @@ import { defaultColorSchemes } from "./color-schemes-defaults/index.js";
|
|
|
6
6
|
import { assertNoCommaInVersionSlugs } from "./version-availability/index.js";
|
|
7
7
|
import {
|
|
8
8
|
assertNoEmptyStringFaviconOrLogo,
|
|
9
|
+
assertValidHeaderBrand,
|
|
9
10
|
assertZdtpBundlingConsistent,
|
|
10
11
|
assertValidSearchMaxBodyLength,
|
|
11
12
|
assertAgentDocsConsistent
|
|
@@ -79,6 +80,7 @@ function zudoDoc(user = {}) {
|
|
|
79
80
|
);
|
|
80
81
|
assertNoCommaInVersionSlugs(settings.versions);
|
|
81
82
|
assertNoEmptyStringFaviconOrLogo(settings);
|
|
83
|
+
assertValidHeaderBrand(settings);
|
|
82
84
|
assertZdtpBundlingConsistent(settings);
|
|
83
85
|
assertValidSearchMaxBodyLength(settings.searchMaxBodyLength);
|
|
84
86
|
assertAgentDocsConsistent(settings);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function pickDiffLines(m) {
|
|
2
|
+
let cur = m;
|
|
3
|
+
for (let i = 0; i < 3 && cur && typeof cur === "object"; i++) {
|
|
4
|
+
const fn = cur.diffLines;
|
|
5
|
+
if (typeof fn === "function") return fn;
|
|
6
|
+
cur = cur.default;
|
|
7
|
+
}
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const diffLines = await import("diff").then(pickDiffLines, () => null);
|
|
11
|
+
export {
|
|
12
|
+
diffLines
|
|
13
|
+
};
|
|
@@ -95,12 +95,13 @@ async function getCachedDiff(olderHash, newerHash, olderContent, newerContent, i
|
|
|
95
95
|
diffCache.set(key, hit);
|
|
96
96
|
return hit;
|
|
97
97
|
}
|
|
98
|
-
const
|
|
99
|
-
(m) => m,
|
|
100
|
-
() =>
|
|
101
|
-
throw new Error('Compare requires the optional peer "diff": install it to use docHistory');
|
|
102
|
-
}
|
|
98
|
+
const diffLines = await import("@takazudo/zudo-doc/diff-loader").then(
|
|
99
|
+
(m) => m.diffLines,
|
|
100
|
+
() => null
|
|
103
101
|
);
|
|
102
|
+
if (!diffLines) {
|
|
103
|
+
throw new Error('Compare requires the optional peer "diff": install it to use docHistory');
|
|
104
|
+
}
|
|
104
105
|
if (!isCurrent()) throw new Error("Comparison cancelled");
|
|
105
106
|
const changes = diffLines(olderContent, newerContent);
|
|
106
107
|
diffCache.set(key, changes);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@takazudo/zfb/zudo-react/jsx-runtime";
|
|
2
2
|
import { ClientRouter } from "@takazudo/zfb-runtime";
|
|
3
3
|
import { buildChromeTransitionBootstrap } from "../transitions/chrome-transition-bootstrap.js";
|
|
4
|
+
import { buildPersistedFocusSettleBootstrap } from "../transitions/persisted-focus-settle-bootstrap.js";
|
|
4
5
|
const DESKTOP_SIDEBAR_ID = "desktop-sidebar";
|
|
5
6
|
function DocLayout(props) {
|
|
6
7
|
const {
|
|
@@ -71,7 +72,10 @@ function DocLayout(props) {
|
|
|
71
72
|
);
|
|
72
73
|
}
|
|
73
74
|
if (head !== void 0) headChildren.push(head);
|
|
74
|
-
if (enableClientRouter !== false)
|
|
75
|
+
if (enableClientRouter !== false) {
|
|
76
|
+
headChildren.push(/* @__PURE__ */ jsx("script", { rawHtml: buildChromeTransitionBootstrap() }));
|
|
77
|
+
headChildren.push(/* @__PURE__ */ jsx("script", { rawHtml: buildPersistedFocusSettleBootstrap() }));
|
|
78
|
+
}
|
|
75
79
|
return /* @__PURE__ */ jsxs("html", { ...htmlAttrs, children: [
|
|
76
80
|
/* @__PURE__ */ jsx("head", { children: headChildren }),
|
|
77
81
|
/* @__PURE__ */ jsxs("body", { class: "min-h-screen antialiased", children: [
|
package/dist/features.css
CHANGED
|
@@ -1026,6 +1026,30 @@ nav[data-zd-toc], div[data-zd-mobile-toc] {
|
|
|
1026
1026
|
|
|
1027
1027
|
/* END --zdc-* chrome component tokens */
|
|
1028
1028
|
|
|
1029
|
+
/* ======== Header brand icon (settings.headerBrand) ======== */
|
|
1030
|
+
|
|
1031
|
+
/* Decorative icon inside the site-name anchor. Sized in `em` so it follows a
|
|
1032
|
+
* theme pack's logo font-size inside the fixed-height header; painted as a
|
|
1033
|
+
* currentColor mask so it always matches the site-name ink. The anchor stays
|
|
1034
|
+
* a truncating flow box — the icon is an inline-block run-in, not a flex item. */
|
|
1035
|
+
[data-header-brand-icon] {
|
|
1036
|
+
display: inline-block;
|
|
1037
|
+
width: 1.1em;
|
|
1038
|
+
height: 1.1em;
|
|
1039
|
+
vertical-align: -0.2em;
|
|
1040
|
+
margin-inline-end: var(--spacing-hsp-sm);
|
|
1041
|
+
background-color: currentColor;
|
|
1042
|
+
-webkit-mask: var(--zd-header-brand-icon) center/contain no-repeat;
|
|
1043
|
+
mask: var(--zd-header-brand-icon) center/contain no-repeat;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/* A brand icon replaces a theme pack's decorative logo emblem rather than
|
|
1047
|
+
* doubling it. Specificity (0,3,2) beats every pack's `[data-header-logo]::before`
|
|
1048
|
+
* rule (0,2,2); `::after` marks are left alone. */
|
|
1049
|
+
html[data-theme-pack] [data-header-logo][data-header-brand]::before {
|
|
1050
|
+
content: none;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1029
1053
|
button[data-zd-pending] {
|
|
1030
1054
|
opacity: 0.7;
|
|
1031
1055
|
pointer-events: none;
|
package/dist/header/header.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { Child } from "@takazudo/zfb/zudo-react";
|
|
3
3
|
import type { JSX } from "@takazudo/zfb/zudo-react/jsx-runtime";
|
|
4
4
|
import type { HeaderNavItem, HeaderRightComponentRegistry, HeaderRightItem, Locale } from "./types.js";
|
|
5
|
+
import type { HeaderBrandConfig } from "../settings.js";
|
|
5
6
|
/**
|
|
6
7
|
* Boundary helpers the host injects into `<Header>`. These are the URL
|
|
7
8
|
* builders the legacy header.tsx used to import from `@/utils/base` —
|
|
@@ -92,6 +93,14 @@ export interface HeaderProps {
|
|
|
92
93
|
persistKey: string;
|
|
93
94
|
/** Site-name string shown in the logo anchor (host `settings.siteName`). */
|
|
94
95
|
siteName: string;
|
|
96
|
+
/**
|
|
97
|
+
* Optional brand icon rendered before `siteName` inside the logo anchor
|
|
98
|
+
* (host `settings.headerBrand`). Omitted or `false` renders the anchor
|
|
99
|
+
* exactly as before. The icon is a decorative `currentColor` CSS mask; an
|
|
100
|
+
* `icon` starting with `/` goes through `urlHelpers.withBase()`, anything
|
|
101
|
+
* else is used verbatim.
|
|
102
|
+
*/
|
|
103
|
+
headerBrand?: false | HeaderBrandConfig;
|
|
95
104
|
/** Header-nav items in render order (host `settings.headerNav`). */
|
|
96
105
|
headerNav: HeaderNavItem[];
|
|
97
106
|
/**
|
package/dist/header/header.js
CHANGED
|
@@ -32,6 +32,7 @@ function Header(props) {
|
|
|
32
32
|
search,
|
|
33
33
|
persistKey,
|
|
34
34
|
siteName,
|
|
35
|
+
headerBrand,
|
|
35
36
|
headerNav,
|
|
36
37
|
headerRightItems,
|
|
37
38
|
headerRightComponents,
|
|
@@ -48,6 +49,8 @@ function Header(props) {
|
|
|
48
49
|
const pathWithoutVersion = stripCurrentVersionPrefix(pathWithoutBase, currentVersion);
|
|
49
50
|
const matchPath = pathForMatch(pathWithoutVersion, lang, i18n.defaultLocale);
|
|
50
51
|
const activeNavPath = computeActiveNavPath(headerNav, matchPath);
|
|
52
|
+
const brandIcon = headerBrand && typeof headerBrand.icon === "string" && headerBrand.icon !== "" ? headerBrand.icon : null;
|
|
53
|
+
const brandIconUrl = brandIcon === null ? null : brandIcon.startsWith("/") && !brandIcon.startsWith("//") ? urlHelpers.withBase(brandIcon) : brandIcon;
|
|
51
54
|
const rightItemDispatch = createRightItemDispatch(headerRightComponents);
|
|
52
55
|
const rightItems = headerRightItems.map((item, i) => ({
|
|
53
56
|
item,
|
|
@@ -98,14 +101,27 @@ function Header(props) {
|
|
|
98
101
|
// (mobile sidebar contents stay accessible to assistive tech
|
|
99
102
|
// even without the toggle island).
|
|
100
103
|
/* @__PURE__ */ jsx(SidebarSlotFallback, { children: sidebarSlot }),
|
|
101
|
-
/* @__PURE__ */
|
|
104
|
+
/* @__PURE__ */ jsxs(
|
|
102
105
|
"a",
|
|
103
106
|
{
|
|
104
107
|
href: urlHelpers.withBase(isNonDefaultLocale ? `/${lang}/` : "/"),
|
|
105
108
|
class: "min-w-0 truncate text-title font-bold text-fg hover:underline focus:underline",
|
|
106
109
|
title: siteName,
|
|
107
110
|
"data-header-logo": true,
|
|
108
|
-
|
|
111
|
+
"data-header-brand": brandIconUrl !== null ? true : void 0,
|
|
112
|
+
children: [
|
|
113
|
+
brandIconUrl !== null && // Painted by features.css as a currentColor mask so it follows the
|
|
114
|
+
// site-name ink; decorative, the anchor's name stays the site name.
|
|
115
|
+
/* @__PURE__ */ jsx(
|
|
116
|
+
"span",
|
|
117
|
+
{
|
|
118
|
+
"aria-hidden": "true",
|
|
119
|
+
"data-header-brand-icon": true,
|
|
120
|
+
style: { "--zd-header-brand-icon": cssUrl(brandIconUrl) }
|
|
121
|
+
}
|
|
122
|
+
),
|
|
123
|
+
siteName
|
|
124
|
+
]
|
|
109
125
|
}
|
|
110
126
|
),
|
|
111
127
|
/* @__PURE__ */ jsxs(
|
|
@@ -486,6 +502,9 @@ function renderRightItem(item, index, ctx, dispatch) {
|
|
|
486
502
|
}
|
|
487
503
|
return null;
|
|
488
504
|
}
|
|
505
|
+
function cssUrl(url) {
|
|
506
|
+
return `url("${url.replace(/[\\"]/g, "\\$&").replace(/[\n\r\f]/g, "\\a ")}")`;
|
|
507
|
+
}
|
|
489
508
|
export {
|
|
490
509
|
Header
|
|
491
510
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @jsxRuntime automatic */
|
|
2
2
|
import type { JSX } from "@takazudo/zfb/zudo-react/jsx-runtime";
|
|
3
3
|
import type { ChromeContext } from "../factory-context/index.js";
|
|
4
|
-
import type { Settings } from "../settings.js";
|
|
4
|
+
import type { HeaderBrandConfig, Settings } from "../settings.js";
|
|
5
5
|
import type { SidebarNavNode } from "../sidebar/types.js";
|
|
6
6
|
export interface HeaderWithDefaultsProps {
|
|
7
7
|
/** Active locale; defaults to the configured defaultLocale. */
|
|
@@ -44,6 +44,8 @@ export interface HeaderVersionEntry {
|
|
|
44
44
|
/** Settings subset read by {@link createHeaderWithDefaults}. */
|
|
45
45
|
export interface HeaderWithDefaultsSettings {
|
|
46
46
|
siteName: string;
|
|
47
|
+
/** Optional header brand icon — forwarded verbatim to `<Header>`. */
|
|
48
|
+
headerBrand?: false | HeaderBrandConfig;
|
|
47
49
|
/** Site base path — fed to the language-switcher SPA re-wire config. */
|
|
48
50
|
base: string;
|
|
49
51
|
/** Trailing-slash policy — fed to the language-switcher SPA re-wire config. */
|
|
@@ -194,6 +194,7 @@ function createHeaderWithDefaults(ctx) {
|
|
|
194
194
|
languageSwitcher,
|
|
195
195
|
persistKey,
|
|
196
196
|
siteName: settings.siteName,
|
|
197
|
+
headerBrand: settings.headerBrand,
|
|
197
198
|
headerNav: settings.headerNav,
|
|
198
199
|
headerRightItems,
|
|
199
200
|
headerRightComponents: ctx.hostBindings.headerRightComponents,
|
package/dist/home-page/index.js
CHANGED
|
@@ -174,7 +174,7 @@ function createHomePageView(ctx) {
|
|
|
174
174
|
}
|
|
175
175
|
) : null,
|
|
176
176
|
/* @__PURE__ */ jsxs("div", { class: "zd-home-copy min-w-0 lg:flex-1", children: [
|
|
177
|
-
/* @__PURE__ */ jsx("h1", { class: "text-heading font-bold mb-vsp-2xs zd-wrap-anywhere", children: settings.siteName }),
|
|
177
|
+
/* @__PURE__ */ jsx("h1", { class: "text-heading font-bold mb-vsp-2xs zd-wrap-anywhere", "data-zd-site-name": true, children: settings.siteName }),
|
|
178
178
|
/* @__PURE__ */ jsx("p", { class: "text-muted text-small mb-vsp-sm", children: rawDescription }),
|
|
179
179
|
/* @__PURE__ */ jsx("div", { class: "zd-home-links flex flex-wrap items-center justify-center lg:justify-start gap-hsp-md text-small", children: rowContent })
|
|
180
180
|
] })
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
function pickKatex(m) {
|
|
2
|
+
let cur = m;
|
|
3
|
+
for (let i = 0; i < 3 && cur && typeof cur === "object"; i++) {
|
|
4
|
+
if (typeof cur.renderToString === "function") return cur;
|
|
5
|
+
cur = cur.default;
|
|
6
|
+
}
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const katex = await import("katex").then(pickKatex, () => null);
|
|
10
|
+
export {
|
|
11
|
+
katex
|
|
12
|
+
};
|
package/dist/math-block/index.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { jsx } from "@takazudo/zfb/zudo-react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
cur = cur.default;
|
|
7
|
-
}
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
const katex = await import("katex").then(pickKatex, () => null);
|
|
2
|
+
const katex = await import("@takazudo/zudo-doc/katex-loader").then(
|
|
3
|
+
(m) => m.katex,
|
|
4
|
+
() => null
|
|
5
|
+
);
|
|
11
6
|
const MISSING_KATEX_MESSAGE = 'MathBlock requires the optional peer "katex": install it and set math: true';
|
|
12
7
|
function MathBlock({ latex, block = false }) {
|
|
13
8
|
if (!katex) throw new Error(MISSING_KATEX_MESSAGE);
|
package/dist/md-utils/index.d.ts
CHANGED
|
@@ -34,8 +34,14 @@ export interface MdDocFrontmatter {
|
|
|
34
34
|
* search excerpts and llms-txt descriptions stay byte-equal across the
|
|
35
35
|
* cutover, with one deliberate divergence: it also strips JSX/MDX block
|
|
36
36
|
* comments (the `{/*`-delimited MDX comment form), which the legacy
|
|
37
|
-
* pipeline leaked into descriptions (zudo-doc#2175)
|
|
38
|
-
*
|
|
37
|
+
* pipeline leaked into descriptions (zudo-doc#2175), and a second one
|
|
38
|
+
* (zudo-doc#4647): inline code keeps its text (only the backticks are
|
|
39
|
+
* dropped, contents protected from the later rules) instead of being deleted,
|
|
40
|
+
* and remark-directive container fence lines (`:::name[label]{attrs}`,
|
|
41
|
+
* `:::name Title`, bare `:::` closers) are removed while the label/title
|
|
42
|
+
* text is kept. Do not add
|
|
43
|
+
* other new rules without also updating the byte-equality fixtures
|
|
44
|
+
* (topic-plugin-audit).
|
|
39
45
|
*/
|
|
40
46
|
export declare function stripMarkdown(md: string): string;
|
|
41
47
|
/**
|
package/dist/md-utils/index.js
CHANGED
|
@@ -31,11 +31,18 @@ function decodeCharacterReferences(value) {
|
|
|
31
31
|
).replace(/&/g, "&");
|
|
32
32
|
}
|
|
33
33
|
function stripMarkdown(md) {
|
|
34
|
-
const
|
|
35
|
-
|
|
34
|
+
const inlineCode = [];
|
|
35
|
+
const withoutCodeCommentsAndTags = md.replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_m, code) => {
|
|
36
|
+
inlineCode.push(code);
|
|
37
|
+
return `\uE000${inlineCode.length - 1}\uE001`;
|
|
38
|
+
}).replace(/\{\/\*[\s\S]*?\*\/\}/g, "").replace(/<[^>]+>/g, "");
|
|
39
|
+
return decodeCharacterReferences(withoutCodeCommentsAndTags).replace(
|
|
40
|
+
/^[ \t]*:{3,}(?:[A-Za-z][\w-]*(?:\[([^\]\n]*)\])?(?:\{[^}\n]*\})?(?:[ \t]+(\S[^\n]*?))?)?[ \t]*$/gm,
|
|
41
|
+
(_m, label, title) => label ?? title ?? ""
|
|
42
|
+
).replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(
|
|
36
43
|
/(^|[^\p{L}\p{N}])(_{1,3})(?=\S)([^_\n]*?\S)\2(?=$|[^\p{L}\p{N}])/gmu,
|
|
37
44
|
"$1$3"
|
|
38
|
-
).replace(/!\[[^\]]*\]\([^)]+\)/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}\s*$/gm, "").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^import\s+.*$/gm, "").replace(/^export\s+.*$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
45
|
+
).replace(/!\[[^\]]*\]\([^)]+\)/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}\s*$/gm, "").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^import\s+.*$/gm, "").replace(/^export\s+.*$/gm, "").replace(/\n{3,}/g, "\n\n").replace(/\uE000(\d+)\uE001/g, (_m, i) => inlineCode[Number(i)] ?? "").trim();
|
|
39
46
|
}
|
|
40
47
|
function collectMdFiles(dir) {
|
|
41
48
|
const results = [];
|
|
@@ -23,7 +23,8 @@ function CardBody({
|
|
|
23
23
|
item,
|
|
24
24
|
locale: props.locale,
|
|
25
25
|
updatedLabel: props.updatedLabel,
|
|
26
|
-
dateFormats: props.dateFormats
|
|
26
|
+
dateFormats: props.dateFormats,
|
|
27
|
+
linked
|
|
27
28
|
}
|
|
28
29
|
) })
|
|
29
30
|
] }),
|
|
@@ -36,24 +37,23 @@ function DateStamp({
|
|
|
36
37
|
locale,
|
|
37
38
|
updatedLabel,
|
|
38
39
|
positioned,
|
|
40
|
+
linked,
|
|
39
41
|
dateFormats
|
|
40
42
|
}) {
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
);
|
|
43
|
+
const stampClass = [
|
|
44
|
+
"hidden sm:flex w-[6.5rem] flex-col items-end self-stretch border-l border-muted pl-hsp-xl text-muted tabular-nums",
|
|
45
|
+
positioned && "sm:col-start-2 sm:row-start-1 sm:row-span-2",
|
|
46
|
+
linked && "group-hover:text-accent group-focus-visible:text-accent"
|
|
47
|
+
].filter(Boolean).join(" ");
|
|
48
|
+
return /* @__PURE__ */ jsxs("time", { datetime: date, class: stampClass, children: [
|
|
49
|
+
/* @__PURE__ */ jsx("span", { class: "block text-title leading-tight font-medium", children: formatMonthDayLabel(date, locale, dateFormats?.monthDay) }),
|
|
50
|
+
/* @__PURE__ */ jsx("span", { class: "block text-caption", children: formatYear(date, locale, dateFormats?.year) }),
|
|
51
|
+
updated && /* @__PURE__ */ jsxs("span", { class: "mt-vsp-3xs block text-micro", children: [
|
|
52
|
+
updatedLabel,
|
|
53
|
+
" ",
|
|
54
|
+
formatMonthDayLabel(updated, locale, dateFormats?.monthDay)
|
|
55
|
+
] })
|
|
56
|
+
] });
|
|
57
57
|
}
|
|
58
58
|
function CardList(props) {
|
|
59
59
|
return /* @__PURE__ */ jsx("div", { class: "grid grid-cols-1 gap-vsp-md", children: props.items.map((item) => /* @__PURE__ */ jsx(
|
|
@@ -84,7 +84,8 @@ function CardList(props) {
|
|
|
84
84
|
locale: props.locale,
|
|
85
85
|
updatedLabel: props.updatedLabel,
|
|
86
86
|
dateFormats: props.dateFormats,
|
|
87
|
-
positioned: true
|
|
87
|
+
positioned: true,
|
|
88
|
+
linked: true
|
|
88
89
|
}
|
|
89
90
|
)
|
|
90
91
|
]
|
|
@@ -107,7 +108,8 @@ function CardList(props) {
|
|
|
107
108
|
locale: props.locale,
|
|
108
109
|
updatedLabel: props.updatedLabel,
|
|
109
110
|
dateFormats: props.dateFormats,
|
|
110
|
-
positioned: true
|
|
111
|
+
positioned: true,
|
|
112
|
+
linked: false
|
|
111
113
|
}
|
|
112
114
|
)
|
|
113
115
|
] }),
|
|
@@ -135,7 +137,8 @@ function CardList(props) {
|
|
|
135
137
|
locale: props.locale,
|
|
136
138
|
updatedLabel: props.updatedLabel,
|
|
137
139
|
dateFormats: props.dateFormats,
|
|
138
|
-
positioned: false
|
|
140
|
+
positioned: false,
|
|
141
|
+
linked: true
|
|
139
142
|
}
|
|
140
143
|
)
|
|
141
144
|
]
|
|
@@ -158,7 +161,8 @@ function CardList(props) {
|
|
|
158
161
|
locale: props.locale,
|
|
159
162
|
updatedLabel: props.updatedLabel,
|
|
160
163
|
dateFormats: props.dateFormats,
|
|
161
|
-
positioned: false
|
|
164
|
+
positioned: false,
|
|
165
|
+
linked: false
|
|
162
166
|
}
|
|
163
167
|
)
|
|
164
168
|
] })
|