@kerfjs/ui 5.0.0-beta.87 → 5.0.0-beta.88
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/ai/public-api-signatures-v1.md +30 -6
- package/ai/skill.md +13 -0
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/browser/catalog.js +1 -1
- package/dist/catalog-resources.d.ts +1 -1
- package/dist/catalog.d.ts +3 -3
- package/dist/catalog.js +73 -16
- package/dist/catalog.js.map +1 -1
- package/dist/{types-Bn-dXLcs.d.ts → types-oLe_N1w0.d.ts} +10 -1
- package/dist/wire-catalog.d.ts +25 -1
- package/dist/wire-catalog.js +40 -0
- package/dist/wire-catalog.js.map +1 -1
- package/docs/catalog.md +39 -8
- package/docs/component-selection.md +46 -0
- package/docs/design-philosophy.md +9 -0
- package/llms.txt +17 -1
- package/package.json +1 -1
|
@@ -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.
|
|
3
|
+
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.88` and `kerfjs@5.0.0-beta.88`. 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
|
|
|
@@ -2408,8 +2408,8 @@ export { DEFAULT_BREAKPOINTS, type DeviceBreakpoints, type DeviceClass, type Dev
|
|
|
2408
2408
|
```ts
|
|
2409
2409
|
import * as kerfjs from 'kerfjs';
|
|
2410
2410
|
import { SafeHtml } from 'kerfjs';
|
|
2411
|
-
import {
|
|
2412
|
-
export {
|
|
2411
|
+
import { b as CatalogProps } from './types-oLe_N1w0.js';
|
|
2412
|
+
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';
|
|
2413
2413
|
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
2414
2414
|
import './toolbar.js';
|
|
2415
2415
|
import './sides-BPSWde0A.js';
|
|
@@ -2432,7 +2432,7 @@ import './resizable-region.js';
|
|
|
2432
2432
|
* standard toggle moves into the entry toolbar while it is collapsed, and on
|
|
2433
2433
|
* a small screen the sidebar overlays the stage like any Workbench rail.
|
|
2434
2434
|
*/
|
|
2435
|
-
declare function Catalog({ id, brand, sections, active, content, collapsed, theme, headerActions, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
|
|
2435
|
+
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;
|
|
2436
2436
|
|
|
2437
2437
|
/** How a specimen aligns its visible edge with its `ListHeader` label. */
|
|
2438
2438
|
type CatalogExampleAlign = 'glyph' | 'inline-control' | 'text-trigger' | 'none';
|
|
@@ -2503,7 +2503,7 @@ export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleP
|
|
|
2503
2503
|
## `@kerfjs/ui/catalog-resources`
|
|
2504
2504
|
|
|
2505
2505
|
```ts
|
|
2506
|
-
import { C as CatalogResource } from './types-
|
|
2506
|
+
import { C as CatalogResource } from './types-oLe_N1w0.js';
|
|
2507
2507
|
import './toolbar.js';
|
|
2508
2508
|
import 'kerfjs';
|
|
2509
2509
|
import './semantic-content-BbzjvSu9.js';
|
|
@@ -2557,6 +2557,21 @@ export { type CatalogGuidanceKind, type CatalogResourceKind, type CatalogResourc
|
|
|
2557
2557
|
|
|
2558
2558
|
```ts
|
|
2559
2559
|
import { Signal } from 'kerfjs';
|
|
2560
|
+
import { a as CatalogBackgroundStyle } from './types-oLe_N1w0.js';
|
|
2561
|
+
import './toolbar.js';
|
|
2562
|
+
import './semantic-content-BbzjvSu9.js';
|
|
2563
|
+
import './sides-BPSWde0A.js';
|
|
2564
|
+
import './pane.js';
|
|
2565
|
+
import './workbench.js';
|
|
2566
|
+
import './nav-stack-BvSKY448.js';
|
|
2567
|
+
import './list.js';
|
|
2568
|
+
import './flex-alignment-4ms8ZbV8.js';
|
|
2569
|
+
import './css-values.js';
|
|
2570
|
+
import './panel-toolbar-CL9tYOkh.js';
|
|
2571
|
+
import './lucide-icon.js';
|
|
2572
|
+
import 'lucide';
|
|
2573
|
+
import './toolbar-text.js';
|
|
2574
|
+
import './resizable-region.js';
|
|
2560
2575
|
|
|
2561
2576
|
interface WireCatalogOptions {
|
|
2562
2577
|
/** Invoked with the entry id when a sidebar item or a related-entry option is chosen. */
|
|
@@ -2565,6 +2580,12 @@ interface WireCatalogOptions {
|
|
|
2565
2580
|
onToggleSidebar?: () => void;
|
|
2566
2581
|
/** Invoked when the theme toggle is activated. */
|
|
2567
2582
|
onToggleTheme?: () => void;
|
|
2583
|
+
/** Report a contrast-toggle press; the app updates its signal and applies the preference. */
|
|
2584
|
+
onToggleContrast?: () => void;
|
|
2585
|
+
/** Report a reduced-motion-toggle press; the app updates its signal and applies the preference. */
|
|
2586
|
+
onToggleMotion?: () => void;
|
|
2587
|
+
/** Report a preview background choice; the app updates `backgroundStyle`. */
|
|
2588
|
+
onSelectBackground?: (style: CatalogBackgroundStyle) => void;
|
|
2568
2589
|
/** Invoked when the secondary (ecosystem) group's disclosure toggle is activated. */
|
|
2569
2590
|
onToggleSecondary?: () => void;
|
|
2570
2591
|
/** When set, `?<urlParam>=<id>` is written on select via `history.replaceState`. */
|
|
@@ -2577,6 +2598,9 @@ interface WireCatalogOptions {
|
|
|
2577
2598
|
selectAction?: string;
|
|
2578
2599
|
toggleSidebarAction?: string;
|
|
2579
2600
|
toggleThemeAction?: string;
|
|
2601
|
+
toggleContrastAction?: string;
|
|
2602
|
+
toggleMotionAction?: string;
|
|
2603
|
+
selectBackgroundAction?: string;
|
|
2580
2604
|
toggleSecondaryAction?: string;
|
|
2581
2605
|
/**
|
|
2582
2606
|
* The sidebar's app-owned collapsed flag. With it, the catalog's Workbench
|
|
@@ -2627,7 +2651,7 @@ declare function revealCatalogEntry(root: HTMLElement, id: string, { block, inli
|
|
|
2627
2651
|
* catalog's panes and every example in it show their chrome dividers only
|
|
2628
2652
|
* while scrolled. Returns a disposer.
|
|
2629
2653
|
*/
|
|
2630
|
-
declare function wireCatalog(root: HTMLElement, { onSelect, onToggleSidebar, onToggleTheme, onToggleSecondary, urlParam, revealSelection, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, collapsed, sidebarSize, sidebarStorageKey, id: catalogId, }: WireCatalogOptions): () => void;
|
|
2654
|
+
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;
|
|
2631
2655
|
|
|
2632
2656
|
export { type CatalogRevealOptions, type WireCatalogOptions, revealCatalogEntry, wireCatalog };
|
|
2633
2657
|
```
|
package/ai/skill.md
CHANGED
|
@@ -21,6 +21,19 @@ documented dynamic-data widening. Do not extend those diagnostics to child
|
|
|
21
21
|
markup, live DOM relationships, disposer invocation, or other conditions that
|
|
22
22
|
TypeScript cannot prove from one call.
|
|
23
23
|
|
|
24
|
+
Before writing JSX, run the
|
|
25
|
+
[component-selection decision pass](../docs/component-selection.md#decision-pass-before-jsx-or-css):
|
|
26
|
+
name the user's task and interaction, find the matching Kerf or application
|
|
27
|
+
component, and use its public props. Compose existing primitives for layout; an
|
|
28
|
+
app component is for a repeatable domain contract or new structure, not a copy
|
|
29
|
+
of a Kerf component with local CSS. For each proposed `div`, `span`, fragment,
|
|
30
|
+
class, or rule, identify the semantics, interaction, accessibility, or
|
|
31
|
+
app-owned geometry it supplies; remove it when a selected component already
|
|
32
|
+
supplies that job. Plan one owner for the surface, inset, scrollport, and gaps.
|
|
33
|
+
Use the shared spacing scale by relationship and preserve useful empty space.
|
|
34
|
+
Compare the result with adjacent screens and inspect real wide/narrow browser
|
|
35
|
+
states before treating a passing analyzer or test as a design approval.
|
|
36
|
+
|
|
24
37
|
### Shared semantic tones
|
|
25
38
|
|
|
26
39
|
`SemanticTone` is the shared color-role type for `Badge`, `Chip`, `StateBanner`,
|
|
@@ -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.
|
|
3
|
+
Generated from the emitted `@kerfjs/ui@5.0.0-beta.88` 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';
|
package/dist/browser/catalog.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import '../styles/foundation.css';
|
|
2
|
+
import '../styles/popup-menu.css';
|
|
2
3
|
import '../styles/loading-spinner.css';
|
|
3
4
|
import '../styles/toolbar-control-group.css';
|
|
4
5
|
import '../styles/skeleton.css';
|
|
@@ -15,7 +16,6 @@ import '../styles/floating-toolbar.css';
|
|
|
15
16
|
import '../styles/nav-stack.css';
|
|
16
17
|
import '../styles/workbench.css';
|
|
17
18
|
import '../styles/text.css';
|
|
18
|
-
import '../styles/popup-menu.css';
|
|
19
19
|
import '../styles/row.css';
|
|
20
20
|
import '../styles/badge.css';
|
|
21
21
|
import '../styles/disclosure-arrow.css';
|
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 {
|
|
4
|
-
export {
|
|
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';
|
|
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, headerActions, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, 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, 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';
|
package/dist/catalog.js
CHANGED
|
@@ -27,7 +27,7 @@ import { LucideIcon } from './chunk-NP3FSLNX.js';
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
import { filterDataAttributes } from './chunk-LAZLBC2Q.js';
|
|
30
|
-
import { Moon, Sun, X, Waypoints, ExternalLink } from 'lucide';
|
|
30
|
+
import { Contrast, ZapOff, Moon, Sun, X, Waypoints, ExternalLink } from 'lucide';
|
|
31
31
|
import { jsx, jsxs, Fragment } from 'kerfjs/jsx-runtime';
|
|
32
32
|
|
|
33
33
|
function relatedMenuItems(related, selectAction) {
|
|
@@ -283,6 +283,9 @@ function Catalog({
|
|
|
283
283
|
content,
|
|
284
284
|
collapsed = false,
|
|
285
285
|
theme,
|
|
286
|
+
increasedContrast,
|
|
287
|
+
reducedMotion,
|
|
288
|
+
backgroundControl = false,
|
|
286
289
|
headerActions,
|
|
287
290
|
secondarySections,
|
|
288
291
|
sidebarFooter,
|
|
@@ -292,6 +295,9 @@ function Catalog({
|
|
|
292
295
|
selectAction = "catalog-select",
|
|
293
296
|
toggleSidebarAction = "catalog-toggle-sidebar",
|
|
294
297
|
toggleThemeAction = "catalog-toggle-theme",
|
|
298
|
+
toggleContrastAction = "catalog-toggle-contrast",
|
|
299
|
+
toggleMotionAction = "catalog-toggle-motion",
|
|
300
|
+
selectBackgroundAction = "catalog-select-background",
|
|
295
301
|
toggleSecondaryAction = "catalog-toggle-secondary",
|
|
296
302
|
headerPlacement = "auto",
|
|
297
303
|
footerPlacement = "auto",
|
|
@@ -305,6 +311,7 @@ function Catalog({
|
|
|
305
311
|
const name = selected?.name ?? "";
|
|
306
312
|
const nextTheme = theme === "dark" ? "light" : "dark";
|
|
307
313
|
const catalogName = `${brand.title} catalog`;
|
|
314
|
+
const displayControls = increasedContrast !== void 0 || reducedMotion !== void 0 || backgroundControl || theme !== void 0;
|
|
308
315
|
return /* @__PURE__ */ jsx(
|
|
309
316
|
"main",
|
|
310
317
|
{
|
|
@@ -381,26 +388,76 @@ function Catalog({
|
|
|
381
388
|
title: /* @__PURE__ */ jsx(ToolbarText, { text: name, size: "xlarge", headingLevel: 2 }),
|
|
382
389
|
trailing: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
383
390
|
headerActions,
|
|
384
|
-
|
|
391
|
+
displayControls ? /* @__PURE__ */ jsxs(
|
|
385
392
|
ToolbarControlGroup,
|
|
386
393
|
{
|
|
387
394
|
appearance: "borderless",
|
|
388
395
|
content: "mixed",
|
|
389
396
|
size: "compact",
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
"
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
397
|
+
overflow: "wrap",
|
|
398
|
+
buttonAppearance: "push",
|
|
399
|
+
label: "Catalog display settings",
|
|
400
|
+
children: [
|
|
401
|
+
increasedContrast !== void 0 ? /* @__PURE__ */ jsxs(
|
|
402
|
+
"button",
|
|
403
|
+
{
|
|
404
|
+
type: "button",
|
|
405
|
+
"data-action": toggleContrastAction,
|
|
406
|
+
"aria-pressed": String(increasedContrast),
|
|
407
|
+
children: [
|
|
408
|
+
/* @__PURE__ */ jsx(LucideIcon, { icon: Contrast, name: "contrast" }),
|
|
409
|
+
/* @__PURE__ */ jsx("span", { children: "Contrast" })
|
|
410
|
+
]
|
|
411
|
+
}
|
|
412
|
+
) : null,
|
|
413
|
+
reducedMotion !== void 0 ? /* @__PURE__ */ jsxs(
|
|
414
|
+
"button",
|
|
415
|
+
{
|
|
416
|
+
type: "button",
|
|
417
|
+
"data-action": toggleMotionAction,
|
|
418
|
+
"aria-pressed": String(reducedMotion),
|
|
419
|
+
children: [
|
|
420
|
+
/* @__PURE__ */ jsx(LucideIcon, { icon: ZapOff, name: "zap-off" }),
|
|
421
|
+
/* @__PURE__ */ jsx("span", { children: "Reduce motion" })
|
|
422
|
+
]
|
|
423
|
+
}
|
|
424
|
+
) : null,
|
|
425
|
+
backgroundControl ? /* @__PURE__ */ jsx(
|
|
426
|
+
PopupMenu,
|
|
427
|
+
{
|
|
428
|
+
text: "Background",
|
|
429
|
+
rootAttributes: { "data-catalog-background-menu": "" },
|
|
430
|
+
items: [
|
|
431
|
+
{ value: "checkerboard", label: "Checkerboard" },
|
|
432
|
+
{
|
|
433
|
+
value: "vertical-stripes",
|
|
434
|
+
label: "Vertical stripes"
|
|
435
|
+
},
|
|
436
|
+
{ value: "layout-guide", label: "Layout guide" },
|
|
437
|
+
{ value: "surface", label: "Surface" },
|
|
438
|
+
{ value: "sunken", label: "Sunken" }
|
|
439
|
+
].map(({ value, label }) => ({
|
|
440
|
+
label,
|
|
441
|
+
action: selectBackgroundAction,
|
|
442
|
+
checked: (backgroundStyle ?? "checkerboard") === value,
|
|
443
|
+
attributes: { "data-background-choice": value }
|
|
444
|
+
}))
|
|
445
|
+
}
|
|
446
|
+
) : null,
|
|
447
|
+
theme ? /* @__PURE__ */ jsxs(
|
|
448
|
+
"button",
|
|
449
|
+
{
|
|
450
|
+
type: "button",
|
|
451
|
+
"data-action": toggleThemeAction,
|
|
452
|
+
"aria-label": `Use ${nextTheme} theme`,
|
|
453
|
+
"data-theme-preview": theme,
|
|
454
|
+
children: [
|
|
455
|
+
nextTheme === "dark" ? /* @__PURE__ */ jsx(LucideIcon, { icon: Moon, name: "moon" }) : /* @__PURE__ */ jsx(LucideIcon, { icon: Sun, name: "sun" }),
|
|
456
|
+
/* @__PURE__ */ jsx("span", { children: nextTheme === "dark" ? "Dark" : "Light" })
|
|
457
|
+
]
|
|
458
|
+
}
|
|
459
|
+
) : null
|
|
460
|
+
]
|
|
404
461
|
}
|
|
405
462
|
) : null
|
|
406
463
|
] })
|
package/dist/catalog.js.map
CHANGED
|
@@ -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 { Moon, Sun, X } from 'lucide';\n\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 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 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\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 {theme ? (\n <ToolbarControlGroup\n appearance=\"borderless\"\n content=\"mixed\"\n size=\"compact\"\n label=\"Catalog display\"\n >\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 </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.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"]}
|
|
@@ -74,6 +74,12 @@ interface CatalogProps {
|
|
|
74
74
|
content: KerfUiContent;
|
|
75
75
|
collapsed?: boolean;
|
|
76
76
|
theme?: 'light' | 'dark';
|
|
77
|
+
/** Show the controlled increased-contrast toggle when supplied. The app applies the preference. */
|
|
78
|
+
increasedContrast?: boolean;
|
|
79
|
+
/** Show the controlled reduced-motion toggle when supplied. The app applies the preference. */
|
|
80
|
+
reducedMotion?: boolean;
|
|
81
|
+
/** Show the preview background chooser; `backgroundStyle` remains app-owned. */
|
|
82
|
+
backgroundControl?: boolean;
|
|
77
83
|
headerActions?: KerfUiContent;
|
|
78
84
|
secondarySections?: CatalogSecondaryGroup;
|
|
79
85
|
sidebarFooter?: KerfUiContent;
|
|
@@ -85,6 +91,9 @@ interface CatalogProps {
|
|
|
85
91
|
selectAction?: string;
|
|
86
92
|
toggleSidebarAction?: string;
|
|
87
93
|
toggleThemeAction?: string;
|
|
94
|
+
toggleContrastAction?: string;
|
|
95
|
+
toggleMotionAction?: string;
|
|
96
|
+
selectBackgroundAction?: string;
|
|
88
97
|
toggleSecondaryAction?: string;
|
|
89
98
|
/**
|
|
90
99
|
* Whether the entry toolbar and description stay pinned above the preview
|
|
@@ -118,4 +127,4 @@ interface CatalogProps {
|
|
|
118
127
|
slot?: string;
|
|
119
128
|
}
|
|
120
129
|
|
|
121
|
-
export type { CatalogResource as C,
|
|
130
|
+
export type { CatalogResource as C, CatalogBackgroundStyle as a, CatalogProps as b, CatalogBrand as c, CatalogEntry as d, CatalogRelated as e, CatalogSecondaryGroup as f, CatalogSection as g, CatalogStageRootAttributes as h };
|
package/dist/wire-catalog.d.ts
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import { Signal } from 'kerfjs';
|
|
2
|
+
import { a as CatalogBackgroundStyle } from './types-oLe_N1w0.js';
|
|
3
|
+
import './toolbar.js';
|
|
4
|
+
import './semantic-content-BbzjvSu9.js';
|
|
5
|
+
import './sides-BPSWde0A.js';
|
|
6
|
+
import './pane.js';
|
|
7
|
+
import './workbench.js';
|
|
8
|
+
import './nav-stack-BvSKY448.js';
|
|
9
|
+
import './list.js';
|
|
10
|
+
import './flex-alignment-4ms8ZbV8.js';
|
|
11
|
+
import './css-values.js';
|
|
12
|
+
import './panel-toolbar-CL9tYOkh.js';
|
|
13
|
+
import './lucide-icon.js';
|
|
14
|
+
import 'lucide';
|
|
15
|
+
import './toolbar-text.js';
|
|
16
|
+
import './resizable-region.js';
|
|
2
17
|
|
|
3
18
|
interface WireCatalogOptions {
|
|
4
19
|
/** Invoked with the entry id when a sidebar item or a related-entry option is chosen. */
|
|
@@ -7,6 +22,12 @@ interface WireCatalogOptions {
|
|
|
7
22
|
onToggleSidebar?: () => void;
|
|
8
23
|
/** Invoked when the theme toggle is activated. */
|
|
9
24
|
onToggleTheme?: () => void;
|
|
25
|
+
/** Report a contrast-toggle press; the app updates its signal and applies the preference. */
|
|
26
|
+
onToggleContrast?: () => void;
|
|
27
|
+
/** Report a reduced-motion-toggle press; the app updates its signal and applies the preference. */
|
|
28
|
+
onToggleMotion?: () => void;
|
|
29
|
+
/** Report a preview background choice; the app updates `backgroundStyle`. */
|
|
30
|
+
onSelectBackground?: (style: CatalogBackgroundStyle) => void;
|
|
10
31
|
/** Invoked when the secondary (ecosystem) group's disclosure toggle is activated. */
|
|
11
32
|
onToggleSecondary?: () => void;
|
|
12
33
|
/** When set, `?<urlParam>=<id>` is written on select via `history.replaceState`. */
|
|
@@ -19,6 +40,9 @@ interface WireCatalogOptions {
|
|
|
19
40
|
selectAction?: string;
|
|
20
41
|
toggleSidebarAction?: string;
|
|
21
42
|
toggleThemeAction?: string;
|
|
43
|
+
toggleContrastAction?: string;
|
|
44
|
+
toggleMotionAction?: string;
|
|
45
|
+
selectBackgroundAction?: string;
|
|
22
46
|
toggleSecondaryAction?: string;
|
|
23
47
|
/**
|
|
24
48
|
* The sidebar's app-owned collapsed flag. With it, the catalog's Workbench
|
|
@@ -69,6 +93,6 @@ declare function revealCatalogEntry(root: HTMLElement, id: string, { block, inli
|
|
|
69
93
|
* catalog's panes and every example in it show their chrome dividers only
|
|
70
94
|
* while scrolled. Returns a disposer.
|
|
71
95
|
*/
|
|
72
|
-
declare function wireCatalog(root: HTMLElement, { onSelect, onToggleSidebar, onToggleTheme, onToggleSecondary, urlParam, revealSelection, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, collapsed, sidebarSize, sidebarStorageKey, id: catalogId, }: WireCatalogOptions): () => void;
|
|
96
|
+
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;
|
|
73
97
|
|
|
74
98
|
export { type CatalogRevealOptions, type WireCatalogOptions, revealCatalogEntry, wireCatalog };
|
package/dist/wire-catalog.js
CHANGED
|
@@ -144,12 +144,18 @@ function wireCatalog(root, {
|
|
|
144
144
|
onSelect,
|
|
145
145
|
onToggleSidebar,
|
|
146
146
|
onToggleTheme,
|
|
147
|
+
onToggleContrast,
|
|
148
|
+
onToggleMotion,
|
|
149
|
+
onSelectBackground,
|
|
147
150
|
onToggleSecondary,
|
|
148
151
|
urlParam,
|
|
149
152
|
revealSelection,
|
|
150
153
|
selectAction = "catalog-select",
|
|
151
154
|
toggleSidebarAction = "catalog-toggle-sidebar",
|
|
152
155
|
toggleThemeAction = "catalog-toggle-theme",
|
|
156
|
+
toggleContrastAction = "catalog-toggle-contrast",
|
|
157
|
+
toggleMotionAction = "catalog-toggle-motion",
|
|
158
|
+
selectBackgroundAction = "catalog-select-background",
|
|
153
159
|
toggleSecondaryAction = "catalog-toggle-secondary",
|
|
154
160
|
collapsed,
|
|
155
161
|
sidebarSize,
|
|
@@ -212,6 +218,40 @@ function wireCatalog(root, {
|
|
|
212
218
|
)
|
|
213
219
|
);
|
|
214
220
|
}
|
|
221
|
+
if (onToggleContrast) {
|
|
222
|
+
disposers.push(
|
|
223
|
+
delegate(
|
|
224
|
+
root,
|
|
225
|
+
"click",
|
|
226
|
+
`[data-action="${toggleContrastAction}"]`,
|
|
227
|
+
() => onToggleContrast()
|
|
228
|
+
)
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
if (onToggleMotion) {
|
|
232
|
+
disposers.push(
|
|
233
|
+
delegate(
|
|
234
|
+
root,
|
|
235
|
+
"click",
|
|
236
|
+
`[data-action="${toggleMotionAction}"]`,
|
|
237
|
+
() => onToggleMotion()
|
|
238
|
+
)
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
if (onSelectBackground) {
|
|
242
|
+
disposers.push(
|
|
243
|
+
delegate(
|
|
244
|
+
root,
|
|
245
|
+
"click",
|
|
246
|
+
`[data-action="${selectBackgroundAction}"]`,
|
|
247
|
+
(_event, element) => {
|
|
248
|
+
const style = element.getAttribute("data-background-choice");
|
|
249
|
+
if (style === "checkerboard" || style === "vertical-stripes" || style === "layout-guide" || style === "surface" || style === "sunken")
|
|
250
|
+
onSelectBackground(style);
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
);
|
|
254
|
+
}
|
|
215
255
|
if (onToggleSecondary) {
|
|
216
256
|
disposers.push(
|
|
217
257
|
delegate(
|
package/dist/wire-catalog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/catalog/wiring/wire-catalog.ts"],"names":[],"mappings":"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","file":"wire-catalog.js","sourcesContent":["import { delegate, type Signal } from 'kerfjs';\n\nimport { readTokenSearchField } from '../../components/forms/token-search-field/token-search-field.js';\nimport { wireWorkbench } from '../../components/layout/workbench/wiring/wire-workbench.js';\nimport { wireScrollDividers } from '../../wiring/wire-scroll-dividers.js';\n\nexport interface WireCatalogOptions {\n /** Invoked with the entry id when a sidebar item or a related-entry option is chosen. */\n onSelect: (id: string) => void;\n /** Invoked when the sidebar collapse/expand control is activated. */\n onToggleSidebar?: () => void;\n /** Invoked when the theme toggle is activated. */\n onToggleTheme?: () => void;\n /** Invoked when the secondary (ecosystem) group's disclosure toggle is activated. */\n onToggleSecondary?: () => void;\n /** When set, `?<urlParam>=<id>` is written on select via `history.replaceState`. */\n urlParam?: string;\n /**\n * Reveal the chosen sidebar row after selection. `true` uses desktop-safe\n * defaults; pass options to customize scroll alignment or the media guard.\n */\n revealSelection?: boolean | CatalogRevealOptions;\n selectAction?: string;\n toggleSidebarAction?: string;\n toggleThemeAction?: string;\n toggleSecondaryAction?: string;\n /**\n * The sidebar's app-owned collapsed flag. With it, the catalog's Workbench\n * sidebar is wired like any Workbench rail: it becomes a transient overlay\n * on a small screen (collapsed as the breakpoint applies, closed on Escape\n * or a press outside, focus handed back), and choosing an entry from the\n * open overlay closes it.\n */\n collapsed?: Signal<boolean>;\n /**\n * The app-owned sidebar width signal for a Catalog rendered with\n * `sidebar={{ resizable: true, size: sidebarSize.value }}`. Each committed\n * drag or keyboard resize is written to it.\n */\n sidebarSize?: Signal<number>;\n /**\n * With `sidebarSize`, load and save the width under this storage key so the\n * catalog remembers the user's sidebar width.\n */\n sidebarStorageKey?: string;\n /** The Catalog's `id`, when it is not the default `kui-catalog`. */\n id?: string;\n}\n\nexport interface CatalogRevealOptions {\n /** Scroll alignment within the sidebar. Default `'nearest'`. */\n block?: ScrollLogicalPosition;\n /** Cross-axis alignment. Default `'nearest'`. */\n inline?: ScrollLogicalPosition;\n /** Scroll behavior. Default `'auto'`. */\n behavior?: ScrollBehavior;\n /**\n * Only reveal when this media query matches. Defaults to the Catalog's\n * desktop layout; pass `false` to reveal at every viewport size.\n */\n media?: string | false;\n}\n\n// The Workbench keeps the sidebar inline above its `narrow` breakpoint (704px).\nconst catalogDesktopMedia = '(min-width: 44.01rem)';\n\n/** Keep the sidebar filter local to the shared Catalog, including across controlled rerenders. */\nfunction wireCatalogFilter(root: HTMLElement): () => void {\n const view = root.ownerDocument.defaultView!;\n let filterValue = '';\n let query = '';\n let currentEditor: HTMLElement | null = null;\n const matches = (name: string) => name.toLocaleLowerCase().includes(query);\n const apply = () => {\n const editor = root.querySelector<HTMLElement>('[data-catalog-filter]');\n const nav = root.querySelector<HTMLElement>('[data-catalog-sidebar]');\n if (!editor || !nav) return;\n if (editor !== currentEditor) {\n currentEditor = editor;\n if (readTokenSearchField(editor).query !== filterValue)\n editor.textContent = filterValue;\n }\n const field = editor.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n )!;\n field.dataset.catalogFilterActive = String(Boolean(query));\n const placeholderVisible = String(!filterValue);\n if (field.dataset.placeholderVisible !== placeholderVisible)\n field.dataset.placeholderVisible = placeholderVisible;\n const clear = field.querySelector<HTMLElement>(\n '[data-action=\"catalog-clear-filter\"]',\n )!;\n clear.style.display = query ? '' : 'none';\n nav.dataset.catalogFilterActive = String(Boolean(query));\n let visibleEntries = 0;\n for (const section of nav.querySelectorAll<HTMLElement>(\n '[data-catalog-section]',\n )) {\n const group = section.closest<HTMLElement>(\n '[data-catalog-secondary-group]',\n );\n const headingMatches =\n matches(section.dataset.catalogSection!) ||\n (group !== null && matches(group.dataset.catalogSecondaryGroup!));\n let sectionEntries = 0;\n for (const entry of section.querySelectorAll<HTMLElement>(\n '[data-catalog-entry-name]',\n )) {\n const visible =\n !query || headingMatches || matches(entry.dataset.catalogEntryName!);\n entry.hidden = !visible;\n if (visible) sectionEntries++;\n }\n section.hidden = Boolean(query) && sectionEntries === 0;\n visibleEntries += sectionEntries;\n }\n for (const group of nav.querySelectorAll<HTMLElement>(\n '[data-catalog-secondary-group]',\n )) {\n group.hidden =\n Boolean(query) &&\n !Array.from(\n group.querySelectorAll<HTMLElement>('[data-catalog-section]'),\n ).some((section) => !section.hidden);\n const toggle = group.querySelector<HTMLElement>('[aria-expanded]');\n const content = group.querySelector<HTMLElement>(\n '[data-catalog-secondary-collapsed]',\n );\n if (toggle && content) {\n const expanded = query\n ? !group.hidden\n : content.dataset.catalogSecondaryCollapsed !== 'true';\n toggle.setAttribute('aria-expanded', String(expanded));\n const arrow = toggle.querySelector<HTMLElement>(\n '[data-component=\"disclosure-arrow\"]',\n );\n if (arrow) {\n arrow.dataset.open = String(expanded);\n arrow.dataset.direction = expanded ? 'down' : 'right';\n arrow.style.setProperty(\n '--_kui-disclosure-arrow-rotation',\n expanded ? '90deg' : '0deg',\n );\n }\n }\n }\n const empty = nav.querySelector<HTMLElement>(\n '[data-catalog-filter-empty]',\n )!;\n empty.dataset.visible = String(Boolean(query) && visibleEntries === 0);\n };\n const onInput = (event: Event) => {\n const target = event.target as HTMLElement | null;\n const editor = target?.closest<HTMLElement>('[data-catalog-filter]');\n if (!editor || !root.contains(editor)) return;\n filterValue = readTokenSearchField(editor).query;\n query = filterValue.trim().toLocaleLowerCase();\n apply();\n };\n const onClick = (event: Event) => {\n const target = event.target as Element;\n if (!target.closest('[data-action=\"catalog-clear-filter\"]')) return;\n const editor = root.querySelector<HTMLElement>('[data-catalog-filter]')!;\n filterValue = '';\n query = '';\n editor.textContent = '';\n apply();\n editor.focus();\n };\n root.addEventListener('input', onInput);\n root.addEventListener('click', onClick);\n const observer = new view.MutationObserver(() => {\n if (filterValue) apply();\n });\n observer.observe(root, {\n attributes: true,\n attributeFilter: ['data-placeholder-visible'],\n childList: true,\n subtree: true,\n });\n apply();\n return () => {\n root.removeEventListener('input', onInput);\n root.removeEventListener('click', onClick);\n observer.disconnect();\n };\n}\n\n/**\n * Reveal one Catalog sidebar entry after the controlled render settles without\n * moving focus. Returns a cancellation function for rapid selection changes.\n */\nexport function revealCatalogEntry(\n root: HTMLElement,\n id: string,\n {\n block = 'nearest',\n inline = 'nearest',\n behavior = 'auto',\n media = catalogDesktopMedia,\n }: CatalogRevealOptions = {},\n): () => void {\n const view = root.ownerDocument.defaultView;\n if (!view || (media && !view.matchMedia(media).matches)) return () => {};\n const frame = view.requestAnimationFrame(() => {\n for (const item of root.querySelectorAll<HTMLElement>('[data-item-id]')) {\n if (item.dataset.itemId !== id) continue;\n item.scrollIntoView({ block, inline, behavior });\n break;\n }\n });\n return () => view.cancelAnimationFrame(frame);\n}\n\n/**\n * Wire a {@link Catalog}'s interactions with one delegated listener set: sidebar\n * item selection (and the related-entry popup menu), the sidebar collapse toggle, and\n * the theme toggle. The app owns the `active`/`collapsed`/`theme` signals and updates\n * them in the callbacks; optionally mirror the active id into the URL via `urlParam`.\n * It also wires the scroll dividers below root (`wireScrollDividers`), so the\n * catalog's panes and every example in it show their chrome dividers only\n * while scrolled. Returns a disposer.\n */\nexport function wireCatalog(\n root: HTMLElement,\n {\n onSelect,\n onToggleSidebar,\n onToggleTheme,\n onToggleSecondary,\n urlParam,\n revealSelection,\n selectAction = 'catalog-select',\n toggleSidebarAction = 'catalog-toggle-sidebar',\n toggleThemeAction = 'catalog-toggle-theme',\n toggleSecondaryAction = 'catalog-toggle-secondary',\n collapsed,\n sidebarSize,\n sidebarStorageKey,\n id: catalogId = 'kui-catalog',\n }: WireCatalogOptions,\n): () => void {\n let cancelReveal: (() => void) | undefined;\n const select = (id: string) => {\n onSelect(id);\n const view = root.ownerDocument.defaultView;\n if (urlParam && view) {\n const url = new URL(view.location.href);\n url.searchParams.set(urlParam, id);\n view.history.replaceState(null, '', url);\n }\n // An open overlay sidebar gives way to the entry just chosen from it.\n const rail = root.ownerDocument.getElementById(`${catalogId}-left-rail`);\n if (\n collapsed &&\n !collapsed.peek() &&\n rail &&\n root.ownerDocument.defaultView?.getComputedStyle(rail).position ===\n 'absolute'\n )\n collapsed.value = true;\n if (revealSelection) {\n cancelReveal?.();\n cancelReveal = revealCatalogEntry(\n root,\n id,\n revealSelection === true ? undefined : revealSelection,\n );\n }\n };\n\n const disposers: Array<() => void> = [\n wireScrollDividers(root),\n wireCatalogFilter(root),\n // Sidebar items AND the footer's related-entry popup-menu items both carry\n // `data-action={selectAction}` + `data-item-id`, so one delegated click covers both.\n delegate(\n root,\n 'click',\n `[data-action=\"${selectAction}\"]`,\n (_event, element) => {\n const id = (element as HTMLElement).dataset.itemId;\n if (id) select(id);\n },\n ),\n ];\n if (onToggleSidebar) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleSidebarAction}\"]`, () =>\n onToggleSidebar(),\n ),\n );\n }\n if (onToggleTheme) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleThemeAction}\"]`, () =>\n onToggleTheme(),\n ),\n );\n }\n if (onToggleSecondary) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleSecondaryAction}\"]`, () =>\n onToggleSecondary(),\n ),\n );\n }\n if (collapsed || sidebarSize)\n disposers.push(\n wireWorkbench(root, {\n id: catalogId,\n panels: {\n leftRail: {\n collapsed,\n size: sidebarSize,\n storageKey: sidebarStorageKey,\n },\n },\n }),\n );\n return () => {\n cancelReveal?.();\n for (const dispose of disposers.splice(0)) dispose();\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/catalog/wiring/wire-catalog.ts"],"names":[],"mappings":"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","file":"wire-catalog.js","sourcesContent":["import { delegate, type Signal } from 'kerfjs';\n\nimport { readTokenSearchField } from '../../components/forms/token-search-field/token-search-field.js';\nimport { wireWorkbench } from '../../components/layout/workbench/wiring/wire-workbench.js';\nimport { wireScrollDividers } from '../../wiring/wire-scroll-dividers.js';\nimport type { CatalogBackgroundStyle } from '../types.js';\n\nexport interface WireCatalogOptions {\n /** Invoked with the entry id when a sidebar item or a related-entry option is chosen. */\n onSelect: (id: string) => void;\n /** Invoked when the sidebar collapse/expand control is activated. */\n onToggleSidebar?: () => void;\n /** Invoked when the theme toggle is activated. */\n onToggleTheme?: () => void;\n /** Report a contrast-toggle press; the app updates its signal and applies the preference. */\n onToggleContrast?: () => void;\n /** Report a reduced-motion-toggle press; the app updates its signal and applies the preference. */\n onToggleMotion?: () => void;\n /** Report a preview background choice; the app updates `backgroundStyle`. */\n onSelectBackground?: (style: CatalogBackgroundStyle) => void;\n /** Invoked when the secondary (ecosystem) group's disclosure toggle is activated. */\n onToggleSecondary?: () => void;\n /** When set, `?<urlParam>=<id>` is written on select via `history.replaceState`. */\n urlParam?: string;\n /**\n * Reveal the chosen sidebar row after selection. `true` uses desktop-safe\n * defaults; pass options to customize scroll alignment or the media guard.\n */\n revealSelection?: boolean | CatalogRevealOptions;\n selectAction?: string;\n toggleSidebarAction?: string;\n toggleThemeAction?: string;\n toggleContrastAction?: string;\n toggleMotionAction?: string;\n selectBackgroundAction?: string;\n toggleSecondaryAction?: string;\n /**\n * The sidebar's app-owned collapsed flag. With it, the catalog's Workbench\n * sidebar is wired like any Workbench rail: it becomes a transient overlay\n * on a small screen (collapsed as the breakpoint applies, closed on Escape\n * or a press outside, focus handed back), and choosing an entry from the\n * open overlay closes it.\n */\n collapsed?: Signal<boolean>;\n /**\n * The app-owned sidebar width signal for a Catalog rendered with\n * `sidebar={{ resizable: true, size: sidebarSize.value }}`. Each committed\n * drag or keyboard resize is written to it.\n */\n sidebarSize?: Signal<number>;\n /**\n * With `sidebarSize`, load and save the width under this storage key so the\n * catalog remembers the user's sidebar width.\n */\n sidebarStorageKey?: string;\n /** The Catalog's `id`, when it is not the default `kui-catalog`. */\n id?: string;\n}\n\nexport interface CatalogRevealOptions {\n /** Scroll alignment within the sidebar. Default `'nearest'`. */\n block?: ScrollLogicalPosition;\n /** Cross-axis alignment. Default `'nearest'`. */\n inline?: ScrollLogicalPosition;\n /** Scroll behavior. Default `'auto'`. */\n behavior?: ScrollBehavior;\n /**\n * Only reveal when this media query matches. Defaults to the Catalog's\n * desktop layout; pass `false` to reveal at every viewport size.\n */\n media?: string | false;\n}\n\n// The Workbench keeps the sidebar inline above its `narrow` breakpoint (704px).\nconst catalogDesktopMedia = '(min-width: 44.01rem)';\n\n/** Keep the sidebar filter local to the shared Catalog, including across controlled rerenders. */\nfunction wireCatalogFilter(root: HTMLElement): () => void {\n const view = root.ownerDocument.defaultView!;\n let filterValue = '';\n let query = '';\n let currentEditor: HTMLElement | null = null;\n const matches = (name: string) => name.toLocaleLowerCase().includes(query);\n const apply = () => {\n const editor = root.querySelector<HTMLElement>('[data-catalog-filter]');\n const nav = root.querySelector<HTMLElement>('[data-catalog-sidebar]');\n if (!editor || !nav) return;\n if (editor !== currentEditor) {\n currentEditor = editor;\n if (readTokenSearchField(editor).query !== filterValue)\n editor.textContent = filterValue;\n }\n const field = editor.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n )!;\n field.dataset.catalogFilterActive = String(Boolean(query));\n const placeholderVisible = String(!filterValue);\n if (field.dataset.placeholderVisible !== placeholderVisible)\n field.dataset.placeholderVisible = placeholderVisible;\n const clear = field.querySelector<HTMLElement>(\n '[data-action=\"catalog-clear-filter\"]',\n )!;\n clear.style.display = query ? '' : 'none';\n nav.dataset.catalogFilterActive = String(Boolean(query));\n let visibleEntries = 0;\n for (const section of nav.querySelectorAll<HTMLElement>(\n '[data-catalog-section]',\n )) {\n const group = section.closest<HTMLElement>(\n '[data-catalog-secondary-group]',\n );\n const headingMatches =\n matches(section.dataset.catalogSection!) ||\n (group !== null && matches(group.dataset.catalogSecondaryGroup!));\n let sectionEntries = 0;\n for (const entry of section.querySelectorAll<HTMLElement>(\n '[data-catalog-entry-name]',\n )) {\n const visible =\n !query || headingMatches || matches(entry.dataset.catalogEntryName!);\n entry.hidden = !visible;\n if (visible) sectionEntries++;\n }\n section.hidden = Boolean(query) && sectionEntries === 0;\n visibleEntries += sectionEntries;\n }\n for (const group of nav.querySelectorAll<HTMLElement>(\n '[data-catalog-secondary-group]',\n )) {\n group.hidden =\n Boolean(query) &&\n !Array.from(\n group.querySelectorAll<HTMLElement>('[data-catalog-section]'),\n ).some((section) => !section.hidden);\n const toggle = group.querySelector<HTMLElement>('[aria-expanded]');\n const content = group.querySelector<HTMLElement>(\n '[data-catalog-secondary-collapsed]',\n );\n if (toggle && content) {\n const expanded = query\n ? !group.hidden\n : content.dataset.catalogSecondaryCollapsed !== 'true';\n toggle.setAttribute('aria-expanded', String(expanded));\n const arrow = toggle.querySelector<HTMLElement>(\n '[data-component=\"disclosure-arrow\"]',\n );\n if (arrow) {\n arrow.dataset.open = String(expanded);\n arrow.dataset.direction = expanded ? 'down' : 'right';\n arrow.style.setProperty(\n '--_kui-disclosure-arrow-rotation',\n expanded ? '90deg' : '0deg',\n );\n }\n }\n }\n const empty = nav.querySelector<HTMLElement>(\n '[data-catalog-filter-empty]',\n )!;\n empty.dataset.visible = String(Boolean(query) && visibleEntries === 0);\n };\n const onInput = (event: Event) => {\n const target = event.target as HTMLElement | null;\n const editor = target?.closest<HTMLElement>('[data-catalog-filter]');\n if (!editor || !root.contains(editor)) return;\n filterValue = readTokenSearchField(editor).query;\n query = filterValue.trim().toLocaleLowerCase();\n apply();\n };\n const onClick = (event: Event) => {\n const target = event.target as Element;\n if (!target.closest('[data-action=\"catalog-clear-filter\"]')) return;\n const editor = root.querySelector<HTMLElement>('[data-catalog-filter]')!;\n filterValue = '';\n query = '';\n editor.textContent = '';\n apply();\n editor.focus();\n };\n root.addEventListener('input', onInput);\n root.addEventListener('click', onClick);\n const observer = new view.MutationObserver(() => {\n if (filterValue) apply();\n });\n observer.observe(root, {\n attributes: true,\n attributeFilter: ['data-placeholder-visible'],\n childList: true,\n subtree: true,\n });\n apply();\n return () => {\n root.removeEventListener('input', onInput);\n root.removeEventListener('click', onClick);\n observer.disconnect();\n };\n}\n\n/**\n * Reveal one Catalog sidebar entry after the controlled render settles without\n * moving focus. Returns a cancellation function for rapid selection changes.\n */\nexport function revealCatalogEntry(\n root: HTMLElement,\n id: string,\n {\n block = 'nearest',\n inline = 'nearest',\n behavior = 'auto',\n media = catalogDesktopMedia,\n }: CatalogRevealOptions = {},\n): () => void {\n const view = root.ownerDocument.defaultView;\n if (!view || (media && !view.matchMedia(media).matches)) return () => {};\n const frame = view.requestAnimationFrame(() => {\n for (const item of root.querySelectorAll<HTMLElement>('[data-item-id]')) {\n if (item.dataset.itemId !== id) continue;\n item.scrollIntoView({ block, inline, behavior });\n break;\n }\n });\n return () => view.cancelAnimationFrame(frame);\n}\n\n/**\n * Wire a {@link Catalog}'s interactions with one delegated listener set: sidebar\n * item selection (and the related-entry popup menu), the sidebar collapse toggle, and\n * the theme toggle. The app owns the `active`/`collapsed`/`theme` signals and updates\n * them in the callbacks; optionally mirror the active id into the URL via `urlParam`.\n * It also wires the scroll dividers below root (`wireScrollDividers`), so the\n * catalog's panes and every example in it show their chrome dividers only\n * while scrolled. Returns a disposer.\n */\nexport function wireCatalog(\n root: HTMLElement,\n {\n onSelect,\n onToggleSidebar,\n onToggleTheme,\n onToggleContrast,\n onToggleMotion,\n onSelectBackground,\n onToggleSecondary,\n urlParam,\n revealSelection,\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 collapsed,\n sidebarSize,\n sidebarStorageKey,\n id: catalogId = 'kui-catalog',\n }: WireCatalogOptions,\n): () => void {\n let cancelReveal: (() => void) | undefined;\n const select = (id: string) => {\n onSelect(id);\n const view = root.ownerDocument.defaultView;\n if (urlParam && view) {\n const url = new URL(view.location.href);\n url.searchParams.set(urlParam, id);\n view.history.replaceState(null, '', url);\n }\n // An open overlay sidebar gives way to the entry just chosen from it.\n const rail = root.ownerDocument.getElementById(`${catalogId}-left-rail`);\n if (\n collapsed &&\n !collapsed.peek() &&\n rail &&\n root.ownerDocument.defaultView?.getComputedStyle(rail).position ===\n 'absolute'\n )\n collapsed.value = true;\n if (revealSelection) {\n cancelReveal?.();\n cancelReveal = revealCatalogEntry(\n root,\n id,\n revealSelection === true ? undefined : revealSelection,\n );\n }\n };\n\n const disposers: Array<() => void> = [\n wireScrollDividers(root),\n wireCatalogFilter(root),\n // Sidebar items AND the footer's related-entry popup-menu items both carry\n // `data-action={selectAction}` + `data-item-id`, so one delegated click covers both.\n delegate(\n root,\n 'click',\n `[data-action=\"${selectAction}\"]`,\n (_event, element) => {\n const id = (element as HTMLElement).dataset.itemId;\n if (id) select(id);\n },\n ),\n ];\n if (onToggleSidebar) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleSidebarAction}\"]`, () =>\n onToggleSidebar(),\n ),\n );\n }\n if (onToggleTheme) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleThemeAction}\"]`, () =>\n onToggleTheme(),\n ),\n );\n }\n if (onToggleContrast) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleContrastAction}\"]`, () =>\n onToggleContrast(),\n ),\n );\n }\n if (onToggleMotion) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleMotionAction}\"]`, () =>\n onToggleMotion(),\n ),\n );\n }\n if (onSelectBackground) {\n disposers.push(\n delegate(\n root,\n 'click',\n `[data-action=\"${selectBackgroundAction}\"]`,\n (_event, element) => {\n const style = element.getAttribute('data-background-choice');\n if (\n style === 'checkerboard' ||\n style === 'vertical-stripes' ||\n style === 'layout-guide' ||\n style === 'surface' ||\n style === 'sunken'\n )\n onSelectBackground(style);\n },\n ),\n );\n }\n if (onToggleSecondary) {\n disposers.push(\n delegate(root, 'click', `[data-action=\"${toggleSecondaryAction}\"]`, () =>\n onToggleSecondary(),\n ),\n );\n }\n if (collapsed || sidebarSize)\n disposers.push(\n wireWorkbench(root, {\n id: catalogId,\n panels: {\n leftRail: {\n collapsed,\n size: sidebarSize,\n storageKey: sidebarStorageKey,\n },\n },\n }),\n );\n return () => {\n cancelReveal?.();\n for (const dispose of disposers.splice(0)) dispose();\n };\n}\n"]}
|
package/docs/catalog.md
CHANGED
|
@@ -20,12 +20,12 @@ npm install @kerfjs/ui # kerfjs is a peer; @kerfjs/ui/select/register is needed
|
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
- `Catalog(props)` returns the shell as `SafeHtml` (a `<main class="kui-catalog">`).
|
|
23
|
-
It is **controlled and stateless**: your app owns the `active`, `collapsed`,
|
|
24
|
-
`theme
|
|
23
|
+
It is **controlled and stateless**: your app owns the `active`, `collapsed`,
|
|
24
|
+
`theme`, and optional display-preference signals and computes the preview `content` from `active` in its own
|
|
25
25
|
`mount()` render.
|
|
26
26
|
- `wireCatalog(root, options)` wires the interactions (sidebar selection, the
|
|
27
|
-
related-entry popup menu, the built-in sidebar filter, and the collapse/
|
|
28
|
-
toggles) with one delegated listener set and returns a disposer; it can also
|
|
27
|
+
related-entry popup menu, the built-in sidebar filter, and the collapse/display
|
|
28
|
+
toggles and background chooser) with one delegated listener set and returns a disposer; it can also
|
|
29
29
|
mirror the active id into the URL and reveal the active sidebar row after a
|
|
30
30
|
controlled render.
|
|
31
31
|
|
|
@@ -46,6 +46,16 @@ description?, tags?, resources?, related? }] }`. Each entry becomes a sidebar
|
|
|
46
46
|
opaque backdrop. `sunken` leaves the stage
|
|
47
47
|
transparent so the main Pane's semitransparent sunken surface paints only once.
|
|
48
48
|
A controlled app may pass its current choice on each render.
|
|
49
|
+
- **Display controls** — `increasedContrast` and `reducedMotion` each show a
|
|
50
|
+
pressed-state toggle when their boolean value is supplied. `backgroundControl`
|
|
51
|
+
shows a `PopupMenu` for the five preview backdrops, marking the current
|
|
52
|
+
`backgroundStyle` as checked. These controls share the entry toolbar's compact,
|
|
53
|
+
wrapping display group with the optional theme toggle. Pass callbacks through
|
|
54
|
+
`wireCatalog`'s `onToggleContrast`, `onToggleMotion`, and `onSelectBackground`;
|
|
55
|
+
update your own signals, apply contrast/motion preferences to your app, and
|
|
56
|
+
persist them there if needed. `Catalog` does not change the document theme,
|
|
57
|
+
classes, or storage. Register `@kerfjs/ui/popup-menu/register` when showing the
|
|
58
|
+
background chooser.
|
|
49
59
|
- **`brand`** — `{ title, subtitle?, logoUrl? }` for the sidebar header. The
|
|
50
60
|
optional logo paints through `ToolbarControlGroup.avatarImage`.
|
|
51
61
|
- **`secondarySections`** — an optional secondary "ecosystem" group shown below the
|
|
@@ -290,12 +300,14 @@ import {
|
|
|
290
300
|
Catalog,
|
|
291
301
|
CatalogExample,
|
|
292
302
|
CatalogExampleStack,
|
|
303
|
+
type CatalogBackgroundStyle,
|
|
293
304
|
type CatalogSection,
|
|
294
305
|
} from "@kerfjs/ui/catalog";
|
|
295
306
|
import {
|
|
296
307
|
revealCatalogEntry,
|
|
297
308
|
wireCatalog,
|
|
298
309
|
} from "@kerfjs/ui/wire-catalog";
|
|
310
|
+
import "@kerfjs/ui/popup-menu/register"; // for the background chooser
|
|
299
311
|
// A CSS-aware (browser-condition) bundler loads the Catalog's CSS with its import.
|
|
300
312
|
|
|
301
313
|
type DemoKind = "component" | "composition";
|
|
@@ -356,12 +368,15 @@ const renderers: Record<string, () => SafeHtml> = {
|
|
|
356
368
|
),
|
|
357
369
|
};
|
|
358
370
|
|
|
359
|
-
// 3. App-owned state (domain: which entry; transient: collapsed;
|
|
371
|
+
// 3. App-owned state (domain: which entry; transient: collapsed; display preferences).
|
|
360
372
|
const initial =
|
|
361
373
|
new URLSearchParams(location.search).get("c") ?? sections[0].entries[0].id;
|
|
362
374
|
const active = signal(initial);
|
|
363
375
|
const collapsed = signal(false);
|
|
364
376
|
const theme = signal<"light" | "dark">("light");
|
|
377
|
+
const increasedContrast = signal(false);
|
|
378
|
+
const reducedMotion = signal(false);
|
|
379
|
+
const backgroundStyle = signal<CatalogBackgroundStyle>("checkerboard");
|
|
365
380
|
|
|
366
381
|
const app = document.getElementById("app")!;
|
|
367
382
|
mount(app, () => (
|
|
@@ -372,6 +387,10 @@ mount(app, () => (
|
|
|
372
387
|
content={renderers[active.value]?.() ?? <></>}
|
|
373
388
|
collapsed={collapsed.value}
|
|
374
389
|
theme={theme.value}
|
|
390
|
+
increasedContrast={increasedContrast.value}
|
|
391
|
+
reducedMotion={reducedMotion.value}
|
|
392
|
+
backgroundControl
|
|
393
|
+
backgroundStyle={backgroundStyle.value}
|
|
375
394
|
/>
|
|
376
395
|
));
|
|
377
396
|
|
|
@@ -386,6 +405,17 @@ wireCatalog(app, {
|
|
|
386
405
|
theme.value = theme.value === "dark" ? "light" : "dark";
|
|
387
406
|
document.documentElement.dataset.theme = theme.value; // apply your theme however you like
|
|
388
407
|
},
|
|
408
|
+
onToggleContrast: () => {
|
|
409
|
+
increasedContrast.value = !increasedContrast.value;
|
|
410
|
+
document.documentElement.classList.toggle("increased-contrast", increasedContrast.value);
|
|
411
|
+
},
|
|
412
|
+
onToggleMotion: () => {
|
|
413
|
+
reducedMotion.value = !reducedMotion.value;
|
|
414
|
+
document.documentElement.classList.toggle("reduced-motion", reducedMotion.value);
|
|
415
|
+
},
|
|
416
|
+
onSelectBackground: (style) => {
|
|
417
|
+
backgroundStyle.value = style;
|
|
418
|
+
},
|
|
389
419
|
urlParam: "c", // mirror the active id into ?c=<id>
|
|
390
420
|
revealSelection: true, // reveal long desktop sidebars without moving focus
|
|
391
421
|
});
|
|
@@ -433,9 +463,10 @@ revealCatalogEntry(app, initial, { block: "center" });
|
|
|
433
463
|
## Custom action names
|
|
434
464
|
|
|
435
465
|
The shell emits `data-action="catalog-select"` (sidebar items),
|
|
436
|
-
`catalog-toggle-sidebar`,
|
|
437
|
-
`
|
|
438
|
-
matching options on `wireCatalog`
|
|
466
|
+
`catalog-toggle-sidebar`, `catalog-toggle-theme`, `catalog-toggle-contrast`,
|
|
467
|
+
`catalog-toggle-motion`, and `catalog-select-background`. Override them with
|
|
468
|
+
the matching `*Action` props on `Catalog` and options on `wireCatalog` if they
|
|
469
|
+
collide with your own action table.
|
|
439
470
|
|
|
440
471
|
## CSS
|
|
441
472
|
|
|
@@ -15,6 +15,52 @@ The application adapter is usually a plain function that maps domain state to
|
|
|
15
15
|
component props plus stable `data-action` values. It is not a fork of package
|
|
16
16
|
markup or CSS.
|
|
17
17
|
|
|
18
|
+
## Decision pass before JSX or CSS
|
|
19
|
+
|
|
20
|
+
Make these choices in order for each region, including a region copied from a
|
|
21
|
+
mockup or another application:
|
|
22
|
+
|
|
23
|
+
1. **Name the job.** What does the person read, choose, edit, or navigate? What
|
|
24
|
+
state and keyboard behavior must survive? Search the Kerf catalog, then the
|
|
25
|
+
consuming application's catalog. Choose by that contract, not by a similar
|
|
26
|
+
silhouette. For example, use `ContentItem` for an owned content surface,
|
|
27
|
+
`List` for vertical rhythm, `Grid` for equal responsive tracks,
|
|
28
|
+
`Toolbar`/`ToolbarText` for a heading with actions, and `PopupMenu` for a
|
|
29
|
+
command menu. `TokenSearchField` is for text plus filter chips; an ordinary
|
|
30
|
+
search input does not gain tokens just to use that component.
|
|
31
|
+
2. **Reuse, compose, then extend.** If a component already owns the job,
|
|
32
|
+
configure it. If several primitives form the job, compose them and keep
|
|
33
|
+
product data/actions in a thin adapter. Create an application component when
|
|
34
|
+
it owns a repeatable domain contract or genuinely new structure. If the
|
|
35
|
+
missing contract would benefit other applications, file a Kerf component or
|
|
36
|
+
recipe gap. Do not clone a component's markup to make a local variant.
|
|
37
|
+
3. **Give every element and class a reason.** An element should supply semantic
|
|
38
|
+
meaning, an interaction target, an accessibility relationship, or layout
|
|
39
|
+
that no selected component already owns. Put accepted content directly in
|
|
40
|
+
the component's props/slots; delete wrapper `div`/`span` elements and
|
|
41
|
+
fragments used only for spacing, styling, or satisfying a child type. Add a
|
|
42
|
+
CSS class only for an application-owned selector, not to restyle a Kerf
|
|
43
|
+
root; use stable `data-action` hooks for behavior. Native links, tables,
|
|
44
|
+
and form controls still belong where their native semantics are the right
|
|
45
|
+
contract.
|
|
46
|
+
4. **Assign geometry once.** Decide which component owns the surface, inset,
|
|
47
|
+
scrollport, and each gap before adding styles. Align neighboring text edges
|
|
48
|
+
and control edges; group related items tightly and separate distinct
|
|
49
|
+
sections with a larger step from the shared scale. Leave useful empty space
|
|
50
|
+
around a short form or sparse state instead of filling it with decorative
|
|
51
|
+
cards, labels, or dividers. Use a public edge-to-edge or inset option where
|
|
52
|
+
available; a negative margin or compensating wrapper is a sign to revisit
|
|
53
|
+
ownership. Check narrow and intermediate widths before choosing fixed
|
|
54
|
+
columns or dimensions.
|
|
55
|
+
5. **Compare the finished composition.** Inspect it beside adjacent screens
|
|
56
|
+
and the catalog specimen, then in a real browser at wide and narrow widths.
|
|
57
|
+
Check reading order, content edges, wrapping, clipping, whitespace, scroll
|
|
58
|
+
ownership, focus, and active/empty/loading states. Revise the component
|
|
59
|
+
choice or composition when the result needs repeated CSS corrections.
|
|
60
|
+
|
|
61
|
+
The package's defaults are the starting design, not an empty canvas. A custom
|
|
62
|
+
component or rule should explain which missing behavior or structure it owns.
|
|
63
|
+
|
|
18
64
|
**Don't fight the components.** The package is built to look right without an
|
|
19
65
|
application customization layer. Before adding `padding`, `margin`, `width`,
|
|
20
66
|
`height`, `border`, `background`, a wrapper card, or a decoration, check whether
|
|
@@ -130,6 +130,15 @@ separation, very minor air, standard within a group, between homogeneous groups,
|
|
|
130
130
|
and major between heterogeneous groups. Off-scale values (12px, 32px) are
|
|
131
131
|
deliberate exceptions. See [`layout.md`](layout.md) "Spacing scale".
|
|
132
132
|
|
|
133
|
+
Empty space also has a job. Keep related controls and content close, leave more
|
|
134
|
+
room between distinct decisions, and let a short form or sparse state occupy
|
|
135
|
+
only the width it needs. Align neighboring content edges before adjusting gaps.
|
|
136
|
+
Do not fill an open area with a card, divider, label, or evenly stretched row
|
|
137
|
+
merely to use the space. Give the pane, surface, and child layout one owner each;
|
|
138
|
+
avoid a negative margin or spacer that only cancels an inset another component
|
|
139
|
+
already provides. Recheck that rhythm with side rails open and at narrow and
|
|
140
|
+
intermediate widths.
|
|
141
|
+
|
|
133
142
|
### Responsive design reprioritizes
|
|
134
143
|
|
|
135
144
|
Protect primary content, readable type, recognizable icons, and usable targets. Relocate secondary information before compressing it below a usable scale. Keep one clear scroll owner per region and test narrow, wide, zoomed, and intermediate layouts.
|
package/llms.txt
CHANGED
|
@@ -59,6 +59,19 @@ not a reason to override — and your own components follow the same rule.
|
|
|
59
59
|
|
|
60
60
|
## How to build a screen (retrieval order)
|
|
61
61
|
|
|
62
|
+
First make the design decision: state what the user must read or do, find the
|
|
63
|
+
Kerf or consuming-app component whose purpose and interaction match, and
|
|
64
|
+
configure it. Compose `Toolbar`, `List`, `Row`, `Grid`, `ContentItem`, and the
|
|
65
|
+
other primitives before creating markup or CSS. A local component should own a
|
|
66
|
+
real domain behavior or new structure; a wrapper made only to re-space or
|
|
67
|
+
re-skin an existing component is the wrong choice. Ask what each `div`, `span`,
|
|
68
|
+
fragment, class, and CSS rule contributes. Remove it if a component already
|
|
69
|
+
owns the semantics, surface, inset, scrollport, or gap. Use the spacing scale
|
|
70
|
+
to show relationships, keep useful negative space, and align neighboring text
|
|
71
|
+
and control edges. Check the result against adjacent screens at wide and narrow
|
|
72
|
+
widths. The concrete [decision pass](./docs/component-selection.md#decision-pass-before-jsx-or-css)
|
|
73
|
+
explains when to reuse, compose, extend, or use native HTML.
|
|
74
|
+
|
|
62
75
|
1. **Pick the component from the interface need**, not by appearance — read
|
|
63
76
|
[component-selection.md](./docs/component-selection.md) (the problem→component
|
|
64
77
|
matrix, with imports, wiring, ownership, and alternatives).
|
|
@@ -548,7 +561,10 @@ shell, `@kerfjs/ui/collapsible-panel` (`CollapsiblePanel`, `CollapsiblePanelTogg
|
|
|
548
561
|
`Catalog` component + `wireCatalog` helper for building a component-gallery catalog
|
|
549
562
|
(collapsible category sidebar + preview stage + resources footer, with
|
|
550
563
|
focus-preserving active-row reveal for long desktop sidebars) from your own
|
|
551
|
-
entries; controlled/stateless like the layouts.
|
|
564
|
+
entries; controlled/stateless like the layouts. Its optional contrast, reduced
|
|
565
|
+
motion, theme, and preview-background controls are built in; pass state and
|
|
566
|
+
`wireCatalog` callbacks instead of recreating their toolbar markup, while your
|
|
567
|
+
app owns applying and persisting preferences. For any Catalog demo, follow
|
|
552
568
|
the [authoritative authoring contract](./docs/catalog.md#catalog-demo-authoring-contract)
|
|
553
569
|
rather than inferring structure from the shell or private CSS.
|
|
554
570
|
`@kerfjs/ui/webawesome` is a
|