@dogsbay/ssg 0.2.0-beta.151 → 0.2.0-beta.152

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.
@@ -420,6 +420,51 @@ var CSS = `@layer properties;@layer theme,base,components,utilities;@layer theme
420
420
  }
421
421
  }
422
422
  }
423
+ .max-2xl\\:hidden {
424
+ @media (width < 96rem) {
425
+ display: none;
426
+ }
427
+ }
428
+ .max-2xl\\:px-2 {
429
+ @media (width < 96rem) {
430
+ padding-inline: calc(var(--spacing) * 2);
431
+ }
432
+ }
433
+ .max-lg\\:hidden {
434
+ @media (width < 64rem) {
435
+ display: none;
436
+ }
437
+ }
438
+ .max-lg\\:h-auto {
439
+ @media (width < 64rem) {
440
+ height: auto;
441
+ }
442
+ }
443
+ .max-lg\\:min-h-12 {
444
+ @media (width < 64rem) {
445
+ min-height: calc(var(--spacing) * 12);
446
+ }
447
+ }
448
+ .max-lg\\:flex-wrap {
449
+ @media (width < 64rem) {
450
+ flex-wrap: wrap;
451
+ }
452
+ }
453
+ .max-lg\\:justify-end {
454
+ @media (width < 64rem) {
455
+ justify-content: flex-end;
456
+ }
457
+ }
458
+ .max-lg\\:gap-y-1 {
459
+ @media (width < 64rem) {
460
+ row-gap: var(--spacing);
461
+ }
462
+ }
463
+ .max-lg\\:py-1 {
464
+ @media (width < 64rem) {
465
+ padding-block: var(--spacing);
466
+ }
467
+ }
423
468
  .max-md\\:hidden {
424
469
  @media (width < 48rem) {
425
470
  display: none;
@@ -475,6 +520,11 @@ var CSS = `@layer properties;@layer theme,base,components,utilities;@layer theme
475
520
  display: block;
476
521
  }
477
522
  }
523
+ .lg\\:flex {
524
+ @media (width >= 64rem) {
525
+ display: flex;
526
+ }
527
+ }
478
528
  .lg\\:hidden {
479
529
  @media (width >= 64rem) {
480
530
  display: none;
@@ -531,6 +581,31 @@ var CSS = `@layer properties;@layer theme,base,components,utilities;@layer theme
531
581
  padding-inline: calc(var(--spacing) * 12);
532
582
  }
533
583
  }
584
+ .xl\\:flex {
585
+ @media (width >= 80rem) {
586
+ display: flex;
587
+ }
588
+ }
589
+ .xl\\:hidden {
590
+ @media (width >= 80rem) {
591
+ display: none;
592
+ }
593
+ }
594
+ .\\32 xl\\:flex {
595
+ @media (width >= 96rem) {
596
+ display: flex;
597
+ }
598
+ }
599
+ .\\32 xl\\:hidden {
600
+ @media (width >= 96rem) {
601
+ display: none;
602
+ }
603
+ }
604
+ .\\32 xl\\:inline {
605
+ @media (width >= 96rem) {
606
+ display: inline;
607
+ }
608
+ }
534
609
  .dark\\:block {
535
610
  &:where(.dark, .dark *) {
536
611
  display: block;
@@ -1663,6 +1738,11 @@ details[open] > summary [data-property-chevron] {
1663
1738
  :root {
1664
1739
  --db-header-height: 3rem;
1665
1740
  }
1741
+ @media (max-width: 63.99rem) {
1742
+ :root[data-header="crowded"] {
1743
+ --db-header-height: 5.25rem;
1744
+ }
1745
+ }
1666
1746
  html {
1667
1747
  scroll-padding-top: calc(var(--db-header-height) + 1rem);
1668
1748
  }
@@ -1800,12 +1880,35 @@ db-select [data-part="trigger"] {
1800
1880
  line-height: var(--tw-leading, var(--text-sm--line-height));
1801
1881
  --tw-font-weight: var(--font-weight-medium);
1802
1882
  font-weight: var(--font-weight-medium);
1883
+ white-space: nowrap;
1803
1884
  color: var(--foreground);
1804
1885
  &:hover {
1805
1886
  @media (hover: hover) {
1806
1887
  background-color: var(--accent);
1807
1888
  }
1808
1889
  }
1890
+ @media (width < 48rem) {
1891
+ padding-inline: calc(var(--spacing) * 2);
1892
+ }
1893
+ }
1894
+ db-select [data-part="value"] {
1895
+ display: block;
1896
+ max-width: 10rem;
1897
+ overflow: hidden;
1898
+ text-overflow: ellipsis;
1899
+ white-space: nowrap;
1900
+ @media (width < 48rem) {
1901
+ max-width: 6rem;
1902
+ }
1903
+ }
1904
+ db-select.db-switch-product [data-part="value"] {
1905
+ max-width: 12rem;
1906
+ @media (width < 48rem) {
1907
+ max-width: 7rem;
1908
+ }
1909
+ }
1910
+ db-select > select {
1911
+ max-width: 12rem;
1809
1912
  }
1810
1913
  db-select [data-part="trigger"] svg {
1811
1914
  margin-left: var(--spacing);
@@ -420,6 +420,51 @@ var CSS = `@layer properties;@layer theme,base,components,utilities;@layer theme
420
420
  }
421
421
  }
