@kerfjs/ui 5.0.0-beta.92 → 5.0.0-beta.93

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/README.md CHANGED
@@ -377,7 +377,11 @@ pretending app-local components are `@kerfjs/ui` exports.
377
377
  For a consumer UX demo, `@kerfjs/ui/catalog-projection` derives rows and
378
378
  relationships from that extension; `kerf-catalog-demo --write` emits a typed
379
379
  module and `--check` catches drift. See the [catalog guide](./docs/catalog.md)
380
- for repository base and source path configuration.
380
+ for repository base and source path configuration. To offer the catalog's
381
+ **Capture region** link to UX Review on a local server, add the Node-only
382
+ `uxReviewPlugin` from `@kerfjs/ui/vite-ux-review` to the Vite config and pass
383
+ `wireCatalog`'s `onUxReviewProject` result to `Catalog`'s `uxReview` (the
384
+ [catalog guide](./docs/catalog.md#ux-review-capture) has the wiring).
381
385
 
382
386
  Composition-aware consumers use
383
387
  [`component-composition-extension.schema.json`](./ai/component-composition-extension.schema.json),
@@ -1,6 +1,6 @@
1
1
  # Public API signatures for the UI authoring corpus
2
2
 
3
- Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.92` and `kerfjs@5.0.0-beta.92`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
3
+ Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.93` and `kerfjs@5.0.0-beta.93`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
4
4
 
5
5
  ## `@kerfjs/ui/css-values`
6
6
 
@@ -2414,8 +2414,8 @@ export { DEFAULT_BREAKPOINTS, type DeviceBreakpoints, type DeviceClass, type Dev
2414
2414
  ```ts
2415
2415
  import * as kerfjs from 'kerfjs';
2416
2416
  import { SafeHtml } from 'kerfjs';
2417
- import { b as CatalogProps } from './types-oLe_N1w0.js';
2418
- export { a as CatalogBackgroundStyle, c as CatalogBrand, d as CatalogEntry, e as CatalogRelated, C as CatalogResource, f as CatalogSecondaryGroup, g as CatalogSection, h as CatalogStageRootAttributes } from './types-oLe_N1w0.js';
2417
+ import { b as CatalogProps } from './types-BNP4gA41.js';
2418
+ export { a as CatalogBackgroundStyle, c as CatalogBrand, d as CatalogEntry, e as CatalogRelated, C as CatalogResource, f as CatalogSecondaryGroup, g as CatalogSection, h as CatalogStageRootAttributes, i as CatalogUxReview } from './types-BNP4gA41.js';
2419
2419
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2420
2420
  import './toolbar.js';
2421
2421
  import './sides-BPSWde0A.js';
@@ -2438,7 +2438,7 @@ import './resizable-region.js';
2438
2438
  * standard toggle moves into the entry toolbar while it is collapsed, and on
2439
2439
  * a small screen the sidebar overlays the stage like any Workbench rail.
2440
2440
  */
2441
- declare function Catalog({ id, brand, sections, active, content, collapsed, theme, increasedContrast, reducedMotion, backgroundControl, headerActions, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
2441
+ declare function Catalog({ id, brand, sections, active, content, collapsed, theme, increasedContrast, reducedMotion, backgroundControl, headerActions, uxReview, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
2442
2442
 
2443
2443
  /** How a specimen aligns its visible edge with its `ListHeader` label. */
2444
2444
  type CatalogExampleAlign = 'glyph' | 'inline-control' | 'text-trigger' | 'none';
@@ -2503,13 +2503,39 @@ interface CatalogExampleStackProps {
2503
2503
  /** A vertically stacked group of catalog examples. */
2504
2504
  declare function CatalogExampleStack({ label, rootAttributes, className, children, slot, }: CatalogExampleStackProps): kerfjs.SafeHtml;
2505
2505
 
2506
- export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleProps, CatalogExampleStack, type CatalogExampleStackProps, type CatalogExampleViewport, CatalogProps };
2506
+ /**
2507
+ * Browser helpers for UX Review region captures from a catalog. The local
2508
+ * project directory comes from `uxReviewPlugin` (`@kerfjs/ui/vite-ux-review`),
2509
+ * which serves it to the catalog page on a Vite dev or preview server; static
2510
+ * hosting has no such endpoint, so a catalog there shows no capture link.
2511
+ */
2512
+ /** Where `uxReviewPlugin` serves `{ projectDirectory }`, relative to the catalog page. */
2513
+ declare const UX_REVIEW_PROJECT_PATH = "__ux-review/project.json";
2514
+ /** What a UX Review region capture is preset with. */
2515
+ interface UxReviewCapture {
2516
+ /** The absolute project directory UX Review files the review under. */
2517
+ projectDirectory: string;
2518
+ /** The review title. */
2519
+ title: string;
2520
+ /** Review context: what was selected and where. */
2521
+ context: string;
2522
+ }
2523
+ /** A `uxreview://capture` link that starts a region screenshot for a project. */
2524
+ declare function uxReviewCaptureUrl({ projectDirectory, title, context, }: UxReviewCapture): string;
2525
+ /**
2526
+ * Ask the server that served `pageUrl` for its UX Review project directory.
2527
+ * Resolves `null` when there is none (static hosting, a server without the
2528
+ * plugin, a malformed answer, or a network failure); never rejects.
2529
+ */
2530
+ declare function loadUxReviewProject(pageUrl: string | URL, fetchImpl?: typeof globalThis.fetch): Promise<string | null>;
2531
+
2532
+ export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleProps, CatalogExampleStack, type CatalogExampleStackProps, type CatalogExampleViewport, CatalogProps, UX_REVIEW_PROJECT_PATH, type UxReviewCapture, loadUxReviewProject, uxReviewCaptureUrl };
2507
2533
  ```
2508
2534
 
2509
2535
  ## `@kerfjs/ui/catalog-resources`
2510
2536
 
2511
2537
  ```ts
2512
- import { C as CatalogResource } from './types-oLe_N1w0.js';
2538
+ import { C as CatalogResource } from './types-BNP4gA41.js';
2513
2539
  import './toolbar.js';
2514
2540
  import 'kerfjs';
2515
2541
  import './semantic-content-BbzjvSu9.js';
@@ -2563,7 +2589,7 @@ export { type CatalogGuidanceKind, type CatalogResourceKind, type CatalogResourc
2563
2589
 
2564
2590
  ```ts
2565
2591
  import { Signal } from 'kerfjs';
2566
- import { a as CatalogBackgroundStyle } from './types-oLe_N1w0.js';
2592
+ import { a as CatalogBackgroundStyle } from './types-BNP4gA41.js';
2567
2593
  import './toolbar.js';
2568
2594
  import './semantic-content-BbzjvSu9.js';
2569
2595
  import './sides-BPSWde0A.js';
@@ -2629,6 +2655,13 @@ interface WireCatalogOptions {
2629
2655
  sidebarStorageKey?: string;
2630
2656
  /** The Catalog's `id`, when it is not the default `kui-catalog`. */
2631
2657
  id?: string;
2658
+ /**
2659
+ * Ask the page's server once for its UX Review project directory (served by
2660
+ * `uxReviewPlugin` from `@kerfjs/ui/vite-ux-review`) and report it, so the
2661
+ * app can render the Catalog with `uxReview`. Never called on static
2662
+ * hosting or a server without the plugin.
2663
+ */
2664
+ onUxReviewProject?: (projectDirectory: string) => void;
2632
2665
  }
2633
2666
  interface CatalogRevealOptions {
2634
2667
  /** Scroll alignment within the sidebar. Default `'nearest'`. */
@@ -2657,7 +2690,7 @@ declare function revealCatalogEntry(root: HTMLElement, id: string, { block, inli
2657
2690
  * catalog's panes and every example in it show their chrome dividers only
2658
2691
  * while scrolled. Returns a disposer.
2659
2692
  */
2660
- declare function wireCatalog(root: HTMLElement, { onSelect, onToggleSidebar, onToggleTheme, onToggleContrast, onToggleMotion, onSelectBackground, onToggleSecondary, urlParam, revealSelection, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, collapsed, sidebarSize, sidebarStorageKey, id: catalogId, }: WireCatalogOptions): () => void;
2693
+ declare function wireCatalog(root: HTMLElement, { onSelect, onToggleSidebar, onToggleTheme, onToggleContrast, onToggleMotion, onSelectBackground, onToggleSecondary, urlParam, revealSelection, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, collapsed, sidebarSize, sidebarStorageKey, id: catalogId, onUxReviewProject, }: WireCatalogOptions): () => void;
2661
2694
 
2662
2695
  export { type CatalogRevealOptions, type WireCatalogOptions, revealCatalogEntry, wireCatalog };
2663
2696
  ```
package/ai/skill.md CHANGED
@@ -139,7 +139,11 @@ against both catalogs; its `source` and `demoSource` are repository-relative
139
139
  files for consumer catalog links. When a consuming project has reusable visual
140
140
  components, derive demo rows with `@kerfjs/ui/catalog-projection` or
141
141
  `kerf-catalog-demo --write`, then guard drift with `--check`; see
142
- `../docs/catalog.md`. Prefer its generated `component-composition.json`. A package
142
+ `../docs/catalog.md`. For a local catalog's UX Review **Capture region** link,
143
+ add `uxReviewPlugin()` from the Node-only `@kerfjs/ui/vite-ux-review` to the
144
+ Vite config, report the project with `wireCatalog`'s `onUxReviewProject`, and
145
+ render `Catalog` with `uxReview={{ projectDirectory }}`; never hand-roll the
146
+ endpoint or the `uxreview://` link. Prefer its generated `component-composition.json`. A package
143
147
  scaffolded by `create-kerf-component` owns the decisions in
144
148
  `kerf.components.json`; run `npm run catalog:check` before using its output. If
145
149
  no generated extension exists, start from the checked examples and require the
@@ -1,6 +1,6 @@
1
1
  # Web Awesome JSX signatures for the UI authoring corpus
2
2
 
3
- Generated from the emitted `@kerfjs/ui@5.0.0-beta.92` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
3
+ Generated from the emitted `@kerfjs/ui@5.0.0-beta.93` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
4
4
 
5
5
  ```ts
6
6
  import { KerfCustomElement } from 'kerfjs/jsx-runtime';
@@ -1,4 +1,4 @@
1
- import { C as CatalogResource } from './types-oLe_N1w0.js';
1
+ import { C as CatalogResource } from './types-BNP4gA41.js';
2
2
  import './toolbar.js';
3
3
  import 'kerfjs';
4
4
  import './semantic-content-BbzjvSu9.js';
package/dist/catalog.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as kerfjs from 'kerfjs';
2
2
  import { SafeHtml } from 'kerfjs';
3
- import { b as CatalogProps } from './types-oLe_N1w0.js';
4
- export { a as CatalogBackgroundStyle, c as CatalogBrand, d as CatalogEntry, e as CatalogRelated, C as CatalogResource, f as CatalogSecondaryGroup, g as CatalogSection, h as CatalogStageRootAttributes } from './types-oLe_N1w0.js';
3
+ import { b as CatalogProps } from './types-BNP4gA41.js';
4
+ export { a as CatalogBackgroundStyle, c as CatalogBrand, d as CatalogEntry, e as CatalogRelated, C as CatalogResource, f as CatalogSecondaryGroup, g as CatalogSection, h as CatalogStageRootAttributes, i as CatalogUxReview } from './types-BNP4gA41.js';
5
5
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
6
6
  import './toolbar.js';
7
7
  import './sides-BPSWde0A.js';
@@ -24,7 +24,7 @@ import './resizable-region.js';
24
24
  * standard toggle moves into the entry toolbar while it is collapsed, and on
25
25
  * a small screen the sidebar overlays the stage like any Workbench rail.
26
26
  */
27
- declare function Catalog({ id, brand, sections, active, content, collapsed, theme, increasedContrast, reducedMotion, backgroundControl, headerActions, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
27
+ declare function Catalog({ id, brand, sections, active, content, collapsed, theme, increasedContrast, reducedMotion, backgroundControl, headerActions, uxReview, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
28
28
 
29
29
  /** How a specimen aligns its visible edge with its `ListHeader` label. */
30
30
  type CatalogExampleAlign = 'glyph' | 'inline-control' | 'text-trigger' | 'none';
@@ -89,4 +89,30 @@ interface CatalogExampleStackProps {
89
89
  /** A vertically stacked group of catalog examples. */
90
90
  declare function CatalogExampleStack({ label, rootAttributes, className, children, slot, }: CatalogExampleStackProps): kerfjs.SafeHtml;
91
91
 
92
- export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleProps, CatalogExampleStack, type CatalogExampleStackProps, type CatalogExampleViewport, CatalogProps };
92
+ /**
93
+ * Browser helpers for UX Review region captures from a catalog. The local
94
+ * project directory comes from `uxReviewPlugin` (`@kerfjs/ui/vite-ux-review`),
95
+ * which serves it to the catalog page on a Vite dev or preview server; static
96
+ * hosting has no such endpoint, so a catalog there shows no capture link.
97
+ */
98
+ /** Where `uxReviewPlugin` serves `{ projectDirectory }`, relative to the catalog page. */
99
+ declare const UX_REVIEW_PROJECT_PATH = "__ux-review/project.json";
100
+ /** What a UX Review region capture is preset with. */
101
+ interface UxReviewCapture {
102
+ /** The absolute project directory UX Review files the review under. */
103
+ projectDirectory: string;
104
+ /** The review title. */
105
+ title: string;
106
+ /** Review context: what was selected and where. */
107
+ context: string;
108
+ }
109
+ /** A `uxreview://capture` link that starts a region screenshot for a project. */
110
+ declare function uxReviewCaptureUrl({ projectDirectory, title, context, }: UxReviewCapture): string;
111
+ /**
112
+ * Ask the server that served `pageUrl` for its UX Review project directory.
113
+ * Resolves `null` when there is none (static hosting, a server without the
114
+ * plugin, a malformed answer, or a network failure); never rejects.
115
+ */
116
+ declare function loadUxReviewProject(pageUrl: string | URL, fetchImpl?: typeof globalThis.fetch): Promise<string | null>;
117
+
118
+ export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleProps, CatalogExampleStack, type CatalogExampleStackProps, type CatalogExampleViewport, CatalogProps, UX_REVIEW_PROJECT_PATH, type UxReviewCapture, loadUxReviewProject, uxReviewCaptureUrl };
package/dist/catalog.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { Workbench } from './chunk-QCLLBMLA.js';
2
+ import { uxReviewCaptureUrl } from './chunk-6C6DLP3W.js';
3
+ export { UX_REVIEW_PROJECT_PATH, loadUxReviewProject, uxReviewCaptureUrl } from './chunk-6C6DLP3W.js';
2
4
 
3
5
 
4
6
  import { TokenSearchField } from './chunk-ROZLJULF.js';
@@ -27,7 +29,7 @@ import { LucideIcon } from './chunk-UKKRPP56.js';
27
29
 
28
30
 
29
31
  import { filterDataAttributes } from './chunk-LAZLBC2Q.js';
30
- import { Contrast, ZapOff, Moon, Sun, X, Waypoints, ExternalLink } from 'lucide';
32
+ import { Contrast, ZapOff, Moon, Sun, X, Waypoints, ExternalLink, Scan } from 'lucide';
31
33
  import { jsx, jsxs, Fragment } from 'kerfjs/jsx-runtime';
32
34
 
33
35
  function relatedMenuItems(related, selectAction) {
@@ -269,9 +271,40 @@ function CatalogStage({
269
271
  }
270
272
  );
271
273
  }
274
+ function CatalogUxReviewLink({
275
+ uxReview: { projectDirectory, name },
276
+ entry,
277
+ category
278
+ }) {
279
+ return /* @__PURE__ */ jsx(
280
+ ToolbarControlGroup,
281
+ {
282
+ appearance: "borderless",
283
+ single: true,
284
+ size: "compact",
285
+ content: "mixed",
286
+ buttonAppearance: "push",
287
+ children: /* @__PURE__ */ jsx(
288
+ ToolbarActionLink,
289
+ {
290
+ href: uxReviewCaptureUrl({
291
+ projectDirectory,
292
+ title: `${name}: ${entry.name}`,
293
+ context: `${name} catalog
294
+ Selected ${category}: ${entry.name} (${entry.id})`
295
+ }),
296
+ label: "Capture region",
297
+ ariaLabel: `Capture ${entry.name} in UX Review`,
298
+ icon: /* @__PURE__ */ jsx(LucideIcon, { icon: Scan, name: "scan" })
299
+ }
300
+ )
301
+ }
302
+ );
303
+ }
272
304
  function findEntry(sections, id) {
273
305
  for (const section of sections) {
274
- for (const entry of section.entries) if (entry.id === id) return entry;
306
+ for (const entry of section.entries)
307
+ if (entry.id === id) return { entry, category: section.category };
275
308
  }
276
309
  return void 0;
277
310
  }
@@ -287,6 +320,7 @@ function Catalog({
287
320
  reducedMotion,
288
321
  backgroundControl = false,
289
322
  headerActions,
323
+ uxReview,
290
324
  secondarySections,
291
325
  sidebarFooter,
292
326
  status,
@@ -307,7 +341,8 @@ function Catalog({
307
341
  className = "",
308
342
  slot
309
343
  }) {
310
- const selected = findEntry(sections, active) ?? (secondarySections ? findEntry(secondarySections.sections, active) : void 0);
344
+ const found = findEntry(sections, active) ?? (secondarySections ? findEntry(secondarySections.sections, active) : void 0);
345
+ const selected = found?.entry;
311
346
  const name = selected?.name ?? "";
312
347
  const nextTheme = theme === "dark" ? "light" : "dark";
313
348
  const catalogName = `${brand.title} catalog`;
@@ -388,6 +423,14 @@ function Catalog({
388
423
  title: /* @__PURE__ */ jsx(ToolbarText, { text: name, size: "xlarge", headingLevel: 2 }),
389
424
  trailing: /* @__PURE__ */ jsxs(Fragment, { children: [
390
425
  headerActions,
426
+ uxReview && found ? /* @__PURE__ */ jsx(
427
+ CatalogUxReviewLink,
428
+ {
429
+ uxReview: { ...uxReview, name: uxReview.name ?? brand.title },
430
+ entry: found.entry,
431
+ category: found.category
432
+ }
433
+ ) : null,
391
434
  displayControls ? /* @__PURE__ */ jsxs(
392
435
  ToolbarControlGroup,
393
436
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/catalog/components/catalog-resource-footer.tsx","../src/catalog/components/catalog-section-entries.tsx","../src/catalog/components/catalog-secondary-sections.tsx","../src/catalog/components/catalog-section-list.tsx","../src/catalog/components/catalog-sidebar.tsx","../src/catalog/components/catalog-stage.tsx","../src/catalog/components/catalog.tsx","../src/catalog/components/catalog-example.tsx","../src/catalog/components/catalog-example-stack.tsx"],"names":["jsxs","jsx","Fragment","protectedAttributes"],"mappings":"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","file":"catalog.js","sourcesContent":["import { ExternalLink, Waypoints } from 'lucide';\n\nimport {\n PopupMenu,\n type PopupMenuEntry,\n} from '../../components/actions/popup-menu/popup-menu.js';\nimport {\n Toolbar,\n type ToolbarConfig,\n} from '../../components/actions/toolbar/toolbar.js';\nimport {\n ToolbarActionLink,\n ToolbarControlGroup,\n} from '../../components/actions/toolbar-control-group/toolbar-control-group.js';\nimport { Row } from '../../components/layout/row/row.js';\nimport { LucideIcon } from '../../components/media/lucide-icon/lucide-icon.js';\nimport type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport type { CatalogRelated, CatalogResource } from '../types.js';\n\ninterface CatalogResourceFooterProps {\n name: string;\n resources: readonly CatalogResource[];\n related: readonly CatalogRelated[];\n status?: KerfUiContent;\n selectAction: string;\n toolbar?: ToolbarConfig;\n}\n\nfunction relatedMenuItems(\n related: readonly CatalogRelated[],\n selectAction: string,\n): PopupMenuEntry[] {\n const groups: string[] = [];\n for (const entry of related)\n if (!groups.includes(entry.group)) groups.push(entry.group);\n\n const items: PopupMenuEntry[] = [];\n groups.forEach((group, index) => {\n if (index > 0) items.push({ kind: 'divider' });\n items.push({ kind: 'heading', label: group });\n for (const entry of related)\n if (entry.group === group)\n items.push({\n label: entry.name,\n action: selectAction,\n attributes: { 'data-item-id': entry.id },\n });\n });\n return items;\n}\n\n/** Status, resources, and related-entry navigation for the active specimen. */\nexport function CatalogResourceFooter({\n name,\n resources,\n related,\n status,\n selectAction,\n toolbar,\n}: CatalogResourceFooterProps) {\n return (\n <>\n {status ? (\n <Row\n hAlign=\"space-between\"\n vAlign=\"baseline\"\n gap=\"xs\"\n wrap\n textInsets=\"trl\"\n >\n {status}\n </Row>\n ) : null}\n <Toolbar\n position=\"footer\"\n label={`${name} resources`}\n dividerSides={toolbar?.dividerSides}\n centerAlign={toolbar?.centerAlign}\n responsive={toolbar?.responsive ?? 'stack'}\n responsiveAt={toolbar?.responsiveAt ?? 'narrow'}\n safeAreaEdges={toolbar?.safeAreaEdges}\n leading={\n resources.length > 0 ? (\n <ToolbarControlGroup\n label={`${name} resources`}\n content=\"mixed\"\n size=\"compact\"\n overflow=\"wrap\"\n >\n {resources.map((resource) => (\n <ToolbarActionLink\n href={resource.href}\n label={resource.label}\n detail={resource.detail}\n ariaLabel={`${name}: ${resource.label} (opens in new tab)`}\n external\n icon={<LucideIcon icon={ExternalLink} name=\"external-link\" />}\n />\n ))}\n </ToolbarControlGroup>\n ) : null\n }\n trailing={\n related.length > 0 ? (\n <ToolbarControlGroup\n single\n content=\"mixed\"\n nestedDropdown\n menuInset=\"compact\"\n size=\"compact\"\n label=\"Related entries\"\n >\n <PopupMenu\n text=\"Components\"\n icon={<LucideIcon icon={Waypoints} name=\"waypoints\" />}\n placement=\"top-end\"\n items={relatedMenuItems(related, selectAction)}\n rootAttributes={{ 'data-catalog-related': '' }}\n />\n </ToolbarControlGroup>\n ) : null\n }\n />\n </>\n );\n}\n","import { List } from '../../components/collections/list/list.js';\nimport { ListHeader } from '../../components/collections/list-header/list-header.js';\nimport { ListItem } from '../../components/collections/list-item/list-item.js';\nimport type { CatalogEntry, CatalogSection } from '../types.js';\n\n/** One labeled section of catalog entries. */\nexport function CatalogSectionEntries({\n section,\n active,\n selectAction,\n}: {\n section: CatalogSection;\n active: string;\n selectAction: string;\n}) {\n return (\n <List rootAttributes={{ 'data-catalog-section': section.category }}>\n <ListHeader label={section.category} />\n <List gap=\"2xs\">\n {section.entries.map((entry: CatalogEntry) => (\n <ListItem\n action={selectAction}\n itemId={entry.id}\n label={entry.name}\n status={entry.tags?.join(' · ')}\n selected={active === entry.id}\n title={entry.description}\n multiline\n rootAttributes={{ 'data-catalog-entry-name': entry.name }}\n />\n ))}\n </List>\n </List>\n );\n}\n","import { List } from '../../components/collections/list/list.js';\nimport { ListHeader } from '../../components/collections/list-header/list-header.js';\nimport type { CatalogSecondaryGroup } from '../types.js';\nimport { CatalogSectionEntries } from './catalog-section-entries.js';\n\ninterface CatalogSecondarySectionsProps {\n group: CatalogSecondaryGroup;\n active: string;\n selectAction: string;\n toggleAction: string;\n}\n\n/** The quieter, optionally collapsible navigation below primary sections. */\nexport function CatalogSecondarySections({\n group,\n active,\n selectAction,\n toggleAction,\n}: CatalogSecondarySectionsProps) {\n const open = !group.collapsible || Boolean(group.expanded);\n return (\n <List\n dividerSides=\"t\"\n controlInsets=\"t\"\n rootAttributes={{ 'data-catalog-secondary-group': group.label }}\n >\n {group.collapsible ? (\n <ListHeader\n label={group.label}\n toggle\n expanded={open}\n action={toggleAction}\n />\n ) : (\n <ListHeader label={group.label} />\n )}\n <List\n gap=\"m\"\n rootAttributes={{\n 'data-catalog-secondary': '',\n 'data-catalog-secondary-collapsed': String(!open),\n }}\n >\n {group.sections.map((section) => (\n <CatalogSectionEntries\n section={section}\n active={active}\n selectAction={selectAction}\n />\n ))}\n </List>\n </List>\n );\n}\n","import type { CatalogSection } from '../types.js';\nimport { CatalogSectionEntries } from './catalog-section-entries.js';\n\n/** The primary category sections in the catalog navigation. */\nexport function CatalogSectionList({\n sections,\n active,\n selectAction,\n}: {\n sections: readonly CatalogSection[];\n active: string;\n selectAction: string;\n}) {\n return (\n <>\n {sections.map((section) => (\n <CatalogSectionEntries\n section={section}\n active={active}\n selectAction={selectAction}\n />\n ))}\n </>\n );\n}\n","import { List } from '../../components/collections/list/list.js';\nimport { ListInsetText } from '../../components/collections/list-inset-text/list-inset-text.js';\nimport { Text } from '../../components/typography/text/text.js';\nimport type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport type {\n CatalogBrand,\n CatalogSecondaryGroup,\n CatalogSection,\n} from '../types.js';\nimport { CatalogSecondarySections } from './catalog-secondary-sections.js';\nimport { CatalogSectionList } from './catalog-section-list.js';\n\ninterface CatalogSidebarProps {\n brand: CatalogBrand;\n sections: readonly CatalogSection[];\n active: string;\n secondarySections?: CatalogSecondaryGroup;\n footer?: KerfUiContent;\n selectAction: string;\n toggleSecondaryAction: string;\n}\n\n/** The catalog navigation: brand subtitle, entry sections, and footer. */\nexport function CatalogSidebar({\n brand,\n sections,\n active,\n secondarySections,\n footer,\n selectAction,\n toggleSecondaryAction,\n}: CatalogSidebarProps) {\n return (\n <nav aria-label={`${brand.title} components`} data-catalog-sidebar>\n <List gap=\"m\" controlInsets=\"b\">\n {brand.subtitle ? (\n <ListInsetText sides=\"rl\">\n <Text variant=\"span\" size=\"compact\" tone=\"quiet\">\n {brand.subtitle}\n </Text>\n </ListInsetText>\n ) : null}\n <CatalogSectionList\n sections={sections}\n active={active}\n selectAction={selectAction}\n />\n {secondarySections ? (\n <CatalogSecondarySections\n group={secondarySections}\n active={active}\n selectAction={selectAction}\n toggleAction={toggleSecondaryAction}\n />\n ) : null}\n <ListInsetText\n sides=\"rl\"\n rootAttributes={{ 'data-catalog-filter-empty': '' }}\n >\n <Text variant=\"span\" tone=\"quiet\">\n No matching items\n </Text>\n </ListInsetText>\n {footer}\n </List>\n </nav>\n );\n}\n","import type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../shared/dom/extension-attributes.js';\nimport type {\n CatalogBackgroundStyle,\n CatalogStageRootAttributes,\n} from '../types.js';\n\nconst protectedAttributes = new Set([\n 'data-catalog-stage',\n 'data-background-style',\n]);\n\ninterface CatalogStageProps {\n name: string;\n content: KerfUiContent;\n backgroundStyle?: CatalogBackgroundStyle;\n rootAttributes?: CatalogStageRootAttributes;\n}\n\n/** The preview canvas for an active Catalog entry. */\nexport function CatalogStage({\n name,\n content,\n backgroundStyle = 'checkerboard',\n rootAttributes = {},\n}: CatalogStageProps) {\n const safeRootAttributes = filterDataAttributes(\n rootAttributes,\n protectedAttributes,\n );\n return (\n <section\n {...safeRootAttributes}\n class=\"kui-catalog__stage\"\n data-catalog-stage\n data-background-style={backgroundStyle}\n aria-label={`${name} preview`}\n >\n <div class=\"kui-catalog__canvas\">{content}</div>\n </section>\n );\n}\n","import { Contrast, Moon, Sun, X, ZapOff } from 'lucide';\n\nimport { PopupMenu } from '../../components/actions/popup-menu/popup-menu.js';\nimport { ToolbarControlGroup } from '../../components/actions/toolbar-control-group/toolbar-control-group.js';\nimport { ToolbarText } from '../../components/actions/toolbar-text/toolbar-text.js';\nimport { ListInsetControl } from '../../components/collections/list-inset-control/list-inset-control.js';\nimport { ListInsetText } from '../../components/collections/list-inset-text/list-inset-text.js';\nimport { TokenSearchField } from '../../components/forms/token-search-field/token-search-field.js';\nimport { Workbench } from '../../components/layout/workbench/workbench.js';\nimport { LucideIcon } from '../../components/media/lucide-icon/lucide-icon.js';\nimport { Text } from '../../components/typography/text/text.js';\nimport type { CatalogEntry, CatalogProps, CatalogSection } from '../types.js';\nimport { CatalogResourceFooter } from './catalog-resource-footer.js';\nimport { CatalogSidebar } from './catalog-sidebar.js';\nimport { CatalogStage } from './catalog-stage.js';\n\nfunction findEntry(\n sections: readonly CatalogSection[],\n id: string,\n): CatalogEntry | undefined {\n for (const section of sections) {\n for (const entry of section.entries) if (entry.id === id) return entry;\n }\n return undefined;\n}\n\n/**\n * Controlled, stateless component-catalog shell: a `Workbench` whose left rail\n * is the catalog navigation and whose work area is the active entry — its\n * toolbar, description, preview stage, and resource footer. The sidebar's\n * standard toggle moves into the entry toolbar while it is collapsed, and on\n * a small screen the sidebar overlays the stage like any Workbench rail.\n */\nexport function Catalog({\n id = 'kui-catalog',\n brand,\n sections,\n active,\n content,\n collapsed = false,\n theme,\n increasedContrast,\n reducedMotion,\n backgroundControl = false,\n headerActions,\n secondarySections,\n sidebarFooter,\n status,\n backgroundStyle,\n stageRootAttributes,\n selectAction = 'catalog-select',\n toggleSidebarAction = 'catalog-toggle-sidebar',\n toggleThemeAction = 'catalog-toggle-theme',\n toggleContrastAction = 'catalog-toggle-contrast',\n toggleMotionAction = 'catalog-toggle-motion',\n selectBackgroundAction = 'catalog-select-background',\n toggleSecondaryAction = 'catalog-toggle-secondary',\n headerPlacement = 'auto',\n footerPlacement = 'auto',\n sidebar = {},\n mainToolbar,\n footerToolbar,\n className = '',\n slot,\n}: CatalogProps) {\n const selected =\n findEntry(sections, active) ??\n (secondarySections\n ? findEntry(secondarySections.sections, active)\n : undefined);\n const name = selected?.name ?? '';\n const nextTheme = theme === 'dark' ? 'light' : 'dark';\n const catalogName = `${brand.title} catalog`;\n const displayControls =\n increasedContrast !== undefined ||\n reducedMotion !== undefined ||\n backgroundControl ||\n theme !== undefined;\n\n return (\n <main\n class={`kui-catalog ${className}`.trim()}\n data-component=\"catalog\"\n data-sidebar-collapsed={String(collapsed)}\n slot={slot}\n >\n <Workbench\n id={id}\n label={catalogName}\n leftRail={{\n label: catalogName,\n size: sidebar.size ?? 288,\n resizable: sidebar.resizable,\n separator: sidebar.separator,\n collapseMotion: sidebar.collapseMotion,\n presentation: sidebar.presentation,\n responsiveOverlayAt: sidebar.responsiveOverlayAt,\n compactOverlay: sidebar.compactOverlay,\n collapsed,\n toolbar: {\n ...sidebar.toolbar,\n label: `${catalogName} header`,\n title: (\n <>\n {brand.logoUrl ? (\n <ToolbarControlGroup\n appearance=\"borderless\"\n content=\"avatar\"\n shape=\"rounded\"\n single\n avatarImage={brand.logoUrl}\n >\n {null}\n </ToolbarControlGroup>\n ) : null}\n <ToolbarText text={brand.title} size=\"large\" headingLevel={1} />\n </>\n ),\n toggle: { action: toggleSidebarAction, name: catalogName },\n },\n header: (\n <ListInsetControl sides=\"rbl\">\n <TokenSearchField\n id={`${id}-filter`}\n label=\"Filter catalog\"\n placeholder=\"Filter items or headings\"\n editorAttributes={{ 'data-catalog-filter': '' }}\n trailingAction={{\n icon: <LucideIcon icon={X} name=\"x\" />,\n label: 'Clear filter',\n action: 'catalog-clear-filter',\n }}\n />\n </ListInsetControl>\n ),\n content: (\n <CatalogSidebar\n brand={brand}\n sections={sections}\n active={active}\n secondarySections={secondarySections}\n footer={sidebarFooter}\n selectAction={selectAction}\n toggleSecondaryAction={toggleSecondaryAction}\n />\n ),\n }}\n mainToolbar={{\n ...mainToolbar,\n label: `${name} header`,\n // The entry title stays whole; actions wrap below it when narrow.\n responsive: mainToolbar?.responsive ?? 'wrap',\n title: <ToolbarText text={name} size=\"xlarge\" headingLevel={2} />,\n trailing: (\n <>\n {headerActions}\n {displayControls ? (\n <ToolbarControlGroup\n appearance=\"borderless\"\n content=\"mixed\"\n size=\"compact\"\n overflow=\"wrap\"\n buttonAppearance=\"push\"\n label=\"Catalog display settings\"\n >\n {increasedContrast !== undefined ? (\n <button\n type=\"button\"\n data-action={toggleContrastAction}\n aria-pressed={String(increasedContrast)}\n >\n <LucideIcon icon={Contrast} name=\"contrast\" />\n <span>Contrast</span>\n </button>\n ) : null}\n {reducedMotion !== undefined ? (\n <button\n type=\"button\"\n data-action={toggleMotionAction}\n aria-pressed={String(reducedMotion)}\n >\n <LucideIcon icon={ZapOff} name=\"zap-off\" />\n <span>Reduce motion</span>\n </button>\n ) : null}\n {backgroundControl ? (\n <PopupMenu\n text=\"Background\"\n rootAttributes={{ 'data-catalog-background-menu': '' }}\n items={[\n { value: 'checkerboard', label: 'Checkerboard' },\n {\n value: 'vertical-stripes',\n label: 'Vertical stripes',\n },\n { value: 'layout-guide', label: 'Layout guide' },\n { value: 'surface', label: 'Surface' },\n { value: 'sunken', label: 'Sunken' },\n ].map(({ value, label }) => ({\n label,\n action: selectBackgroundAction,\n checked: (backgroundStyle ?? 'checkerboard') === value,\n attributes: { 'data-background-choice': value },\n }))}\n />\n ) : null}\n {theme ? (\n <button\n type=\"button\"\n data-action={toggleThemeAction}\n aria-label={`Use ${nextTheme} theme`}\n data-theme-preview={theme}\n >\n {nextTheme === 'dark' ? (\n <LucideIcon icon={Moon} name=\"moon\" />\n ) : (\n <LucideIcon icon={Sun} name=\"sun\" />\n )}\n <span>{nextTheme === 'dark' ? 'Dark' : 'Light'}</span>\n </button>\n ) : null}\n </ToolbarControlGroup>\n ) : null}\n </>\n ),\n }}\n mainPane={{ appearance: 'sunken' }}\n mainFooter={\n <CatalogResourceFooter\n name={name}\n resources={selected?.resources ?? []}\n related={selected?.related ?? []}\n status={status}\n selectAction={selectAction}\n toolbar={footerToolbar}\n />\n }\n mainHeader={\n selected?.description ? (\n <ListInsetText\n sides=\"trbl\"\n rootAttributes={{ 'data-catalog-description': '' }}\n >\n <Text variant=\"span\">{selected.description}</Text>\n </ListInsetText>\n ) : null\n }\n mainHeaderPlacement={headerPlacement}\n mainFooterPlacement={footerPlacement}\n main={\n <CatalogStage\n name={name}\n content={content}\n backgroundStyle={backgroundStyle}\n rootAttributes={stageRootAttributes}\n />\n }\n />\n </main>\n );\n}\n","import type { SafeHtml } from 'kerfjs';\n\nimport { ListHeader } from '../../components/collections/list-header/list-header.js';\nimport { ListInsetText } from '../../components/collections/list-inset-text/list-inset-text.js';\nimport { Text } from '../../components/typography/text/text.js';\nimport type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../shared/dom/extension-attributes.js';\n\n/** How a specimen aligns its visible edge with its `ListHeader` label. */\nexport type CatalogExampleAlign =\n 'glyph' | 'inline-control' | 'text-trigger' | 'none';\n\nexport interface CatalogExampleViewport {\n layout?: 'grid' | 'flex' | 'flex-column';\n width?: 'full' | 'compact' | 'medium' | 'wide' | 'text' | 'control';\n /** Fixed specimen height; `app` frames an application-sized recipe or layout.\n * A fixed height is definite, so a child that fills with `height: 100%`\n * (a horizontal `ResizableRegion`, say) spans the whole frame. */\n height?: 'short' | 'reduced' | 'medium' | 'tall' | 'app';\n /** A minimum the frame may grow past. It is not a definite height: a child\n * sized with `height: 100%` falls back to its content height, so use\n * `height` when the specimen must fill the frame. */\n minHeight?: 'short' | 'medium';\n frame?: 'solid' | 'dashed';\n surface?: 'default' | 'lowered';\n overflow?: 'hidden' | 'auto-x';\n responsive?: 'roomy-only';\n shadow?: boolean;\n /** Public component custom properties applied to the specimen viewport. */\n tokens?: Readonly<Record<`--${string}`, string>>;\n}\n\nconst protectedAttributes = new Set([\n 'data-catalog-example',\n 'data-catalog-example-stack',\n 'data-catalog-example-label',\n 'data-catalog-example-note',\n 'data-align',\n]);\n\ntype CatalogExampleRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-catalog-example'?: never;\n 'data-catalog-example-stack'?: never;\n 'data-catalog-example-label'?: never;\n 'data-catalog-example-note'?: never;\n 'data-align'?: never;\n }\n>;\n\nexport interface CatalogExampleProps {\n label?: string;\n note?: SafeHtml | string;\n align?: CatalogExampleAlign;\n /** Optional catalog-owned constraints for demonstrating layout components. */\n viewport?: CatalogExampleViewport;\n /** Replacement guidance shown when a roomy-only viewport is hidden. */\n compactFallback?: SafeHtml | string;\n rootAttributes?: CatalogExampleRootAttributes;\n className?: string;\n children?: KerfUiContent;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A labeled catalog specimen with optional explanatory text and alignment. */\nexport function CatalogExample({\n label,\n note,\n align = 'none',\n viewport,\n compactFallback,\n rootAttributes = {},\n className = '',\n children,\n slot,\n}: CatalogExampleProps) {\n const safeRootAttributes = filterDataAttributes(\n rootAttributes,\n protectedAttributes,\n );\n const viewportStyle = viewport?.tokens\n ? Object.entries(viewport.tokens)\n .map(([name, value]) => `${name}:${value}`)\n .join(';')\n : undefined;\n const specimen = viewport ? (\n <div\n class=\"kui-catalog-example__viewport\"\n data-catalog-example-viewport\n data-layout={viewport.layout}\n data-width={viewport.width}\n data-height={viewport.height}\n data-min-height={viewport.minHeight}\n data-frame={viewport.frame}\n data-surface={viewport.surface}\n data-overflow={viewport.overflow}\n data-responsive={viewport.responsive}\n data-shadow={viewport.shadow ? 'true' : undefined}\n style={viewportStyle}\n >\n {children}\n </div>\n ) : (\n children\n );\n\n return (\n <section\n {...safeRootAttributes}\n class={`kui-catalog-example ${className}`.trim()}\n data-catalog-example\n data-align={align}\n slot={slot}\n >\n {label !== undefined ? (\n <ListHeader\n label={label}\n width=\"content\"\n rootAttributes={{ 'data-catalog-example-label': '' }}\n />\n ) : null}\n {note !== undefined ? (\n <ListInsetText\n sides=\"rl\"\n className=\"kui-catalog-example__note\"\n rootAttributes={{ 'data-catalog-example-note': '' }}\n >\n <Text variant=\"span\" size=\"compact\" tone=\"quiet\">\n {note}\n </Text>\n </ListInsetText>\n ) : null}\n {compactFallback !== undefined ? (\n <Text tone=\"quiet\" className=\"kui-catalog-example__compact-fallback\">\n {compactFallback}\n </Text>\n ) : null}\n {specimen}\n </section>\n );\n}\n","import type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../shared/dom/extension-attributes.js';\n\nconst protectedAttributes = new Set([\n 'data-catalog-example',\n 'data-catalog-example-stack',\n 'data-catalog-example-label',\n 'data-catalog-example-note',\n 'data-align',\n]);\n\ntype CatalogExampleStackRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-catalog-example'?: never;\n 'data-catalog-example-stack'?: never;\n 'data-catalog-example-label'?: never;\n 'data-catalog-example-note'?: never;\n 'data-align'?: never;\n }\n>;\n\nexport interface CatalogExampleStackProps {\n label?: string;\n rootAttributes?: CatalogExampleStackRootAttributes;\n className?: string;\n children?: KerfUiContent;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A vertically stacked group of catalog examples. */\nexport function CatalogExampleStack({\n label,\n rootAttributes = {},\n className = '',\n children,\n slot,\n}: CatalogExampleStackProps) {\n const safeRootAttributes = filterDataAttributes(\n rootAttributes,\n protectedAttributes,\n );\n\n return (\n <section\n {...safeRootAttributes}\n class={`kui-catalog-example-stack ${className}`.trim()}\n data-catalog-example-stack\n aria-label={label}\n slot={slot}\n >\n {children}\n </section>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/catalog/components/catalog-resource-footer.tsx","../src/catalog/components/catalog-section-entries.tsx","../src/catalog/components/catalog-secondary-sections.tsx","../src/catalog/components/catalog-section-list.tsx","../src/catalog/components/catalog-sidebar.tsx","../src/catalog/components/catalog-stage.tsx","../src/catalog/components/catalog-ux-review-link.tsx","../src/catalog/components/catalog.tsx","../src/catalog/components/catalog-example.tsx","../src/catalog/components/catalog-example-stack.tsx"],"names":["jsxs","jsx","Fragment","protectedAttributes"],"mappings":"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","file":"catalog.js","sourcesContent":["import { ExternalLink, Waypoints } from 'lucide';\n\nimport {\n PopupMenu,\n type PopupMenuEntry,\n} from '../../components/actions/popup-menu/popup-menu.js';\nimport {\n Toolbar,\n type ToolbarConfig,\n} from '../../components/actions/toolbar/toolbar.js';\nimport {\n ToolbarActionLink,\n ToolbarControlGroup,\n} from '../../components/actions/toolbar-control-group/toolbar-control-group.js';\nimport { Row } from '../../components/layout/row/row.js';\nimport { LucideIcon } from '../../components/media/lucide-icon/lucide-icon.js';\nimport type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport type { CatalogRelated, CatalogResource } from '../types.js';\n\ninterface CatalogResourceFooterProps {\n name: string;\n resources: readonly CatalogResource[];\n related: readonly CatalogRelated[];\n status?: KerfUiContent;\n selectAction: string;\n toolbar?: ToolbarConfig;\n}\n\nfunction relatedMenuItems(\n related: readonly CatalogRelated[],\n selectAction: string,\n): PopupMenuEntry[] {\n const groups: string[] = [];\n for (const entry of related)\n if (!groups.includes(entry.group)) groups.push(entry.group);\n\n const items: PopupMenuEntry[] = [];\n groups.forEach((group, index) => {\n if (index > 0) items.push({ kind: 'divider' });\n items.push({ kind: 'heading', label: group });\n for (const entry of related)\n if (entry.group === group)\n items.push({\n label: entry.name,\n action: selectAction,\n attributes: { 'data-item-id': entry.id },\n });\n });\n return items;\n}\n\n/** Status, resources, and related-entry navigation for the active specimen. */\nexport function CatalogResourceFooter({\n name,\n resources,\n related,\n status,\n selectAction,\n toolbar,\n}: CatalogResourceFooterProps) {\n return (\n <>\n {status ? (\n <Row\n hAlign=\"space-between\"\n vAlign=\"baseline\"\n gap=\"xs\"\n wrap\n textInsets=\"trl\"\n >\n {status}\n </Row>\n ) : null}\n <Toolbar\n position=\"footer\"\n label={`${name} resources`}\n dividerSides={toolbar?.dividerSides}\n centerAlign={toolbar?.centerAlign}\n responsive={toolbar?.responsive ?? 'stack'}\n responsiveAt={toolbar?.responsiveAt ?? 'narrow'}\n safeAreaEdges={toolbar?.safeAreaEdges}\n leading={\n resources.length > 0 ? (\n <ToolbarControlGroup\n label={`${name} resources`}\n content=\"mixed\"\n size=\"compact\"\n overflow=\"wrap\"\n >\n {resources.map((resource) => (\n <ToolbarActionLink\n href={resource.href}\n label={resource.label}\n detail={resource.detail}\n ariaLabel={`${name}: ${resource.label} (opens in new tab)`}\n external\n icon={<LucideIcon icon={ExternalLink} name=\"external-link\" />}\n />\n ))}\n </ToolbarControlGroup>\n ) : null\n }\n trailing={\n related.length > 0 ? (\n <ToolbarControlGroup\n single\n content=\"mixed\"\n nestedDropdown\n menuInset=\"compact\"\n size=\"compact\"\n label=\"Related entries\"\n >\n <PopupMenu\n text=\"Components\"\n icon={<LucideIcon icon={Waypoints} name=\"waypoints\" />}\n placement=\"top-end\"\n items={relatedMenuItems(related, selectAction)}\n rootAttributes={{ 'data-catalog-related': '' }}\n />\n </ToolbarControlGroup>\n ) : null\n }\n />\n </>\n );\n}\n","import { List } from '../../components/collections/list/list.js';\nimport { ListHeader } from '../../components/collections/list-header/list-header.js';\nimport { ListItem } from '../../components/collections/list-item/list-item.js';\nimport type { CatalogEntry, CatalogSection } from '../types.js';\n\n/** One labeled section of catalog entries. */\nexport function CatalogSectionEntries({\n section,\n active,\n selectAction,\n}: {\n section: CatalogSection;\n active: string;\n selectAction: string;\n}) {\n return (\n <List rootAttributes={{ 'data-catalog-section': section.category }}>\n <ListHeader label={section.category} />\n <List gap=\"2xs\">\n {section.entries.map((entry: CatalogEntry) => (\n <ListItem\n action={selectAction}\n itemId={entry.id}\n label={entry.name}\n status={entry.tags?.join(' · ')}\n selected={active === entry.id}\n title={entry.description}\n multiline\n rootAttributes={{ 'data-catalog-entry-name': entry.name }}\n />\n ))}\n </List>\n </List>\n );\n}\n","import { List } from '../../components/collections/list/list.js';\nimport { ListHeader } from '../../components/collections/list-header/list-header.js';\nimport type { CatalogSecondaryGroup } from '../types.js';\nimport { CatalogSectionEntries } from './catalog-section-entries.js';\n\ninterface CatalogSecondarySectionsProps {\n group: CatalogSecondaryGroup;\n active: string;\n selectAction: string;\n toggleAction: string;\n}\n\n/** The quieter, optionally collapsible navigation below primary sections. */\nexport function CatalogSecondarySections({\n group,\n active,\n selectAction,\n toggleAction,\n}: CatalogSecondarySectionsProps) {\n const open = !group.collapsible || Boolean(group.expanded);\n return (\n <List\n dividerSides=\"t\"\n controlInsets=\"t\"\n rootAttributes={{ 'data-catalog-secondary-group': group.label }}\n >\n {group.collapsible ? (\n <ListHeader\n label={group.label}\n toggle\n expanded={open}\n action={toggleAction}\n />\n ) : (\n <ListHeader label={group.label} />\n )}\n <List\n gap=\"m\"\n rootAttributes={{\n 'data-catalog-secondary': '',\n 'data-catalog-secondary-collapsed': String(!open),\n }}\n >\n {group.sections.map((section) => (\n <CatalogSectionEntries\n section={section}\n active={active}\n selectAction={selectAction}\n />\n ))}\n </List>\n </List>\n );\n}\n","import type { CatalogSection } from '../types.js';\nimport { CatalogSectionEntries } from './catalog-section-entries.js';\n\n/** The primary category sections in the catalog navigation. */\nexport function CatalogSectionList({\n sections,\n active,\n selectAction,\n}: {\n sections: readonly CatalogSection[];\n active: string;\n selectAction: string;\n}) {\n return (\n <>\n {sections.map((section) => (\n <CatalogSectionEntries\n section={section}\n active={active}\n selectAction={selectAction}\n />\n ))}\n </>\n );\n}\n","import { List } from '../../components/collections/list/list.js';\nimport { ListInsetText } from '../../components/collections/list-inset-text/list-inset-text.js';\nimport { Text } from '../../components/typography/text/text.js';\nimport type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport type {\n CatalogBrand,\n CatalogSecondaryGroup,\n CatalogSection,\n} from '../types.js';\nimport { CatalogSecondarySections } from './catalog-secondary-sections.js';\nimport { CatalogSectionList } from './catalog-section-list.js';\n\ninterface CatalogSidebarProps {\n brand: CatalogBrand;\n sections: readonly CatalogSection[];\n active: string;\n secondarySections?: CatalogSecondaryGroup;\n footer?: KerfUiContent;\n selectAction: string;\n toggleSecondaryAction: string;\n}\n\n/** The catalog navigation: brand subtitle, entry sections, and footer. */\nexport function CatalogSidebar({\n brand,\n sections,\n active,\n secondarySections,\n footer,\n selectAction,\n toggleSecondaryAction,\n}: CatalogSidebarProps) {\n return (\n <nav aria-label={`${brand.title} components`} data-catalog-sidebar>\n <List gap=\"m\" controlInsets=\"b\">\n {brand.subtitle ? (\n <ListInsetText sides=\"rl\">\n <Text variant=\"span\" size=\"compact\" tone=\"quiet\">\n {brand.subtitle}\n </Text>\n </ListInsetText>\n ) : null}\n <CatalogSectionList\n sections={sections}\n active={active}\n selectAction={selectAction}\n />\n {secondarySections ? (\n <CatalogSecondarySections\n group={secondarySections}\n active={active}\n selectAction={selectAction}\n toggleAction={toggleSecondaryAction}\n />\n ) : null}\n <ListInsetText\n sides=\"rl\"\n rootAttributes={{ 'data-catalog-filter-empty': '' }}\n >\n <Text variant=\"span\" tone=\"quiet\">\n No matching items\n </Text>\n </ListInsetText>\n {footer}\n </List>\n </nav>\n );\n}\n","import type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../shared/dom/extension-attributes.js';\nimport type {\n CatalogBackgroundStyle,\n CatalogStageRootAttributes,\n} from '../types.js';\n\nconst protectedAttributes = new Set([\n 'data-catalog-stage',\n 'data-background-style',\n]);\n\ninterface CatalogStageProps {\n name: string;\n content: KerfUiContent;\n backgroundStyle?: CatalogBackgroundStyle;\n rootAttributes?: CatalogStageRootAttributes;\n}\n\n/** The preview canvas for an active Catalog entry. */\nexport function CatalogStage({\n name,\n content,\n backgroundStyle = 'checkerboard',\n rootAttributes = {},\n}: CatalogStageProps) {\n const safeRootAttributes = filterDataAttributes(\n rootAttributes,\n protectedAttributes,\n );\n return (\n <section\n {...safeRootAttributes}\n class=\"kui-catalog__stage\"\n data-catalog-stage\n data-background-style={backgroundStyle}\n aria-label={`${name} preview`}\n >\n <div class=\"kui-catalog__canvas\">{content}</div>\n </section>\n );\n}\n","import { Scan } from 'lucide';\n\nimport {\n ToolbarActionLink,\n ToolbarControlGroup,\n} from '../../components/actions/toolbar-control-group/toolbar-control-group.js';\nimport { LucideIcon } from '../../components/media/lucide-icon/lucide-icon.js';\nimport type { CatalogEntry, CatalogUxReview } from '../types.js';\nimport { uxReviewCaptureUrl } from '../ux-review.js';\n\n/**\n * The \"Capture region\" header link for the active entry. `wireCatalog` adds\n * the page URL to its context when it is followed, since the URL can change\n * after this render (`urlParam`).\n */\nexport function CatalogUxReviewLink({\n uxReview: { projectDirectory, name },\n entry,\n category,\n}: {\n uxReview: CatalogUxReview & { name: string };\n entry: CatalogEntry;\n category: string;\n}) {\n return (\n <ToolbarControlGroup\n appearance=\"borderless\"\n single\n size=\"compact\"\n content=\"mixed\"\n buttonAppearance=\"push\"\n >\n <ToolbarActionLink\n href={uxReviewCaptureUrl({\n projectDirectory,\n title: `${name}: ${entry.name}`,\n context: `${name} catalog\\nSelected ${category}: ${entry.name} (${entry.id})`,\n })}\n label=\"Capture region\"\n ariaLabel={`Capture ${entry.name} in UX Review`}\n icon={<LucideIcon icon={Scan} name=\"scan\" />}\n />\n </ToolbarControlGroup>\n );\n}\n","import { Contrast, Moon, Sun, X, ZapOff } from 'lucide';\n\nimport { PopupMenu } from '../../components/actions/popup-menu/popup-menu.js';\nimport { ToolbarControlGroup } from '../../components/actions/toolbar-control-group/toolbar-control-group.js';\nimport { ToolbarText } from '../../components/actions/toolbar-text/toolbar-text.js';\nimport { ListInsetControl } from '../../components/collections/list-inset-control/list-inset-control.js';\nimport { ListInsetText } from '../../components/collections/list-inset-text/list-inset-text.js';\nimport { TokenSearchField } from '../../components/forms/token-search-field/token-search-field.js';\nimport { Workbench } from '../../components/layout/workbench/workbench.js';\nimport { LucideIcon } from '../../components/media/lucide-icon/lucide-icon.js';\nimport { Text } from '../../components/typography/text/text.js';\nimport type { CatalogEntry, CatalogProps, CatalogSection } from '../types.js';\nimport { CatalogResourceFooter } from './catalog-resource-footer.js';\nimport { CatalogSidebar } from './catalog-sidebar.js';\nimport { CatalogStage } from './catalog-stage.js';\nimport { CatalogUxReviewLink } from './catalog-ux-review-link.js';\n\nfunction findEntry(\n sections: readonly CatalogSection[],\n id: string,\n): { entry: CatalogEntry; category: string } | undefined {\n for (const section of sections) {\n for (const entry of section.entries)\n if (entry.id === id) return { entry, category: section.category };\n }\n return undefined;\n}\n\n/**\n * Controlled, stateless component-catalog shell: a `Workbench` whose left rail\n * is the catalog navigation and whose work area is the active entry — its\n * toolbar, description, preview stage, and resource footer. The sidebar's\n * standard toggle moves into the entry toolbar while it is collapsed, and on\n * a small screen the sidebar overlays the stage like any Workbench rail.\n */\nexport function Catalog({\n id = 'kui-catalog',\n brand,\n sections,\n active,\n content,\n collapsed = false,\n theme,\n increasedContrast,\n reducedMotion,\n backgroundControl = false,\n headerActions,\n uxReview,\n secondarySections,\n sidebarFooter,\n status,\n backgroundStyle,\n stageRootAttributes,\n selectAction = 'catalog-select',\n toggleSidebarAction = 'catalog-toggle-sidebar',\n toggleThemeAction = 'catalog-toggle-theme',\n toggleContrastAction = 'catalog-toggle-contrast',\n toggleMotionAction = 'catalog-toggle-motion',\n selectBackgroundAction = 'catalog-select-background',\n toggleSecondaryAction = 'catalog-toggle-secondary',\n headerPlacement = 'auto',\n footerPlacement = 'auto',\n sidebar = {},\n mainToolbar,\n footerToolbar,\n className = '',\n slot,\n}: CatalogProps) {\n const found =\n findEntry(sections, active) ??\n (secondarySections\n ? findEntry(secondarySections.sections, active)\n : undefined);\n const selected = found?.entry;\n const name = selected?.name ?? '';\n const nextTheme = theme === 'dark' ? 'light' : 'dark';\n const catalogName = `${brand.title} catalog`;\n const displayControls =\n increasedContrast !== undefined ||\n reducedMotion !== undefined ||\n backgroundControl ||\n theme !== undefined;\n\n return (\n <main\n class={`kui-catalog ${className}`.trim()}\n data-component=\"catalog\"\n data-sidebar-collapsed={String(collapsed)}\n slot={slot}\n >\n <Workbench\n id={id}\n label={catalogName}\n leftRail={{\n label: catalogName,\n size: sidebar.size ?? 288,\n resizable: sidebar.resizable,\n separator: sidebar.separator,\n collapseMotion: sidebar.collapseMotion,\n presentation: sidebar.presentation,\n responsiveOverlayAt: sidebar.responsiveOverlayAt,\n compactOverlay: sidebar.compactOverlay,\n collapsed,\n toolbar: {\n ...sidebar.toolbar,\n label: `${catalogName} header`,\n title: (\n <>\n {brand.logoUrl ? (\n <ToolbarControlGroup\n appearance=\"borderless\"\n content=\"avatar\"\n shape=\"rounded\"\n single\n avatarImage={brand.logoUrl}\n >\n {null}\n </ToolbarControlGroup>\n ) : null}\n <ToolbarText text={brand.title} size=\"large\" headingLevel={1} />\n </>\n ),\n toggle: { action: toggleSidebarAction, name: catalogName },\n },\n header: (\n <ListInsetControl sides=\"rbl\">\n <TokenSearchField\n id={`${id}-filter`}\n label=\"Filter catalog\"\n placeholder=\"Filter items or headings\"\n editorAttributes={{ 'data-catalog-filter': '' }}\n trailingAction={{\n icon: <LucideIcon icon={X} name=\"x\" />,\n label: 'Clear filter',\n action: 'catalog-clear-filter',\n }}\n />\n </ListInsetControl>\n ),\n content: (\n <CatalogSidebar\n brand={brand}\n sections={sections}\n active={active}\n secondarySections={secondarySections}\n footer={sidebarFooter}\n selectAction={selectAction}\n toggleSecondaryAction={toggleSecondaryAction}\n />\n ),\n }}\n mainToolbar={{\n ...mainToolbar,\n label: `${name} header`,\n // The entry title stays whole; actions wrap below it when narrow.\n responsive: mainToolbar?.responsive ?? 'wrap',\n title: <ToolbarText text={name} size=\"xlarge\" headingLevel={2} />,\n trailing: (\n <>\n {headerActions}\n {uxReview && found ? (\n <CatalogUxReviewLink\n uxReview={{ ...uxReview, name: uxReview.name ?? brand.title }}\n entry={found.entry}\n category={found.category}\n />\n ) : null}\n {displayControls ? (\n <ToolbarControlGroup\n appearance=\"borderless\"\n content=\"mixed\"\n size=\"compact\"\n overflow=\"wrap\"\n buttonAppearance=\"push\"\n label=\"Catalog display settings\"\n >\n {increasedContrast !== undefined ? (\n <button\n type=\"button\"\n data-action={toggleContrastAction}\n aria-pressed={String(increasedContrast)}\n >\n <LucideIcon icon={Contrast} name=\"contrast\" />\n <span>Contrast</span>\n </button>\n ) : null}\n {reducedMotion !== undefined ? (\n <button\n type=\"button\"\n data-action={toggleMotionAction}\n aria-pressed={String(reducedMotion)}\n >\n <LucideIcon icon={ZapOff} name=\"zap-off\" />\n <span>Reduce motion</span>\n </button>\n ) : null}\n {backgroundControl ? (\n <PopupMenu\n text=\"Background\"\n rootAttributes={{ 'data-catalog-background-menu': '' }}\n items={[\n { value: 'checkerboard', label: 'Checkerboard' },\n {\n value: 'vertical-stripes',\n label: 'Vertical stripes',\n },\n { value: 'layout-guide', label: 'Layout guide' },\n { value: 'surface', label: 'Surface' },\n { value: 'sunken', label: 'Sunken' },\n ].map(({ value, label }) => ({\n label,\n action: selectBackgroundAction,\n checked: (backgroundStyle ?? 'checkerboard') === value,\n attributes: { 'data-background-choice': value },\n }))}\n />\n ) : null}\n {theme ? (\n <button\n type=\"button\"\n data-action={toggleThemeAction}\n aria-label={`Use ${nextTheme} theme`}\n data-theme-preview={theme}\n >\n {nextTheme === 'dark' ? (\n <LucideIcon icon={Moon} name=\"moon\" />\n ) : (\n <LucideIcon icon={Sun} name=\"sun\" />\n )}\n <span>{nextTheme === 'dark' ? 'Dark' : 'Light'}</span>\n </button>\n ) : null}\n </ToolbarControlGroup>\n ) : null}\n </>\n ),\n }}\n mainPane={{ appearance: 'sunken' }}\n mainFooter={\n <CatalogResourceFooter\n name={name}\n resources={selected?.resources ?? []}\n related={selected?.related ?? []}\n status={status}\n selectAction={selectAction}\n toolbar={footerToolbar}\n />\n }\n mainHeader={\n selected?.description ? (\n <ListInsetText\n sides=\"trbl\"\n rootAttributes={{ 'data-catalog-description': '' }}\n >\n <Text variant=\"span\">{selected.description}</Text>\n </ListInsetText>\n ) : null\n }\n mainHeaderPlacement={headerPlacement}\n mainFooterPlacement={footerPlacement}\n main={\n <CatalogStage\n name={name}\n content={content}\n backgroundStyle={backgroundStyle}\n rootAttributes={stageRootAttributes}\n />\n }\n />\n </main>\n );\n}\n","import type { SafeHtml } from 'kerfjs';\n\nimport { ListHeader } from '../../components/collections/list-header/list-header.js';\nimport { ListInsetText } from '../../components/collections/list-inset-text/list-inset-text.js';\nimport { Text } from '../../components/typography/text/text.js';\nimport type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../shared/dom/extension-attributes.js';\n\n/** How a specimen aligns its visible edge with its `ListHeader` label. */\nexport type CatalogExampleAlign =\n 'glyph' | 'inline-control' | 'text-trigger' | 'none';\n\nexport interface CatalogExampleViewport {\n layout?: 'grid' | 'flex' | 'flex-column';\n width?: 'full' | 'compact' | 'medium' | 'wide' | 'text' | 'control';\n /** Fixed specimen height; `app` frames an application-sized recipe or layout.\n * A fixed height is definite, so a child that fills with `height: 100%`\n * (a horizontal `ResizableRegion`, say) spans the whole frame. */\n height?: 'short' | 'reduced' | 'medium' | 'tall' | 'app';\n /** A minimum the frame may grow past. It is not a definite height: a child\n * sized with `height: 100%` falls back to its content height, so use\n * `height` when the specimen must fill the frame. */\n minHeight?: 'short' | 'medium';\n frame?: 'solid' | 'dashed';\n surface?: 'default' | 'lowered';\n overflow?: 'hidden' | 'auto-x';\n responsive?: 'roomy-only';\n shadow?: boolean;\n /** Public component custom properties applied to the specimen viewport. */\n tokens?: Readonly<Record<`--${string}`, string>>;\n}\n\nconst protectedAttributes = new Set([\n 'data-catalog-example',\n 'data-catalog-example-stack',\n 'data-catalog-example-label',\n 'data-catalog-example-note',\n 'data-align',\n]);\n\ntype CatalogExampleRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-catalog-example'?: never;\n 'data-catalog-example-stack'?: never;\n 'data-catalog-example-label'?: never;\n 'data-catalog-example-note'?: never;\n 'data-align'?: never;\n }\n>;\n\nexport interface CatalogExampleProps {\n label?: string;\n note?: SafeHtml | string;\n align?: CatalogExampleAlign;\n /** Optional catalog-owned constraints for demonstrating layout components. */\n viewport?: CatalogExampleViewport;\n /** Replacement guidance shown when a roomy-only viewport is hidden. */\n compactFallback?: SafeHtml | string;\n rootAttributes?: CatalogExampleRootAttributes;\n className?: string;\n children?: KerfUiContent;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A labeled catalog specimen with optional explanatory text and alignment. */\nexport function CatalogExample({\n label,\n note,\n align = 'none',\n viewport,\n compactFallback,\n rootAttributes = {},\n className = '',\n children,\n slot,\n}: CatalogExampleProps) {\n const safeRootAttributes = filterDataAttributes(\n rootAttributes,\n protectedAttributes,\n );\n const viewportStyle = viewport?.tokens\n ? Object.entries(viewport.tokens)\n .map(([name, value]) => `${name}:${value}`)\n .join(';')\n : undefined;\n const specimen = viewport ? (\n <div\n class=\"kui-catalog-example__viewport\"\n data-catalog-example-viewport\n data-layout={viewport.layout}\n data-width={viewport.width}\n data-height={viewport.height}\n data-min-height={viewport.minHeight}\n data-frame={viewport.frame}\n data-surface={viewport.surface}\n data-overflow={viewport.overflow}\n data-responsive={viewport.responsive}\n data-shadow={viewport.shadow ? 'true' : undefined}\n style={viewportStyle}\n >\n {children}\n </div>\n ) : (\n children\n );\n\n return (\n <section\n {...safeRootAttributes}\n class={`kui-catalog-example ${className}`.trim()}\n data-catalog-example\n data-align={align}\n slot={slot}\n >\n {label !== undefined ? (\n <ListHeader\n label={label}\n width=\"content\"\n rootAttributes={{ 'data-catalog-example-label': '' }}\n />\n ) : null}\n {note !== undefined ? (\n <ListInsetText\n sides=\"rl\"\n className=\"kui-catalog-example__note\"\n rootAttributes={{ 'data-catalog-example-note': '' }}\n >\n <Text variant=\"span\" size=\"compact\" tone=\"quiet\">\n {note}\n </Text>\n </ListInsetText>\n ) : null}\n {compactFallback !== undefined ? (\n <Text tone=\"quiet\" className=\"kui-catalog-example__compact-fallback\">\n {compactFallback}\n </Text>\n ) : null}\n {specimen}\n </section>\n );\n}\n","import type { KerfUiContent } from '../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../shared/dom/extension-attributes.js';\n\nconst protectedAttributes = new Set([\n 'data-catalog-example',\n 'data-catalog-example-stack',\n 'data-catalog-example-label',\n 'data-catalog-example-note',\n 'data-align',\n]);\n\ntype CatalogExampleStackRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-catalog-example'?: never;\n 'data-catalog-example-stack'?: never;\n 'data-catalog-example-label'?: never;\n 'data-catalog-example-note'?: never;\n 'data-align'?: never;\n }\n>;\n\nexport interface CatalogExampleStackProps {\n label?: string;\n rootAttributes?: CatalogExampleStackRootAttributes;\n className?: string;\n children?: KerfUiContent;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A vertically stacked group of catalog examples. */\nexport function CatalogExampleStack({\n label,\n rootAttributes = {},\n className = '',\n children,\n slot,\n}: CatalogExampleStackProps) {\n const safeRootAttributes = filterDataAttributes(\n rootAttributes,\n protectedAttributes,\n );\n\n return (\n <section\n {...safeRootAttributes}\n class={`kui-catalog-example-stack ${className}`.trim()}\n data-catalog-example-stack\n aria-label={label}\n slot={slot}\n >\n {children}\n </section>\n );\n}\n"]}
@@ -0,0 +1,31 @@
1
+ // src/catalog/ux-review.ts
2
+ var UX_REVIEW_PROJECT_PATH = "__ux-review/project.json";
3
+ function uxReviewCaptureUrl({
4
+ projectDirectory,
5
+ title,
6
+ context
7
+ }) {
8
+ const url = new URL("uxreview://capture");
9
+ url.searchParams.set("kind", "screenshot");
10
+ url.searchParams.set("target", "region");
11
+ url.searchParams.set("project", projectDirectory);
12
+ url.searchParams.set("title", title);
13
+ url.searchParams.set("context", context);
14
+ return url.href;
15
+ }
16
+ var ABSOLUTE_PATH = /^(?:\/|[A-Za-z]:[\\/])/;
17
+ async function loadUxReviewProject(pageUrl, fetchImpl = globalThis.fetch) {
18
+ try {
19
+ const response = await fetchImpl(new URL(UX_REVIEW_PROJECT_PATH, pageUrl));
20
+ if (!response.ok) return null;
21
+ const data = await response.json();
22
+ const directory = typeof data === "object" && data !== null && "projectDirectory" in data ? data.projectDirectory : void 0;
23
+ return typeof directory === "string" && ABSOLUTE_PATH.test(directory) ? directory : null;
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
28
+
29
+ export { UX_REVIEW_PROJECT_PATH, loadUxReviewProject, uxReviewCaptureUrl };
30
+
31
+ //# sourceMappingURL=chunk-6C6DLP3W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/catalog/ux-review.ts"],"names":[],"mappings":";AAQO,IAAM,sBAAA,GAAyB;AAa/B,SAAS,kBAAA,CAAmB;AAAA,EACjC,gBAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,EAA4B;AAC1B,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,oBAAoB,CAAA;AACxC,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,MAAA,EAAQ,YAAY,CAAA;AACzC,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACvC,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,SAAA,EAAW,gBAAgB,CAAA;AAChD,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AACnC,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,SAAA,EAAW,OAAO,CAAA;AACvC,EAAA,OAAO,GAAA,CAAI,IAAA;AACb;AAGA,IAAM,aAAA,GAAgB,wBAAA;AAOtB,eAAsB,mBAAA,CACpB,OAAA,EACA,SAAA,GAAqC,UAAA,CAAW,KAAA,EACxB;AACxB,EAAA,IAAI;AACF,IAAA,MAAM,WAAW,MAAM,SAAA,CAAU,IAAI,GAAA,CAAI,sBAAA,EAAwB,OAAO,CAAC,CAAA;AACzE,IAAA,IAAI,CAAC,QAAA,CAAS,EAAA,EAAI,OAAO,IAAA;AACzB,IAAA,MAAM,IAAA,GAAgB,MAAM,QAAA,CAAS,IAAA,EAAK;AAC1C,IAAA,MAAM,SAAA,GACJ,OAAO,IAAA,KAAS,QAAA,IAAY,SAAS,IAAA,IAAQ,kBAAA,IAAsB,IAAA,GAC/D,IAAA,CAAK,gBAAA,GACL,KAAA,CAAA;AACN,IAAA,OAAO,OAAO,SAAA,KAAc,QAAA,IAAY,cAAc,IAAA,CAAK,SAAS,IAChE,SAAA,GACA,IAAA;AAAA,EACN,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"chunk-6C6DLP3W.js","sourcesContent":["/**\n * Browser helpers for UX Review region captures from a catalog. The local\n * project directory comes from `uxReviewPlugin` (`@kerfjs/ui/vite-ux-review`),\n * which serves it to the catalog page on a Vite dev or preview server; static\n * hosting has no such endpoint, so a catalog there shows no capture link.\n */\n\n/** Where `uxReviewPlugin` serves `{ projectDirectory }`, relative to the catalog page. */\nexport const UX_REVIEW_PROJECT_PATH = '__ux-review/project.json';\n\n/** What a UX Review region capture is preset with. */\nexport interface UxReviewCapture {\n /** The absolute project directory UX Review files the review under. */\n projectDirectory: string;\n /** The review title. */\n title: string;\n /** Review context: what was selected and where. */\n context: string;\n}\n\n/** A `uxreview://capture` link that starts a region screenshot for a project. */\nexport function uxReviewCaptureUrl({\n projectDirectory,\n title,\n context,\n}: UxReviewCapture): string {\n const url = new URL('uxreview://capture');\n url.searchParams.set('kind', 'screenshot');\n url.searchParams.set('target', 'region');\n url.searchParams.set('project', projectDirectory);\n url.searchParams.set('title', title);\n url.searchParams.set('context', context);\n return url.href;\n}\n\n/** POSIX (`/…`) or Windows drive (`C:\\…`, `C:/…`) absolute path. */\nconst ABSOLUTE_PATH = /^(?:\\/|[A-Za-z]:[\\\\/])/;\n\n/**\n * Ask the server that served `pageUrl` for its UX Review project directory.\n * Resolves `null` when there is none (static hosting, a server without the\n * plugin, a malformed answer, or a network failure); never rejects.\n */\nexport async function loadUxReviewProject(\n pageUrl: string | URL,\n fetchImpl: typeof globalThis.fetch = globalThis.fetch,\n): Promise<string | null> {\n try {\n const response = await fetchImpl(new URL(UX_REVIEW_PROJECT_PATH, pageUrl));\n if (!response.ok) return null;\n const data: unknown = await response.json();\n const directory =\n typeof data === 'object' && data !== null && 'projectDirectory' in data\n ? data.projectDirectory\n : undefined;\n return typeof directory === 'string' && ABSOLUTE_PATH.test(directory)\n ? directory\n : null;\n } catch {\n return null;\n }\n}\n"]}