@kerfjs/ui 5.0.0-beta.86 → 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 +30 -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/styles/app-tab.css +8 -0
- package/dist/styles/components/navigation/app-tab/app-tab.css +8 -0
- package/dist/styles/components/navigation/tab-bar/tab-bar.css +4 -1
- package/dist/styles/tab-bar.css +4 -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 +50 -3
- package/dist/wire-catalog.js.map +1 -1
- package/docs/catalog.md +42 -10
- package/docs/component-contract.md +4 -1
- package/docs/component-selection.md +46 -0
- package/docs/design-philosophy.md +9 -0
- package/docs/webawesome-theme.md +13 -0
- package/llms.txt +33 -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`,
|
|
@@ -31,6 +44,21 @@ Use `info` for the role backed by the existing `--kui-color-brand-*` tokens.
|
|
|
31
44
|
Migrate Badge/Chip `tone="brand"` to `tone="info"`; `BadgeTone` and
|
|
32
45
|
`StateBannerTone` remain deprecated aliases of `SemanticTone`.
|
|
33
46
|
|
|
47
|
+
### Lowered surfaces are translucent
|
|
48
|
+
|
|
49
|
+
The sunken/lowered background is a semi-transparent color, not a solid canvas.
|
|
50
|
+
`--wa-color-surface-lowered` and its Kerf mirror
|
|
51
|
+
`--kui-color-surface-lowered` provide the shared tint;
|
|
52
|
+
`--kui-color-neutral-fill-quiet` uses that tint too. `SunkenPanel`, sunken
|
|
53
|
+
`Pane`/`Workbench`/`TabNavigator` surfaces, and Web Awesome
|
|
54
|
+
`appearance="sunken"` consume it through `--kui-sunken-panel-background` or
|
|
55
|
+
`--kui-wa-sunken-background` (their optional override tokens). Each painted
|
|
56
|
+
layer composites with everything beneath it. Use a separate lowered component
|
|
57
|
+
when its nested depth is intentional; do not paint the same visual surface
|
|
58
|
+
twice through a wrapper, a second background, or an unnecessary override.
|
|
59
|
+
Check the resulting contrast in both color schemes, especially over a custom
|
|
60
|
+
backdrop. See `../docs/webawesome-theme.md#contextual-transparency`.
|
|
61
|
+
|
|
34
62
|
## Components own their styles; configure, never override
|
|
35
63
|
|
|
36
64
|
This is the rule every Kerf UI surface follows, and applications and
|
|
@@ -271,6 +299,8 @@ clips focus painting; never restyle Select shadow parts from application CSS.
|
|
|
271
299
|
|
|
272
300
|
For application tabs, `AppTab presentation="icon-only"` retains its accessible `name`, `labelMaxWidth` truncates the visible name, and `attention` colors it through `--kui-app-tab-attention-color`. Configure TabBar strip geometry through public `--kui-tab-bar-strip-*` tokens.
|
|
273
301
|
|
|
302
|
+
`TabBar presentation="inspector"` uses the shared rounded rectangle radius for its strip and inset segmented tabs. Ordinary `presentation="segmented"` keeps pill strip ends and smaller corners between tabs; do not restyle AppTab to make one presentation match the other.
|
|
303
|
+
|
|
274
304
|
Set `AppTab dropTarget` while content is dragged over a tab to highlight the target without changing selection. Use `nameOverflow="visible"` for an inline loading treatment that needs the full visible name; the default is an ellipsis.
|
|
275
305
|
|
|
276
306
|
Set `pinned` on the first `AppTab` when it must stay visible while peers scroll. Keep it inside `TabBar` children so it remains in the tablist and roving focus order. Use `--kui-app-tab-pinned-background` for a non-default surrounding surface; the pinned backdrop must cover tabs beneath it.
|
|
@@ -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"]}
|
package/dist/styles/app-tab.css
CHANGED
|
@@ -94,6 +94,14 @@
|
|
|
94
94
|
border-radius: var(--kui-radius-s);
|
|
95
95
|
box-shadow: none;
|
|
96
96
|
}
|
|
97
|
+
.kui-tab-bar[data-presentation="inspector"]
|
|
98
|
+
.kui-app-tab[data-presentation="segmented"] {
|
|
99
|
+
border-radius: calc(
|
|
100
|
+
var(--kui-tab-bar-strip-radius, var(--kui-layout-rounded-radius)) -
|
|
101
|
+
var(--kui-tab-bar-strip-padding, 1px) -
|
|
102
|
+
var(--kui-tab-bar-strip-border-width, 1px)
|
|
103
|
+
);
|
|
104
|
+
}
|
|
97
105
|
.kui-app-tab:hover {
|
|
98
106
|
border-color: var(--kui-color-neutral-border-normal);
|
|
99
107
|
background: var(--kui-app-tab-hover-background);
|
|
@@ -94,6 +94,14 @@
|
|
|
94
94
|
border-radius: var(--kui-radius-s);
|
|
95
95
|
box-shadow: none;
|
|
96
96
|
}
|
|
97
|
+
.kui-tab-bar[data-presentation="inspector"]
|
|
98
|
+
.kui-app-tab[data-presentation="segmented"] {
|
|
99
|
+
border-radius: calc(
|
|
100
|
+
var(--kui-tab-bar-strip-radius, var(--kui-layout-rounded-radius)) -
|
|
101
|
+
var(--kui-tab-bar-strip-padding, 1px) -
|
|
102
|
+
var(--kui-tab-bar-strip-border-width, 1px)
|
|
103
|
+
);
|
|
104
|
+
}
|
|
97
105
|
.kui-app-tab:hover {
|
|
98
106
|
border-color: var(--kui-color-neutral-border-normal);
|
|
99
107
|
background: var(--kui-app-tab-hover-background);
|
|
@@ -78,7 +78,10 @@
|
|
|
78
78
|
}
|
|
79
79
|
.kui-tab-bar[data-presentation="inspector"] .kui-tab-bar__tabs {
|
|
80
80
|
min-height: var(--kui-tab-bar-strip-min-height, 2.125rem);
|
|
81
|
-
border-radius: var(
|
|
81
|
+
border-radius: var(
|
|
82
|
+
--kui-tab-bar-strip-radius,
|
|
83
|
+
var(--kui-layout-rounded-radius)
|
|
84
|
+
);
|
|
82
85
|
}
|
|
83
86
|
.kui-tab-bar[data-trailing-placement="adjacent"] .kui-tab-bar__tabs {
|
|
84
87
|
flex: 0 1 auto;
|
package/dist/styles/tab-bar.css
CHANGED
|
@@ -78,7 +78,10 @@
|
|
|
78
78
|
}
|
|
79
79
|
.kui-tab-bar[data-presentation="inspector"] .kui-tab-bar__tabs {
|
|
80
80
|
min-height: var(--kui-tab-bar-strip-min-height, 2.125rem);
|
|
81
|
-
border-radius: var(
|
|
81
|
+
border-radius: var(
|
|
82
|
+
--kui-tab-bar-strip-radius,
|
|
83
|
+
var(--kui-layout-rounded-radius)
|
|
84
|
+
);
|
|
82
85
|
}
|
|
83
86
|
.kui-tab-bar[data-trailing-placement="adjacent"] .kui-tab-bar__tabs {
|
|
84
87
|
flex: 0 1 auto;
|
|
@@ -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
|
@@ -28,7 +28,9 @@ function wireCatalogFilter(root) {
|
|
|
28
28
|
'[data-component="token-search-field"]'
|
|
29
29
|
);
|
|
30
30
|
field.dataset.catalogFilterActive = String(Boolean(query));
|
|
31
|
-
|
|
31
|
+
const placeholderVisible = String(!filterValue);
|
|
32
|
+
if (field.dataset.placeholderVisible !== placeholderVisible)
|
|
33
|
+
field.dataset.placeholderVisible = placeholderVisible;
|
|
32
34
|
const clear = field.querySelector(
|
|
33
35
|
'[data-action="catalog-clear-filter"]'
|
|
34
36
|
);
|
|
@@ -105,9 +107,14 @@ function wireCatalogFilter(root) {
|
|
|
105
107
|
root.addEventListener("input", onInput);
|
|
106
108
|
root.addEventListener("click", onClick);
|
|
107
109
|
const observer = new view.MutationObserver(() => {
|
|
108
|
-
if (
|
|
110
|
+
if (filterValue) apply();
|
|
111
|
+
});
|
|
112
|
+
observer.observe(root, {
|
|
113
|
+
attributes: true,
|
|
114
|
+
attributeFilter: ["data-placeholder-visible"],
|
|
115
|
+
childList: true,
|
|
116
|
+
subtree: true
|
|
109
117
|
});
|
|
110
|
-
observer.observe(root, { childList: true, subtree: true });
|
|
111
118
|
apply();
|
|
112
119
|
return () => {
|
|
113
120
|
root.removeEventListener("input", onInput);
|
|
@@ -137,12 +144,18 @@ function wireCatalog(root, {
|
|
|
137
144
|
onSelect,
|
|
138
145
|
onToggleSidebar,
|
|
139
146
|
onToggleTheme,
|
|
147
|
+
onToggleContrast,
|
|
148
|
+
onToggleMotion,
|
|
149
|
+
onSelectBackground,
|
|
140
150
|
onToggleSecondary,
|
|
141
151
|
urlParam,
|
|
142
152
|
revealSelection,
|
|
143
153
|
selectAction = "catalog-select",
|
|
144
154
|
toggleSidebarAction = "catalog-toggle-sidebar",
|
|
145
155
|
toggleThemeAction = "catalog-toggle-theme",
|
|
156
|
+
toggleContrastAction = "catalog-toggle-contrast",
|
|
157
|
+
toggleMotionAction = "catalog-toggle-motion",
|
|
158
|
+
selectBackgroundAction = "catalog-select-background",
|
|
146
159
|
toggleSecondaryAction = "catalog-toggle-secondary",
|
|
147
160
|
collapsed,
|
|
148
161
|
sidebarSize,
|
|
@@ -205,6 +218,40 @@ function wireCatalog(root, {
|
|
|
205
218
|
)
|
|
206
219
|
);
|
|
207
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
|
+
}
|
|
208
255
|
if (onToggleSecondary) {
|
|
209
256
|
disposers.push(
|
|
210
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 field.dataset.placeholderVisible = String(!filterValue);\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 (query) apply();\n });\n observer.observe(root, { childList: true, subtree: true });\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
|
|
@@ -61,8 +71,9 @@ filters entry names and section headings as text is typed,
|
|
|
61
71
|
ignoring case. A heading match shows all its entries; a matching secondary
|
|
62
72
|
group heading searches its sections too, even while that group is collapsed.
|
|
63
73
|
Empty sections disappear and an empty-result message appears when nothing
|
|
64
|
-
matches. The query survives controlled Catalog rerenders
|
|
65
|
-
|
|
74
|
+
matches. The query survives controlled Catalog rerenders, with the field's
|
|
75
|
+
placeholder hidden while text remains, and clears through the field's clear
|
|
76
|
+
action. Filtering does not change the selected
|
|
66
77
|
entry or its preview.
|
|
67
78
|
|
|
68
79
|
Per-entry `resources` render as "open in new tab" links in the footer, and
|
|
@@ -289,12 +300,14 @@ import {
|
|
|
289
300
|
Catalog,
|
|
290
301
|
CatalogExample,
|
|
291
302
|
CatalogExampleStack,
|
|
303
|
+
type CatalogBackgroundStyle,
|
|
292
304
|
type CatalogSection,
|
|
293
305
|
} from "@kerfjs/ui/catalog";
|
|
294
306
|
import {
|
|
295
307
|
revealCatalogEntry,
|
|
296
308
|
wireCatalog,
|
|
297
309
|
} from "@kerfjs/ui/wire-catalog";
|
|
310
|
+
import "@kerfjs/ui/popup-menu/register"; // for the background chooser
|
|
298
311
|
// A CSS-aware (browser-condition) bundler loads the Catalog's CSS with its import.
|
|
299
312
|
|
|
300
313
|
type DemoKind = "component" | "composition";
|
|
@@ -355,12 +368,15 @@ const renderers: Record<string, () => SafeHtml> = {
|
|
|
355
368
|
),
|
|
356
369
|
};
|
|
357
370
|
|
|
358
|
-
// 3. App-owned state (domain: which entry; transient: collapsed;
|
|
371
|
+
// 3. App-owned state (domain: which entry; transient: collapsed; display preferences).
|
|
359
372
|
const initial =
|
|
360
373
|
new URLSearchParams(location.search).get("c") ?? sections[0].entries[0].id;
|
|
361
374
|
const active = signal(initial);
|
|
362
375
|
const collapsed = signal(false);
|
|
363
376
|
const theme = signal<"light" | "dark">("light");
|
|
377
|
+
const increasedContrast = signal(false);
|
|
378
|
+
const reducedMotion = signal(false);
|
|
379
|
+
const backgroundStyle = signal<CatalogBackgroundStyle>("checkerboard");
|
|
364
380
|
|
|
365
381
|
const app = document.getElementById("app")!;
|
|
366
382
|
mount(app, () => (
|
|
@@ -371,6 +387,10 @@ mount(app, () => (
|
|
|
371
387
|
content={renderers[active.value]?.() ?? <></>}
|
|
372
388
|
collapsed={collapsed.value}
|
|
373
389
|
theme={theme.value}
|
|
390
|
+
increasedContrast={increasedContrast.value}
|
|
391
|
+
reducedMotion={reducedMotion.value}
|
|
392
|
+
backgroundControl
|
|
393
|
+
backgroundStyle={backgroundStyle.value}
|
|
374
394
|
/>
|
|
375
395
|
));
|
|
376
396
|
|
|
@@ -385,6 +405,17 @@ wireCatalog(app, {
|
|
|
385
405
|
theme.value = theme.value === "dark" ? "light" : "dark";
|
|
386
406
|
document.documentElement.dataset.theme = theme.value; // apply your theme however you like
|
|
387
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
|
+
},
|
|
388
419
|
urlParam: "c", // mirror the active id into ?c=<id>
|
|
389
420
|
revealSelection: true, // reveal long desktop sidebars without moving focus
|
|
390
421
|
});
|
|
@@ -432,9 +463,10 @@ revealCatalogEntry(app, initial, { block: "center" });
|
|
|
432
463
|
## Custom action names
|
|
433
464
|
|
|
434
465
|
The shell emits `data-action="catalog-select"` (sidebar items),
|
|
435
|
-
`catalog-toggle-sidebar`,
|
|
436
|
-
`
|
|
437
|
-
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.
|
|
438
470
|
|
|
439
471
|
## CSS
|
|
440
472
|
|
|
@@ -339,7 +339,10 @@ parent's name. `ResizableRegion` widens its edge extent by the unsafe inset a
|
|
|
339
339
|
split `SplitView` provides, and a `Skeleton` derives its fill from a solid
|
|
340
340
|
`Badge`'s on-solid color, both in their own stylesheets; an `AppTab` rounds its
|
|
341
341
|
outer corners in a segmented `TabBar` and shares a fill-allocated strip from
|
|
342
|
-
`app-tab.css`.
|
|
342
|
+
`app-tab.css`. An inspector `TabBar` uses the shared 12px rounded rectangle
|
|
343
|
+
radius on its strip; its segmented `AppTab` corners follow that strip's inner
|
|
344
|
+
curve, while an ordinary segmented strip keeps its pill ends and smaller
|
|
345
|
+
interior corners. A `PopupMenu` sizes
|
|
343
346
|
its trigger and applies a group's `menuInset` in its own stylesheet, and an
|
|
344
347
|
icon-only `Select` reads the control slot a `ToolbarControlGroup` provides
|
|
345
348
|
(`--_kui-toolbar-control-group-slot-*`). A parent may still style its own
|
|
@@ -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/docs/webawesome-theme.md
CHANGED
|
@@ -149,6 +149,19 @@ is absent. Nested SunkenPanel, Pane, and Web Awesome sunken surfaces therefore
|
|
|
149
149
|
composite on their actual backdrop without application-owned depth wrappers
|
|
150
150
|
or component-token overrides.
|
|
151
151
|
|
|
152
|
+
The lowered tint is `--wa-color-surface-lowered` in the Web Awesome theme and
|
|
153
|
+
`--kui-color-surface-lowered` in the Kerf foundation fallback;
|
|
154
|
+
`--wa-color-neutral-fill-quiet` and `--kui-color-neutral-fill-quiet` share it.
|
|
155
|
+
`SunkenPanel`, sunken Pane, Workbench, and TabNavigator surfaces read it by
|
|
156
|
+
default through the optional `--kui-sunken-panel-background` override. Web
|
|
157
|
+
Awesome Accordion, Card, and Details with `appearance="sunken"` read it
|
|
158
|
+
through the optional `--kui-wa-sunken-background` override. These names do
|
|
159
|
+
not denote separate opaque colors or distinct depth levels. A deliberate
|
|
160
|
+
nested surface adds another translucent layer and can make hierarchy clearer;
|
|
161
|
+
avoid painting a second background on a wrapper that represents the same
|
|
162
|
+
surface. Inspect the composed result over the real backdrop in light and dark
|
|
163
|
+
modes.
|
|
164
|
+
|
|
152
165
|
The lowered light tint is `rgb(0 0 98.076923 / 0.05098)` (approximately
|
|
153
166
|
`#f2f2f7` over white); dark is `rgb(228.157895 228.157895 255 / 0.07451)`
|
|
154
167
|
(approximately `#111113` over black). Repeated layers darken in light mode
|
package/llms.txt
CHANGED
|
@@ -12,6 +12,18 @@ npm install kerfjs @kerfjs/ui # kerfjs is a peer; Web Awesome is an optional pee
|
|
|
12
12
|
Import each component from its own subpath (`@kerfjs/ui/list-item`, `@kerfjs/ui/toolbar`,
|
|
13
13
|
…); the browser build pulls that component's reachable CSS automatically, so do not
|
|
14
14
|
maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
15
|
+
|
|
16
|
+
The sunken/lowered background is semi-transparent: Web Awesome's
|
|
17
|
+
`--wa-color-surface-lowered` is mirrored by `--kui-color-surface-lowered` and
|
|
18
|
+
used by `--kui-color-neutral-fill-quiet`. `SunkenPanel`, sunken
|
|
19
|
+
`Pane`/`Workbench`/`TabNavigator` surfaces, and Web Awesome
|
|
20
|
+
`appearance="sunken"` use that tint by default through their optional
|
|
21
|
+
`--kui-sunken-panel-background` / `--kui-wa-sunken-background` override tokens.
|
|
22
|
+
Each layer composites over its backdrop. Intentional nested layers create
|
|
23
|
+
depth; avoid a wrapper or extra background that paints the same visual surface
|
|
24
|
+
twice. Check contrast in both color schemes over the actual backdrop. See
|
|
25
|
+
[contextual transparency](./docs/webawesome-theme.md#contextual-transparency).
|
|
26
|
+
|
|
15
27
|
For arbitrary interactive help or popup content, use `openAnchoredSurface` or
|
|
16
28
|
`openAnchoredSurfaceAt` from `@kerfjs/ui/anchored-surface`; see
|
|
17
29
|
[AnchoredSurface](./docs/anchored-surface.md). The app owns content and actions.
|
|
@@ -47,6 +59,19 @@ not a reason to override — and your own components follow the same rule.
|
|
|
47
59
|
|
|
48
60
|
## How to build a screen (retrieval order)
|
|
49
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
|
+
|
|
50
75
|
1. **Pick the component from the interface need**, not by appearance — read
|
|
51
76
|
[component-selection.md](./docs/component-selection.md) (the problem→component
|
|
52
77
|
matrix, with imports, wiring, ownership, and alternatives).
|
|
@@ -494,6 +519,10 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
|
|
|
494
519
|
`dropTarget` highlights a drag-over without changing selection. `attention`
|
|
495
520
|
uses `--kui-app-tab-attention-color`. TabBar's public
|
|
496
521
|
`--kui-tab-bar-strip-*` tokens set compact strip geometry.
|
|
522
|
+
An inspector TabBar uses the shared rounded rectangle radius on its strip
|
|
523
|
+
and inset segmented tabs; an ordinary segmented TabBar keeps pill ends and
|
|
524
|
+
smaller interior tab corners. Configure the presentation instead of
|
|
525
|
+
restyling AppTab.
|
|
497
526
|
Set `pinned` on the first AppTab to keep it visible within a scrolling
|
|
498
527
|
tablist; it remains in keyboard order. Use `--kui-app-tab-pinned-background`
|
|
499
528
|
for the surrounding surface and keep that backdrop opaque.
|
|
@@ -532,7 +561,10 @@ shell, `@kerfjs/ui/collapsible-panel` (`CollapsiblePanel`, `CollapsiblePanelTogg
|
|
|
532
561
|
`Catalog` component + `wireCatalog` helper for building a component-gallery catalog
|
|
533
562
|
(collapsible category sidebar + preview stage + resources footer, with
|
|
534
563
|
focus-preserving active-row reveal for long desktop sidebars) from your own
|
|
535
|
-
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
|
|
536
568
|
the [authoritative authoring contract](./docs/catalog.md#catalog-demo-authoring-contract)
|
|
537
569
|
rather than inferring structure from the shell or private CSS.
|
|
538
570
|
`@kerfjs/ui/webawesome` is a
|