@kerfjs/ui 5.0.0-beta.56 → 5.0.0-beta.58
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 +81 -37
- 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 +211 -33
- 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 +102 -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 +174 -43
- 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 +8 -7
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-QQOTQTDD.js → chunk-2CCMJTVY.js} +13 -10
- package/dist/chunk-2CCMJTVY.js.map +1 -0
- 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-ZIYOJFZD.js → chunk-7JUBXOIV.js} +17 -4
- package/dist/chunk-7JUBXOIV.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-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-VNPQDCQZ.js → chunk-QOWG4ZCL.js} +3 -2
- package/dist/chunk-QOWG4ZCL.js.map +1 -0
- package/dist/{chunk-V65EOWNF.js → chunk-QPUPLNNB.js} +20 -8
- package/dist/chunk-QPUPLNNB.js.map +1 -0
- package/dist/{chunk-O3EXIBEZ.js → chunk-W4XKTST6.js} +8 -7
- package/dist/chunk-W4XKTST6.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 +9 -9
- 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 +11 -9
- 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-DqwtBxQL.d.ts} +13 -13
- 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-control-group.d.ts +3 -1
- package/dist/toolbar-control-group.js +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 +17 -16
- package/dist/workbench.js +1 -1
- package/docs/app-layouts.md +9 -1
- package/docs/catalog.md +10 -5
- package/docs/collapsible-panel.md +22 -13
- package/docs/component-contract.md +147 -21
- package/docs/component-selection.md +21 -8
- 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 +31 -20
- 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
- package/dist/chunk-ZIYOJFZD.js.map +0 -1
package/docs/workbench.md
CHANGED
|
@@ -9,9 +9,15 @@ desktop-class devices.
|
|
|
9
9
|
|
|
10
10
|
```ts
|
|
11
11
|
import { Workbench } from "@kerfjs/ui/workbench";
|
|
12
|
-
import "@kerfjs/ui/workbench.css";
|
|
13
12
|
```
|
|
14
13
|
|
|
14
|
+
In a browser bundler that honors the `browser` export condition (Vite, esbuild, and
|
|
15
|
+
webpack do by default), the import above also
|
|
16
|
+
loads Workbench's stylesheet and those of the components it renders internally
|
|
17
|
+
(`Pane`, `Toolbar`, `ToolbarControlGroup`, `FloatingToolbar`, `ResizableRegion`,
|
|
18
|
+
`List`, `LucideIcon`). Without that condition, import the manual stylesheets instead:
|
|
19
|
+
`@kerfjs/ui/workbench.css` plus those components' CSS, or `@kerfjs/ui/styles.css`.
|
|
20
|
+
|
|
15
21
|
A top-level `Workbench` needs a definite containing height. Import the opt-in
|
|
16
22
|
`@kerfjs/ui/document.css` baseline and add `.kui-app-root` to the direct mount
|
|
17
23
|
container, or provide an equivalent definite height in application-owned
|
|
@@ -152,22 +158,23 @@ A panel's controls follow it open and closed when the Workbench composes the
|
|
|
152
158
|
toolbars. Give a panel a `toolbar` and the work area a `mainToolbar` (and, for
|
|
153
159
|
a drawer, optionally a `mainBottomToolbar`); the Workbench renders each as a
|
|
154
160
|
standard `Toolbar` over a `Pane`, and moves groups between them as panels open
|
|
155
|
-
and close. A panel's `toolbar` has
|
|
161
|
+
and close. A panel's `toolbar` has these parts:
|
|
156
162
|
|
|
157
163
|
- `title` — the panel's `ToolbarText` (the quiet default size in a rail).
|
|
158
|
-
- `
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
164
|
+
- `leading`, `center`, and `trailing` — the open panel's toolbar zones. Put
|
|
165
|
+
`ToolbarControlGroup`s in any order in these zones. Mark a group with
|
|
166
|
+
`relocateOnCollapse` to make it available in the work area while the panel
|
|
167
|
+
is closed; unmarked groups remain in the inert panel. Pass marked groups
|
|
168
|
+
directly or in arrays, including nested arrays, rather than JSX fragments
|
|
169
|
+
so their render-time annotation remains available.
|
|
163
170
|
- `toggle: { action, name, showLabel?, hideLabel? }` — the standard collapse
|
|
164
171
|
toggle, which the Workbench renders: the per-side panel glyph,
|
|
165
172
|
`aria-controls` naming the panel, `aria-expanded`, a "Show …"/"Hide …"
|
|
166
173
|
label (or your localized `showLabel` / `hideLabel`), and the `data-action`
|
|
167
174
|
the app handles. It is always the last group.
|
|
168
|
-
- `center` — optional panel-only center content.
|
|
169
175
|
|
|
170
|
-
While a panel is closed,
|
|
176
|
+
While a panel is closed, marked groups follow their open-panel zone order
|
|
177
|
+
(`leading`, `center`, `trailing`), followed by its toggle:
|
|
171
178
|
|
|
172
179
|
| Panel | Where they go |
|
|
173
180
|
| ------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
@@ -191,8 +198,8 @@ toggle, so it never depends on a control it covers. An app's own
|
|
|
191
198
|
toolbar: {
|
|
192
199
|
label: "Navigator",
|
|
193
200
|
title: <ToolbarText text="Navigator" />,
|
|
194
|
-
|
|
195
|
-
|
|
201
|
+
leading: <NewFileGroup />,
|
|
202
|
+
trailing: <ToolbarControlGroup relocateOnCollapse label="Search files"><SearchButton /></ToolbarControlGroup>,
|
|
196
203
|
toggle: { action: "toggle-navigator", name: "navigator" },
|
|
197
204
|
},
|
|
198
205
|
content: <Files />,
|
|
@@ -215,10 +222,13 @@ Every toolbar the Workbench composes — `mainToolbar`, `mainBottomToolbar`, and
|
|
|
215
222
|
each panel's `toolbar` — takes the `Toolbar`'s configuration (`ToolbarConfig`):
|
|
216
223
|
`dividerSides`, `centerAlign`, `responsive`, `responsiveAt`, and
|
|
217
224
|
`safeAreaEdges`. Configure the toolbar through these props rather than styling
|
|
218
|
-
it.
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
225
|
+
it. No toolbar draws a divider by default: each `Pane` draws one line under
|
|
226
|
+
its header chrome and one over its footer chrome, wherever that chrome ends,
|
|
227
|
+
only while its content is scrolled beneath it (see
|
|
228
|
+
[Scroll dividers](./layout.md#scroll-dividers) — call `wireScrollDividers`
|
|
229
|
+
once at the app root). Set `dividerSides` only for a permanent separator edge,
|
|
230
|
+
or `chromeDividers: "always"` on the pane for a line that never hides.
|
|
231
|
+
`responsive: "wrap"` keeps a long title whole and wraps its actions
|
|
222
232
|
below it. `mainBottomToolbar` also takes a `center`. A panel's
|
|
223
233
|
`restorePosition` also places its floating restore controls.
|
|
224
234
|
|
|
@@ -226,7 +236,7 @@ The `Pane`s and `List`s the Workbench composes around your content are
|
|
|
226
236
|
configurable the same way:
|
|
227
237
|
|
|
228
238
|
- `mainPane` (`PaneConfig`: `contentElement`, `contentLabel`, `separators`,
|
|
229
|
-
`safeAreaEdges`) configures the work area's `Pane`, which exists whenever the
|
|
239
|
+
`safeAreaEdges`, `chromeDividers`) configures the work area's `Pane`, which exists whenever the
|
|
230
240
|
work area has a toolbar, `mainHeader`, or `mainFooter`;
|
|
231
241
|
- a panel's `pane` configures the `Pane` a `toolbar` panel's `content` renders
|
|
232
242
|
in — for example `{ contentElement: "nav", contentLabel: "Files" }` for a
|
|
@@ -235,12 +245,12 @@ configurable the same way:
|
|
|
235
245
|
`vAlign`, `dividerSides`, `textInsets`, `controlInsets`) configure the
|
|
236
246
|
`List`s holding `mainHeader` / `mainFooter`.
|
|
237
247
|
|
|
238
|
-
An omitted or `undefined` field keeps
|
|
239
|
-
|
|
248
|
+
An omitted or `undefined` field keeps the default, including the scroll
|
|
249
|
+
dividers described above.
|
|
240
250
|
|
|
241
251
|
Size a rail so its title and groups fit at its narrowest (a resizable rail's
|
|
242
252
|
`min`); a toolbar that cannot hold them drops the title rather than
|
|
243
|
-
truncating it.
|
|
253
|
+
truncating it. Relocated content renders in both places while the panel is
|
|
244
254
|
closed (the panel's copy is inert), so give it no `id`s. With `wireWorkbench`
|
|
245
255
|
given the panel's `collapsed` signal, focus follows the toggle: closing a
|
|
246
256
|
panel from its own toggle focuses the relocated toggle in the work area, and
|
|
@@ -523,7 +533,8 @@ when each policy applies.
|
|
|
523
533
|
|
|
524
534
|
## Public styling boundary
|
|
525
535
|
|
|
526
|
-
|
|
536
|
+
The component subpath's browser build loads `workbench.css`; import
|
|
537
|
+
`@kerfjs/ui/workbench.css` manually only without the `browser` condition. Applications may
|
|
527
538
|
set `--kui-workbench-rail-width` and `--kui-workbench-drawer-height` on a
|
|
528
539
|
Workbench instance. The supported composition classes are `.kui-workbench`,
|
|
529
540
|
`.kui-workbench__rail`, `.kui-workbench__rail--left`,
|
package/doctor/index.mjs
CHANGED
|
@@ -21,7 +21,11 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
21
21
|
import { createRequire } from 'node:module';
|
|
22
22
|
|
|
23
23
|
import { loadApplicationUiProfile } from '../ai/application-ui-profile.mjs';
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
analyzeUiProject,
|
|
26
|
+
UI_ANALYSIS_ACTIONS,
|
|
27
|
+
UI_ANALYSIS_RULES,
|
|
28
|
+
} from '../analyzer/index.mjs';
|
|
25
29
|
import { evaluateUi, UI_EVALUATION_RULES } from '../evaluator/index.mjs';
|
|
26
30
|
import {
|
|
27
31
|
isForeignRuleDefinitionDiagnostic,
|
|
@@ -547,6 +551,7 @@ function normalizeAnalyzer(report) {
|
|
|
547
551
|
evidence: item.evidence,
|
|
548
552
|
catalogFacts: item.chain,
|
|
549
553
|
action:
|
|
554
|
+
UI_ANALYSIS_ACTIONS[item.ruleId] ??
|
|
550
555
|
'Apply the catalog-declared composition or geometry boundary at this source location.',
|
|
551
556
|
meaning: UI_ANALYSIS_RULES[item.ruleId]?.title ?? item.ruleId,
|
|
552
557
|
}),
|
package/llms.txt
CHANGED
|
@@ -17,6 +17,17 @@ component per source file and one owned stylesheet per visual component. Keep it
|
|
|
17
17
|
compatibility entrypoints implementation-free: JavaScript/TypeScript only re-exports
|
|
18
18
|
the folder modules, and CSS only imports their owner stylesheets.
|
|
19
19
|
|
|
20
|
+
## The rule: components own their styles
|
|
21
|
+
|
|
22
|
+
Configure components through their typed props (size, density, inset,
|
|
23
|
+
presentation, `ToolbarConfig`, `PaneConfig`, …); never restyle one from outside.
|
|
24
|
+
No application or parent CSS may select a `.kui-*` class, a `[data-component]`
|
|
25
|
+
root, a `wa-*` element a Kerf component renders, or its `::part()`s, and no
|
|
26
|
+
writing another component's `--_kui-*` / `--kui-*` variables where a prop
|
|
27
|
+
exists. When a component adapts inside another, it styles itself in that
|
|
28
|
+
context in its own stylesheet. A missing prop is a component gap to report,
|
|
29
|
+
not a reason to override — and your own components follow the same rule.
|
|
30
|
+
|
|
20
31
|
## How to build a screen (retrieval order)
|
|
21
32
|
|
|
22
33
|
1. **Pick the component from the interface need**, not by appearance — read
|
|
@@ -25,20 +36,32 @@ the folder modules, and CSS only imports their owner stylesheets.
|
|
|
25
36
|
2. **Get exact signatures before emitting code** — read
|
|
26
37
|
[public-api-signatures-v1.md](./ai/public-api-signatures-v1.md) (real prop names,
|
|
27
38
|
callback shapes, disposer return types).
|
|
28
|
-
3. **
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
3. **Look up each component you use** in the
|
|
40
|
+
[component reference index](./ai/components/README.md) — one line per
|
|
41
|
+
entry — then read only those `ai/components/<id>.md` pages (1–7 KB each):
|
|
42
|
+
use/avoid, imports and side effects, a link to exact props, legal parents,
|
|
43
|
+
zones with their JSX prop and child count, app- and wiring-owned state,
|
|
44
|
+
geometry, accessibility, the styling boundary (configure through props;
|
|
45
|
+
never override internals), and `KUI-C###` diagnostics. Do not load the
|
|
46
|
+
large JSON catalogs just to choose or compose components; the pages are
|
|
47
|
+
generated from them.
|
|
48
|
+
**Tools and mechanical checks** use the JSON sources instead: the
|
|
49
|
+
[Machine-readable component catalog](./ai/component-catalog.json) (ids,
|
|
50
|
+
exports, variants, `publicClasses`, relationships, side effects, and
|
|
51
|
+
geometry ownership) — the canonical checked-in source; its schema is
|
|
52
|
+
alongside it. Also load the
|
|
32
53
|
consuming application's catalog extension when present; generate one from the
|
|
33
54
|
[Consumer catalog extension schema](./ai/component-catalog-extension.schema.json)
|
|
34
55
|
when app-owned components must participate in selection or alignment.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
56
|
+
A tool loads the [Composition catalog](./ai/component-composition.json) — a
|
|
57
|
+
generated composition layer beside the component catalog, not a replacement
|
|
58
|
+
for it — to mechanically evaluate parents, contexts, zones/cardinality,
|
|
59
|
+
children, state, wiring (including the wiring-owned `stateAttributes` an app
|
|
60
|
+
must never render or remove), responsive/layout/accessibility rules, and
|
|
61
|
+
public boundaries. The component catalog stays the selection and delivery
|
|
62
|
+
surface; the composition layer joins catalogs by `package:id`. Consumer
|
|
63
|
+
composition catalogs use
|
|
64
|
+
[the composition extension schema](./ai/component-composition-extension.schema.json).
|
|
42
65
|
Load [compile-time contracts](./ai/compile-time-contracts-v1.json) for stable
|
|
43
66
|
`KUI-T###` ids, exact declaration symbols, and the boundary between rejected
|
|
44
67
|
source states and relationships that still require runtime/catalog checks.
|
|
@@ -83,7 +106,10 @@ the folder modules, and CSS only imports their owner stylesheets.
|
|
|
83
106
|
prefer its canonical shorthand or typed helper over raw CSS strings; a
|
|
84
107
|
`--wa-color-{tone}-fill-loud` override without a governing `on-loud` (same
|
|
85
108
|
or ancestor scope, possibly in a co-loaded stylesheet), or whose literal
|
|
86
|
-
pair measures below 4.5:1, is review finding `KUI-L018` (set both);
|
|
109
|
+
pair measures below 4.5:1, is review finding `KUI-L018` (set both); CSS that restyles a component
|
|
110
|
+
(`KUI-L019`), touches its private `--_*` variables (`KUI-L020`), overrides a token a typed prop sets
|
|
111
|
+
(`KUI-L021`), or styles it through a hook class on its root (`KUI-L022`) is an error: configure the
|
|
112
|
+
component instead, and report a component gap when no prop exists; repair source-located errors until exit 0. Use full mode for release gates;
|
|
87
113
|
generated `dist`/`coverage`, dependency, cache, evidence, and nested-worktree
|
|
88
114
|
directories are excluded consistently from every static stage.
|
|
89
115
|
[`kerf-ui-analyze`](./docs/ui-analyzer.md) remains available when only static
|
|
@@ -98,6 +124,12 @@ the folder modules, and CSS only imports their owner stylesheets.
|
|
|
98
124
|
|
|
99
125
|
## Core rules (do the right thing)
|
|
100
126
|
|
|
127
|
+
- **Prefer a Kerf UI component over a Web Awesome component over a raw HTML
|
|
128
|
+
tag**, using each for what it is good at. Never render a `Discouraged` Web
|
|
129
|
+
Awesome element (`wa-dropdown`, `wa-button-group`, `wa-select`, `wa-tab-group`,
|
|
130
|
+
`wa-icon`, …) directly; reach it only through the Kerf component that wraps or
|
|
131
|
+
replaces it (`PopupMenu`, `SegmentedControl`, `Select`, `TabBar`,
|
|
132
|
+
`LucideIcon`), and file a component gap rather than dropping to the raw tag.
|
|
101
133
|
- **Reach for the primitive, not for CSS.** The package is built to look right
|
|
102
134
|
without an application customization layer. Before adding `padding`, `margin`,
|
|
103
135
|
`width`, `height`, `border`, `background`, a wrapper card, or a decoration,
|
|
@@ -210,12 +242,19 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
|
|
|
210
242
|
(`@kerfjs/ui/popup-menu`, registered once via `@kerfjs/ui/popup-menu/register`)
|
|
211
243
|
in a `single` `ToolbarControlGroup` with `nestedDropdown`; never hand-write
|
|
212
244
|
`wa-dropdown` markup for a menu. Let the group size the trigger from its icon,
|
|
213
|
-
localized text, and caret; do not force a dropdown or button width.
|
|
245
|
+
localized text, and caret; do not force a dropdown or button width. Nothing
|
|
246
|
+
wraps inside a group: an icon sits beside its label on one row, and a
|
|
247
|
+
`ToolbarText` is one ellipsized line unless you opt into `wrap`/`maxLines`. A
|
|
248
|
+
Select or PopupMenu trigger drops its focus ring while its popup is open and
|
|
249
|
+
the ring follows the control's shape; never add ring CSS. Compact
|
|
214
250
|
mixed groups keep standard item padding and raised selected chrome without an
|
|
215
251
|
internal separator; the selected item paints over the outer border. For an
|
|
216
252
|
avatar control, set `content="avatar"` and `avatarImage` on the group instead of
|
|
217
253
|
inserting an `img`; a lone control paints the group and a multi-button group
|
|
218
|
-
paints only its pressed highlight.
|
|
254
|
+
paints only its pressed highlight. Dividers earn their place: a `Toolbar`
|
|
255
|
+
draws none by default and pinned chrome gets its line from scroll state (see
|
|
256
|
+
the scroll-divider rule below); never fake one with a border or pad below a
|
|
257
|
+
divider to make it look right.
|
|
219
258
|
- **Use one direct toolbar composition for panel/dialog/page headings.** Put an
|
|
220
259
|
optional icon in a `ToolbarControlGroup`, an extra-large `ToolbarText` directly
|
|
221
260
|
in the leading zone, and actions in a trailing group. Supporting copy is
|
|
@@ -242,10 +281,29 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
|
|
|
242
281
|
radius minus `--kui-layout-highlight-inset`. Do not give an inner highlight an
|
|
243
282
|
unrelated radius.
|
|
244
283
|
- **Panes share one child-owned geometry.** Sidebars, main areas, inspectors, and
|
|
245
|
-
dialogs all
|
|
246
|
-
scrolling `.kui-pane__content`, optional
|
|
247
|
-
|
|
248
|
-
|
|
284
|
+
dialogs all render `Pane`: an unpadded `.kui-pane` (optional header, one
|
|
285
|
+
scrolling `.kui-pane__content`, optional footer). Never write a component's
|
|
286
|
+
anatomy classes onto your own element to recreate it (`KUI-L103`); only
|
|
287
|
+
the catalog's `placeableClasses` (layout utilities, `.kui-app-root`,
|
|
288
|
+
`.kui-content-item` on a non-div carrier) belong there. A visible pane owns
|
|
289
|
+
its collapse control (the last control of its last group); a hidden pane's
|
|
290
|
+
restore moves to the adjacent main toolbar's matching edge — no icon-only
|
|
291
|
+
rail — and a collapsed drawer's restore sits in the bottom toolbar or a
|
|
292
|
+
`FloatingToolbar` beside the drawer, near where its effect appears. Align
|
|
293
|
+
text to text and icons to icons across a pane; a border is decoration, never
|
|
294
|
+
the alignment anchor. Keep one scroll owner per region.
|
|
295
|
+
- **Dividers between pinned chrome and scrolling content are scroll state.**
|
|
296
|
+
Toolbars draw no divider by default. Call `wireScrollDividers(appRoot)`
|
|
297
|
+
(`@kerfjs/ui/wire-scroll-dividers`) once and keep its disposer: every `Pane`
|
|
298
|
+
then draws the line under its header only while content is scrolled beneath
|
|
299
|
+
it and the line over its footer only while more content lies below (never
|
|
300
|
+
when the content fits), every `NavStack`'s top chrome and bottom toolbar and
|
|
301
|
+
every `TabScaffold` bar do the same around the active view or scene, and
|
|
302
|
+
every `TabBar` marks each side of its strip with tabs scrolled out of view. Configure a pane with `chromeDividers`
|
|
303
|
+
(`scroll` default, `always`, `none`), and a `NavStack` or `TabScaffold`
|
|
304
|
+
with its own `chromeDividers` (same values; a `SplitView` forwards it through
|
|
305
|
+
`compactStack`); name app-owned chrome in `targets`.
|
|
306
|
+
Never add a border, or a permanent `dividerSides`, to fake one.
|
|
249
307
|
While a side overlay is open (a Workbench rail overlay, a `wireSidebar` compact
|
|
250
308
|
overlay, an overlay `CollapsiblePanel` or horizontal `ResizableRegion`), the
|
|
251
309
|
layout hides the covered work area's `FloatingToolbar`s and restore corners
|
|
@@ -264,7 +322,9 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
|
|
|
264
322
|
(mark a preferred new-view target with `data-nav-focus`), `wireTabBars` the
|
|
265
323
|
overflow autoscroll, drag preview, and
|
|
266
324
|
replacement focus after controlled automatic tab activation,
|
|
267
|
-
`wireResizableRegions` the live drag preview
|
|
325
|
+
`wireResizableRegions` the live drag preview, `wireScrollDividers` the
|
|
326
|
+
scroll-state attributes from which a `Pane` draws its chrome dividers and a
|
|
327
|
+
`TabBar` its overflow dividers; they report committed changes via
|
|
268
328
|
callbacks. For a tab-local action plus a separate far-edge action, set
|
|
269
329
|
`TabBar trailingPlacement="adjacent"`, put the local action in `trailing`, and
|
|
270
330
|
the workspace action in `end`; the component keeps both visible while its tab
|
|
@@ -326,9 +386,13 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
|
|
|
326
386
|
`ListInsetText`, `SegmentedControl`,
|
|
327
387
|
`Select`, `TokenSearchField` (+ `readTokenSearchField`, `placeTokenSearchCaret`,
|
|
328
388
|
`wireTokenSearchFields`), `AppTab`, `TabBar` (+ `wireTabBars`, `reorderTabs`),
|
|
389
|
+
`wireScrollDividers` (scroll-state dividers for every `Pane`, `NavStack`,
|
|
390
|
+
`TabScaffold`, and `TabBar`),
|
|
329
391
|
`ResizableRegion` (+ `wireResizableRegions`), `StateBanner`, `EmptyState`,
|
|
330
392
|
`LoadingSpinner`, `Skeleton`, `ValueTable`, `ValueTableRow`. Whole-screen layouts (opt-in,
|
|
331
|
-
tree-shakeable, declarative with `wire…` helpers
|
|
393
|
+
tree-shakeable, declarative with `wire…` helpers; the browser build of each layout
|
|
394
|
+
subpath loads its CSS and that of the components it renders, and a companion
|
|
395
|
+
CSS subpath remains for pipelines without the `browser` condition):
|
|
332
396
|
`NavStack`, `SplitView`, `Workbench`, `TabScaffold`, driven by `deviceClass()` from
|
|
333
397
|
`@kerfjs/ui/device-class`. For a standalone collapsible rail/drawer outside a full
|
|
334
398
|
shell, `@kerfjs/ui/collapsible-panel` (`CollapsiblePanel`, `CollapsiblePanelToggle`)
|
|
@@ -357,6 +421,7 @@ shell, `@kerfjs/ui/collapsible-panel` (`CollapsiblePanel`, `CollapsiblePanelTogg
|
|
|
357
421
|
- [workbench.md](./docs/workbench.md): the `Workbench` multi-panel shell, its collapse policies, and opt-in `resizable` panels driven by `wireWorkbench` (`@kerfjs/ui/wire-workbench`: drag, keyboard, min/max, persistence, compact suspension), the `mainMinSize` / `mainMinHeight` work-area minimums (default 320px wide beside any inline rail, 120px tall above the drawer) that resizable panels stop at and inline panels shrink around, and a panel's `responsiveOverlayAt` (`narrow` / `compact`, rails and the bottom drawer) that presents it as an overlay below a Workbench container breakpoint without a device-class check; a panel given its `collapsed` signal is a transient overlay (collapsed on entering the breakpoint, takes focus and keeps Tab inside while open, closed by Escape or an outside press, focus returned; `dismissOverlays`), and overlays are exclusive by default (opening one closes the others; `exclusiveOverlays: false` opts out).
|
|
358
422
|
- [app-layouts.md](./docs/app-layouts.md): choosing `NavStack`/`SplitView`/`Workbench`/`TabScaffold` by data + interaction + device, and dialog presentation, plus the safe-area model (surfaces paint through unsafe areas; content pads only the edges it reaches; `Pane.safeAreaEdges` for app-owned arrangements, `Toolbar.safeAreaEdges` for an app bar or bottom bar at a screen edge).
|
|
359
423
|
- [webawesome-theme.md](./docs/webawesome-theme.md): the optional Web Awesome theme; catalog coverage means themed-and-supported, not preferred (prefer the Kerf primitive when one exists). The UX sidebar visibly tags superseded and exceptional Web Awesome choices as `Discouraged`; Popup remains an available conditional positioning primitive.
|
|
424
|
+
- [ai/components/README.md](./ai/components/README.md): the generated per-component markdown reference — the assistant entry point over both JSON catalogs.
|
|
360
425
|
- [component-catalog.json](./ai/component-catalog.json) + [component-catalog-extension.schema.json](./ai/component-catalog-extension.schema.json) + [catalog-authoring.json](./ai/catalog-authoring.json) + [public-api-signatures-v1.md](./ai/public-api-signatures-v1.md) + [webawesome-jsx-signatures-v1.md](./ai/webawesome-jsx-signatures-v1.md): machine-readable selection facts, a reusable app-component extension contract, Catalog authoring discovery, and exact signatures.
|
|
361
426
|
- [compile-time-contracts-v1.json](./ai/compile-time-contracts-v1.json) + [type-contracts.md](./docs/type-contracts.md): stable compile diagnostics, packed-declaration proof, migrations, and explicit non-goals.
|
|
362
427
|
- [README.md](./README.md): package overview and the component subpath table.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kerfjs/ui",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.58",
|
|
4
4
|
"description": "Accessible, composable UI primitives for kerf applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -165,6 +165,7 @@
|
|
|
165
165
|
},
|
|
166
166
|
"./catalog": {
|
|
167
167
|
"types": "./dist/catalog.d.ts",
|
|
168
|
+
"browser": "./dist/browser/catalog.js",
|
|
168
169
|
"import": "./dist/catalog.js"
|
|
169
170
|
},
|
|
170
171
|
"./catalog-resources": {
|
|
@@ -200,8 +201,13 @@
|
|
|
200
201
|
"types": "./dist/wire-tab-bars.d.ts",
|
|
201
202
|
"import": "./dist/wire-tab-bars.js"
|
|
202
203
|
},
|
|
204
|
+
"./wire-scroll-dividers": {
|
|
205
|
+
"types": "./dist/wire-scroll-dividers.d.ts",
|
|
206
|
+
"import": "./dist/wire-scroll-dividers.js"
|
|
207
|
+
},
|
|
203
208
|
"./nav-stack": {
|
|
204
209
|
"types": "./dist/nav-stack.d.ts",
|
|
210
|
+
"browser": "./dist/browser/nav-stack.js",
|
|
205
211
|
"import": "./dist/nav-stack.js"
|
|
206
212
|
},
|
|
207
213
|
"./wire-nav-stack": {
|
|
@@ -210,6 +216,7 @@
|
|
|
210
216
|
},
|
|
211
217
|
"./split-view": {
|
|
212
218
|
"types": "./dist/split-view.d.ts",
|
|
219
|
+
"browser": "./dist/browser/split-view.js",
|
|
213
220
|
"import": "./dist/split-view.js"
|
|
214
221
|
},
|
|
215
222
|
"./pane": {
|
|
@@ -219,10 +226,12 @@
|
|
|
219
226
|
},
|
|
220
227
|
"./workbench": {
|
|
221
228
|
"types": "./dist/workbench.d.ts",
|
|
229
|
+
"browser": "./dist/browser/workbench.js",
|
|
222
230
|
"import": "./dist/workbench.js"
|
|
223
231
|
},
|
|
224
232
|
"./collapsible-panel": {
|
|
225
233
|
"types": "./dist/collapsible-panel.d.ts",
|
|
234
|
+
"browser": "./dist/browser/collapsible-panel.js",
|
|
226
235
|
"import": "./dist/collapsible-panel.js"
|
|
227
236
|
},
|
|
228
237
|
"./wire-sidebar": {
|
|
@@ -231,6 +240,7 @@
|
|
|
231
240
|
},
|
|
232
241
|
"./tab-scaffold": {
|
|
233
242
|
"types": "./dist/tab-scaffold.d.ts",
|
|
243
|
+
"browser": "./dist/browser/tab-scaffold.js",
|
|
234
244
|
"import": "./dist/tab-scaffold.js"
|
|
235
245
|
},
|
|
236
246
|
"./wire-tab-scaffold": {
|
|
@@ -385,12 +395,12 @@
|
|
|
385
395
|
"format": "prettier --write . --ignore-unknown",
|
|
386
396
|
"format:css": "prettier --write \"src/**/*.css\" \"ux-demo/**/*.css\"",
|
|
387
397
|
"check:format": "prettier --check . --ignore-unknown",
|
|
388
|
-
"catalog:sync": "node scripts/sync-component-catalog.mjs && node scripts/sync-component-
|
|
389
|
-
"
|
|
398
|
+
"catalog:sync": "node scripts/sync-component-catalog.mjs && node scripts/sync-component-composition.mjs && node scripts/sync-component-docs.mjs",
|
|
399
|
+
"composition:sync": "node scripts/sync-component-composition.mjs && node scripts/sync-component-docs.mjs",
|
|
390
400
|
"check:component-integrations": "node scripts/check-component-integrations.mjs",
|
|
391
401
|
"component-integrations:dry-run": "node scripts/check-component-integrations.mjs --dry-run",
|
|
392
402
|
"check:change": "node scripts/check-ui-change.mjs",
|
|
393
|
-
"check:catalog": "node scripts/sync-component-catalog.mjs --check && node scripts/sync-component-
|
|
403
|
+
"check:catalog": "node scripts/sync-component-catalog.mjs --check && node scripts/sync-component-composition.mjs --check && node scripts/sync-component-docs.mjs --check && node scripts/check-component-catalog.mjs",
|
|
394
404
|
"check:profile": "node scripts/check-application-ui-profile.mjs",
|
|
395
405
|
"check:demo-conformance": "node scripts/check-catalog-demo-conformance.mjs",
|
|
396
406
|
"check:recipes": "node scripts/check-recipes.mjs",
|
|
@@ -402,6 +412,7 @@
|
|
|
402
412
|
"ai:compatibility:sync": "node scripts/sync-ai-compatibility.mjs --write",
|
|
403
413
|
"ai:regressions:compile": "node scripts/compile-ai-regression-response.mjs",
|
|
404
414
|
"ai:regressions:prepare": "node scripts/prepare-ai-regression.mjs",
|
|
415
|
+
"ai:regressions:measure-context": "node scripts/measure-ai-regression-context.mjs",
|
|
405
416
|
"ai:regressions:record": "node scripts/record-ai-regression-run.mjs",
|
|
406
417
|
"ai:regressions:record-v3": "node scripts/record-ai-regression-run-v3.mjs",
|
|
407
418
|
"ai:regressions:replay-v3": "node scripts/replay-ai-regression-run-v3.mjs",
|
|
@@ -410,12 +421,13 @@
|
|
|
410
421
|
"lint:eslint": "eslint src tests ux-demo docs/examples --max-warnings 0",
|
|
411
422
|
"lint": "npm run lint:eslint && npm run check:format",
|
|
412
423
|
"typecheck": "node node_modules/typescript7/bin/tsc --noEmit",
|
|
413
|
-
"test": "npm run test:unit && npm run test:bundle && npm run test:analyzer && npm run test:doctor && npm run test:evaluator",
|
|
424
|
+
"test": "npm run test:unit && npm run test:bundle && npm run test:analyzer && npm run test:doctor && npm run test:evaluator && npm run test:ai-regressions",
|
|
414
425
|
"test:unit": "vitest run tests/unit --coverage",
|
|
415
426
|
"test:bundle": "npm run build && vitest run tests/bundle",
|
|
416
427
|
"test:analyzer": "vitest run tests/integration/ui-analyzer-downstream.test.ts",
|
|
417
428
|
"test:doctor": "vitest run tests/unit/ui-doctor.test.ts tests/integration/ui-doctor-downstream.test.ts",
|
|
418
429
|
"test:evaluator": "vitest run tests/unit/ui-evaluator.test.ts tests/integration/ui-evaluator-downstream.test.ts",
|
|
430
|
+
"test:ai-regressions": "vitest run tests/integration/ai-regressions-v3.test.ts",
|
|
419
431
|
"test:contract-types:source": "node node_modules/typescript7/bin/tsc -p tests/consumer-types/contracts/tsconfig.source.json",
|
|
420
432
|
"test:contract-types:packed": "node scripts/check-packed-type-contracts.mjs",
|
|
421
433
|
"test:consumer-types": "npm run test:contract-types:source && npm run build && node node_modules/typescript7/bin/tsc -p tests/consumer-types/webawesome/tsconfig.json && npm run test:contract-types:packed",
|
|
@@ -114,7 +114,6 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
114
114
|
header={
|
|
115
115
|
<Toolbar
|
|
116
116
|
label="Recent projects"
|
|
117
|
-
dividerSides=""
|
|
118
117
|
leading={<ToolbarText text="Recent projects" />}
|
|
119
118
|
/>
|
|
120
119
|
}
|
|
@@ -131,7 +130,6 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
131
130
|
header={
|
|
132
131
|
<Toolbar
|
|
133
132
|
label="Project details"
|
|
134
|
-
dividerSides=""
|
|
135
133
|
leading={
|
|
136
134
|
<ToolbarText
|
|
137
135
|
text={record.name}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://raw.githubusercontent.com/brianwestphal/kerf/main/ui/ai/component-catalog-extension-v2.schema.json",
|
|
4
|
-
"title": "Kerf UI consumer composition catalog extension v2",
|
|
5
|
-
"allOf": [{ "$ref": "./component-catalog-v2.schema.json" }],
|
|
6
|
-
"description": "Consumer catalogs use the v2 entry contract with their own non-empty package identity; keys are always package:id."
|
|
7
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pane.tsx"],"names":[],"mappings":"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","file":"chunk-AK67F6QN.js","sourcesContent":["import { filterDataAttributes } from './extension-attributes.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\n/**\n * Logical pane sides: where a {@link Pane} can show a separator and where it can\n * compensate for a device safe-area inset.\n */\nexport type PaneSeparatorSide =\n 'block-start' | 'block-end' | 'inline-start' | 'inline-end';\n\n/** Semantic root elements supported by {@link Pane}. */\nexport type PaneElement = 'article' | 'aside' | 'div' | 'main' | 'section';\n\n/** Semantic elements supported by the scrolling content slot. */\nexport type PaneContentElement = 'div' | 'main' | 'nav' | 'section';\n\nconst paneProtectedAttributes = new Set([\n 'data-component',\n 'data-chrome-placement',\n 'data-separator-block-start',\n 'data-separator-block-end',\n 'data-separator-inline-start',\n 'data-separator-inline-end',\n 'data-safe-area-block-start',\n 'data-safe-area-block-end',\n 'data-safe-area-inline-start',\n 'data-safe-area-inline-end',\n]);\n\nconst allPaneSides: readonly PaneSeparatorSide[] = [\n 'block-start',\n 'block-end',\n 'inline-start',\n 'inline-end',\n];\n\ntype PaneRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-separator-block-start'?: never;\n 'data-separator-block-end'?: never;\n 'data-separator-inline-start'?: never;\n 'data-separator-inline-end'?: never;\n 'data-safe-area-block-start'?: never;\n 'data-safe-area-block-end'?: never;\n 'data-safe-area-inline-start'?: never;\n 'data-safe-area-inline-end'?: never;\n 'data-chrome-placement'?: never;\n }\n>;\n\n/** How a Pane's header and footer relate to its scrolling content. */\nexport type PaneChromePlacement = 'fixed' | 'auto';\n\nexport interface PaneProps {\n /** Optional fixed chrome above the scrolling content, arranged vertically. */\n header?: KerfUiContent;\n /** The pane's primary vertical, scrolling content stack. */\n children?: KerfUiContent;\n /** Optional fixed chrome below the scrolling content. */\n footer?: KerfUiContent;\n /**\n * Whether the header and footer stay pinned around the scrolling content.\n * `fixed` (default) always pins them. `auto` pins them while the pane is\n * tall enough, and below 480px of height (30rem, so it scales with the text\n * size) lets the whole pane scroll as one column, so tall chrome can never\n * squeeze the content to nothing.\n */\n chromePlacement?: PaneChromePlacement;\n /** Root semantics. Defaults to `div`. */\n element?: PaneElement;\n /** Scrolling content semantics. Defaults to `div`. */\n contentElement?: PaneContentElement;\n /** Independent logical-edge separator lines. Defaults to none. */\n separators?: readonly PaneSeparatorSide[];\n /**\n * Sides on which the pane may compensate for a device safe-area inset.\n * Defaults to every side: the pane pads its slots for each side that still\n * reaches an unsafe screen edge, as its surrounding layout reports, while its\n * background and separators paint through. List only the sides an app-owned\n * layout places at a screen edge, or pass `[]` to opt out.\n */\n safeAreaEdges?: readonly PaneSeparatorSide[];\n id?: string;\n /** Accessible name for a landmark root such as `aside` or `main`. */\n label?: string;\n /** Accessible name for a landmark scrolling slot such as `nav`. */\n contentLabel?: string;\n className?: string;\n headerClassName?: string;\n contentClassName?: string;\n footerClassName?: string;\n /** Safe `data-*` metadata; Pane-owned structural attributes remain protected. */\n rootAttributes?: PaneRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A pane's configuration, apart from its content and styling hooks: the props a\n * composite that renders a `Pane` for the app (a Workbench panel or work area,\n * or a CollapsiblePanel) forwards, so the app configures that pane instead of\n * styling it. An omitted or `undefined` field keeps the composite's default.\n */\nexport type PaneConfig = Pick<\n PaneProps,\n 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges'\n>;\n\nfunction paneContent(\n element: PaneContentElement,\n children: KerfUiContent,\n className: string,\n label: string | undefined,\n) {\n const attributes = {\n class: `kui-pane__content kui-content ${className}`.trim(),\n 'aria-label': label,\n };\n if (element === 'main') return <main {...attributes}>{children}</main>;\n if (element === 'nav') return <nav {...attributes}>{children}</nav>;\n if (element === 'section')\n return <section {...attributes}>{children}</section>;\n return <div {...attributes}>{children}</div>;\n}\n\n/**\n * An unpadded application column with optional fixed header/footer slots and one\n * scrolling vertical content owner. Separator lines are independently opt-in on\n * each logical edge, so the same component works as a sidebar, main area,\n * inspector, or dialog column.\n */\nexport function Pane({\n header,\n children,\n footer,\n chromePlacement = 'fixed',\n element = 'div',\n contentElement = 'div',\n separators = [],\n safeAreaEdges = allPaneSides,\n id,\n label,\n contentLabel,\n className = '',\n headerClassName = '',\n contentClassName = '',\n footerClassName = '',\n rootAttributes = {},\n slot,\n}: PaneProps) {\n const safeRootAttributes = filterDataAttributes(\n rootAttributes,\n paneProtectedAttributes,\n );\n const content = paneContent(\n contentElement,\n children,\n contentClassName,\n contentLabel,\n );\n const body = (\n <>\n {header === undefined ? null : (\n <header\n class={`kui-pane__header kui-pane__toolbar ${headerClassName}`.trim()}\n >\n {header}\n </header>\n )}\n {content}\n {footer === undefined ? null : (\n <footer class={`kui-pane__footer ${footerClassName}`.trim()}>\n {footer}\n </footer>\n )}\n </>\n );\n const attributes = {\n ...safeRootAttributes,\n class: `kui-pane ${className}`.trim(),\n id,\n 'data-component': 'pane',\n 'data-chrome-placement': chromePlacement === 'auto' ? 'auto' : undefined,\n 'data-separator-block-start': String(separators.includes('block-start')),\n 'data-separator-block-end': String(separators.includes('block-end')),\n 'data-separator-inline-start': String(separators.includes('inline-start')),\n 'data-separator-inline-end': String(separators.includes('inline-end')),\n 'data-safe-area-block-start': String(safeAreaEdges.includes('block-start')),\n 'data-safe-area-block-end': String(safeAreaEdges.includes('block-end')),\n 'data-safe-area-inline-start': String(\n safeAreaEdges.includes('inline-start'),\n ),\n 'data-safe-area-inline-end': String(safeAreaEdges.includes('inline-end')),\n 'aria-label': label,\n slot,\n };\n\n if (element === 'article') return <article {...attributes}>{body}</article>;\n if (element === 'aside') return <aside {...attributes}>{body}</aside>;\n if (element === 'main') return <main {...attributes}>{body}</main>;\n if (element === 'section') return <section {...attributes}>{body}</section>;\n return <div {...attributes}>{body}</div>;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/toolbar.tsx"],"names":[],"mappings":";;;AA0DA,IAAM,KAAA,GAAQ,CACZ,KAAA,EACA,IAAA,KACI,OAAO,QAAA,CAAS,IAAI,IAAI,MAAA,GAAS,MAAA;AAEhC,SAAS,OAAA,CAAQ;AAAA,EACtB,OAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA,GAAe,GAAA;AAAA,EACf,WAAA,GAAc,QAAA;AAAA,EACd,UAAA,GAAa,MAAA;AAAA,EACb,YAAA,GAAe,QAAA;AAAA,EACf,aAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAiB;AACf,EAAA,uBACE,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,YAAA,EAAe,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACvC,gBAAA,EAAe,SAAA;AAAA,MACf,iBAAe,YAAA,IAAgB,MAAA;AAAA,MAC/B,iBAAA,EAAiB,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAC,CAAA;AAAA,MACvC,mBAAA,EAAmB,WAAA;AAAA,MACnB,iBAAA,EAAiB,UAAA;AAAA,MACjB,oBAAA,EAAoB,YAAA;AAAA,MACpB,4BAAA,EAA4B,KAAA,CAAM,aAAA,EAAe,aAAa,CAAA;AAAA,MAC9D,0BAAA,EAA0B,KAAA,CAAM,aAAA,EAAe,WAAW,CAAA;AAAA,MAC1D,6BAAA,EAA6B,KAAA,CAAM,aAAA,EAAe,cAAc,CAAA;AAAA,MAChE,2BAAA,EAA2B,KAAA,CAAM,aAAA,EAAe,YAAY,CAAA;AAAA,MAC5D,YAAA,EAAY,KAAA;AAAA,MACZ,IAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,sBAAA,EAAwB,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,wBAC3C,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,qBAAA,EAAuB,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,wBACzC,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,uBAAA,EAAyB,QAAA,EAAA,QAAA,EAAS;AAAA;AAAA;AAAA,GAC/C;AAEJ","file":"chunk-G33XC2NB.js","sourcesContent":["import type { PaneSeparatorSide } from './pane.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport type { Sides } from './sides.js';\n\nexport interface ToolbarProps {\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n label?: string;\n /** Physical divider edges in canonical top/right/bottom/left order. Defaults to bottom. */\n dividerSides?: Sides;\n /** Horizontal treatment of the center zone. Defaults to centered content. */\n centerAlign?: 'center' | 'stretch';\n /**\n * Component-owned responsive layout; applications choose the policy rather\n * than restyling toolbar internals. Under every policy the trailing zone\n * wraps its groups instead of clipping an action, and the center zone keeps\n * its whole content width: when the zones do not fit one row, the leading\n * title truncates with an ellipsis rather than the center overlapping it.\n * - `none` keeps one row; the leading identity truncates first.\n * - `stack` stacks the zones at `responsiveAt`, wrapping stacked control\n * groups onto further rows.\n * - `wrap` keeps one row while every zone fits at its natural width, and\n * otherwise moves the trailing zone below a whole leading identity.\n * - `center-priority` gives an expanded center control the full row.\n */\n responsive?: 'none' | 'stack' | 'wrap' | 'center-priority';\n /** Container width at which `responsive=\"stack\"` activates. */\n responsiveAt?: 'compact' | 'narrow';\n /**\n * Screen edges this toolbar claims for device safe-area compensation, for an\n * app bar or bottom bar that sits directly at a screen edge rather than in a\n * Pane header or footer. Each listed side pads by the inset its surrounding\n * layout reports through `--kui-edge-inset-*`, or the full device inset when\n * nothing routes that edge, while the toolbar's box and dividers paint\n * through. Omitted, the toolbar pads only the inline edges an owner such as\n * a Pane header hands it, and never a block edge.\n */\n safeAreaEdges?: readonly PaneSeparatorSide[];\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A toolbar's configuration, apart from its content: the props a composite\n * that renders a `Toolbar` for the app (a Workbench or CollapsiblePanel\n * toolbar) forwards, so the app configures that toolbar instead of styling it.\n */\nexport type ToolbarConfig = Pick<\n ToolbarProps,\n | 'dividerSides'\n | 'centerAlign'\n | 'responsive'\n | 'responsiveAt'\n | 'safeAreaEdges'\n>;\n\nconst claim = (\n edges: readonly PaneSeparatorSide[] | undefined,\n side: PaneSeparatorSide,\n) => (edges?.includes(side) ? 'true' : undefined);\n\nexport function Toolbar({\n leading,\n center,\n trailing,\n label,\n dividerSides = 'b',\n centerAlign = 'center',\n responsive = 'none',\n responsiveAt = 'narrow',\n safeAreaEdges,\n className = '',\n slot,\n}: ToolbarProps) {\n return (\n <header\n class={`kui-toolbar ${className}`.trim()}\n data-component=\"toolbar\"\n divider-sides={dividerSides || undefined}\n data-has-center={String(Boolean(center))}\n data-center-align={centerAlign}\n data-responsive={responsive}\n data-responsive-at={responsiveAt}\n data-safe-area-block-start={claim(safeAreaEdges, 'block-start')}\n data-safe-area-block-end={claim(safeAreaEdges, 'block-end')}\n data-safe-area-inline-start={claim(safeAreaEdges, 'inline-start')}\n data-safe-area-inline-end={claim(safeAreaEdges, 'inline-end')}\n aria-label={label}\n slot={slot}\n >\n <div class=\"kui-toolbar__leading\">{leading}</div>\n <div class=\"kui-toolbar__center\">{center}</div>\n <div class=\"kui-toolbar__trailing\">{trailing}</div>\n </header>\n );\n}\n\nexport type { Sides } from './sides.js';\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/toolbar-text.tsx"],"names":[],"mappings":";;;;AA8CO,SAAS,WAAA,CAAY;AAAA,EAC1B,IAAA;AAAA,EACA,IAAA,GAAO,SAAA;AAAA,EACP,SAAA,GAAY,EAAA;AAAA,EACZ,EAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,IAAA,GAAO,KAAA;AAAA,EACP,QAAA,GAAW,IAAA;AAAA,EACX,QAAA,GAAW,IAAA;AAAA,EACX;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,MAAA,GAAS,IAAA,IAAQ,QAAA,IAAY,IAAA,IAAQ,QAAA,GAAW,CAAA;AACtD,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC5C,gBAAA,EAAe,cAAA;AAAA,MACf,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAW,OAAO,MAAA,GAAS,MAAA;AAAA,MAC3B,eAAA,EAAe,WAAW,MAAA,GAAY,OAAA;AAAA,MACtC,gBAAA,EAAgB,MAAA,GAAS,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA;AAAA,MAC5C,KAAA,EAAO,MAAA,GAAS,CAAA,6BAAA,EAAgC,QAAQ,CAAA,CAAA,GAAK,MAAA;AAAA,MAC7D,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,MACzC,EAAA;AAAA,MACA,IAAA,EAAM,eAAe,SAAA,GAAY,MAAA;AAAA,MACjC,YAAA,EAAY,YAAA,GAAe,MAAA,CAAO,YAAY,CAAA,GAAI,MAAA;AAAA,MAClD,WAAA,EAAW,cAAc,MAAA,GAAS,MAAA;AAAA,MAClC,IAAA;AAAA,MAEC,QAAA,EAAA,WAAA,mBACC,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAO,EAAA,CAAG,CAAC,CAAA,EAAG,CAAA,mBAExB,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,wBAAA,EAA0B,QAAA,EAAA,IAAA,EAAK;AAAA;AAAA,GAE/C;AAEJ","file":"chunk-K6UNVKDK.js","sourcesContent":["import { em } from './css-values.js';\nimport { Skeleton } from './skeleton.js';\n\nexport type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small';\n\n/** ARIA heading level for a title exposed as a heading landmark. */\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\ninterface ToolbarTextBaseProps {\n text: string;\n size?: ToolbarTextSize;\n className?: string;\n /** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */\n id?: string;\n /**\n * Expose heading semantics (`role=\"heading\"` + `aria-level`) so the text acts as\n * a heading landmark — e.g. a page's primary title. Omit to keep the plain span\n * (the default), which suits a dialog title referenced via `aria-labelledby`.\n */\n headingLevel?: HeadingLevel;\n /** Render the text as an unanimated loading skeleton instead of its value. */\n placeholder?: boolean;\n /**\n * Show a trailing ellipsis (…) where the text is truncated — on the single line\n * (default), or at the `maxLines` boundary when wrapping. Set false to hard-clip\n * instead. Default true.\n */\n ellipsis?: boolean;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n /**\n * Cap wrapped text to this many lines, truncating past it. Only takes effect with\n * `wrap`; ignored on a single line. `null`/omitted wraps without a line cap. Default null.\n */\n}\n\ntype ToolbarTextWrappingProps =\n | {\n /** Wrap onto multiple lines; combine with `maxLines` to cap them. */\n wrap: true;\n maxLines?: number | null;\n }\n | { wrap?: false; maxLines?: never };\n\nexport type ToolbarTextProps = ToolbarTextBaseProps & ToolbarTextWrappingProps;\n\nexport function ToolbarText({\n text,\n size = 'default',\n className = '',\n id,\n headingLevel,\n placeholder = false,\n wrap = false,\n ellipsis = true,\n maxLines = null,\n slot,\n}: ToolbarTextProps) {\n const capped = wrap && maxLines != null && maxLines > 0;\n return (\n <span\n class={`kui-toolbar-text ${className}`.trim()}\n data-component=\"toolbar-text\"\n data-size={size}\n data-wrap={wrap ? 'true' : undefined}\n data-ellipsis={ellipsis ? undefined : 'false'}\n data-max-lines={capped ? String(maxLines) : undefined}\n style={capped ? `--kui-toolbar-text-max-lines:${maxLines}` : undefined}\n data-placeholder={placeholder ? 'true' : undefined}\n id={id}\n role={headingLevel ? 'heading' : undefined}\n aria-level={headingLevel ? String(headingLevel) : undefined}\n aria-busy={placeholder ? 'true' : undefined}\n slot={slot}\n >\n {placeholder ? (\n <Skeleton width={em(8)} />\n ) : (\n <span class=\"kui-toolbar-text__text\">{text}</span>\n )}\n </span>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/list-action-row.tsx"],"names":[],"mappings":"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","file":"chunk-MA6Z6EIM.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { em, remify } from './css-values.js';\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from './extension-attributes.js';\nimport { LoadingSpinner } from './loading-spinner.js';\nimport { Skeleton } from './skeleton.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-has-icon',\n 'data-multiline',\n 'data-density',\n 'data-divider',\n 'data-busy',\n 'data-trailing-visibility',\n 'data-state',\n 'data-selected',\n 'data-pressed',\n]);\nconst PROTECTED_TRAILING_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-kui-disabled',\n]);\n\ntype ListActionRowRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-has-icon'?: never;\n 'data-multiline'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-busy'?: never;\n 'data-trailing-visibility'?: never;\n 'data-state'?: never;\n 'data-selected'?: never;\n 'data-pressed'?: never;\n }\n>;\n\ntype ListActionRowTrailingAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-kui-disabled'?: never;\n popoverTarget?: string;\n popoverTargetAction?: 'toggle' | 'show' | 'hide';\n 'aria-controls'?: string;\n 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';\n }\n>;\n\nexport interface ListActionRowProps {\n /** Visible dormant content for the primary button. Must not contain interactive descendants. */\n label: string | SafeHtml;\n description?: string | SafeHtml;\n status?: string | SafeHtml;\n busy?: boolean;\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Decorative dormant content for the primary button. Must not contain interactive descendants. */\n icon?: SafeHtml;\n action: string;\n itemId?: string;\n selected?: boolean;\n pressed?: boolean;\n accessibleLabel?: string;\n title?: string;\n multiline?: boolean;\n state?: string;\n disabled?: boolean;\n tabIndex?: number;\n /** Render as an unanimated loading skeleton, disabling both actions: label, description, icon, and status text become skeletons; the `busy` indicator stays live. */\n placeholder?: boolean;\n trailingAction: string;\n trailingActionLabel: string;\n /** Decorative dormant content for the trailing button. Must not contain interactive descendants. */\n trailingActionIcon: SafeHtml;\n trailingActionDisabled?: boolean;\n trailingActionTitle?: string;\n trailingActionVisibility?: 'always' | 'interaction';\n className?: string;\n rootAttributes?: ListActionRowRootAttributes;\n trailingActionAttributes?: ListActionRowTrailingAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport function ListActionRow({\n label,\n description,\n status,\n busy = false,\n density = 'standard',\n divider = 'none',\n icon,\n action,\n itemId,\n selected = false,\n pressed,\n accessibleLabel,\n title,\n multiline = false,\n state,\n disabled = false,\n tabIndex,\n placeholder = false,\n trailingAction,\n trailingActionLabel,\n trailingActionIcon,\n trailingActionDisabled = false,\n trailingActionTitle,\n trailingActionVisibility = 'always',\n className = '',\n rootAttributes = {},\n trailingActionAttributes = {},\n slot,\n}: ListActionRowProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTrailingAttributes = filterControlAttributes(\n trailingActionAttributes,\n PROTECTED_TRAILING_DATA_ATTRIBUTES,\n );\n\n return (\n <div\n {...extensionRootAttributes}\n class={`kui-list-action-row ${className}`.trim()}\n data-component=\"list-action-row\"\n data-item-id={itemId}\n data-has-icon={String(Boolean(icon))}\n data-multiline={multiline ? 'true' : undefined}\n data-density={density}\n data-divider={divider}\n data-busy={busy ? 'true' : undefined}\n data-trailing-visibility={trailingActionVisibility}\n data-state={state}\n data-selected={String(selected)}\n data-pressed={pressed === undefined ? undefined : String(pressed)}\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={placeholder || busy ? 'true' : undefined}\n slot={slot}\n >\n <button\n type=\"button\"\n class=\"kui-list-action-row__primary\"\n title={placeholder ? undefined : title}\n disabled={disabled || placeholder}\n tabindex={placeholder ? -1 : tabIndex}\n data-kui-disabled={disabled ? 'true' : undefined}\n data-action={placeholder ? undefined : action}\n data-item-id={itemId}\n aria-label={accessibleLabel}\n aria-current={selected ? 'page' : undefined}\n aria-pressed={pressed === undefined ? undefined : String(pressed)}\n >\n {icon && (\n <span class=\"kui-list-action-row__icon\">\n {placeholder ? (\n <Skeleton block width={remify(18)} height={remify(18)} />\n ) : (\n icon\n )}\n </span>\n )}\n <span class=\"kui-list-action-row__label\">\n <span class=\"kui-list-action-row__primary-label\">\n {placeholder ? <Skeleton width={em(9)} /> : label}\n </span>\n {description && (\n <span class=\"kui-list-action-row__description\">\n {placeholder ? <Skeleton width={em(11)} /> : description}\n </span>\n )}\n {(busy || status) && (\n <span class=\"kui-list-action-row__status\">\n {/* The busy spinner is component-owned chrome drawn from a\n known prop, so a placeholder keeps it live; only the status\n text is a value and becomes a skeleton. */}\n {busy && <LoadingSpinner />}\n {status && (placeholder ? <Skeleton width={em(6)} /> : status)}\n </span>\n )}\n </span>\n </button>\n <button\n {...extensionTrailingAttributes}\n type=\"button\"\n class=\"kui-list-action-row__trailing-action\"\n data-action={placeholder ? undefined : trailingAction}\n data-item-id={itemId}\n aria-label={trailingActionLabel}\n title={trailingActionTitle ?? trailingActionLabel}\n disabled={trailingActionDisabled || placeholder || undefined}\n data-kui-disabled={trailingActionDisabled ? 'true' : undefined}\n >\n {trailingActionIcon}\n </button>\n </div>\n );\n}\n"]}
|