422
422
  }
423
+ .max-2xl\\:hidden {
424
+ @media (width < 96rem) {
425
+ display: none;
426
+ }
427
+ }
428
+ .max-2xl\\:px-2 {
429
+ @media (width < 96rem) {
430
+ padding-inline: calc(var(--spacing) * 2);
431
+ }
432
+ }
433
+ .max-lg\\:hidden {
434
+ @media (width < 64rem) {
435
+ display: none;
436
+ }
437
+ }
438
+ .max-lg\\:h-auto {
439
+ @media (width < 64rem) {
440
+ height: auto;
441
+ }
442
+ }
443
+ .max-lg\\:min-h-12 {
444
+ @media (width < 64rem) {
445
+ min-height: calc(var(--spacing) * 12);
446
+ }
447
+ }
448
+ .max-lg\\:flex-wrap {
449
+ @media (width < 64rem) {
450
+ flex-wrap: wrap;
451
+ }
452
+ }
453
+ .max-lg\\:justify-end {
454
+ @media (width < 64rem) {
455
+ justify-content: flex-end;
456
+ }
457
+ }
458
+ .max-lg\\:gap-y-1 {
459
+ @media (width < 64rem) {
460
+ row-gap: var(--spacing);
461
+ }
462
+ }
463
+ .max-lg\\:py-1 {
464
+ @media (width < 64rem) {
465
+ padding-block: var(--spacing);
466
+ }
467
+ }
423
468
  .max-md\\:hidden {
424
469
  @media (width < 48rem) {
425
470
  display: none;
@@ -475,6 +520,11 @@ var CSS = `@layer properties;@layer theme,base,components,utilities;@layer theme
475
520
  display: block;
476
521
  }
477
522
  }
523
+ .lg\\:flex {
524
+ @media (width >= 64rem) {
525
+ display: flex;
526
+ }
527
+ }
478
528
  .lg\\:hidden {
479
529
  @media (width >= 64rem) {
480
530
  display: none;
@@ -531,6 +581,31 @@ var CSS = `@layer properties;@layer theme,base,components,utilities;@layer theme
531
581
  padding-inline: calc(var(--spacing) * 12);
532
582
  }
533
583
  }
