@kerfjs/ui 5.0.0-beta.56 → 5.0.0-beta.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -32
- package/ai/application-ui-diagnostic-ids-v1.json +9 -1
- package/ai/application-ui-profile-sync.cjs +1 -1
- package/ai/application-ui-profile.defaults.json +63 -8
- package/ai/application-ui-profile.mjs +1 -1
- package/ai/component-catalog.json +208 -32
- package/ai/component-catalog.schema.json +2 -0
- package/ai/component-class-owners.cjs +83 -0
- package/ai/component-composition-extension.d.ts +7 -0
- package/ai/component-composition-extension.schema.json +7 -0
- package/ai/{component-catalog-v2-overrides.json → component-composition-rules.json} +2 -1
- package/ai/{component-catalog-v2.d.ts → component-composition.d.ts} +9 -5
- package/ai/{component-catalog-v2.json → component-composition.json} +155 -24
- package/ai/{component-catalog-v2.schema.json → component-composition.schema.json} +21 -5
- package/ai/components/README.md +170 -0
- package/ai/components/application-tabs.md +65 -0
- package/ai/components/badge.md +72 -0
- package/ai/components/collapsible-panel.md +102 -0
- package/ai/components/content-item.md +90 -0
- package/ai/components/disclosure-arrow.md +77 -0
- package/ai/components/document-baseline.md +75 -0
- package/ai/components/empty-state.md +80 -0
- package/ai/components/feedback.md +71 -0
- package/ai/components/floating-toolbar.md +80 -0
- package/ai/components/foundation.md +65 -0
- package/ai/components/grid.md +93 -0
- package/ai/components/headers.md +63 -0
- package/ai/components/layout.md +75 -0
- package/ai/components/list-action-row.md +91 -0
- package/ai/components/list-header.md +89 -0
- package/ai/components/list-inset-control.md +74 -0
- package/ai/components/list-inset-text.md +72 -0
- package/ai/components/list-item.md +88 -0
- package/ai/components/list.md +103 -0
- package/ai/components/loading-spinner.md +72 -0
- package/ai/components/lucide-icon.md +66 -0
- package/ai/components/nav-stack.md +103 -0
- package/ai/components/pane.md +100 -0
- package/ai/components/popup-menu.md +82 -0
- package/ai/components/recipe-app-shell.md +57 -0
- package/ai/components/recipe-collapsible-sidebar.md +57 -0
- package/ai/components/recipe-compact-toolbar.md +57 -0
- package/ai/components/recipe-composer-form.md +57 -0
- package/ai/components/recipe-list-detail-dialog.md +57 -0
- package/ai/components/recipe-list-workspace-states.md +57 -0
- package/ai/components/recipe-loading-inspector.md +57 -0
- package/ai/components/recipe-navigation-sidebar.md +57 -0
- package/ai/components/recipe-navigation-stack.md +57 -0
- package/ai/components/recipe-workspace-header.md +57 -0
- package/ai/components/resize.md +101 -0
- package/ai/components/row.md +96 -0
- package/ai/components/segmented-control.md +82 -0
- package/ai/components/select.md +107 -0
- package/ai/components/skeleton.md +84 -0
- package/ai/components/spacer.md +86 -0
- package/ai/components/split-view.md +102 -0
- package/ai/components/state-banner.md +92 -0
- package/ai/components/sunken-panel.md +79 -0
- package/ai/components/surface-scaffold.md +78 -0
- package/ai/components/tab-bar.md +112 -0
- package/ai/components/tab-scaffold.md +94 -0
- package/ai/components/tabs.md +90 -0
- package/ai/components/text.md +82 -0
- package/ai/components/token-search-field.md +101 -0
- package/ai/components/toolbar-control-group.md +100 -0
- package/ai/components/toolbar-text.md +76 -0
- package/ai/components/toolbar.md +95 -0
- package/ai/components/value-table.md +72 -0
- package/ai/components/wa-accordion-item.md +55 -0
- package/ai/components/wa-accordion.md +65 -0
- package/ai/components/wa-animated-image.md +55 -0
- package/ai/components/wa-animation.md +55 -0
- package/ai/components/wa-avatar.md +55 -0
- package/ai/components/wa-badge.md +55 -0
- package/ai/components/wa-breadcrumb-item.md +53 -0
- package/ai/components/wa-breadcrumb.md +55 -0
- package/ai/components/wa-button-group.md +59 -0
- package/ai/components/wa-button.md +55 -0
- package/ai/components/wa-callout.md +58 -0
- package/ai/components/wa-card.md +59 -0
- package/ai/components/wa-carousel-item.md +53 -0
- package/ai/components/wa-carousel.md +55 -0
- package/ai/components/wa-checkbox-group.md +55 -0
- package/ai/components/wa-checkbox.md +55 -0
- package/ai/components/wa-color-picker.md +55 -0
- package/ai/components/wa-comparison.md +55 -0
- package/ai/components/wa-copy-button.md +55 -0
- package/ai/components/wa-details.md +61 -0
- package/ai/components/wa-dialog.md +59 -0
- package/ai/components/wa-divider.md +53 -0
- package/ai/components/wa-drawer.md +55 -0
- package/ai/components/wa-dropdown-item.md +60 -0
- package/ai/components/wa-dropdown.md +60 -0
- package/ai/components/wa-format-bytes.md +53 -0
- package/ai/components/wa-format-date.md +53 -0
- package/ai/components/wa-format-number.md +53 -0
- package/ai/components/wa-icon.md +58 -0
- package/ai/components/wa-include.md +53 -0
- package/ai/components/wa-input.md +59 -0
- package/ai/components/wa-intersection-observer.md +53 -0
- package/ai/components/wa-known-date.md +53 -0
- package/ai/components/wa-markdown.md +53 -0
- package/ai/components/wa-mutation-observer.md +53 -0
- package/ai/components/wa-number-input.md +55 -0
- package/ai/components/wa-option.md +59 -0
- package/ai/components/wa-otp-input.md +53 -0
- package/ai/components/wa-page.md +53 -0
- package/ai/components/wa-pagination.md +55 -0
- package/ai/components/wa-popover.md +55 -0
- package/ai/components/wa-popup.md +53 -0
- package/ai/components/wa-progress-bar.md +53 -0
- package/ai/components/wa-progress-ring.md +53 -0
- package/ai/components/wa-qr-code.md +53 -0
- package/ai/components/wa-radio-group.md +59 -0
- package/ai/components/wa-radio.md +55 -0
- package/ai/components/wa-random-content.md +53 -0
- package/ai/components/wa-rating.md +55 -0
- package/ai/components/wa-relative-time.md +53 -0
- package/ai/components/wa-resize-observer.md +53 -0
- package/ai/components/wa-scroller.md +53 -0
- package/ai/components/wa-select.md +63 -0
- package/ai/components/wa-skeleton.md +53 -0
- package/ai/components/wa-slider.md +55 -0
- package/ai/components/wa-spinner.md +58 -0
- package/ai/components/wa-split-panel.md +58 -0
- package/ai/components/wa-switch.md +53 -0
- package/ai/components/wa-tab-group.md +69 -0
- package/ai/components/wa-tab-panel.md +60 -0
- package/ai/components/wa-tab.md +59 -0
- package/ai/components/wa-tag.md +59 -0
- package/ai/components/wa-textarea.md +53 -0
- package/ai/components/wa-time-input.md +55 -0
- package/ai/components/wa-toast-item.md +60 -0
- package/ai/components/wa-toast.md +60 -0
- package/ai/components/wa-tooltip.md +55 -0
- package/ai/components/wa-tree-item.md +55 -0
- package/ai/components/wa-tree.md +55 -0
- package/ai/components/wa-zoomable-frame.md +55 -0
- package/ai/components/workbench.md +114 -0
- package/ai/public-api-signatures-v1.md +161 -32
- package/ai/skill.md +100 -48
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/component-ownership.d.mts +56 -0
- package/analyzer/component-ownership.mjs +184 -0
- package/analyzer/index.d.mts +3 -0
- package/analyzer/index.mjs +274 -20
- package/analyzer/selectors.d.mts +21 -0
- package/analyzer/selectors.mjs +212 -0
- package/dist/browser/catalog.js +25 -0
- package/dist/browser/collapsible-panel.js +7 -0
- package/dist/browser/nav-stack.js +8 -0
- package/dist/browser/split-view.js +10 -0
- package/dist/browser/tab-scaffold.js +4 -0
- package/dist/browser/workbench.js +10 -0
- package/dist/catalog-resources.d.ts +2 -2
- package/dist/catalog.d.ts +3 -3
- package/dist/catalog.js +7 -6
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-PK4N5QTO.js → chunk-553ASUK6.js} +2 -3
- package/dist/chunk-553ASUK6.js.map +1 -0
- package/dist/{chunk-G33XC2NB.js → chunk-6YFHCLHG.js} +2 -2
- package/dist/chunk-6YFHCLHG.js.map +1 -0
- package/dist/{chunk-T4UZTNZ4.js → chunk-EVYKTVBQ.js} +2 -11
- package/dist/chunk-EVYKTVBQ.js.map +1 -0
- package/dist/{chunk-AK67F6QN.js → chunk-EZVNC4J6.js} +4 -1
- package/dist/chunk-EZVNC4J6.js.map +1 -0
- package/dist/{chunk-MA6Z6EIM.js → chunk-F4QMLOXJ.js} +3 -2
- package/dist/chunk-F4QMLOXJ.js.map +1 -0
- package/dist/{chunk-QQOTQTDD.js → chunk-G2RKFVRB.js} +13 -10
- package/dist/chunk-G2RKFVRB.js.map +1 -0
- package/dist/chunk-JCV4GXWB.js +249 -0
- package/dist/chunk-JCV4GXWB.js.map +1 -0
- package/dist/chunk-K47P7QZC.js +17 -0
- package/dist/chunk-K47P7QZC.js.map +1 -0
- package/dist/{chunk-MOBRFZH3.js → chunk-OUK6QRDR.js} +2 -12
- package/dist/chunk-OUK6QRDR.js.map +1 -0
- package/dist/{chunk-O3EXIBEZ.js → chunk-PWXNJS2B.js} +7 -6
- package/dist/chunk-PWXNJS2B.js.map +1 -0
- package/dist/{chunk-VNPQDCQZ.js → chunk-QOWG4ZCL.js} +3 -2
- package/dist/chunk-QOWG4ZCL.js.map +1 -0
- package/dist/{chunk-V65EOWNF.js → chunk-XCO6YCYM.js} +5 -4
- package/dist/chunk-XCO6YCYM.js.map +1 -0
- package/dist/{chunk-K6UNVKDK.js → chunk-XDKAYSVD.js} +3 -1
- package/dist/chunk-XDKAYSVD.js.map +1 -0
- package/dist/collapsible-panel.d.ts +3 -3
- package/dist/collapsible-panel.js +2 -2
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +10 -8
- package/dist/list-action-row.js +2 -1
- package/dist/list-header.js +1 -1
- package/dist/list-item.js +2 -1
- package/dist/nav-stack.d.ts +13 -1
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +20 -3
- package/dist/pane.js +1 -1
- package/dist/{panel-toolbar-C8sF-YZC.d.ts → panel-toolbar-BN4x0rth.d.ts} +3 -2
- package/dist/select.js +1 -1
- package/dist/split-view.d.ts +3 -3
- package/dist/split-view.js +3 -2
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.js +1 -1
- package/dist/styles/app-tab.css +31 -0
- package/dist/styles/badge.css +19 -11
- package/dist/styles/collapsible-panel.css +13 -9
- package/dist/styles/floating-toolbar.css +25 -6
- package/dist/styles/list-header.css +0 -12
- package/dist/styles/list.css +4 -4
- package/dist/styles/nav-stack.css +46 -19
- package/dist/styles/pane.css +50 -0
- package/dist/styles/popup-menu.css +151 -0
- package/dist/styles/resizable-region.css +22 -10
- package/dist/styles/select.css +28 -14
- package/dist/styles/skeleton.css +30 -3
- package/dist/styles/split-view.css +10 -7
- package/dist/styles/state-banner.css +0 -19
- package/dist/styles/surface-scaffold.css +8 -3
- package/dist/styles/tab-bar.css +79 -28
- package/dist/styles/tab-scaffold.css +25 -1
- package/dist/styles/text.css +16 -0
- package/dist/styles/toolbar-control-group.css +121 -66
- package/dist/styles/toolbar-text.css +21 -0
- package/dist/styles/toolbar.css +8 -32
- package/dist/styles/workbench.css +18 -18
- package/dist/tab-scaffold.d.ts +11 -1
- package/dist/tab-scaffold.js +2 -0
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/toolbar-text.d.ts +7 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +8 -1
- package/dist/toolbar.js +1 -1
- package/dist/{types-DXAGogOS.d.ts → types-BuHELdXR.d.ts} +1 -1
- package/dist/wire-catalog.d.ts +3 -1
- package/dist/wire-catalog.js +2 -0
- package/dist/wire-catalog.js.map +1 -1
- package/dist/wire-scroll-dividers.d.ts +69 -0
- package/dist/wire-scroll-dividers.js +3 -0
- package/dist/wire-scroll-dividers.js.map +1 -0
- package/dist/workbench.d.ts +13 -12
- package/dist/workbench.js +1 -1
- package/docs/app-layouts.md +9 -1
- package/docs/catalog.md +10 -5
- package/docs/collapsible-panel.md +10 -6
- package/docs/component-contract.md +147 -21
- package/docs/component-selection.md +18 -6
- package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -1
- package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -1
- package/docs/design/templates/tab-bar-dark.svg +1 -1
- package/docs/design/templates/tab-bar.svg +1 -1
- package/docs/design-philosophy.md +30 -3
- package/docs/examples/application-ui-profile.json +4 -4
- package/docs/examples/{component-catalog-extension-v2.json → component-composition-extension.json} +3 -3
- package/docs/layout.md +82 -3
- package/docs/nav-stack.md +33 -3
- package/docs/split-view.md +10 -5
- package/docs/tab-scaffold.md +23 -1
- package/docs/type-contracts.md +4 -3
- package/docs/ui-analyzer.md +99 -5
- package/docs/ui-doctor.md +10 -0
- package/docs/workbench.md +19 -9
- package/doctor/index.mjs +6 -1
- package/llms.txt +85 -20
- package/package.json +17 -5
- package/ux-demo/recipes/collapsible-sidebar.tsx +0 -1
- package/ux-demo/recipes/composer-form.tsx +0 -1
- package/ux-demo/recipes/list-detail-dialog.tsx +0 -2
- package/ux-demo/recipes/list-workspace-states.tsx +0 -1
- package/ux-demo/recipes/loading-inspector.tsx +0 -1
- package/ux-demo/recipes/workspace-header.tsx +0 -1
- package/ai/component-catalog-extension-v2.d.ts +0 -7
- package/ai/component-catalog-extension-v2.schema.json +0 -7
- package/dist/chunk-AK67F6QN.js.map +0 -1
- package/dist/chunk-G33XC2NB.js.map +0 -1
- package/dist/chunk-K6UNVKDK.js.map +0 -1
- package/dist/chunk-MA6Z6EIM.js.map +0 -1
- package/dist/chunk-MOBRFZH3.js.map +0 -1
- package/dist/chunk-O3EXIBEZ.js.map +0 -1
- package/dist/chunk-PK4N5QTO.js.map +0 -1
- package/dist/chunk-QQOTQTDD.js.map +0 -1
- package/dist/chunk-T4UZTNZ4.js.map +0 -1
- package/dist/chunk-V65EOWNF.js.map +0 -1
- package/dist/chunk-VNPQDCQZ.js.map +0 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# ResizableRegion
|
|
2
|
+
|
|
3
|
+
<!-- Generated by scripts/sync-component-docs.mjs from ai/component-catalog.json and ai/component-composition.json. Do not edit; run `npm run catalog:sync`. -->
|
|
4
|
+
|
|
5
|
+
`@kerfjs/ui:resize` · Kerf UI · component · Controls
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
Pointer and keyboard-operable split region with a customizable handle icon.
|
|
10
|
+
|
|
11
|
+
- Provide a controlled user-resizable application pane.
|
|
12
|
+
|
|
13
|
+
**Not when:**
|
|
14
|
+
|
|
15
|
+
- Do not use for static columns; use CSS grid.
|
|
16
|
+
|
|
17
|
+
**Alternatives:**
|
|
18
|
+
|
|
19
|
+
- [Application layout](./layout.md) (nearest)
|
|
20
|
+
- [Split Panel](./wa-split-panel.md) (prefer-over)
|
|
21
|
+
|
|
22
|
+
## Imports
|
|
23
|
+
|
|
24
|
+
- JavaScript: `@kerfjs/ui/resizable-region` — exports `ResizableRegion`, `clampRegionSize`, `resizeRegionFromPointer`, `wireResizableRegions`.
|
|
25
|
+
- CSS: the browser build of `@kerfjs/ui/resizable-region` pulls its CSS automatically; import `@kerfjs/ui/resizable-region.css` manually only without the `browser` export condition.
|
|
26
|
+
- Wiring: `wireResizableRegions` from `@kerfjs/ui/wire-resizable-regions` (required).
|
|
27
|
+
- Wiring: `clampRegionSize` from `@kerfjs/ui/resizable-region` (optional).
|
|
28
|
+
- Wiring: `resizeRegionFromPointer` from `@kerfjs/ui/resizable-region` (optional).
|
|
29
|
+
- Declared side effects: browser-condition-css.
|
|
30
|
+
|
|
31
|
+
## Props
|
|
32
|
+
|
|
33
|
+
Exact prop names and types: [`@kerfjs/ui/resizable-region`](../public-api-signatures-v1.md#kerfjsuiresizable-region), [`@kerfjs/ui/wire-resizable-regions`](../public-api-signatures-v1.md#kerfjsuiwire-resizable-regions) in `public-api-signatures-v1.md`. Do not infer props from examples.
|
|
34
|
+
|
|
35
|
+
**Variants (configure, do not restyle):**
|
|
36
|
+
|
|
37
|
+
- horizontal
|
|
38
|
+
- vertical
|
|
39
|
+
- start edge
|
|
40
|
+
- end edge
|
|
41
|
+
- collapsed
|
|
42
|
+
- custom handle icon
|
|
43
|
+
- hidden separator
|
|
44
|
+
- slide, fade-slide, or instant content
|
|
45
|
+
- clipped, scrolling, or popup-visible content
|
|
46
|
+
- inline, overlay, or hidden responsive presentation
|
|
47
|
+
- safe-area restore control
|
|
48
|
+
|
|
49
|
+
## Composition
|
|
50
|
+
|
|
51
|
+
- Parents: any.
|
|
52
|
+
- Contexts: `adjustable-pane-boundary`.
|
|
53
|
+
- Children: unrestricted.
|
|
54
|
+
- Built from: [LucideIcon](./lucide-icon.md).
|
|
55
|
+
|
|
56
|
+
## State and wiring
|
|
57
|
+
|
|
58
|
+
- size — controlled (required)
|
|
59
|
+
|
|
60
|
+
**Wiring:** `wireResizableRegions` is required.
|
|
61
|
+
|
|
62
|
+
- Retain and invoke the disposer.
|
|
63
|
+
- Persist committed size in the application when persistence is required.
|
|
64
|
+
|
|
65
|
+
**Wiring-owned state attributes** — never render, remove, or branch on these as app state:
|
|
66
|
+
|
|
67
|
+
- `data-handle-inset` on `kui-resizable-region` (`wireResizableRegions`): Present while a clipping edge clamps the region: the handle and its focus ring sit inside the region instead of overhanging that edge.
|
|
68
|
+
- `data-resizing` on `kui-resizable-region` (`wireResizableRegions`): "true" during an active pointer drag of the handle.
|
|
69
|
+
|
|
70
|
+
## Geometry
|
|
71
|
+
|
|
72
|
+
Margin: none · border: conditional · padding: conditional (layout role: controls). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
|
|
73
|
+
|
|
74
|
+
- The region delegates visible separator geometry and hit-area padding to its orientation-specific handle.
|
|
75
|
+
|
|
76
|
+
## Accessibility
|
|
77
|
+
|
|
78
|
+
- Preserve separator naming, value ARIA, and keyboard behavior.
|
|
79
|
+
- Keep handleIcon decorative and free of interactive descendants; the separator owns focus, naming, and pointer/keyboard interaction.
|
|
80
|
+
|
|
81
|
+
## Styling boundary
|
|
82
|
+
|
|
83
|
+
The component owns its own styles. Configure it through its props and variants; do not override its internals.
|
|
84
|
+
|
|
85
|
+
Public class hooks (select for layout placement only, never to change the component's look): `kui-resizable-region`, `kui-resizable-region__content`, `kui-resizable-region__handle`, `kui-resizable-region__handle-icon`, `kui-resizable-region__restore`.
|
|
86
|
+
|
|
87
|
+
Never put `kui-resizable-region`, `kui-resizable-region__content`, `kui-resizable-region__handle`, `kui-resizable-region__handle-icon`, `kui-resizable-region__restore` on an element you write; render `ResizableRegion` instead (`KUI-L103`).
|
|
88
|
+
|
|
89
|
+
Public tokens it reads: `--kui-color-neutral-border-normal`, `--kui-color-neutral-on-quiet`, `--kui-color-text-link`, `--kui-focus-ring`, `--kui-radius-s`, `--kui-resizable-region-edge-extent`, `--kui-resizable-region-handle-active-color`, `--kui-resizable-region-handle-color`, `--kui-resizable-region-overlay-z`, `--kui-resizable-region-popup-z`, `--kui-resizable-region-restore-inset`, `--kui-resizable-region-restore-z`, `--kui-resizable-region-separator-color`, `--kui-resizable-region-size`. Set a token only where its public contract allows; prefer a prop.
|
|
90
|
+
|
|
91
|
+
Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
|
|
92
|
+
|
|
93
|
+
## Diagnostics
|
|
94
|
+
|
|
95
|
+
- `KUI-C106` (error) when wireResizableRegions is absent: ResizableRegion requires wireResizableRegions for pointer and keyboard operation.
|
|
96
|
+
|
|
97
|
+
## Related
|
|
98
|
+
|
|
99
|
+
- Components: [LucideIcon](./lucide-icon.md), [Application layout](./layout.md), [Split Panel](./wa-split-panel.md).
|
|
100
|
+
- Docs: [`docs/component-selection.md`](../../docs/component-selection.md), [`docs/accessibility.md#resizableregion`](../../docs/accessibility.md#resizableregion).
|
|
101
|
+
- UX catalog route: `?component=resize`.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Row
|
|
2
|
+
|
|
3
|
+
<!-- Generated by scripts/sync-component-docs.mjs from ai/component-catalog.json and ai/component-composition.json. Do not edit; run `npm run catalog:sync`. -->
|
|
4
|
+
|
|
5
|
+
`@kerfjs/ui:row` · Kerf UI · component · Structure
|
|
6
|
+
|
|
7
|
+
A horizontal flex row with physical-axis alignment, side-selectable text/control insets, a typed xs gap by default, flex participation, and opt-in wrapping.
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
Arrange related content horizontally with consistent spacing, optional physical-side text/control insets, and explicit left/center/right/full plus top/middle/bottom/full/baseline alignment instead of application-owned flex wrappers.
|
|
12
|
+
|
|
13
|
+
- Arrange a group of sibling components horizontally.
|
|
14
|
+
- Choose physical horizontal distribution and vertical alignment without writing one-off flex CSS.
|
|
15
|
+
- Use a finite flex keyword or the flex() builder when Row participates in a flexible parent layout.
|
|
16
|
+
- Allow a bounded group to wrap while retaining the same typed gap and alignment contract.
|
|
17
|
+
- Apply the standard text or control inset to selected physical sides without an application wrapper.
|
|
18
|
+
|
|
19
|
+
**Not when:**
|
|
20
|
+
|
|
21
|
+
- Do not use Row when content belongs in a semantic list or when a named-zone component such as Toolbar owns the composition.
|
|
22
|
+
- Do not pass raw CSS strings to gap or flex, mix their distinct grammars, or use s/xl spacing steps without a deliberate exception.
|
|
23
|
+
- Do not use alignment to replace semantic grouping or responsive relocation.
|
|
24
|
+
|
|
25
|
+
**Alternatives:**
|
|
26
|
+
|
|
27
|
+
- [List](./list.md) (axis-alternative) — Use List when the main layout axis is vertical.
|
|
28
|
+
- [Toolbar](./toolbar.md) (semantic-alternative) — Use Toolbar when content belongs to named leading, center, and trailing application-chrome zones.
|
|
29
|
+
|
|
30
|
+
## Imports
|
|
31
|
+
|
|
32
|
+
- JavaScript: `@kerfjs/ui/row` — exports `Row`.
|
|
33
|
+
- CSS: the browser build of `@kerfjs/ui/row` pulls its CSS automatically; import `@kerfjs/ui/row.css` manually only without the `browser` export condition.
|
|
34
|
+
- Declared side effects: browser-condition-css.
|
|
35
|
+
|
|
36
|
+
## Props
|
|
37
|
+
|
|
38
|
+
Exact prop names and types: [`@kerfjs/ui/row`](../public-api-signatures-v1.md#kerfjsuirow) in `public-api-signatures-v1.md`. Do not infer props from examples.
|
|
39
|
+
|
|
40
|
+
**Variants (configure, do not restyle):**
|
|
41
|
+
|
|
42
|
+
- left/center/right/full horizontal alignment with l/c/r/f and flex aliases
|
|
43
|
+
- top/middle/bottom/full vertical alignment with t/m/c/b/f and flex aliases, plus baseline alignment
|
|
44
|
+
- named none/2xs/xs/s/m/l/xl token gap
|
|
45
|
+
- typed CssLength gap
|
|
46
|
+
- boolean, finite-keyword, or typed CssFlex flex
|
|
47
|
+
- nowrap or wrapping
|
|
48
|
+
- top/right/bottom/left text and control inset combinations
|
|
49
|
+
- fill: the layout root fills a definite-height parent
|
|
50
|
+
- rootAttributes: safe data-\* metadata on the root
|
|
51
|
+
|
|
52
|
+
**CSS-value props** (typed builders from `@kerfjs/ui/css-values`; raw CSS strings are rejected):
|
|
53
|
+
|
|
54
|
+
- `gap`: length grammar; raw values: forbid; shorthands `none`, `2xs`, `xs`, `m`, `l`; exceptional (justify) `s`, `xl`; helpers `px`, `rem`, `em`, `pct`, `space`, `lengthVar`, `calc` — e.g. `gap="xs"`
|
|
55
|
+
- `flex`: flex grammar; raw values: forbid; shorthands `none`, `auto`, `initial`; helpers `flex` — e.g. `flex`
|
|
56
|
+
|
|
57
|
+
## Composition
|
|
58
|
+
|
|
59
|
+
- Parents: any.
|
|
60
|
+
- Contexts: `application-ui`, `horizontal-layout`.
|
|
61
|
+
- Children: unrestricted.
|
|
62
|
+
|
|
63
|
+
## State and wiring
|
|
64
|
+
|
|
65
|
+
**The app owns:** child semantics and content; alignment and wrapping policy; typed gap and flex choices.
|
|
66
|
+
|
|
67
|
+
No wiring helper.
|
|
68
|
+
|
|
69
|
+
## Geometry
|
|
70
|
+
|
|
71
|
+
Margin: none · border: none · padding: conditional (layout role: structure). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
|
|
72
|
+
|
|
73
|
+
- Row adds no margin or border. textInsets adds the full 17px content inset and controlInsets adds 8px on selected physical sides; text wins when both select a side.
|
|
74
|
+
|
|
75
|
+
## Accessibility
|
|
76
|
+
|
|
77
|
+
- Row adds layout only and no grouping role; children retain responsibility for native or ARIA semantics.
|
|
78
|
+
- Wrapping must preserve a readable source and focus order.
|
|
79
|
+
|
|
80
|
+
## Styling boundary
|
|
81
|
+
|
|
82
|
+
The component owns its own styles. Configure it through its props and variants; do not override its internals.
|
|
83
|
+
|
|
84
|
+
Public class hooks (select for layout placement only, never to change the component's look): `kui-row`.
|
|
85
|
+
|
|
86
|
+
Never put `kui-row` on an element you write; render `Row` instead (`KUI-L103`).
|
|
87
|
+
|
|
88
|
+
Public tokens it reads: `--kui-layout-item-gap`, `--kui-row-gap`. Set a token only where its public contract allows; prefer a prop.
|
|
89
|
+
|
|
90
|
+
Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
|
|
91
|
+
|
|
92
|
+
## Related
|
|
93
|
+
|
|
94
|
+
- Components: [List](./list.md), [Toolbar](./toolbar.md).
|
|
95
|
+
- Docs: [`docs/layout.md`](../../docs/layout.md), [`docs/layout.md#row-and-list-alignment`](../../docs/layout.md#row-and-list-alignment).
|
|
96
|
+
- UX catalog route: `?component=row`.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# SegmentedControl
|
|
2
|
+
|
|
3
|
+
<!-- Generated by scripts/sync-component-docs.mjs from ai/component-catalog.json and ai/component-composition.json. Do not edit; run `npm run catalog:sync`. -->
|
|
4
|
+
|
|
5
|
+
`@kerfjs/ui:segmented-control` · Kerf UI · component · Controls
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
Controlled exclusive choices in toolbar, rounded-rectangle, and pill presentations.
|
|
10
|
+
|
|
11
|
+
- Expose a small controlled exclusive choice set.
|
|
12
|
+
|
|
13
|
+
**Not when:**
|
|
14
|
+
|
|
15
|
+
- Do not use for tabpanel semantics or many choices.
|
|
16
|
+
|
|
17
|
+
**Alternatives:**
|
|
18
|
+
|
|
19
|
+
- [TabBar](./tab-bar.md) (nearest)
|
|
20
|
+
- [Select](./select.md) (nearest)
|
|
21
|
+
- [Button Group](./wa-button-group.md) (prefer-over)
|
|
22
|
+
|
|
23
|
+
## Imports
|
|
24
|
+
|
|
25
|
+
- JavaScript: `@kerfjs/ui/segmented-control` — exports `SegmentedControl`.
|
|
26
|
+
- CSS: the browser build of `@kerfjs/ui/segmented-control` pulls its CSS automatically; import `@kerfjs/ui/segmented-control.css` manually only without the `browser` export condition.
|
|
27
|
+
- Declared side effects: browser-condition-css.
|
|
28
|
+
|
|
29
|
+
## Props
|
|
30
|
+
|
|
31
|
+
Exact prop names and types: [`@kerfjs/ui/segmented-control`](../public-api-signatures-v1.md#kerfjsuisegmented-control) in `public-api-signatures-v1.md`. Do not infer props from examples.
|
|
32
|
+
|
|
33
|
+
**Variants (configure, do not restyle):**
|
|
34
|
+
|
|
35
|
+
- filled
|
|
36
|
+
- outlined
|
|
37
|
+
- toolbar
|
|
38
|
+
- rounded
|
|
39
|
+
- pill
|
|
40
|
+
- equal width
|
|
41
|
+
- small
|
|
42
|
+
- placeholder (loading)
|
|
43
|
+
|
|
44
|
+
## Composition
|
|
45
|
+
|
|
46
|
+
- Parents: any.
|
|
47
|
+
- Contexts: `compact-exclusive-choice`.
|
|
48
|
+
- Children: unrestricted.
|
|
49
|
+
- Built from: [LucideIcon](./lucide-icon.md).
|
|
50
|
+
|
|
51
|
+
## State and wiring
|
|
52
|
+
|
|
53
|
+
- value — controlled (required)
|
|
54
|
+
|
|
55
|
+
No wiring helper.
|
|
56
|
+
|
|
57
|
+
## Geometry
|
|
58
|
+
|
|
59
|
+
Margin: none · border: self · padding: self (layout role: controls). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
|
|
60
|
+
|
|
61
|
+
## Accessibility
|
|
62
|
+
|
|
63
|
+
- Every enabled choice remains in sequential tab order.
|
|
64
|
+
- Every choice has a meaningful label.
|
|
65
|
+
|
|
66
|
+
## Styling boundary
|
|
67
|
+
|
|
68
|
+
The component owns its own styles. Configure it through its props and variants; do not override its internals.
|
|
69
|
+
|
|
70
|
+
Public class hooks (select for layout placement only, never to change the component's look): `kui-segmented-control`, `kui-segmented-control__item`.
|
|
71
|
+
|
|
72
|
+
Never put `kui-segmented-control`, `kui-segmented-control__item` on an element you write; render `SegmentedControl` instead (`KUI-L103`).
|
|
73
|
+
|
|
74
|
+
Public tokens it reads: `--kui-color-brand-on-quiet`, `--kui-color-neutral-border-normal`, `--kui-color-neutral-fill-normal`, `--kui-color-neutral-on-quiet`, `--kui-color-surface`, `--kui-focus-ring`, `--kui-font-2xs`, `--kui-font-weight-semibold`, `--kui-font-xs`, `--kui-segmented-background`, `--kui-segmented-border`, `--kui-segmented-foreground`, `--kui-segmented-hover-background`, `--kui-segmented-item-radius`, `--kui-segmented-radius`, `--kui-segmented-selected-background`, `--kui-segmented-selected-border`, `--kui-segmented-selected-foreground`, `--kui-segmented-selected-shadow`, `--kui-shadow-s`, `--kui-toolbar-control-color`, `--kui-toolbar-control-hover-background`, `--kui-toolbar-control-selected-background`, `--kui-toolbar-control-selected-color`, `--kui-toolbar-control-selected-shadow`. Set a token only where its public contract allows; prefer a prop.
|
|
75
|
+
|
|
76
|
+
Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
|
|
77
|
+
|
|
78
|
+
## Related
|
|
79
|
+
|
|
80
|
+
- Components: [LucideIcon](./lucide-icon.md), [TabBar](./tab-bar.md), [Select](./select.md), [Button Group](./wa-button-group.md).
|
|
81
|
+
- Docs: [`docs/component-selection.md`](../../docs/component-selection.md), [`docs/accessibility.md#segmentedcontrol`](../../docs/accessibility.md#segmentedcontrol).
|
|
82
|
+
- UX catalog route: `?component=segmented-control`.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Select
|
|
2
|
+
|
|
3
|
+
<!-- Generated by scripts/sync-component-docs.mjs from ai/component-catalog.json and ai/component-composition.json. Do not edit; run `npm run catalog:sync`. -->
|
|
4
|
+
|
|
5
|
+
`@kerfjs/ui:select` · Kerf UI · component · Controls
|
|
6
|
+
|
|
7
|
+
Controlled Web Awesome select with typed single or multiple values and form, toolbar, navigation, compact, icon-only, truncating, hint, and grouped-choice presentations.
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
Controlled Web Awesome select with typed form, toolbar, navigation, compact, icon-only, truncating, hint, and grouped-choice presentations.
|
|
12
|
+
|
|
13
|
+
- Choose a controlled value from a moderate or long list, including grouped and icon-bearing choices.
|
|
14
|
+
- Color an optional choice icon with a CssForegroundColor: uiColor() with a foreground token such as success-on-quiet, or foregroundColorVar() for an app-owned property. Fill tokens such as success are backgrounds that leave the icon nearly invisible, so they, lengths, raw color strings, and unqualified colorVar() values are rejected.
|
|
15
|
+
|
|
16
|
+
**Not when:**
|
|
17
|
+
|
|
18
|
+
- Do not use for commands or a small choice set that should stay visible.
|
|
19
|
+
|
|
20
|
+
**Alternatives:**
|
|
21
|
+
|
|
22
|
+
- [SegmentedControl](./segmented-control.md) (nearest)
|
|
23
|
+
- [Select](./wa-select.md) (prefer-over)
|
|
24
|
+
- [Dropdown](./wa-dropdown.md) (prefer-over)
|
|
25
|
+
|
|
26
|
+
## Imports
|
|
27
|
+
|
|
28
|
+
- JavaScript: `@kerfjs/ui/select` — exports `Select`, `uiColor`, `colorVar`, `foregroundColorVar`.
|
|
29
|
+
- CSS: the browser build of `@kerfjs/ui/select` pulls its CSS automatically; import `@kerfjs/ui/select.css` manually only without the `browser` export condition.
|
|
30
|
+
- Registration: import `@kerfjs/ui/select/register` once (a side effect).
|
|
31
|
+
- Declared side effects: custom-element-registration.
|
|
32
|
+
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
Exact prop names and types: [`@kerfjs/ui/select`](../public-api-signatures-v1.md#kerfjsuiselect) in `public-api-signatures-v1.md`. Do not infer props from examples.
|
|
36
|
+
|
|
37
|
+
**Variants (configure, do not restyle):**
|
|
38
|
+
|
|
39
|
+
- placeholder
|
|
40
|
+
- disabled
|
|
41
|
+
- fit menu
|
|
42
|
+
- grouped
|
|
43
|
+
- custom selected content
|
|
44
|
+
- hint text
|
|
45
|
+
- placeholder (loading)
|
|
46
|
+
- form, toolbar-borderless, or navigation presentation
|
|
47
|
+
- default or compact size
|
|
48
|
+
- label or icon-only selected presentation
|
|
49
|
+
- select- or group-owned focus ring
|
|
50
|
+
- label maximum width and truncation
|
|
51
|
+
- multiple selection
|
|
52
|
+
- multiple icon-only filter trigger with a fixed triggerIcon
|
|
53
|
+
|
|
54
|
+
**CSS-value props** (typed builders from `@kerfjs/ui/css-values`; raw CSS strings are rejected):
|
|
55
|
+
|
|
56
|
+
- `choices[].color`: color grammar; raw values: forbid; helpers `uiColor`, `foregroundColorVar` — e.g. `color: uiColor("success-on-quiet")`
|
|
57
|
+
|
|
58
|
+
## Composition
|
|
59
|
+
|
|
60
|
+
- Parents: any.
|
|
61
|
+
- Contexts: `controlled-value-selection`.
|
|
62
|
+
- Children: unrestricted.
|
|
63
|
+
- Built from: [LucideIcon](./lucide-icon.md), [Badge](./badge.md), [Select](./wa-select.md), [Option](./wa-option.md).
|
|
64
|
+
|
|
65
|
+
## State and wiring
|
|
66
|
+
|
|
67
|
+
- value — controlled (required)
|
|
68
|
+
|
|
69
|
+
**Wiring:** `@kerfjs/ui/select/register` is required.
|
|
70
|
+
|
|
71
|
+
- Import the registration module once in the application.
|
|
72
|
+
|
|
73
|
+
## Geometry
|
|
74
|
+
|
|
75
|
+
Margin: none · border: self · padding: self (layout role: controls). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
|
|
76
|
+
|
|
77
|
+
## Accessibility
|
|
78
|
+
|
|
79
|
+
- Verify the live value, standard events, focus, and rendered output.
|
|
80
|
+
- A nonempty label names the internal combobox; otherwise ariaLabel supplies a visually hidden label without adding control height, including custom selected content.
|
|
81
|
+
- Hint text is visible below the control through Web Awesome's native hint relationship; placeholderText remains the empty value inside the closed control.
|
|
82
|
+
- Import select/register once; its scoped lifecycle adapter keeps the latest open/close request authoritative across animation reversals, canceled transitions, and removal. Do not add consumer popup timing or position repairs.
|
|
83
|
+
- With multiple, the popup stays open while choices toggle (pointer, Enter, or Space) and closes on an outside press, Escape, or focus leaving; each chosen option shows a check, and the closed control summarizes the chosen labels in choice order.
|
|
84
|
+
- A multiple icon-only trigger shows its fixed triggerIcon and, while any choice is chosen, an aria-hidden count Badge; the combobox's accessible name ends with the chosen labels in choice order, and its hidden value stays empty.
|
|
85
|
+
- Once registered, an icon-only trigger (single or multiple) shows an aria-hidden Web Awesome help tag repeating its accessible name (a single Select adds its current choice) after a 500ms hover and at once on keyboard focus; it hides while the popup is open, on a press, and on Escape, and never joins aria-labelledby. Do not add a title or another tooltip.
|
|
86
|
+
|
|
87
|
+
## Styling boundary
|
|
88
|
+
|
|
89
|
+
The component owns its own styles. Configure it through its props and variants; do not override its internals.
|
|
90
|
+
|
|
91
|
+
Public class hooks (select for layout placement only, never to change the component's look): `kui-select`, `kui-select--custom-selected`, `kui-select--fit-menu`, `kui-select--label-hidden`, `kui-select__custom-selected`, `kui-select__group`, `kui-select__group--separated`, `kui-select__group-title`, `kui-select__icon`.
|
|
92
|
+
|
|
93
|
+
Never put `kui-select`, `kui-select--custom-selected`, `kui-select--fit-menu`, `kui-select--label-hidden`, `kui-select__custom-selected`, `kui-select__group`, `kui-select__group--separated`, `kui-select__group-title`, `kui-select__icon` on an element you write; render `Select` instead (`KUI-L103`).
|
|
94
|
+
|
|
95
|
+
Public tokens it reads: `--kui-color-neutral-border-quiet`, `--kui-color-neutral-on-quiet`, `--kui-disclosure-icon-scale`, `--kui-font-2xs`. Set a token only where its public contract allows; prefer a prop.
|
|
96
|
+
|
|
97
|
+
Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
|
|
98
|
+
|
|
99
|
+
## Diagnostics
|
|
100
|
+
|
|
101
|
+
- `KUI-C107` (error) when the registration import is absent: Select requires @kerfjs/ui/select/register once per application.
|
|
102
|
+
|
|
103
|
+
## Related
|
|
104
|
+
|
|
105
|
+
- Components: [LucideIcon](./lucide-icon.md), [Badge](./badge.md), [Select](./wa-select.md), [Option](./wa-option.md), [SegmentedControl](./segmented-control.md), [Dropdown](./wa-dropdown.md).
|
|
106
|
+
- Docs: [`docs/component-selection.md`](../../docs/component-selection.md), [`docs/component-selection.md#web-awesome-overlap-policy`](../../docs/component-selection.md#web-awesome-overlap-policy).
|
|
107
|
+
- UX catalog route: `?component=select`.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Skeleton
|
|
2
|
+
|
|
3
|
+
<!-- Generated by scripts/sync-component-docs.mjs from ai/component-catalog.json and ai/component-composition.json. Do not edit; run `npm run catalog:sync`. -->
|
|
4
|
+
|
|
5
|
+
`@kerfjs/ui:skeleton` · Kerf UI · component · Feedback
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
A subtle, unanimated loading placeholder block for a not-yet-known value slot.
|
|
10
|
+
|
|
11
|
+
- Stand in for a value that is still loading, on its own or via a component's placeholder prop, keeping the surrounding layout stable.
|
|
12
|
+
- Placeholder a custom or free-text slot with the same visual the components' placeholder mode uses.
|
|
13
|
+
- Set width and height with typed length builders or finite intrinsic-size keywords; set radius with a typed length.
|
|
14
|
+
|
|
15
|
+
**Not when:**
|
|
16
|
+
|
|
17
|
+
- Do not use for known progress or a busy spinner; use LoadingSpinner.
|
|
18
|
+
- Do not animate it or use it as decorative filler.
|
|
19
|
+
- Do not pass raw CSS strings or cross property grammars into width, height, or radius.
|
|
20
|
+
|
|
21
|
+
**Alternatives:**
|
|
22
|
+
|
|
23
|
+
- [Skeleton](./wa-skeleton.md) (prefer-over)
|
|
24
|
+
|
|
25
|
+
## Imports
|
|
26
|
+
|
|
27
|
+
- JavaScript: `@kerfjs/ui/skeleton` — exports `Skeleton`.
|
|
28
|
+
- CSS: the browser build of `@kerfjs/ui/skeleton` pulls its CSS automatically; import `@kerfjs/ui/skeleton.css` manually only without the `browser` export condition.
|
|
29
|
+
- Declared side effects: browser-condition-css.
|
|
30
|
+
|
|
31
|
+
## Props
|
|
32
|
+
|
|
33
|
+
Exact prop names and types: [`@kerfjs/ui/skeleton`](../public-api-signatures-v1.md#kerfjsuiskeleton) in `public-api-signatures-v1.md`. Do not infer props from examples.
|
|
34
|
+
|
|
35
|
+
**Variants (configure, do not restyle):**
|
|
36
|
+
|
|
37
|
+
- block
|
|
38
|
+
- lines
|
|
39
|
+
- labeled
|
|
40
|
+
- typed width, height, and radius
|
|
41
|
+
|
|
42
|
+
**CSS-value props** (typed builders from `@kerfjs/ui/css-values`; raw CSS strings are rejected):
|
|
43
|
+
|
|
44
|
+
- `width`: size grammar; raw values: forbid; shorthands `auto`, `min-content`, `max-content`, `fit-content`; helpers `px`, `rem`, `em`, `pct`, `space`, `lengthVar`, `calc` — e.g. `width={em(12)}`
|
|
45
|
+
- `height`: size grammar; raw values: forbid; shorthands `auto`, `min-content`, `max-content`, `fit-content`; helpers `px`, `rem`, `em`, `pct`, `space`, `lengthVar`, `calc` — e.g. `height={em(1.5)}`
|
|
46
|
+
- `radius`: length grammar; raw values: forbid; helpers `px`, `rem`, `em`, `pct`, `space`, `lengthVar`, `calc` — e.g. `radius={px(999)}`
|
|
47
|
+
|
|
48
|
+
## Composition
|
|
49
|
+
|
|
50
|
+
- Parents: any.
|
|
51
|
+
- Contexts: `application-ui`.
|
|
52
|
+
- Children: unrestricted.
|
|
53
|
+
|
|
54
|
+
## State and wiring
|
|
55
|
+
|
|
56
|
+
**The app owns:** loading lifecycle; which slots are unknown; announcing the loading region.
|
|
57
|
+
|
|
58
|
+
No wiring helper.
|
|
59
|
+
|
|
60
|
+
## Geometry
|
|
61
|
+
|
|
62
|
+
Margin: none · border: none · padding: none (layout role: feedback). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
|
|
63
|
+
|
|
64
|
+
## Accessibility
|
|
65
|
+
|
|
66
|
+
- Decorative by default (aria-hidden); pass label to announce it as an image. A component in placeholder mode marks itself aria-busy and disables its own controls.
|
|
67
|
+
|
|
68
|
+
## Styling boundary
|
|
69
|
+
|
|
70
|
+
The component owns its own styles. Configure it through its props and variants; do not override its internals.
|
|
71
|
+
|
|
72
|
+
Public class hooks (select for layout placement only, never to change the component's look): `kui-skeleton`, `kui-skeleton-lines`.
|
|
73
|
+
|
|
74
|
+
Never put `kui-skeleton`, `kui-skeleton-lines` on an element you write; render `Skeleton` instead (`KUI-L103`).
|
|
75
|
+
|
|
76
|
+
Public tokens it reads: `--kui-skeleton-radius`. Set a token only where its public contract allows; prefer a prop.
|
|
77
|
+
|
|
78
|
+
Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
|
|
79
|
+
|
|
80
|
+
## Related
|
|
81
|
+
|
|
82
|
+
- Components: [Skeleton](./wa-skeleton.md).
|
|
83
|
+
- Docs: [`docs/component-selection.md`](../../docs/component-selection.md), [`docs/component-selection.md#problem-to-component-matrix`](../../docs/component-selection.md#problem-to-component-matrix).
|
|
84
|
+
- UX catalog route: `?component=skeleton`.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Spacer
|
|
2
|
+
|
|
3
|
+
<!-- Generated by scripts/sync-component-docs.mjs from ai/component-catalog.json and ai/component-composition.json. Do not edit; run `npm run catalog:sync`. -->
|
|
4
|
+
|
|
5
|
+
`@kerfjs/ui:spacer` · Kerf UI · component · Structure
|
|
6
|
+
|
|
7
|
+
A decorative, non-shrinking fixed gap or flexible main-axis spacer with typed physical width and height.
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
Express an intentional empty dimension or consume remaining flex space without application-owned spacer markup or raw CSS lengths.
|
|
12
|
+
|
|
13
|
+
- Reserve a fixed empty width or height from the UI spacing scale inside a layout.
|
|
14
|
+
- Push siblings to opposite ends of a Row or other flex container by passing flex.
|
|
15
|
+
- Use a typed CssLength when the finite spacing scale cannot express the required dimension.
|
|
16
|
+
|
|
17
|
+
**Not when:**
|
|
18
|
+
|
|
19
|
+
- Do not use Spacer for ordinary rhythm between siblings; prefer Row.gap or List.gap so the parent owns repeated spacing.
|
|
20
|
+
- Do not use Spacer to compensate for component-owned padding, margin, alignment, or responsive layout defects.
|
|
21
|
+
- Do not pass raw CSS strings to width or height.
|
|
22
|
+
|
|
23
|
+
**Alternatives:**
|
|
24
|
+
|
|
25
|
+
- [Row](./row.md) (parent-spacing-alternative) — Use Row.gap when every horizontal sibling needs the same repeated separation.
|
|
26
|
+
- [List](./list.md) (parent-spacing-alternative) — Use List.gap when every vertical sibling needs the same repeated separation.
|
|
27
|
+
|
|
28
|
+
## Imports
|
|
29
|
+
|
|
30
|
+
- JavaScript: `@kerfjs/ui/spacer` — exports `Spacer`.
|
|
31
|
+
- CSS: the browser build of `@kerfjs/ui/spacer` pulls its CSS automatically; import `@kerfjs/ui/spacer.css` manually only without the `browser` export condition.
|
|
32
|
+
- Declared side effects: browser-condition-css.
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
Exact prop names and types: [`@kerfjs/ui/spacer`](../public-api-signatures-v1.md#kerfjsuispacer) in `public-api-signatures-v1.md`. Do not infer props from examples.
|
|
37
|
+
|
|
38
|
+
**Variants (configure, do not restyle):**
|
|
39
|
+
|
|
40
|
+
- fixed named width and/or height
|
|
41
|
+
- fixed typed CssLength width and/or height
|
|
42
|
+
- flexible main-axis space
|
|
43
|
+
|
|
44
|
+
**CSS-value props** (typed builders from `@kerfjs/ui/css-values`; raw CSS strings are rejected):
|
|
45
|
+
|
|
46
|
+
- `width`: length grammar; raw values: forbid; shorthands `none`, `2xs`, `xs`, `m`, `l`; exceptional (justify) `s`, `xl`; helpers `px`, `rem`, `em`, `pct`, `space`, `lengthVar`, `calc` — e.g. `width="m"`
|
|
47
|
+
- `height`: length grammar; raw values: forbid; shorthands `none`, `2xs`, `xs`, `m`, `l`; exceptional (justify) `s`, `xl`; helpers `px`, `rem`, `em`, `pct`, `space`, `lengthVar`, `calc` — e.g. `height="xs"`
|
|
48
|
+
|
|
49
|
+
## Composition
|
|
50
|
+
|
|
51
|
+
- Parents: any.
|
|
52
|
+
- Contexts: `application-ui`.
|
|
53
|
+
- Children: unrestricted.
|
|
54
|
+
|
|
55
|
+
## State and wiring
|
|
56
|
+
|
|
57
|
+
**The app owns:** whether the empty space carries structural meaning; the named or typed dimensions; whether the spacer fills the flex main axis.
|
|
58
|
+
|
|
59
|
+
No wiring helper.
|
|
60
|
+
|
|
61
|
+
## Geometry
|
|
62
|
+
|
|
63
|
+
Margin: none · border: none · padding: none (layout role: structure). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
|
|
64
|
+
|
|
65
|
+
- A fixed Spacer does not shrink. flex changes its flex shorthand from 0 0 auto to 1 1 auto; width and height remain physical dimensions.
|
|
66
|
+
|
|
67
|
+
## Accessibility
|
|
68
|
+
|
|
69
|
+
- Spacer is always decorative and hidden from the accessibility tree.
|
|
70
|
+
- Spacer must not contain content or become an interaction target.
|
|
71
|
+
|
|
72
|
+
## Styling boundary
|
|
73
|
+
|
|
74
|
+
The component owns its own styles. Configure it through its props and variants; do not override its internals.
|
|
75
|
+
|
|
76
|
+
Public class hooks (select for layout placement only, never to change the component's look): `kui-spacer`.
|
|
77
|
+
|
|
78
|
+
Never put `kui-spacer` on an element you write; render `Spacer` instead (`KUI-L103`).
|
|
79
|
+
|
|
80
|
+
Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
|
|
81
|
+
|
|
82
|
+
## Related
|
|
83
|
+
|
|
84
|
+
- Components: [Row](./row.md), [List](./list.md).
|
|
85
|
+
- Docs: [`docs/layout.md`](../../docs/layout.md), [`docs/layout.md#spacer`](../../docs/layout.md#spacer).
|
|
86
|
+
- UX catalog route: `?component=spacer`.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# SplitView
|
|
2
|
+
|
|
3
|
+
<!-- Generated by scripts/sync-component-docs.mjs from ai/component-catalog.json and ai/component-composition.json. Do not edit; run `npm run catalog:sync`. -->
|
|
4
|
+
|
|
5
|
+
`@kerfjs/ui:split-view` · Kerf UI · component · Structure
|
|
6
|
+
|
|
7
|
+
A responsive list-detail layout that shows both panes on roomy device classes and collapses to a navigation stack on compact classes.
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
Present a selectable list and its detail together when space permits, with a one-pane drill-down replacement on compact devices.
|
|
12
|
+
|
|
13
|
+
- Selection in a primary list updates a related detail pane and both should remain visible on roomy device classes.
|
|
14
|
+
- The same list-detail flow must become a navigation stack on a handset or portrait tablet.
|
|
15
|
+
|
|
16
|
+
**Not when:**
|
|
17
|
+
|
|
18
|
+
- Do not use SplitView for a single linear flow; use NavStack.
|
|
19
|
+
- Do not use it for a complex desktop tool with multiple peripheral panels; use Workbench.
|
|
20
|
+
|
|
21
|
+
**Alternatives:**
|
|
22
|
+
|
|
23
|
+
- [Navigation stack](./recipe-navigation-stack.md) (responsive-alternative) — SplitView renders the one-pane navigation-stack form on compact device classes.
|
|
24
|
+
- [Workbench](./workbench.md) (nearest) — Use Workbench when a desktop-class tool needs more than the list and detail regions.
|
|
25
|
+
|
|
26
|
+
## Imports
|
|
27
|
+
|
|
28
|
+
- JavaScript: `@kerfjs/ui/split-view` — exports `SplitView`, `SplitViewProps`, `SplitViewResizable`, `SplitViewCompactStack`, `SplitViewCompactViewToolbars`.
|
|
29
|
+
- CSS: the browser build of `@kerfjs/ui/split-view` pulls its CSS automatically; import `@kerfjs/ui/split-view.css` manually only without the `browser` export condition.
|
|
30
|
+
- Wiring: `wireResizableRegions` from `@kerfjs/ui/wire-resizable-regions` (optional).
|
|
31
|
+
- Wiring: `wireNavStack` from `@kerfjs/ui/wire-nav-stack` (required).
|
|
32
|
+
- Declared side effects: browser-condition-css.
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
Exact prop names and types: [`@kerfjs/ui/split-view`](../public-api-signatures-v1.md#kerfjsuisplit-view), [`@kerfjs/ui/wire-resizable-regions`](../public-api-signatures-v1.md#kerfjsuiwire-resizable-regions), [`@kerfjs/ui/wire-nav-stack`](../public-api-signatures-v1.md#kerfjsuiwire-nav-stack) in `public-api-signatures-v1.md`. Do not infer props from examples.
|
|
37
|
+
|
|
38
|
+
**Variants (configure, do not restyle):**
|
|
39
|
+
|
|
40
|
+
- fixed roomy split
|
|
41
|
+
- resizable roomy split
|
|
42
|
+
- collapsed resizable list with a restore control
|
|
43
|
+
- compact list
|
|
44
|
+
- compact detail
|
|
45
|
+
- compact stack with configured toolbars
|
|
46
|
+
|
|
47
|
+
## Composition
|
|
48
|
+
|
|
49
|
+
- Parents: any.
|
|
50
|
+
- Contexts: `list-detail`, `responsive-master-detail`.
|
|
51
|
+
- Children: unrestricted.
|
|
52
|
+
- Built from: [NavStack](./nav-stack.md), [ResizableRegion](./resize.md).
|
|
53
|
+
|
|
54
|
+
Zones (a zone is bound to JSX only through its listed prop; never assume the zone id is a prop):
|
|
55
|
+
|
|
56
|
+
- `list` — JSX prop `list`; accepts `list-region`; exactly 1.
|
|
57
|
+
- `detail` — JSX prop `detail`; accepts `detail-region`; exactly 1.
|
|
58
|
+
|
|
59
|
+
## State and wiring
|
|
60
|
+
|
|
61
|
+
**The app owns:** device-class policy; selected item and detail-active state; list and detail content; optional list width and persistence; optional list collapse state and its restore control; compact list and detail toolbar groups, toolbar configuration, and chrome dividers; back action.
|
|
62
|
+
|
|
63
|
+
**Wiring:** `wireResizableRegions`, `wireNavStack` is required.
|
|
64
|
+
|
|
65
|
+
- Use wireNavStack as documented.
|
|
66
|
+
|
|
67
|
+
**Wiring-owned state attributes** — never render, remove, or branch on these as app state:
|
|
68
|
+
|
|
69
|
+
- `data-handle-inset` on `kui-resizable-region` (`wireResizableRegions`): Present while a clipping edge clamps the region: the handle and its focus ring sit inside the region instead of overhanging that edge.
|
|
70
|
+
- `data-resizing` on `kui-resizable-region` (`wireResizableRegions`): "true" during an active pointer drag of the handle.
|
|
71
|
+
- `data-nav-chrome-transition` on `kui-nav-stack` (`wireNavStack`): "true" while the chrome cross-fades between the outgoing and incoming view.
|
|
72
|
+
- `data-nav-chrome-copy` on `kui-nav-stack__chrome-copy` (`wireNavStack`): Marks the inert, aria-hidden snapshot of the outgoing chrome shown during the cross-fade.
|
|
73
|
+
- `data-nav-exiting` on `kui-nav-stack__view` (`wireNavStack`): "true" on a popped view the helper briefly re-inserts to slide it out.
|
|
74
|
+
|
|
75
|
+
## Geometry
|
|
76
|
+
|
|
77
|
+
Margin: none · border: self · padding: child (layout role: structure). `self` means the component already owns it — do not add wrapper padding, margin, or borders around it.
|
|
78
|
+
|
|
79
|
+
- The root owns the two-column split and the list pane owns its separator; list and detail content own their internal padding and scroll behavior.
|
|
80
|
+
|
|
81
|
+
## Accessibility
|
|
82
|
+
|
|
83
|
+
- Give the overall split and both meaningful panes accessible labels.
|
|
84
|
+
- Wire the compact back action and optional separator keyboard behavior, and restore focus when controlled navigation replaces a view.
|
|
85
|
+
|
|
86
|
+
## Styling boundary
|
|
87
|
+
|
|
88
|
+
The component owns its own styles. Configure it through its props and variants; do not override its internals.
|
|
89
|
+
|
|
90
|
+
Public class hooks (select for layout placement only, never to change the component's look): `kui-split-view`, `kui-split-view__list`, `kui-split-view__detail`, `kui-split-view--compact`.
|
|
91
|
+
|
|
92
|
+
Never put `kui-split-view`, `kui-split-view__list`, `kui-split-view__detail`, `kui-split-view--compact` on an element you write; render `SplitView` instead (`KUI-L103`).
|
|
93
|
+
|
|
94
|
+
Public tokens it reads: `--kui-split-view-list-width`. Set a token only where its public contract allows; prefer a prop.
|
|
95
|
+
|
|
96
|
+
Everything else is internal: `kerf-ui-analyze` reports private or unknown `.kui-*` selectors (`KUI-L001`, `KUI-L010`), unknown or private tokens (`KUI-L002`, `KUI-L012`), and any application rule that restyles the component, forced dimensions included (`KUI-L019`).
|
|
97
|
+
|
|
98
|
+
## Related
|
|
99
|
+
|
|
100
|
+
- Components: [NavStack](./nav-stack.md), [ResizableRegion](./resize.md), [Navigation stack](./recipe-navigation-stack.md), [Workbench](./workbench.md).
|
|
101
|
+
- Docs: [`docs/split-view.md`](../../docs/split-view.md), [`docs/app-layouts.md#decision-matrix`](../../docs/app-layouts.md#decision-matrix).
|
|
102
|
+
- UX catalog route: `?component=split-view`.
|