@kerfjs/ui 5.0.0-beta.96 → 5.0.0-beta.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ai/component-catalog.json +3 -1
- package/ai/components/list-action-row.md +1 -0
- package/ai/components/list-item.md +1 -0
- package/ai/public-api-signatures-v1.md +1 -1
- package/ai/skill.md +2 -2
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +11 -3
- package/dist/styles/components/collections/list-action-row/list-action-row.css +14 -0
- package/dist/styles/components/collections/list-item/list-item.css +14 -0
- package/dist/styles/components/forms/token-search-field/token-search-field.css +23 -5
- package/dist/styles/list-action-row.css +14 -0
- package/dist/styles/list-item.css +14 -0
- package/dist/styles/token-search-field.css +23 -5
- package/dist/styles/toolbar-control-group.css +11 -3
- package/docs/component-contract.md +4 -0
- package/docs/component-selection.md +16 -0
- package/llms.txt +14 -1
- package/package.json +1 -1
|
@@ -3766,6 +3766,7 @@
|
|
|
3766
3766
|
"interaction-revealed trailing action",
|
|
3767
3767
|
"trailing overflow menu",
|
|
3768
3768
|
"before, after, or paired group divider",
|
|
3769
|
+
"position-aware divided-list corners: flat wherever a divider line (this row's or a neighbor's) meets the edge",
|
|
3769
3770
|
"draggable row with dragging and drop-before / drop-after insertion states"
|
|
3770
3771
|
],
|
|
3771
3772
|
"accessibility": [
|
|
@@ -3932,7 +3933,8 @@
|
|
|
3932
3933
|
"draggable row with dragging and drop-before / drop-after insertion states",
|
|
3933
3934
|
"description and status",
|
|
3934
3935
|
"busy while retaining content",
|
|
3935
|
-
"before, after, or paired group divider"
|
|
3936
|
+
"before, after, or paired group divider",
|
|
3937
|
+
"position-aware divided-list corners: flat wherever a divider line (this row's or a neighbor's) meets the edge"
|
|
3936
3938
|
],
|
|
3937
3939
|
"accessibility": [
|
|
3938
3940
|
"ListItem uses native button activation and pressed maps to aria-pressed; ListItemLink uses native anchor activation and external opens a new tab with safe rel and an announced default label. Both map selected to aria-current; disabled or loading links omit href and leave the tab order. rootAttributes cannot add role=menuitem or replace owned ARIA; trailing is dormant content and must not contain controls. A draggable row reorders by pointer drag or, with wireListReorder, Alt+Shift+ArrowUp/ArrowDown; a placeholder is never draggable."
|
|
@@ -49,6 +49,7 @@ Exact prop names and types: [`@kerfjs/ui/list-action-row`](../public-api-signatu
|
|
|
49
49
|
- interaction-revealed trailing action
|
|
50
50
|
- trailing overflow menu
|
|
51
51
|
- before, after, or paired group divider
|
|
52
|
+
- position-aware divided-list corners: flat wherever a divider line (this row's or a neighbor's) meets the edge
|
|
52
53
|
- draggable row with dragging and drop-before / drop-after insertion states
|
|
53
54
|
|
|
54
55
|
**CSS-value props** (typed builders from `@kerfjs/ui/css-values`; raw CSS strings are rejected):
|
|
@@ -51,6 +51,7 @@ Exact prop names and types: [`@kerfjs/ui/list-item`](../public-api-signatures-v1
|
|
|
51
51
|
- description and status
|
|
52
52
|
- busy while retaining content
|
|
53
53
|
- before, after, or paired group divider
|
|
54
|
+
- position-aware divided-list corners: flat wherever a divider line (this row's or a neighbor's) meets the edge
|
|
54
55
|
|
|
55
56
|
**CSS-value props** (typed builders from `@kerfjs/ui/css-values`; raw CSS strings are rejected):
|
|
56
57
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Public API signatures for the UI authoring corpus
|
|
2
2
|
|
|
3
|
-
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.
|
|
3
|
+
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.97` and `kerfjs@5.0.0-beta.97`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
|
|
4
4
|
|
|
5
5
|
## `@kerfjs/ui/css-values`
|
|
6
6
|
|
package/ai/skill.md
CHANGED
|
@@ -338,7 +338,7 @@ Set `pinned` on the first `AppTab` when it must stay visible while peers scroll.
|
|
|
338
338
|
|
|
339
339
|
Use `--kui-resizable-region-background` for a region surface and `contentOverflow="visible"` while its anchored popup needs to escape. Choose a top or bottom `restorePosition`, typed `restoreInset`, or `restorePlacement="inline"` for its collapsed restore control. `FloatingToolbar placement="inline"` stays in normal flow; its per-edge inset tokens and `safeAreaInsets` configure floating placement.
|
|
340
340
|
|
|
341
|
-
Use `ListItem density="spacious"` for larger option rows, `multiline` plus `multilineIconAlign="center"` when its icon should center on wrapped copy, `divider` for row separators, and `state="drag-target"` for the drop target treatment. For a reorderable list, set `draggable` and `itemId` on each `ListItem`, `ListItemLink`, or `ListActionRow` and call `wireListReorder(root, { onReorder })` from `@kerfjs/ui/wire-list-reorder` once: it dims the dragged rows, draws the brand insertion line on the hovered row's `before`/`after` edge, supports Alt+Shift+ArrowUp/ArrowDown, and reports `{ listId, sourceIds, target: { id, position }, source }` (a selected or pressed row drags every selected row of its `List`; `data-list-id` on the `List` names it). Apply it with `reorderListItems` and re-render; the `dragging` and `dropPosition` props render the same states from app-owned drag state. Never hand-style drag rows. Public `--kui-list-item-*` tokens adjust row, icon, label, and trailing geometry and color; ListHeader height, title padding, and border tokens adjust section density.
|
|
341
|
+
Use `ListItem density="spacious"` for larger option rows, `multiline` plus `multilineIconAlign="center"` when its icon should center on wrapped copy, `divider` for row separators (for lines only between rows, every row but the last takes `divider="after"` and the last `"none"`; corners are flat wherever a divider line meets them, so the group rounds only its outer corners), and `state="drag-target"` for the drop target treatment. For a reorderable list, set `draggable` and `itemId` on each `ListItem`, `ListItemLink`, or `ListActionRow` and call `wireListReorder(root, { onReorder })` from `@kerfjs/ui/wire-list-reorder` once: it dims the dragged rows, draws the brand insertion line on the hovered row's `before`/`after` edge, supports Alt+Shift+ArrowUp/ArrowDown, and reports `{ listId, sourceIds, target: { id, position }, source }` (a selected or pressed row drags every selected row of its `List`; `data-list-id` on the `List` names it). Apply it with `reorderListItems` and re-render; the `dragging` and `dropPosition` props render the same states from app-owned drag state. Never hand-style drag rows. Public `--kui-list-item-*` tokens adjust row, icon, label, and trailing geometry and color; ListHeader height, title padding, and border tokens adjust section density.
|
|
342
342
|
|
|
343
343
|
Set `ListHeader.size` to `xs`, `sm`, `m`, `l`, or `xl` for label scale. The default `sm` remains the small uppercase style shared with `FieldLabel`; `xs` is 2xs and capitalized, while `m`/`l`/`xl` match themed h5/h4/h3 typography. Choose `headingLevel` separately from the document outline.
|
|
344
344
|
|
|
@@ -429,7 +429,7 @@ For a tab scene with drill-down, place a `NavStack` directly in `TabNavigatorTab
|
|
|
429
429
|
Use `Pane.deepInset` (also in `PaneConfig`) or `TabNavigatorTab.deepInset` for a plain scene when its scrolling content needs an extra 8px on all four sides, giving ordinary items a 16px inline gutter. The extra 8px is applied to the scroll surface, while nested Row/List/Grid item margins stay 8px. When a tab scene is a sole Pane or NavStack, configure deep inset on that child's Pane; the tab bar and top toolbar stay full width.
|
|
430
430
|
An edge-to-edge table or similar Pane child can read `--kui-pane-content-inset-inline-start` and `--kui-pane-content-inset-inline-end`: negate them for the child's logical margins, then add them to the child's text padding. The inherited values include routed safe areas and `deepInset`; keep the child in the Pane's single scroll slot. See `docs/app-layouts.md` for the CSS recipe.
|
|
431
431
|
|
|
432
|
-
Expanded search groups accept `expandedOverflow="visible"` to anchor app-owned suggestion/date/help surfaces below their relative root; collapsed/default groups retain existing clipping. Apps own surface placement/dismissal and use `data-token-search-keep-open` or `collapsible.keepOpenOn` for focus.
|
|
432
|
+
Do not grow a collapsible search past the room beside its sibling groups: when it does not fit, the siblings wrap onto a new row while it opens. Size the expanded search to fit (`--kui-token-search-expanded-width`, or `sizing="grow"` with a fitting `growBasis`), and if a useful search still cannot fit, set aside the other controls while it is open, with `visibility="yield-to-expanded-sibling"` on those groups (they leave a 480px-or-narrower toolbar while a sibling is expanded) or behind a "…" `PopupMenu` overflow group; the app chooses which controls yield. Expanded search groups accept `expandedOverflow="visible"` to anchor app-owned suggestion/date/help surfaces below their relative root; collapsed/default groups retain existing clipping. Apps own surface placement/dismissal and use `data-token-search-keep-open` or `collapsible.keepOpenOn` for focus.
|
|
433
433
|
|
|
434
434
|
`ToolbarText` and `ToolbarControlGroup` accept typed `hideBelow`/`showBelow`
|
|
435
435
|
lengths (for example `px(416)`). Wire `wireToolbarVisibility(root)` from
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Web Awesome JSX signatures for the UI authoring corpus
|
|
2
2
|
|
|
3
|
-
Generated from the emitted `@kerfjs/ui@5.0.0-beta.
|
|
3
|
+
Generated from the emitted `@kerfjs/ui@5.0.0-beta.97` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
|
|
4
4
|
|
|
5
5
|
```ts
|
|
6
6
|
import { KerfCustomElement } from 'kerfjs/jsx-runtime';
|
|
@@ -173,6 +173,13 @@
|
|
|
173
173
|
align-self: center;
|
|
174
174
|
}
|
|
175
175
|
.kui-toolbar-control-group[data-content="search"] {
|
|
176
|
+
/* The group owns the open/close width motion, and a collapsible search
|
|
177
|
+
inside follows it on every frame (no second, lagging width transition,
|
|
178
|
+
which left an empty band). For the length of the opening it also asks the
|
|
179
|
+
search to keep its query on one line, so the group's clip reveals the
|
|
180
|
+
query instead of re-wrapping it every frame (KF-CXQB30). */
|
|
181
|
+
--_kui-toolbar-group-search-width-duration: 0s;
|
|
182
|
+
--_kui-toolbar-group-search-reveal-duration: 0.25s;
|
|
176
183
|
width: min(var(--kui-token-search-expanded-width, 30rem), 100%);
|
|
177
184
|
max-width: 100%;
|
|
178
185
|
height: auto;
|
|
@@ -232,9 +239,9 @@
|
|
|
232
239
|
inside animated, leaving an empty band (KF-50K0JM). The collapsed state names
|
|
233
240
|
a definite basis and minimum so all three flex lengths interpolate. */
|
|
234
241
|
.kui-toolbar-control-group[data-content="search"][data-sizing="grow"] {
|
|
235
|
-
/* The group owns this motion;
|
|
236
|
-
|
|
237
|
-
--_kui-toolbar-group-
|
|
242
|
+
/* The group's flex size owns this motion; its basis-wide minimum (above)
|
|
243
|
+
already keeps the query on one line. */
|
|
244
|
+
--_kui-toolbar-group-search-reveal-duration: 0s;
|
|
238
245
|
transition-property:
|
|
239
246
|
width, flex-basis, flex-grow, min-width, background-color, border-color;
|
|
240
247
|
transition-duration: 0.25s, 0.25s, 0.25s, 0.25s, 0.2s, 0.2s;
|
|
@@ -845,6 +852,7 @@
|
|
|
845
852
|
@media (prefers-reduced-motion: reduce) {
|
|
846
853
|
.kui-toolbar-control-group[data-content="search"],
|
|
847
854
|
.kui-toolbar-control-group[data-content="search"][data-sizing="grow"] {
|
|
855
|
+
--_kui-toolbar-group-search-reveal-duration: 0s;
|
|
848
856
|
transition-duration: 0s;
|
|
849
857
|
}
|
|
850
858
|
|
|
@@ -46,6 +46,20 @@
|
|
|
46
46
|
border-end-end-radius: 0;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
/* In a divided list, a corner is flat wherever its edge carries a divider
|
|
50
|
+
line, whichever row draws it (see ListItem). */
|
|
51
|
+
:is([data-divider="after"], [data-divider="both"]) + .kui-list-action-row {
|
|
52
|
+
border-start-start-radius: 0;
|
|
53
|
+
border-start-end-radius: 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.kui-list-action-row:has(
|
|
57
|
+
+ :is([data-divider="before"], [data-divider="both"])
|
|
58
|
+
) {
|
|
59
|
+
border-end-start-radius: 0;
|
|
60
|
+
border-end-end-radius: 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
49
63
|
.kui-list-action-row:not([data-placeholder="true"]):has(
|
|
50
64
|
.kui-list-action-row__primary:hover
|
|
51
65
|
) {
|
|
@@ -68,6 +68,20 @@
|
|
|
68
68
|
border-end-end-radius: 0;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/* In a divided list, a corner is flat wherever its edge carries a divider
|
|
72
|
+
line, whichever row draws it: the previous row's after line squares this
|
|
73
|
+
row's top, and the next row's before line squares its bottom. So first,
|
|
74
|
+
middle, last, and only rows round just their outer corners. */
|
|
75
|
+
:is([data-divider="after"], [data-divider="both"]) + .kui-list-item {
|
|
76
|
+
border-start-start-radius: 0;
|
|
77
|
+
border-start-end-radius: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.kui-list-item:has(+ :is([data-divider="before"], [data-divider="both"])) {
|
|
81
|
+
border-end-start-radius: 0;
|
|
82
|
+
border-end-end-radius: 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
71
85
|
.kui-list-item[data-has-icon="true"] {
|
|
72
86
|
grid-template-columns: var(
|
|
73
87
|
--kui-list-item-columns,
|
|
@@ -284,12 +284,12 @@
|
|
|
284
284
|
no-grow / may-shrink behavior a toolbar row wants without leaking the width
|
|
285
285
|
into the cross axis. */
|
|
286
286
|
flex: 0 1 auto;
|
|
287
|
-
/* A
|
|
288
|
-
to 0s: the field is the group's width on every frame instead of
|
|
289
|
-
second, lagging width transition that left an empty band beside
|
|
290
|
-
query (KF-50K0JM). */
|
|
287
|
+
/* A search toolbar group animates the open/close itself and sets this
|
|
288
|
+
duration to 0s: the field is the group's width on every frame instead of
|
|
289
|
+
running a second, lagging width transition that left an empty band beside
|
|
290
|
+
a wrapped query (KF-50K0JM, KF-CXQB30). */
|
|
291
291
|
transition:
|
|
292
|
-
width var(--_kui-toolbar-group-
|
|
292
|
+
width var(--_kui-toolbar-group-search-width-duration, 0.25s) ease,
|
|
293
293
|
background-color 0.2s ease,
|
|
294
294
|
border-color 0.2s ease;
|
|
295
295
|
}
|
|
@@ -301,6 +301,24 @@
|
|
|
301
301
|
min-width: var(--_kui-toolbar-group-grow-search-min-width, 0px);
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
/* While a search group opens, keep the query on one line: the group's clip
|
|
305
|
+
reveals it instead of re-wrapping it in the narrow, still-growing field.
|
|
306
|
+
Wrapping returns when the opening ends. The duration is 0s (no effect)
|
|
307
|
+
outside a search group and under reduced motion. */
|
|
308
|
+
.kui-token-search[data-collapsible="true"][data-expanded="true"]
|
|
309
|
+
> .kui-token-search__editor {
|
|
310
|
+
animation: kui-token-search-reveal
|
|
311
|
+
var(--_kui-toolbar-group-search-reveal-duration, 0s) linear;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
@keyframes kui-token-search-reveal {
|
|
315
|
+
from,
|
|
316
|
+
to {
|
|
317
|
+
overflow-wrap: normal;
|
|
318
|
+
white-space: pre;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
304
322
|
.kui-token-search[data-collapsible="true"][data-expanded="true"][data-fill="true"] {
|
|
305
323
|
width: 100%;
|
|
306
324
|
flex: 1 1 auto;
|
|
@@ -46,6 +46,20 @@
|
|
|
46
46
|
border-end-end-radius: 0;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
/* In a divided list, a corner is flat wherever its edge carries a divider
|
|
50
|
+
line, whichever row draws it (see ListItem). */
|
|
51
|
+
:is([data-divider="after"], [data-divider="both"]) + .kui-list-action-row {
|
|
52
|
+
border-start-start-radius: 0;
|
|
53
|
+
border-start-end-radius: 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.kui-list-action-row:has(
|
|
57
|
+
+ :is([data-divider="before"], [data-divider="both"])
|
|
58
|
+
) {
|
|
59
|
+
border-end-start-radius: 0;
|
|
60
|
+
border-end-end-radius: 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
49
63
|
.kui-list-action-row:not([data-placeholder="true"]):has(
|
|
50
64
|
.kui-list-action-row__primary:hover
|
|
51
65
|
) {
|
|
@@ -68,6 +68,20 @@
|
|
|
68
68
|
border-end-end-radius: 0;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/* In a divided list, a corner is flat wherever its edge carries a divider
|
|
72
|
+
line, whichever row draws it: the previous row's after line squares this
|
|
73
|
+
row's top, and the next row's before line squares its bottom. So first,
|
|
74
|
+
middle, last, and only rows round just their outer corners. */
|
|
75
|
+
:is([data-divider="after"], [data-divider="both"]) + .kui-list-item {
|
|
76
|
+
border-start-start-radius: 0;
|
|
77
|
+
border-start-end-radius: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.kui-list-item:has(+ :is([data-divider="before"], [data-divider="both"])) {
|
|
81
|
+
border-end-start-radius: 0;
|
|
82
|
+
border-end-end-radius: 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
71
85
|
.kui-list-item[data-has-icon="true"] {
|
|
72
86
|
grid-template-columns: var(
|
|
73
87
|
--kui-list-item-columns,
|
|
@@ -284,12 +284,12 @@
|
|
|
284
284
|
no-grow / may-shrink behavior a toolbar row wants without leaking the width
|
|
285
285
|
into the cross axis. */
|
|
286
286
|
flex: 0 1 auto;
|
|
287
|
-
/* A
|
|
288
|
-
to 0s: the field is the group's width on every frame instead of
|
|
289
|
-
second, lagging width transition that left an empty band beside
|
|
290
|
-
query (KF-50K0JM). */
|
|
287
|
+
/* A search toolbar group animates the open/close itself and sets this
|
|
288
|
+
duration to 0s: the field is the group's width on every frame instead of
|
|
289
|
+
running a second, lagging width transition that left an empty band beside
|
|
290
|
+
a wrapped query (KF-50K0JM, KF-CXQB30). */
|
|
291
291
|
transition:
|
|
292
|
-
width var(--_kui-toolbar-group-
|
|
292
|
+
width var(--_kui-toolbar-group-search-width-duration, 0.25s) ease,
|
|
293
293
|
background-color 0.2s ease,
|
|
294
294
|
border-color 0.2s ease;
|
|
295
295
|
}
|
|
@@ -301,6 +301,24 @@
|
|
|
301
301
|
min-width: var(--_kui-toolbar-group-grow-search-min-width, 0px);
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
/* While a search group opens, keep the query on one line: the group's clip
|
|
305
|
+
reveals it instead of re-wrapping it in the narrow, still-growing field.
|
|
306
|
+
Wrapping returns when the opening ends. The duration is 0s (no effect)
|
|
307
|
+
outside a search group and under reduced motion. */
|
|
308
|
+
.kui-token-search[data-collapsible="true"][data-expanded="true"]
|
|
309
|
+
> .kui-token-search__editor {
|
|
310
|
+
animation: kui-token-search-reveal
|
|
311
|
+
var(--_kui-toolbar-group-search-reveal-duration, 0s) linear;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
@keyframes kui-token-search-reveal {
|
|
315
|
+
from,
|
|
316
|
+
to {
|
|
317
|
+
overflow-wrap: normal;
|
|
318
|
+
white-space: pre;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
304
322
|
.kui-token-search[data-collapsible="true"][data-expanded="true"][data-fill="true"] {
|
|
305
323
|
width: 100%;
|
|
306
324
|
flex: 1 1 auto;
|
|
@@ -173,6 +173,13 @@
|
|
|
173
173
|
align-self: center;
|
|
174
174
|
}
|
|
175
175
|
.kui-toolbar-control-group[data-content="search"] {
|
|
176
|
+
/* The group owns the open/close width motion, and a collapsible search
|
|
177
|
+
inside follows it on every frame (no second, lagging width transition,
|
|
178
|
+
which left an empty band). For the length of the opening it also asks the
|
|
179
|
+
search to keep its query on one line, so the group's clip reveals the
|
|
180
|
+
query instead of re-wrapping it every frame (KF-CXQB30). */
|
|
181
|
+
--_kui-toolbar-group-search-width-duration: 0s;
|
|
182
|
+
--_kui-toolbar-group-search-reveal-duration: 0.25s;
|
|
176
183
|
width: min(var(--kui-token-search-expanded-width, 30rem), 100%);
|
|
177
184
|
max-width: 100%;
|
|
178
185
|
height: auto;
|
|
@@ -232,9 +239,9 @@
|
|
|
232
239
|
inside animated, leaving an empty band (KF-50K0JM). The collapsed state names
|
|
233
240
|
a definite basis and minimum so all three flex lengths interpolate. */
|
|
234
241
|
.kui-toolbar-control-group[data-content="search"][data-sizing="grow"] {
|
|
235
|
-
/* The group owns this motion;
|
|
236
|
-
|
|
237
|
-
--_kui-toolbar-group-
|
|
242
|
+
/* The group's flex size owns this motion; its basis-wide minimum (above)
|
|
243
|
+
already keeps the query on one line. */
|
|
244
|
+
--_kui-toolbar-group-search-reveal-duration: 0s;
|
|
238
245
|
transition-property:
|
|
239
246
|
width, flex-basis, flex-grow, min-width, background-color, border-color;
|
|
240
247
|
transition-duration: 0.25s, 0.25s, 0.25s, 0.25s, 0.2s, 0.2s;
|
|
@@ -845,6 +852,7 @@
|
|
|
845
852
|
@media (prefers-reduced-motion: reduce) {
|
|
846
853
|
.kui-toolbar-control-group[data-content="search"],
|
|
847
854
|
.kui-toolbar-control-group[data-content="search"][data-sizing="grow"] {
|
|
855
|
+
--_kui-toolbar-group-search-reveal-duration: 0s;
|
|
848
856
|
transition-duration: 0s;
|
|
849
857
|
}
|
|
850
858
|
|
|
@@ -578,6 +578,10 @@ close motion: its flex size animates while a collapsible `TokenSearchField`
|
|
|
578
578
|
inside fills it on every frame, laid out at least basis-wide and clipped by the
|
|
579
579
|
group, so a query never wraps or leaves an empty band mid-transition. At 480px
|
|
580
580
|
container width or less, and under reduced motion, it opens in one frame.
|
|
581
|
+
A plain collapsible search group (no `sizing`) animates its own width the same
|
|
582
|
+
way: the `TokenSearchField` follows the group on every frame and keeps its
|
|
583
|
+
query on one line until the opening ends, so it never shows an empty band or a
|
|
584
|
+
query wrapped in a narrow, still-opening field.
|
|
581
585
|
Use `sizing="fill"` for a group, including a non-search segmented control,
|
|
582
586
|
that spans its wrapping row. Set `visibility="hide-collapsed-tiny"` on a
|
|
583
587
|
collapsible group to omit its closed icon at 224px or less; expanded content
|
|
@@ -579,6 +579,22 @@ the control's dimensions, shows `LoadingSpinner` in its icon slot, sets
|
|
|
579
579
|
| A command menu | `<ToolbarControlGroup single nestedDropdown><PopupMenu … /></ToolbarControlGroup>` | Register `@kerfjs/ui/popup-menu/register` once; set `menuInset` on the group |
|
|
580
580
|
| A collapsible search box | `<ToolbarControlGroup single><TokenSearchField collapsible … /></ToolbarControlGroup>` | The group animates the iconic ↔ expanded states; `wireTokenSearchFields` manages expand/collapse/focus by default |
|
|
581
581
|
|
|
582
|
+
### Room for an expanded search
|
|
583
|
+
|
|
584
|
+
A collapsible search group grows into the room beside its sibling groups. When
|
|
585
|
+
that room is too small, the siblings wrap onto a new row partway through the
|
|
586
|
+
opening, and the toolbar grows a row taller. Kerf does not hide or move your
|
|
587
|
+
other controls; plan for it instead:
|
|
588
|
+
|
|
589
|
+
- Size the expanded search to what fits: `--kui-token-search-expanded-width`
|
|
590
|
+
for a plain search group, or `sizing="grow"` with a `growBasis` that fits
|
|
591
|
+
beside the siblings.
|
|
592
|
+
- If a useful search cannot fit beside the other controls, set those controls
|
|
593
|
+
aside while it is open. Mark them `visibility="yield-to-expanded-sibling"`
|
|
594
|
+
(they leave a 480px-or-narrower toolbar while a sibling is expanded), or
|
|
595
|
+
gather them behind a "…" `PopupMenu` overflow group. The application decides
|
|
596
|
+
which controls yield.
|
|
597
|
+
|
|
582
598
|
### Application surfaces below search
|
|
583
599
|
|
|
584
600
|
Pass `expandedOverflow="visible"` to `ToolbarControlGroup content="search"`
|
package/llms.txt
CHANGED
|
@@ -254,7 +254,10 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
|
|
|
254
254
|
gives option rows more room. `multiline` wraps labels, with
|
|
255
255
|
`multilineIconAlign="center"` when the icon should center on the whole copy.
|
|
256
256
|
`divider` owns row separators and `state="drag-target"` paints the drop
|
|
257
|
-
target. For
|
|
257
|
+
target. For lines only between rows, give every row but the last
|
|
258
|
+
`divider="after"` (the last `"none"`); a row's corners are flat wherever a
|
|
259
|
+
divider line meets them, so the group rounds only its outer corners on
|
|
260
|
+
hover and selection. For a reorderable list, set `draggable` + `itemId` on `ListItem`,
|
|
258
261
|
`ListItemLink`, or `ListActionRow` rows and call `wireListReorder` (from
|
|
259
262
|
`@kerfjs/ui/wire-list-reorder`) once; it paints the dimmed dragging rows and
|
|
260
263
|
the before/after insertion line, supports Alt+Shift+ArrowUp/ArrowDown, and
|
|
@@ -368,6 +371,16 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
|
|
|
368
371
|
`LucideIcon` is 24px); if it looks wrong, fix the surrounding layout, not the
|
|
369
372
|
control. Never force a component's width/height to size it — that leaves a halo
|
|
370
373
|
or a stretched oval.
|
|
374
|
+
- **Make room for an expanded search instead of growing it past what fits.** A
|
|
375
|
+
collapsible search group grows into the space beside its sibling groups; if
|
|
376
|
+
that space is too small, the siblings wrap onto a new row while it opens.
|
|
377
|
+
Size the expanded search to what fits (`--kui-token-search-expanded-width`,
|
|
378
|
+
or `sizing="grow"` with a `growBasis` that fits), and if a useful search
|
|
379
|
+
cannot fit beside the other controls, set aside those controls while the
|
|
380
|
+
search is open: mark them `visibility="yield-to-expanded-sibling"` (they
|
|
381
|
+
leave a 480px-or-narrower toolbar while a sibling is expanded) or gather
|
|
382
|
+
them behind a "…" `PopupMenu` overflow group. The app decides which
|
|
383
|
+
controls yield.
|
|
371
384
|
- **Toolbars hold only `ToolbarText` and `ToolbarControlGroup`.** Never put a bare
|
|
372
385
|
button, input, link, or loose markup in a `leading`/`center`/`trailing` zone.
|
|
373
386
|
Wrap every control — `SegmentedControl`, `Select`, a collapsible
|