584
+ .xl\\:flex {
585
+ @media (width >= 80rem) {
586
+ display: flex;
587
+ }
588
+ }
589
+ .xl\\:hidden {
590
+ @media (width >= 80rem) {
591
+ display: none;
592
+ }
593
+ }
594
+ .\\32 xl\\:flex {
595
+ @media (width >= 96rem) {
596
+ display: flex;
597
+ }
598
+ }
599
+ .\\32 xl\\:hidden {
600
+ @media (width >= 96rem) {
601
+ display: none;
602
+ }
603
+ }
604
+ .\\32 xl\\:inline {
605
+ @media (width >= 96rem) {
606
+ display: inline;
607
+ }
608
+ }
534
609
  .dark\\:block {
535
610
  &:where(.dark, .dark *) {
536
611
  display: block;
@@ -1663,6 +1738,11 @@ details[open] > summary [data-property-chevron] {
1663
1738
  :root {
1664
1739
  --db-header-height: 3rem;
1665
1740
  }
1741
+ @media (max-width: 63.99rem) {
1742
+ :root[data-header="crowded"] {
1743
+ --db-header-height: 5.25rem;
1744
+ }
1745
+ }
1666
1746
  html {
1667
1747
  scroll-padding-top: calc(var(--db-header-height) + 1rem);
1668
1748
  }
@@ -1800,12 +1880,35 @@ db-select [data-part="trigger"] {
1800
1880
  line-height: var(--tw-leading, var(--text-sm--line-height));
1801
1881
  --tw-font-weight: var(--font-weight-medium);
1802
1882
  font-weight: var(--font-weight-medium);
1883
+ white-space: nowrap;
1803
1884
  color: var(--foreground);
1804
1885
  &:hover {
1805
1886
  @media (hover: hover) {
1806
1887
  background-color: var(--accent);
1807
1888
  }
1808
1889
  }
1890
+ @media (width < 48rem) {
1891
+ padding-inline: calc(var(--spacing) * 2);
1892
+ }
1893
+ }
1894
+ db-select [data-part="value"] {
1895
+ display: block;
1896
+ max-width: 10rem;
1897
+ overflow: hidden;
1898
+ text-overflow: ellipsis;
1899
+ white-space: nowrap;
1900
+ @media (width < 48rem) {
1901
+ max-width: 6rem;
1902
+ }
1903
+ }
1904
+ db-select.db-switch-product [data-part="value"] {
1905
+ max-width: 12rem;
1906
+ @media (width < 48rem) {
1907
+ max-width: 7rem;
1908
+ }
1909
+ }
1910
+ db-select > select {
1911
+ max-width: 12rem;
1809
1912
  }
1810
1913
  db-select [data-part="trigger"] svg {
1811
1914
  margin-left: var(--spacing);
@@ -392,6 +392,11 @@ var THEME_CSS = { "api.css": "/* Generated by packages/render-html/scripts/sync-
392
392
  */
393
393
 
394
394
  :root { --db-header-height: 3rem; }
395
+ /* A crowded header (links and menus, DocsLayout) wraps its menus below 1024 px and grows with them, usually
396
+ to two rows: the height is that estimate, for what offsets by it and where a jumped-to heading lands. */
397
+ @media (max-width: 63.99rem) {
398
+ :root[data-header="crowded"] { --db-header-height: 5.25rem; }
399
+ }
395
400
  html { scroll-padding-top: calc(var(--db-header-height) + 1rem); }
396
401
 
397
402
  :where(db-tabs, db-accordion, db-collapsible, db-code-block, db-nav-tree, db-toc, db-combobox) { display: block; }
@@ -434,8 +439,12 @@ db-nav-tree [data-part="toggle"][aria-expanded="true"] [data-part="chevron"] { t
434
439
 
435
440
  /* \u2500\u2500\u2500 Version and language switchers (VersionSwitcher look, db-select parts) \u2500 */
436
441
  db-select [data-part="trigger"] {
437
- @apply flex cursor-pointer items-center gap-1 rounded-md border border-border bg-transparent px-3 py-1.5 text-sm font-medium text-foreground hover:bg-accent;
442
+ @apply flex cursor-pointer items-center gap-1 whitespace-nowrap rounded-md border border-border bg-transparent px-3 py-1.5 text-sm font-medium text-foreground hover:bg-accent max-md:px-2;
438
443
  }
444
+ /* Long names are cut short, as the Astro switchers' labels are (10rem, the product's 12rem; less on phones). */
445
+ db-select [data-part="value"] { @apply block max-w-[10rem] truncate max-md:max-w-[6rem]; }
446
+ db-select.db-switch-product [data-part="value"] { @apply max-w-[12rem] max-md:max-w-[7rem]; }
447
+ db-select > select { @apply max-w-[12rem]; }
439
448
  db-select [data-part="trigger"] svg { @apply ml-1 size-3.5 transition-transform; }
440
449
  db-select[data-state="open"] [data-part="trigger"] svg { transform: rotate(180deg); }
441
450
  db-select [data-part="content"] {
@@ -34,11 +34,11 @@ export type SinkContent = string | Uint8Array | FileRef | TextStream;
34
34
  /** A built file held in memory (no sink). */
35
35
  export type OutputContent = string | Uint8Array;
36
36
  /**
37
- * Icon name → SVG markup or an emoji (undefined when unknown). `notices`, when the host has it,
38
- * returns the attribution for the icon sets the pages drew from, for THIRD-PARTY-NOTICES.txt.
37
+ * Icon name → SVG markup or an emoji (undefined when unknown). `sets`, when the host has it, returns
38
+ * the Iconify sets the pages drew from, whose attribution goes in THIRD-PARTY-NOTICES.txt.
39
39
  */
40
40
  export type IconResolver = ((name: string) => string | undefined) & {
41
- notices?: () => string | undefined;
41
+ sets?: () => string[];
42
42
  };
43
43
  export interface BuildInput {
44
44
  /** Project files keyed by path relative to the project root (where the config lives). */
@@ -47,6 +47,17 @@ export interface BuildInput {
47
47
  config?: string | SiteConfig;
48
48
  /** Build only the units with these prefixes (a Worker builds one unit per request). */
49
49
  units?: string[];
50
+ /**
51
+ * The unit manifests of the site this build updates (`_dogsbay/units/…`, plans/unit-publishing.md):
52
+ * a unit not built here is represented by its manifest in the site-wide files (`_redirects`, the
53
+ * sitemap index, the root forwards), so a one-unit build writes them as a full build would.
54
+ * `path` names the file in warnings. The build empties the array once it has read them, so their
55
+ * text is not held through the build (the Worker's memory).
56
+ */
57
+ manifests?: Array<{
58
+ path: string;
59
+ text: string;
60
+ }>;
50
61
  /**
51
62
  * content.html when the project does not set it: "keep" (the default) or "sanitize"
52
63
  * (the Worker's, where projects come from anyone with the token and share one origin).
@@ -236,6 +247,8 @@ export interface SiteState {
236
247
  };
237
248
  /** A page rendered math, so the KaTeX stylesheet and fonts are written. */
238
249
  usedMath: boolean;
250
+ /** The units (prefixes) a page of which rendered math, for their manifests. */
251
+ mathUnits: Set<string>;
239
252
  /** Rendered diagrams, shared by the units of the build. */
240
253
  diagrams?: DiagramStore;
241
254
  /** The default version's pages and redirects per language, for older versions' canonical links (src/core/canonical.ts). */
@@ -479,4 +492,6 @@ export interface LoadedTheme {
479
492
  * unit was built here, only to a page it wrote (the nav may leave pages out). In another
480
493
  * language a redirect source holds its URL, so it counts as present. Returns the stubs written.
481
494
  */
482
- export declare function writeTranslationStubs(cfg: SiteConfig, all: BuildUnit[], built: BuildUnit[], tables: Map<string, DefaultTable>, state: Pick<SiteState, "written" | "pageOut">, emit: (path: string, c: FileContent) => Promise<void>, exists?: (path: string) => boolean): Promise<string[]>;
495
+ export declare function writeTranslationStubs(cfg: SiteConfig, all: BuildUnit[], built: BuildUnit[], tables: Map<string, DefaultTable>, state: Pick<SiteState, "written" | "pageOut">, emit: (path: string, c: FileContent) => Promise<void>, exists?: (path: string) => boolean,
496
+ /** Units not built here whose pages `state.pageOut` holds (from their manifests). */
497
+ stored?: ReadonlySet<string>): Promise<string[]>;
@@ -0,0 +1,9 @@
1
+ /** An Iconify set name as a unit manifest may record it (the `icon-notices` table's keys are of this shape). */
2
+ export declare const ICON_SET_NAME: RegExp;
3
+ /**
4
+ * THIRD-PARTY-NOTICES.txt's section for the Iconify sets the pages drew from (`sets`, prefixes), or
5
+ * undefined when there is none to list. Lucide and MDI are listed with render-html's built-in icons in
6
+ * every site already. Pure, so a one-unit build lists the sets its stored units recorded too
7
+ * (plans/unit-publishing.md).
8
+ */
9
+ export declare function iconSetNotices(sets: Iterable<string>): string | undefined;
@@ -117,5 +117,11 @@ export declare function splitSuffix(raw: string): {
117
117
  export declare function stubFile(rule: RedirectRule): string;
118
118
  /** A meta-refresh page, as `renderMetaRefreshPage`, with a relative target so it works from disk. */
119
119
  export declare function renderRedirectPage(rule: RedirectRule, cfg: SiteConfig): string;
120
+ /** A rule as the site serves it: `from` and `to` with the base path, `to` as its page is served. */
121
+ export declare function servedRedirect(r: RedirectRule, cfg: SiteConfig): {
122
+ from: string;
123
+ to: string;
124
+ status: number;
125
+ };
120
126
  /** _redirects (Cloudflare), as `renderRedirectsFile`, with served paths. */
121
127
  export declare function renderRedirectsFile(rules: RedirectRule[], cfg: SiteConfig): string;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * A manifest per unit (plans/unit-publishing.md): what each unit's build leaves for the site-wide
3
+ * files, so one product, version or language can be built and published on its own and the
4
+ * `_redirects`, sitemap index and root forwards still cover every unit. The format is
5
+ * @dogsbay/site-files' `UnitManifest` (shared with the Dogsbay CLI), with our own `ssg` section.
6
+ * Written at `_dogsbay/units/<unitKeyString>.json` on sites with two or more units. Pure: the CLI
7
+ * and the Worker read the files and hand them to `build()` as `BuildInput.manifests`.
8
+ */
9
+ import { type UnitManifest } from "@dogsbay/site-files";
10
+ import type { BuildUnit } from "./config.js";
11
+ import type { RedirectInput } from "./site-files.js";
12
+ /** What a unit's build records for the next one-unit build or assemble. */
13
+ export interface SsgUnitData {
14
+ /** The unit's folder in the site ("" at the root). */
15
+ prefix: string;
16
+ /** Its redirects before they are resolved (front matter and aliases; config redirects come from the config). */
17
+ redirectInputs: RedirectInput[];
18
+ /** `[site path, output file]` of its pages, so other units' redirects resolve against them. */
19
+ pageOut: Array<[string, string]>;
20
+ /** Its sitemap files, for the sitemap index. */
21
+ sitemaps: string[];
22
+ /** The page its home forwards to, when it has no home page. */
23
+ homeForward?: string;
24
+ /** Every file it wrote, so the next publish of the unit can remove the ones it no longer writes. */
25
+ files: string[];
26
+ /** The client file its pages load (`_dogsbay/assets/<client>`). */
27
+ client: string;
28
+ /** The dogsbay-ssg version that built it. */
29
+ builder: string;
30
+ /** A page rendered math: the site keeps KaTeX's files and its notice. */
31
+ math?: boolean;
32
+ /** The Iconify sets its pages drew from, for THIRD-PARTY-NOTICES.txt (may list sets an earlier unit of the same build used). */
33
+ iconSets?: string[];
34
+ }
35
+ export type SsgUnitManifest = UnitManifest & {
36
+ ssg: SsgUnitData;
37
+ };
38
+ /** The unit's key, as site-files names a unit (`calico/_/3.32`). */
39
+ export declare function unitKey(u: Pick<BuildUnit, "product" | "locale" | "version">): string;
40
+ /** Where a unit's manifest is written, from the site root. */
41
+ export declare function manifestPath(u: Pick<BuildUnit, "product" | "locale" | "version">): string;
42
+ /** The folder the manifests sit in, from the site root. */
43
+ export declare const MANIFEST_DIR = "_dogsbay/units/";
44
+ export declare function makeManifest(u: BuildUnit, ssg: SsgUnitData, redirects: Array<[string, string, number]>): SsgUnitManifest;
45
+ /**
46
+ * A manifest read back (JSON text or a parsed value), checked: undefined, with a reason, when it is
47
+ * not one this build can use (another format, or written by something other than dogsbay-ssg).
48
+ */
49
+ export declare function parseManifest(raw: unknown): {
50
+ manifest?: SsgUnitManifest;
51
+ problem?: string;
52
+ };
53
+ /** The hashed client files (`dogsbay-<hash>.js`, in `_dogsbay/assets/`) an update removes when no unit loads them. */
54
+ export declare const CLIENT_PATTERN: RegExp;
55
+ /** What removing stale files needs of a manifest. */
56
+ export interface UnitFiles {
57
+ prefix: string;
58
+ files: string[];
59
+ client: string;
60
+ }
61
+ /** A manifest's `UnitFiles`, or null when the text is not a manifest this version can read. */
62
+ export declare function unitFilesOf(text: string): UnitFiles | null;
63
+ /**
64
+ * After a one-unit update, the files to remove (site paths). `previous` and `now` are the site's
65
+ * manifests before and after the build, by path (null: unreadable); a unit counts as rebuilt when this
66
+ * build wrote its manifest (`written` holds every path the build wrote).
67
+ * - A rebuilt unit's files its previous manifest listed and its new one does not (pages deleted or
68
+ * moved), unless this build wrote them, or they are not in that unit's own folder: the unit whose
69
+ * prefix is the longest to hold the path (a version at the root holds the others' folders), so a
70
+ * manifest can only ever remove files of its own unit.
71
+ * - The hashed clients in `assets` (file names) no manifest loads any more; none when a manifest
72
+ * cannot be read, since its pages may load one.
73
+ */
74
+ export declare function staleUnitFiles(previous: ReadonlyMap<string, UnitFiles | null>, now: ReadonlyMap<string, UnitFiles | null>, written: ReadonlySet<string>, assets: readonly string[]): string[];
@@ -1,4 +1,11 @@
1
1
  export declare const CLIENT_JS: string;
2
+ /**
3
+ * The name the pages load the client by, from its content (_dogsbay/assets/<CLIENT_FILE>): a unit built
4
+ * by another version of the client keeps loading its own (plans/unit-publishing.md).
5
+ */
6
+ export declare const CLIENT_FILE: string;
7
+ /** This package's version, recorded in each unit's manifest. */
8
+ export declare const SSG_VERSION: string;
2
9
  export declare const THEME_TEMPLATES: Record<string, string>;
3
10
  export declare const CLIENT_CANDIDATES: string[];
4
11
  /** _dogsbay/assets/THIRD-PARTY-NOTICES.txt: the client's packages and Tailwind (scripts/notices.mjs). */
@@ -0,0 +1,2 @@
1
+ /** Each Iconify set's attribution and licence (scripts/notices.mjs iconSetNotice), by prefix. */
2
+ export declare const ICON_SET_NOTICES: Record<string, string>;
@@ -50,3 +50,15 @@ export declare const isMenu: (l: SiteChromeLink | SiteChromeMenu) => l is SiteCh
50
50
  export declare const isExternal: (href: string) => boolean;
51
51
  /** The announcement's colours by tone: the callout tokens, so the theme and dark mode apply. */
52
52
  export declare const ANNOUNCEMENT_TONE_CLASS: Record<string, string>;
53
+ /** The width the header's links show in the bar from (in the sidebar's list below it); `never`: the list only. */
54
+ export type LinksFrom = "lg" | "xl" | "2xl" | "never";
55
+ /**
56
+ * Where the header's links fit: the first width at which their estimated width fits beside what
57
+ * else the header holds, or `never`. Estimated from the labels (about 6.2 px a character at the
58
+ * header's text size, 28 px padding a link, 14 px a dropdown's chevron) against the header beside
59
+ * the 256 px sidebar, less the trigger and padding (80 px) and the menus: about 520 px for a
60
+ * crowded header (product, version, page actions, icons), 210 px otherwise (search with its
61
+ * text, the icons). A crowded header starts at xl. Measured on Tigera's (47 characters, 4 links:
62
+ * xl) and the products fixture; a long navbar stays in the sidebar rather than push the page wide.
63
+ */
64
+ export declare function headerLinksFrom(links: Array<SiteChromeLink | SiteChromeMenu>, crowded: boolean): LinksFrom;
@@ -88,25 +88,11 @@ export declare function resolveTagDisplayLabel(tag: string, labels?: Record<stri
88
88
  */
89
89
  export declare function resolveTagKeywords(tags: readonly unknown[] | undefined, labels?: Record<string, string>): string[];
90
90
  /**
91
- * Resolve the display label for a term identified by its fullPath
92
- * array (e.g. `["concept"]` or `["concept", "a11y"]`).
93
- *
94
- * Used by `<TaxonomyIndex>` term-cloud chips, `<TaxonomyTerm>`
95
- * page headings and breadcrumbs, and sub-tag pills — anywhere a
96
- * structural slug needs to render as a human label.
97
- *
98
- * Resolution order:
99
- * 1. `labels[fullSlug]` (joined fullPath) — explicit override
100
- * wins, regardless of depth.
101
- * 2. For top-level terms (`fullPath.length === 1`):
102
- * `prefixes[segment].label` — lets a top-level segment
103
- * (`concept`, `difficulty`) render as "Concept", "Difficulty".
104
- * 3. The leaf segment of the path — the rendered fallback for
105
- * deeper terms with no override.
106
- *
107
- * URLs continue to use the slug-form `fullPath`. Display only.
91
+ * Display label of a term path (`labels` override, then a top-level
92
+ * `prefixes` label, then the leaf). One implementation, shared with the
93
+ * search facet column: `@dogsbay/search/facets`.
108
94
  */
109
- export declare function resolveTermLabel(fullPath: readonly string[], prefixes?: Record<string, PrefixDisplay>, labels?: Record<string, string>): string;
95
+ export { resolveTermLabel } from "@dogsbay/search/facets";
110
96
  /**
111
97
  * Map raw tag slugs to render-ready chip models, applying prefix
112
98
  * + label config rules.
@@ -14,6 +14,7 @@ export declare function sidebar(opts: {
14
14
  nav: string;
15
15
  label: string;
16
16
  links?: string;
17
+ linksClass?: string;
17
18
  }): string;
18
19
  export declare function sidebarTrigger(label: string): string;
19
20
  export interface NavOptions {
@@ -54,7 +55,8 @@ export declare function navTree(nodes: NavNode[], o: NavOptions): string;
54
55
  export type CompactNav = [string, string | null, CompactNav[]?, 1?];
55
56
  export declare function compactNav(nodes: NavNode[], href: (slug: string) => string | undefined): CompactNav[];
56
57
  export declare function navSize(nodes: NavNode[]): number;
57
- export declare function searchButton(label: string): string;
58
+ /** `compact`: a crowded header (SearchDialog's `compact`), the label and key only from 2xl. */
59
+ export declare function searchButton(label: string, compact?: boolean): string;
58
60
  export declare function themeToggle(label: string): string;
59
61
  export interface SwitchOption {
60
62
  label: string;
@@ -67,6 +69,7 @@ export interface SwitchOption {
67
69
  /** A versionMenu link after the versions: the client goes straight to it. */
68
70
  link?: boolean;
69
71
  }
72
+ /** `compact`: a crowded header, the button an icon below 2xl (PageActions.astro `compact`; its aria-label names it). */
70
73
  export declare function pageActions(o: {
71
74
  mdHref: string;
72
75
  label: string;
@@ -77,6 +80,7 @@ export declare function pageActions(o: {
77
80
  href: string;
78
81
  }[];
79
82
  copy: boolean;
83
+ compact?: boolean;
80
84
  }): string;
81
85
  export declare function h1(title: string): string;
82
86
  export declare function lede(text: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dogsbay/ssg",
3
- "version": "0.2.0-beta.151",
3
+ "version": "0.2.0-beta.152",
4
4
  "type": "module",
5
5
  "description": "Documentation static site generator for Dogsbay-MD that builds inside Cloudflare Workers and publishes sites that work offline",
6
6
  "license": "Apache-2.0",
@@ -49,38 +49,38 @@
49
49
  "tailwindcss": "^4.3.2"
50
50
  },
51
51
  "peerDependencies": {
52
- "@dogsbay/elements": "0.2.0-beta.151",
53
- "@dogsbay/format-dogsbay-md": "0.2.0-beta.151",
54
- "@dogsbay/format-openapi": "0.2.0-beta.151",
55
- "@dogsbay/format-topicmap": "0.2.0-beta.151",
56
- "@dogsbay/highlight": "0.2.0-beta.151",
57
- "@dogsbay/minja": "0.2.0-beta.151",
58
- "@dogsbay/primitives": "0.2.0-beta.151",
59
- "@dogsbay/render-html": "0.2.0-beta.151",
60
- "@dogsbay/search": "0.2.0-beta.151",
61
- "@dogsbay/serialize-core": "0.2.0-beta.151",
62
- "@dogsbay/site-check": "0.2.0-beta.151",
63
- "@dogsbay/site-files": "0.2.0-beta.151",
64
- "@dogsbay/types": "0.2.0-beta.151"
52
+ "@dogsbay/elements": "0.2.0-beta.152",
53
+ "@dogsbay/format-dogsbay-md": "0.2.0-beta.152",
54
+ "@dogsbay/format-openapi": "0.2.0-beta.152",
55
+ "@dogsbay/format-topicmap": "0.2.0-beta.152",
56
+ "@dogsbay/highlight": "0.2.0-beta.152",
57
+ "@dogsbay/minja": "0.2.0-beta.152",
58
+ "@dogsbay/primitives": "0.2.0-beta.152",
59
+ "@dogsbay/render-html": "0.2.0-beta.152",
60
+ "@dogsbay/search": "0.2.0-beta.152",
61
+ "@dogsbay/serialize-core": "0.2.0-beta.152",
62
+ "@dogsbay/site-check": "0.2.0-beta.152",
63
+ "@dogsbay/site-files": "0.2.0-beta.152",
64
+ "@dogsbay/types": "0.2.0-beta.152"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@axe-core/playwright": "^4.12.1",
68
68
  "@cloudflare/workers-types": "^5.20260921.1",
69
- "@dogsbay/elements": "0.2.0-beta.151",
70
- "@dogsbay/format-dogsbay-md": "0.2.0-beta.151",
71
- "@dogsbay/format-openapi": "0.2.0-beta.151",
72
- "@dogsbay/format-topicmap": "0.2.0-beta.151",
73
- "@dogsbay/highlight": "0.2.0-beta.151",
74
- "@dogsbay/icons": "0.2.0-beta.151",
75
- "@dogsbay/minja": "0.2.0-beta.151",
76
- "@dogsbay/primitives": "0.2.0-beta.151",
77
- "@dogsbay/render-html": "0.2.0-beta.151",
78
- "@dogsbay/search": "0.2.0-beta.151",
79
- "@dogsbay/serialize-core": "0.2.0-beta.151",
80
- "@dogsbay/site-check": "0.2.0-beta.151",
81
- "@dogsbay/site-files": "0.2.0-beta.151",
82
- "@dogsbay/types": "0.2.0-beta.151",
83
- "@dogsbay/ui": "0.2.0-beta.151",
69
+ "@dogsbay/elements": "0.2.0-beta.152",
70
+ "@dogsbay/format-dogsbay-md": "0.2.0-beta.152",
71
+ "@dogsbay/format-openapi": "0.2.0-beta.152",
72
+ "@dogsbay/format-topicmap": "0.2.0-beta.152",
73
+ "@dogsbay/highlight": "0.2.0-beta.152",
74
+ "@dogsbay/icons": "0.2.0-beta.152",
75
+ "@dogsbay/minja": "0.2.0-beta.152",
76
+ "@dogsbay/primitives": "0.2.0-beta.152",
77
+ "@dogsbay/render-html": "0.2.0-beta.152",
78
+ "@dogsbay/search": "0.2.0-beta.152",
79
+ "@dogsbay/serialize-core": "0.2.0-beta.152",
80
+ "@dogsbay/site-check": "0.2.0-beta.152",
81
+ "@dogsbay/site-files": "0.2.0-beta.152",
82
+ "@dogsbay/types": "0.2.0-beta.152",
83
+ "@dogsbay/ui": "0.2.0-beta.152",
84
84
  "@mermanjs/web": "0.7.0",
85
85
  "@playwright/test": "1.61.1",
86
86
  "@types/node": "^22.10.0",