@kerfjs/ui 5.0.0-beta.59 → 5.0.0-beta.60

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.
Files changed (117) hide show
  1. package/ai/component-catalog.json +99 -10
  2. package/ai/component-composition.json +78 -6
  3. package/ai/components/README.md +1 -1
  4. package/ai/components/floating-toolbar.md +3 -1
  5. package/ai/components/list-header.md +1 -1
  6. package/ai/components/list-item.md +4 -1
  7. package/ai/components/resize.md +6 -1
  8. package/ai/components/select.md +5 -3
  9. package/ai/components/state-banner.md +3 -1
  10. package/ai/components/tab-bar.md +1 -1
  11. package/ai/components/tabs.md +2 -1
  12. package/ai/components/text.md +2 -1
  13. package/ai/components/token-search-field.md +1 -1
  14. package/ai/components/toolbar-text.md +4 -2
  15. package/ai/components/toolbar.md +2 -1
  16. package/ai/components/value-table.md +2 -1
  17. package/ai/public-api-signatures-v1.md +55 -18
  18. package/ai/skill.md +18 -6
  19. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  20. package/dist/app-tab.d.ts +4 -1
  21. package/dist/app-tab.js +1 -1
  22. package/dist/catalog.js +6 -6
  23. package/dist/{chunk-2CCMJTVY.js → chunk-2OXQHM7I.js} +5 -5
  24. package/dist/{chunk-2CCMJTVY.js.map → chunk-2OXQHM7I.js.map} +1 -1
  25. package/dist/{chunk-XDKAYSVD.js → chunk-3SXMEK3B.js} +1 -1
  26. package/dist/chunk-3SXMEK3B.js.map +1 -0
  27. package/dist/{chunk-QOWG4ZCL.js → chunk-5I7OHCIP.js} +5 -2
  28. package/dist/chunk-5I7OHCIP.js.map +1 -0
  29. package/dist/{chunk-W4XKTST6.js → chunk-5PESG2VP.js} +3 -3
  30. package/dist/{chunk-W4XKTST6.js.map → chunk-5PESG2VP.js.map} +1 -1
  31. package/dist/{chunk-UX2VVXZ3.js → chunk-5Q3N6EV7.js} +2 -2
  32. package/dist/{chunk-UX2VVXZ3.js.map → chunk-5Q3N6EV7.js.map} +1 -1
  33. package/dist/{chunk-UFYZHYWU.js → chunk-A3CKOW2R.js} +4 -3
  34. package/dist/chunk-A3CKOW2R.js.map +1 -0
  35. package/dist/{chunk-UXT7TE6B.js → chunk-AUKT3KMG.js} +5 -1
  36. package/dist/chunk-AUKT3KMG.js.map +1 -0
  37. package/dist/{chunk-EVYKTVBQ.js → chunk-GLDWRCAM.js} +5 -1
  38. package/dist/chunk-GLDWRCAM.js.map +1 -0
  39. package/dist/{chunk-M7QV3IHH.js → chunk-I3Q7KKYM.js} +5 -1
  40. package/dist/chunk-I3Q7KKYM.js.map +1 -0
  41. package/dist/{chunk-3CGQ7ZNO.js → chunk-IA7TMD4Y.js} +2 -2
  42. package/dist/{chunk-3CGQ7ZNO.js.map → chunk-IA7TMD4Y.js.map} +1 -1
  43. package/dist/{chunk-VHADGP3B.js → chunk-KLJKU6ZL.js} +5 -1
  44. package/dist/chunk-KLJKU6ZL.js.map +1 -0
  45. package/dist/{chunk-6YFHCLHG.js → chunk-MERWRTBG.js} +1 -1
  46. package/dist/chunk-MERWRTBG.js.map +1 -0
  47. package/dist/{chunk-KH6VUGHU.js → chunk-NNMLEDMD.js} +2 -2
  48. package/dist/{chunk-KH6VUGHU.js.map → chunk-NNMLEDMD.js.map} +1 -1
  49. package/dist/{chunk-6CINWX2E.js → chunk-P7D3EMXM.js} +3 -1
  50. package/dist/chunk-P7D3EMXM.js.map +1 -0
  51. package/dist/{chunk-QPUPLNNB.js → chunk-T57AXDFM.js} +2 -2
  52. package/dist/{chunk-QPUPLNNB.js.map → chunk-T57AXDFM.js.map} +1 -1
  53. package/dist/{chunk-WOUF7YXM.js → chunk-T66UNBXL.js} +5 -2
  54. package/dist/chunk-T66UNBXL.js.map +1 -0
  55. package/dist/{chunk-XQV2B4IL.js → chunk-UIDKY4UB.js} +2 -2
  56. package/dist/{chunk-XQV2B4IL.js.map → chunk-UIDKY4UB.js.map} +1 -1
  57. package/dist/{chunk-OUK6QRDR.js → chunk-WPLIO5WJ.js} +5 -2
  58. package/dist/chunk-WPLIO5WJ.js.map +1 -0
  59. package/dist/collapsible-panel.d.ts +1 -0
  60. package/dist/collapsible-panel.js +2 -2
  61. package/dist/floating-toolbar.d.ts +8 -2
  62. package/dist/floating-toolbar.js +1 -1
  63. package/dist/index.js +13 -13
  64. package/dist/list-header.js +1 -1
  65. package/dist/list-item.d.ts +5 -2
  66. package/dist/list-item.js +1 -1
  67. package/dist/nav-stack.js +1 -1
  68. package/dist/resizable-region.d.ts +8 -3
  69. package/dist/resizable-region.js +1 -1
  70. package/dist/select.d.ts +4 -1
  71. package/dist/select.js +1 -1
  72. package/dist/split-view.d.ts +1 -0
  73. package/dist/split-view.js +2 -2
  74. package/dist/state-banner.d.ts +8 -2
  75. package/dist/state-banner.js +1 -1
  76. package/dist/styles/app-tab.css +3 -0
  77. package/dist/styles/floating-toolbar.css +56 -4
  78. package/dist/styles/list-header.css +15 -7
  79. package/dist/styles/list-item.css +60 -18
  80. package/dist/styles/resizable-region.css +33 -1
  81. package/dist/styles/select.css +26 -0
  82. package/dist/styles/state-banner.css +37 -0
  83. package/dist/styles/tab-bar.css +25 -10
  84. package/dist/styles/text.css +9 -0
  85. package/dist/styles/token-search-field.css +1 -1
  86. package/dist/styles/toolbar-text.css +4 -0
  87. package/dist/styles/toolbar.css +83 -1
  88. package/dist/styles/value-table.css +16 -3
  89. package/dist/text.d.ts +7 -2
  90. package/dist/text.js +1 -1
  91. package/dist/toolbar-text.d.ts +1 -1
  92. package/dist/toolbar-text.js +1 -1
  93. package/dist/toolbar.d.ts +4 -2
  94. package/dist/toolbar.js +1 -1
  95. package/dist/value-table.d.ts +3 -1
  96. package/dist/value-table.js +1 -1
  97. package/dist/wire-catalog.js +1 -1
  98. package/dist/wire-resizable-regions.js +1 -1
  99. package/dist/wire-token-search-fields.js +1 -1
  100. package/dist/wire-workbench.js +1 -1
  101. package/dist/workbench.js +1 -1
  102. package/docs/collapsible-panel.md +7 -1
  103. package/docs/component-selection.md +61 -0
  104. package/docs/document-baseline.md +3 -0
  105. package/llms.txt +32 -0
  106. package/package.json +1 -1
  107. package/dist/chunk-6CINWX2E.js.map +0 -1
  108. package/dist/chunk-6YFHCLHG.js.map +0 -1
  109. package/dist/chunk-EVYKTVBQ.js.map +0 -1
  110. package/dist/chunk-M7QV3IHH.js.map +0 -1
  111. package/dist/chunk-OUK6QRDR.js.map +0 -1
  112. package/dist/chunk-QOWG4ZCL.js.map +0 -1
  113. package/dist/chunk-UFYZHYWU.js.map +0 -1
  114. package/dist/chunk-UXT7TE6B.js.map +0 -1
  115. package/dist/chunk-VHADGP3B.js.map +0 -1
  116. package/dist/chunk-WOUF7YXM.js.map +0 -1
  117. package/dist/chunk-XDKAYSVD.js.map +0 -1
@@ -156,6 +156,43 @@
156
156
  height instead of the larger inherited strut. */
157
157
  font-size: var(--kui-font-xs);
158
158
  }
159
+ .kui-state-banner[data-copy-layout="stacked"] > .kui-state-banner__copy {
160
+ display: flex;
161
+ flex-wrap: wrap;
162
+ align-items: baseline;
163
+ column-gap: var(--kui-state-banner-copy-gap, var(--kui-space-xs));
164
+ row-gap: var(--kui-state-banner-copy-row-gap, var(--kui-space-2xs));
165
+ }
166
+ .kui-state-banner[data-copy-layout="stacked"]
167
+ > .kui-state-banner__copy
168
+ > strong {
169
+ margin-inline-end: 0;
170
+ }
171
+ .kui-state-banner[data-copy-layout="stacked"]
172
+ > .kui-state-banner__copy
173
+ > .kui-state-banner__detail {
174
+ flex-basis: 100%;
175
+ white-space: normal;
176
+ }
177
+ .kui-state-banner[data-copy-layout="stacked"]
178
+ > .kui-state-banner__copy
179
+ > .kui-state-banner__detail
180
+ > span {
181
+ overflow: visible;
182
+ text-overflow: clip;
183
+ }
184
+ .kui-state-banner[data-action-placement="below"] {
185
+ grid-template-columns: auto minmax(0, 1fr);
186
+ }
187
+ .kui-state-banner[data-action-placement="below"]:not(
188
+ :has(> .kui-state-banner__icon)
189
+ )
190
+ > .kui-state-banner__copy {
191
+ grid-column: 1 / -1;
192
+ }
193
+ .kui-state-banner[data-action-placement="below"] > .kui-state-banner__action {
194
+ grid-column: 1 / -1;
195
+ }
159
196
  .kui-state-banner__copy strong {
160
197
  margin-inline-end: var(--kui-layout-item-gap, 0.5rem);
161
198
  font-size: var(--kui-font-xs);
@@ -18,19 +18,31 @@
18
18
  .kui-tab-bar__tabs {
19
19
  display: flex;
20
20
  min-width: 0;
21
- min-height: var(--kui-toolbar-group-size, calc(2px + 2.625rem));
22
- padding: 1px;
21
+ min-height: var(
22
+ --kui-tab-bar-strip-min-height,
23
+ var(--kui-toolbar-group-size, calc(2px + 2.625rem))
24
+ );
25
+ margin-block: var(--kui-tab-bar-strip-margin-block, 0);
26
+ padding: var(--kui-tab-bar-strip-padding, 1px);
23
27
  /* Scroll along the strip only: overflow-x alone computes overflow-y to auto,
24
28
  so any vertical excess would let the strip scroll vertically on touch. */
25
- overflow: auto hidden;
29
+ overflow: auto var(--kui-tab-bar-strip-overflow-block, hidden);
26
30
  box-sizing: border-box;
27
- border: 1px solid var(--kui-tab-bar-border);
28
- border-radius: var(--kui-layout-pill-radius, calc(1px + 1.3125rem));
29
- background: var(--kui-tab-bar-background);
31
+ border: var(--kui-tab-bar-strip-border-width, 1px) solid
32
+ var(--kui-tab-bar-border);
33
+ border-radius: var(
34
+ --kui-tab-bar-strip-radius,
35
+ var(--kui-layout-pill-radius, calc(1px + 1.3125rem))
36
+ );
37
+ background: var(
38
+ --kui-tab-bar-strip-background,
39
+ var(--kui-tab-bar-background)
40
+ );
30
41
  scrollbar-width: none;
31
42
  align-items: center;
32
- flex: 1 1 auto;
33
- gap: 0;
43
+ flex: var(--kui-tab-bar-strip-flex, 1 1 auto);
44
+ gap: var(--kui-tab-bar-strip-gap, 0);
45
+ scroll-padding-inline: var(--kui-tab-bar-strip-scroll-padding-inline, 0);
34
46
  overscroll-behavior-inline: contain;
35
47
  }
36
48
  .kui-tab-bar[data-presentation="segmented"],
@@ -54,8 +66,8 @@
54
66
  padding: 0;
55
67
  }
56
68
  .kui-tab-bar[data-presentation="inspector"] .kui-tab-bar__tabs {
57
- min-height: 2.125rem;
58
- border-radius: var(--kui-radius-s);
69
+ min-height: var(--kui-tab-bar-strip-min-height, 2.125rem);
70
+ border-radius: var(--kui-tab-bar-strip-radius, var(--kui-radius-s));
59
71
  }
60
72
  .kui-tab-bar[data-trailing-placement="adjacent"] .kui-tab-bar__tabs {
61
73
  flex: 0 1 auto;
@@ -73,6 +85,9 @@
73
85
  align-items: center;
74
86
  flex: none;
75
87
  }
88
+ .kui-tab-bar__trailing {
89
+ flex: var(--kui-tab-bar-trailing-flex, none);
90
+ }
76
91
 
77
92
  .kui-tab-bar__end {
78
93
  margin-inline-start: auto;
@@ -33,6 +33,15 @@
33
33
  border: 0;
34
34
  }
35
35
 
36
+ .kui-text[data-flush="true"] {
37
+ padding: 0;
38
+ border: 0;
39
+ }
40
+
41
+ .kui-text[data-line-height="tight"] {
42
+ line-height: 1.2;
43
+ }
44
+
36
45
  span.kui-text {
37
46
  margin: 0;
38
47
  border: 0;
@@ -48,7 +48,7 @@
48
48
 
49
49
  .kui-token-search__editor {
50
50
  grid-column: 2;
51
- min-width: 5rem;
51
+ min-width: var(--kui-token-search-editor-min-width, 0px);
52
52
  min-height: var(--kui-token-search-line-size);
53
53
  padding-block: calc((var(--kui-token-search-line-size) - 1.35em) / 2) 0;
54
54
  box-sizing: border-box;
@@ -75,6 +75,10 @@
75
75
  font-size: var(--kui-font-xs);
76
76
  }
77
77
 
78
+ .kui-toolbar-text[data-size="xsmall"] {
79
+ font-size: var(--kui-font-2xs);
80
+ }
81
+
78
82
  /* Single line, no ellipsis: hard-clip the overflow instead of showing …. */
79
83
  .kui-toolbar-text[data-ellipsis="false"] .kui-toolbar-text__text {
80
84
  text-overflow: clip;
@@ -92,6 +92,14 @@
92
92
  grid-template-columns: minmax(0, 1fr) auto;
93
93
  }
94
94
 
95
+ .kui-toolbar[data-responsive="trailing-priority"][data-has-center="false"]:has(
96
+ > .kui-toolbar__trailing [data-expanded="true"]
97
+ ) {
98
+ grid-template-columns:
99
+ minmax(0, 1fr)
100
+ minmax(0, var(--kui-token-search-expanded-width, 30rem));
101
+ }
102
+
95
103
  .kui-toolbar {
96
104
  --_kui-toolbar-divider-top: transparent;
97
105
  --_kui-toolbar-divider-right: transparent;
@@ -154,6 +162,8 @@
154
162
  display: flex;
155
163
  min-width: 0;
156
164
  min-height: var(--_kui-toolbar-band);
165
+ padding-inline: var(--kui-toolbar-zone-padding-inline, 0px);
166
+ box-sizing: border-box;
157
167
  align-items: flex-start;
158
168
  gap: var(--kui-toolbar-gap, 0.5rem);
159
169
  }
@@ -165,6 +175,11 @@
165
175
  the 3- and 2-column layouts, and still stacks under the leading zone when a
166
176
  consumer collapses the toolbar to a single column. */
167
177
  .kui-toolbar__leading {
178
+ min-width: var(--kui-toolbar-leading-min-width, 0px);
179
+ padding-inline: var(
180
+ --kui-toolbar-leading-padding-inline,
181
+ var(--kui-toolbar-zone-padding-inline, 0px)
182
+ );
168
183
  grid-column: 1;
169
184
  overflow: hidden;
170
185
  }
@@ -175,6 +190,10 @@
175
190
  the leading identity gives way first, the way a platform toolbar truncates
176
191
  its title before it overlaps the centered controls. */
177
192
  min-width: min-content;
193
+ padding-inline: var(
194
+ --kui-toolbar-center-padding-inline,
195
+ var(--kui-toolbar-zone-padding-inline, 0px)
196
+ );
178
197
  justify-content: center;
179
198
  grid-column: 2;
180
199
  }
@@ -189,8 +208,14 @@
189
208
  }
190
209
 
191
210
  .kui-toolbar__trailing {
192
- justify-content: flex-end;
211
+ padding-inline: var(
212
+ --kui-toolbar-trailing-padding-inline,
213
+ var(--kui-toolbar-zone-padding-inline, 0px)
214
+ );
215
+ justify-content: var(--kui-toolbar-trailing-justify, flex-end);
216
+ justify-self: var(--kui-toolbar-trailing-justify-self, stretch);
193
217
  grid-column: -2 / -1;
218
+ gap: var(--kui-toolbar-trailing-gap, var(--kui-toolbar-gap, 0.5rem));
194
219
  /* Trailing actions never clip (KF-4EYES0): the zone wraps its groups, so its
195
220
  track can shrink only to the widest single group. When one row cannot hold
196
221
  every group, the next group moves to a new trailing-aligned row instead of
@@ -198,6 +223,63 @@
198
223
  flex-wrap: wrap;
199
224
  }
200
225
 
226
+ /* An expanded trailing search gets a complete second row while the leading
227
+ identity and optional center controls remain in the first. The query styles
228
+ descendants because a toolbar cannot query its own container width. */
229
+ @container kui-toolbar (max-width: 52rem) {
230
+ .kui-toolbar[data-responsive="trailing-priority"][data-responsive-at="narrow"][data-has-center="false"]:has(
231
+ > .kui-toolbar__trailing [data-expanded="true"]
232
+ )
233
+ > .kui-toolbar__leading {
234
+ grid-column: 1 / -1;
235
+ grid-row: 1;
236
+ }
237
+
238
+ .kui-toolbar[data-responsive="trailing-priority"][data-responsive-at="narrow"]:has(
239
+ > .kui-toolbar__trailing [data-expanded="true"]
240
+ )
241
+ > .kui-toolbar__trailing {
242
+ width: 100%;
243
+ grid-column: 1 / -1;
244
+ grid-row: 2;
245
+ justify-self: stretch;
246
+ }
247
+
248
+ .kui-toolbar[data-responsive="trailing-priority"][data-responsive-at="narrow"]
249
+ > .kui-toolbar__trailing
250
+ > [data-expanded="true"] {
251
+ width: 100%;
252
+ flex: 1 1 100%;
253
+ }
254
+ }
255
+
256
+ @container kui-toolbar (max-width: 44rem) {
257
+ .kui-toolbar[data-responsive="trailing-priority"][data-responsive-at="compact"][data-has-center="false"]:has(
258
+ > .kui-toolbar__trailing [data-expanded="true"]
259
+ )
260
+ > .kui-toolbar__leading {
261
+ grid-column: 1 / -1;
262
+ grid-row: 1;
263
+ }
264
+
265
+ .kui-toolbar[data-responsive="trailing-priority"][data-responsive-at="compact"]:has(
266
+ > .kui-toolbar__trailing [data-expanded="true"]
267
+ )
268
+ > .kui-toolbar__trailing {
269
+ width: 100%;
270
+ grid-column: 1 / -1;
271
+ grid-row: 2;
272
+ justify-self: stretch;
273
+ }
274
+
275
+ .kui-toolbar[data-responsive="trailing-priority"][data-responsive-at="compact"]
276
+ > .kui-toolbar__trailing
277
+ > [data-expanded="true"] {
278
+ width: 100%;
279
+ flex: 1 1 100%;
280
+ }
281
+ }
282
+
201
283
  /* Content-driven wrap: one row while every zone fits at its natural width;
202
284
  otherwise the trailing zone moves below the identity, still trailing-aligned,
203
285
  instead of truncating the leading title or clipping an action. For panel,
@@ -19,7 +19,10 @@
19
19
  position: relative;
20
20
  display: grid;
21
21
  min-height: 2.55rem;
22
- padding-block: 0.5rem;
22
+ padding-block: var(
23
+ --kui-value-table-row-padding-block,
24
+ var(--_kui-value-table-density-padding-block, 0.5rem)
25
+ );
23
26
  padding-inline: var(--_kui-value-table-inline-padding);
24
27
  box-sizing: border-box;
25
28
  /* Two content-sized tracks share the free space equally, and each stops
@@ -29,9 +32,19 @@
29
32
  when both are long they split the row. A `1fr` value track would get
30
33
  nothing until the label reached its full width, starving the value to 0px
31
34
  beside a long single-word label. */
32
- grid-template-columns: minmax(0, auto) minmax(0, auto);
35
+ grid-template-columns: var(
36
+ --kui-value-table-row-columns,
37
+ minmax(0, auto) minmax(0, auto)
38
+ );
33
39
  align-items: center;
34
- gap: var(--kui-layout-item-gap, 0.5rem);
40
+ gap: var(
41
+ --kui-value-table-row-gap,
42
+ var(--_kui-value-table-density-gap, var(--kui-layout-item-gap, 0.5rem))
43
+ );
44
+ }
45
+ .kui-value-table[data-density="compact"] .kui-value-table__row {
46
+ --_kui-value-table-density-padding-block: 0.25rem;
47
+ --_kui-value-table-density-gap: 0.25rem;
35
48
  }
36
49
  .kui-value-table__row[data-has-icon="true"] {
37
50
  --_kui-value-table-separator-start: calc(
package/dist/text.d.ts CHANGED
@@ -7,6 +7,7 @@ type TextTone = 'default' | 'quiet' | 'danger';
7
7
  type TextSize = 'compact' | 'default' | 'large' | 'xlarge';
8
8
  type TextFont = 'default' | 'monospace';
9
9
  type TextBorder = 'transparent' | 'none';
10
+ type TextLineHeight = 'default' | 'tight';
10
11
  type TextContent = KerfUiContent | string | number | readonly TextContent[];
11
12
  type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
12
13
  /** Native heading, paragraph, or inline span element to render. Defaults to `p`. */
@@ -19,6 +20,10 @@ type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
19
20
  font?: TextFont;
20
21
  /** Transparent alignment border or no border when embedded in owner chrome. */
21
22
  border?: TextBorder;
23
+ /** Remove the block variant's item padding and border in compact content. */
24
+ flush?: boolean;
25
+ /** Use compact leading for short dialog or metadata copy. */
26
+ lineHeight?: TextLineHeight;
22
27
  children: TextContent;
23
28
  class?: string;
24
29
  className?: string;
@@ -28,6 +33,6 @@ type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
28
33
  * content-item padding; `span` adds no box geometry.
29
34
  * All ordinary native heading/paragraph attributes pass through to the element.
30
35
  */
31
- declare function Text({ variant: Variant, tone, size, font, border, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
36
+ declare function Text({ variant: Variant, tone, size, font, border, flush, lineHeight, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
32
37
 
33
- export { Text, type TextBorder, type TextContent, type TextFont, type TextProps, type TextSize, type TextTone, type TextVariant };
38
+ export { Text, type TextBorder, type TextContent, type TextFont, type TextLineHeight, type TextProps, type TextSize, type TextTone, type TextVariant };
package/dist/text.js CHANGED
@@ -1,3 +1,3 @@
1
- export { Text } from './chunk-UXT7TE6B.js';
1
+ export { Text } from './chunk-AUKT3KMG.js';
2
2
 
3
3
  //# sourceMappingURL=text.js.map
@@ -1,6 +1,6 @@
1
1
  import * as kerfjs from 'kerfjs';
2
2
 
3
- type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small';
3
+ type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small' | 'xsmall';
4
4
  /** ARIA heading level for a title exposed as a heading landmark. */
5
5
  type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
6
6
  interface ToolbarTextBaseProps {
@@ -1,4 +1,4 @@
1
- export { ToolbarText } from './chunk-XDKAYSVD.js';
1
+ export { ToolbarText } from './chunk-3SXMEK3B.js';
2
2
 
3
3
 
4
4
 
package/dist/toolbar.d.ts CHANGED
@@ -31,9 +31,11 @@ interface ToolbarProps {
31
31
  * - `wrap` keeps one row while every zone fits at its natural width, and
32
32
  * otherwise moves the trailing zone below a whole leading identity.
33
33
  * - `center-priority` gives an expanded center control the full row.
34
+ * - `trailing-priority` moves an expanded trailing control to a full row
35
+ * below the leading identity at `responsiveAt`.
34
36
  */
35
- responsive?: 'none' | 'stack' | 'wrap' | 'center-priority';
36
- /** Container width at which `responsive="stack"` activates. */
37
+ responsive?: 'none' | 'stack' | 'wrap' | 'center-priority' | 'trailing-priority';
38
+ /** Container width at which `stack` or `trailing-priority` activates. */
37
39
  responsiveAt?: 'compact' | 'narrow';
38
40
  /**
39
41
  * Screen edges this toolbar claims for device safe-area compensation, for an
package/dist/toolbar.js CHANGED
@@ -1,3 +1,3 @@
1
- export { Toolbar } from './chunk-6YFHCLHG.js';
1
+ export { Toolbar } from './chunk-MERWRTBG.js';
2
2
 
3
3
  //# sourceMappingURL=toolbar.js.map
@@ -16,11 +16,13 @@ declare function ValueTableRow({ label, value, icon, className, placeholder, slo
16
16
 
17
17
  interface ValueTableProps {
18
18
  label: string;
19
+ /** Compact row spacing for metadata-dense surfaces. */
20
+ density?: 'default' | 'compact';
19
21
  className?: string;
20
22
  children: KerfUiContent;
21
23
  /** Native named-slot assignment when composed inside a web component. */
22
24
  slot?: string;
23
25
  }
24
- declare function ValueTable({ label, className, children, slot, }: ValueTableProps): kerfjs.SafeHtml;
26
+ declare function ValueTable({ label, density, className, children, slot, }: ValueTableProps): kerfjs.SafeHtml;
25
27
 
26
28
  export { ValueTable, type ValueTableProps, ValueTableRow, type ValueTableRowProps };
@@ -1,4 +1,4 @@
1
- export { ValueTable, ValueTableRow } from './chunk-6CINWX2E.js';
1
+ export { ValueTable, ValueTableRow } from './chunk-P7D3EMXM.js';
2
2
 
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
- import { wireWorkbench } from './chunk-KH6VUGHU.js';
1
+ import { wireWorkbench } from './chunk-NNMLEDMD.js';
2
2
  import { wireScrollDividers } from './chunk-JCV4GXWB.js';
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
- export { wireResizableRegions } from './chunk-XQV2B4IL.js';
1
+ export { wireResizableRegions } from './chunk-UIDKY4UB.js';
2
2
 
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
- export { wireTokenSearchFields } from './chunk-UFYZHYWU.js';
1
+ export { wireTokenSearchFields } from './chunk-A3CKOW2R.js';
2
2
 
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
- export { wireWorkbench } from './chunk-KH6VUGHU.js';
1
+ export { wireWorkbench } from './chunk-NNMLEDMD.js';
2
2
 
3
3
 
4
4
 
package/dist/workbench.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Workbench } from './chunk-2CCMJTVY.js';
1
+ export { Workbench } from './chunk-2OXQHM7I.js';
2
2
 
3
3
 
4
4
 
@@ -76,7 +76,13 @@ and that of the components it renders (`Pane`, `Toolbar`, `ToolbarControlGroup`,
76
76
  the region itself (and `inert` on its `.kui-resizable-region__content`
77
77
  wrapper), so its label leaves the accessibility tree with its content; its
78
78
  separator is already hidden while collapsed, and the restore control stays
79
- outside the region.
79
+ outside the region. Its `restorePosition` accepts top or bottom start/end
80
+ corners, with typed `restoreInset` for the corner distance. Set
81
+ `restorePlacement="inline"` when the container should place the control in
82
+ normal flow. An inline region's surface uses
83
+ `--kui-resizable-region-background`; set `contentOverflow="visible"` while
84
+ an anchored popup must escape the region's content box, then return to the
85
+ normal overflow policy when it closes.
80
86
  Overlay presentation also clamps fixed-size animated content to the configured
81
87
  responsive overlay maximum, so a remembered desktop size cannot escape a narrow
82
88
  viewport.
@@ -174,9 +174,69 @@ an upstream component or recipe request.
174
174
 
175
175
  ## Ambiguous choices
176
176
 
177
+ Set `ResizableRegion`'s `--kui-resizable-region-background` for an inline
178
+ surface. Use `contentOverflow="visible"` while an anchored popup must escape
179
+ the region; this also raises the region on its public popup layer. A collapsed
180
+ region can place `restoreControl` in a top or bottom corner with
181
+ `restorePosition`, set its typed `restoreInset`, or use
182
+ `restorePlacement="inline"` for a control in normal flow.
183
+
184
+ Use `FloatingToolbar placement="inline"` when a restore owner supplies the
185
+ position. Floating placement supports per-edge `--kui-floating-toolbar-inset-*`
186
+ tokens; `safeAreaInsets` adds the layout-routed or device safe-area inset to
187
+ the positioned edges.
188
+
189
+ For a larger option row, use `ListItem density="spacious"`; `compact` and
190
+ `standard` remain available. `multiline` wraps its label and aligns its icon
191
+ to the first line; `multilineIconAlign="center"` centers the icon against the
192
+ whole label. `divider` owns a before or after separator. Set
193
+ `state="drag-target"` for the component's drop outline and background. Public
194
+ `--kui-list-item-*` tokens control its row, icon, label, and trailing geometry
195
+ and color. `ListHeader` exposes `--kui-list-header-min-height`, title padding,
196
+ title minimum height, and border-width tokens for section density.
197
+
198
+ Use `Toolbar responsive="trailing-priority"` for a collapsible search in the
199
+ trailing zone that should take a full second row when expanded. `responsiveAt`
200
+ chooses the compact or narrow container breakpoint. The leading identity stays
201
+ in the first row. `--kui-toolbar-leading-min-width`,
202
+ `--kui-toolbar-trailing-gap`, `--kui-toolbar-trailing-justify`, and the
203
+ `--kui-toolbar-*-padding-inline` zone tokens adjust local geometry without
204
+ selecting toolbar anatomy from application CSS.
205
+
206
+ For compact dialog copy, use `Text flush lineHeight="tight"`; block Text still
207
+ resets native margins. `ValueTable density="compact"` reduces row padding and
208
+ gap. Its `--kui-value-table-row-columns`, `--kui-value-table-row-padding-block`,
209
+ and `--kui-value-table-row-gap` tokens support a specific metadata layout.
210
+ Use `ToolbarText size="xsmall"` for a dense rail heading. A
211
+ `TokenSearchField` editor can shrink to zero minimum width inside a narrow
212
+ group; set `--kui-token-search-editor-min-width` only when a wider editor is
213
+ required.
214
+
177
215
  - `Toolbar` serves persistent app chrome and headings; the zone contents and accessible naming distinguish the purpose.
178
216
  - `TabBar` changes tabpanels and supports overflow/reorder; `SegmentedControl` chooses among a few compact views; `Select` handles a longer value list.
217
+
218
+ Use `AppTab presentation="icon-only"` with its `name` kept as the accessible
219
+ tab name, and `labelMaxWidth` for an ellipsized visible name. Set `attention`
220
+ to color a tab's name with `--kui-app-tab-attention-color`. A `TabBar` owns its
221
+ scrolling strip; its public `--kui-tab-bar-strip-*` tokens configure strip
222
+ height, spacing, border, radius, background, and scroll inset without styling
223
+ its internal classes. `--kui-tab-bar-trailing-flex` controls the trailing zone.
224
+
179
225
  - `StateBanner` persists beside affected work; `EmptyState` replaces absent content; `wa-callout` is contextual ecosystem content; `wa-toast` and `wa-toast-item` are transient and must not carry the only copy of important state.
226
+
227
+ For a banner with multi-line supporting copy, use `copyLayout="stacked"` to put
228
+ the detail below the title and badge. Use `actionPlacement="below"` when its
229
+ action needs a separate trailing row. The default values keep both inline;
230
+ `--kui-state-banner-copy-gap` and `--kui-state-banner-copy-row-gap` adjust the
231
+ stacked copy's spacing at an instance boundary.
232
+
233
+ For a compact `Select`, set `triggerWidth` to `"fit-content"`, `"max-content"`,
234
+ or `"fill"` and cap it with `--kui-select-trigger-max-width` when needed.
235
+ Custom `renderSelected` text inherits the control color by default; the
236
+ `--kui-select-selected-color`, `--kui-select-selected-font-size`, and
237
+ `--kui-select-selected-font-weight` tokens configure its typography. Plain
238
+ selected text stays on one ellipsized line when the trigger narrows.
239
+
180
240
  - `ResizableRegion` is an interactive controlled pane. `Grid` is the right answer for static equal-width columns; application CSS grid remains the answer for asymmetric or intrinsic tracks.
181
241
  - A `ResizableRegion`'s content spans the whole region, like its separator. Give
182
242
  it one child — normally a `Pane` — and that child fills the region, so the
@@ -211,6 +271,7 @@ an upstream component or recipe request.
211
271
  - `TokenSearchField` is a structured editor. A native input or `wa-input` is the right answer for ordinary text.
212
272
 
213
273
  For common structured search, use `createTokenSearchModel` from `@kerfjs/ui/token-search-model`, pass the model to `TokenSearchField`, and register it under the field id in `wireTokenSearchFields(root, { models })`. Rules parse `name:value` expressions and provide suggestions; the model owns chips, selection, removal, clear, and an optional evaluation result. Omit `model` and `models` for full manual control.
274
+ When one root contains both kinds of field, a registered model enables chip keyboard behavior only for its own field. Other fields keep native editing unless the root opts into `keyboard` with an application removal callback.
214
275
 
215
276
  ## Toolbar composition
216
277
 
@@ -24,6 +24,9 @@ whose child is a `Workbench`, `SplitView`, `NavStack`, or another percentage-
24
24
  height shell. Ordinary document-flow pages can import the baseline without the
25
25
  class. Do not put `.kui-app-root` on several sibling containers: each requests
26
26
  the full available document height.
27
+ The class sets `height: 100%`, not a viewport minimum; the direct child shell
28
+ must also fill its parent (for example with its `fill` prop). If the host page
29
+ already supplies a definite height, use that host geometry instead.
27
30
 
28
31
  `kui-app-root` is the public class of the component catalog's
29
32
  `document-baseline` entry, so `kerf-ui-doctor` and the
package/llms.txt CHANGED
@@ -151,6 +151,27 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
151
151
  margin. Put `.kui-app-root` on the one direct mount container only when a
152
152
  percentage-height shell needs the provided `html` → `body` → app-root height
153
153
  chain. The baseline is not part of `styles.css` or component browser imports.
154
+ - **Use compact layout options where needed.** `Text flush lineHeight="tight"`
155
+ fits short dialog copy; `ValueTable density="compact"` reduces row spacing,
156
+ with public row column, padding, and gap tokens for specific metadata layouts.
157
+ `ToolbarText size="xsmall"` suits a dense rail heading. The
158
+ `TokenSearchField` editor shrinks in narrow groups; its minimum width can be
159
+ set with `--kui-token-search-editor-min-width`.
160
+ - **Use Toolbar zone options.** `responsive="trailing-priority"` moves an
161
+ expanded trailing control to a full second row at `responsiveAt`; the leading
162
+ title remains above it. Public leading-min-width, trailing-gap/justify, and
163
+ per-zone inline-padding tokens cover app-specific toolbar geometry.
164
+ - **Position region restore controls declaratively.** A ResizableRegion has a
165
+ background token, `contentOverflow="visible"` for an anchored popup,
166
+ top/bottom `restorePosition`, typed `restoreInset`, and
167
+ `restorePlacement="inline"` for normal flow. FloatingToolbar also has
168
+ `placement="inline"`, per-edge inset tokens, and `safeAreaInsets`.
169
+ - **Configure list rows through their APIs.** `ListItem density="spacious"`
170
+ gives option rows more room. `multiline` wraps labels, with
171
+ `multilineIconAlign="center"` when the icon should center on the whole copy.
172
+ `divider` owns row separators and `state="drag-target"` paints the drop
173
+ target. Public ListItem tokens set row, icon, label, and trailing geometry;
174
+ ListHeader height, title padding, and border tokens tune section density.
154
175
  - **Use `Row` for horizontal and `List` for vertical layout.** Both expose
155
176
  physical `hAlign`/`vAlign` props and typed gaps. Row defaults to left/full,
156
177
  an `xs` gap, and no wrapping; List retains full/top and zero-gap defaults.
@@ -374,6 +395,17 @@ headingLevel`, `TokenSearchField clearIcon`, `ContentItem frame="framed"` for a
374
395
  optional string `badge` for a terse count or status beside the title. It
375
396
  inherits the banner tone and is announced with the banner, so keep its text
376
397
  meaningful and never rely on color alone.
398
+ - **Configure StateBanner copy and action placement.** `copyLayout="stacked"`
399
+ puts detail below the title and badge; `actionPlacement="below"` gives the
400
+ action a separate trailing row. The inline defaults remain compact.
401
+ - **Size a Select through its API.** `triggerWidth` chooses `fit-content`,
402
+ `max-content`, or `fill`; `--kui-select-trigger-max-width` caps it. For custom
403
+ selected text, use the public color, font-size, and font-weight tokens; the
404
+ closed value ellipsizes when space runs out.
405
+ - **Configure application tabs at their owners.** AppTab's `icon-only`
406
+ presentation keeps `name` accessible, `labelMaxWidth` ellipsizes a long name,
407
+ and `attention` uses `--kui-app-tab-attention-color`. TabBar's public
408
+ `--kui-tab-bar-strip-*` tokens set compact strip geometry.
377
409
  - **Use `Badge` for compact non-interactive metadata.** Configure its semantic
378
410
  tone, appearance, shape, and size instead of creating badge CSS in an app or
379
411
  consuming component. Use a real button or link for interactive content.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kerfjs/ui",
3
- "version": "5.0.0-beta.59",
3
+ "version": "5.0.0-beta.60",
4
4
  "description": "Accessible, composable UI primitives for kerf applications.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/value-table-row.tsx","../src/value-table.tsx"],"names":["jsx"],"mappings":";;;;AAgBO,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,WAAA,GAAc,KAAA;AAAA,EACd;AACF,CAAA,EAAuB;AACrB,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,qBAAA,EAAwB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAChD,eAAA,EAAe,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,MACnC,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,MACzC,IAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,IAAA,EAAA,EACE,QAAA,EAAA;AAAA,UAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,uBAAA,EAAyB,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,0BACnD,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,wBAAA,EAA0B,QAAA,EAAA,KAAA,EAAM;AAAA,SAAA,EAC9C,CAAA;AAAA,wBACA,GAAA,CAAC,IAAA,EAAA,EAAI,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,QAAA,EAAA,EAAS,OAAO,EAAA,CAAG,EAAE,CAAA,EAAG,CAAA,GAAK,KAAA,EAAM;AAAA;AAAA;AAAA,GACzD;AAEJ;AC1BO,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,QAAA;AAAA,EACA;AACF,CAAA,EAAoB;AAClB,EAAA,uBACEA,GAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,gBAAA,EAAmB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC3C,gBAAA,EAAe,aAAA;AAAA,MACf,YAAA,EAAY,KAAA;AAAA,MACZ,IAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"chunk-6CINWX2E.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { em } from './css-values.js';\nimport { Skeleton } from './skeleton.js';\n\nexport interface ValueTableRowProps {\n label: string | SafeHtml;\n value: string | SafeHtml;\n icon?: SafeHtml;\n className?: string;\n /** Render the value as an unanimated loading skeleton, keeping the field label. */\n placeholder?: boolean;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport function ValueTableRow({\n label,\n value,\n icon,\n className = '',\n placeholder = false,\n slot,\n}: ValueTableRowProps) {\n return (\n <div\n class={`kui-value-table__row ${className}`.trim()}\n data-has-icon={String(Boolean(icon))}\n data-placeholder={placeholder ? 'true' : undefined}\n slot={slot}\n >\n <dt>\n {icon && <span class=\"kui-value-table__icon\">{icon}</span>}\n <span class=\"kui-value-table__label\">{label}</span>\n </dt>\n <dd>{placeholder ? <Skeleton width={em(10)} /> : value}</dd>\n </div>\n );\n}\n","import type { KerfUiContent } from './semantic-content.js';\n\nexport { ValueTableRow, type ValueTableRowProps } from './value-table-row.js';\n\nexport interface ValueTableProps {\n label: string;\n className?: string;\n children: KerfUiContent;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport function ValueTable({\n label,\n className = '',\n children,\n slot,\n}: ValueTableProps) {\n return (\n <dl\n class={`kui-value-table ${className}`.trim()}\n data-component=\"value-table\"\n aria-label={label}\n slot={slot}\n >\n {children}\n </dl>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/toolbar.tsx"],"names":[],"mappings":";;;AAiEA,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,EAAA;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-6YFHCLHG.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 /**\n * Physical divider edges in canonical top/right/bottom/left order, drawn\n * always. Defaults to none: a toolbar pinned over or under scrolling content\n * gets its divider from the scroll state instead — a `Pane` draws the line\n * between its chrome and content while content is scrolled away beneath it,\n * and `wireScrollDividers` `targets` can name a toolbar as chrome, which\n * then draws its facing side the same way.\n */\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 = '',\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/state-banner.tsx"],"names":[],"mappings":";;;;;AA2BO,SAAS,WAAA,CAAY;AAAA,EAC1B,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA,GAAO,MAAA;AAAA,EACP,OAAA,GAAU,QAAA;AAAA,EACV,SAAA,GAAY,EAAA;AAAA,EACZ,WAAA,GAAc,KAAA;AAAA,EACd;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,SAAA,GAAY,IAAA,KAAS,MAAA,GAAS,OAAA,GAAU,IAAA;AAC9C,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;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,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,MACzC,IAAA,EAAM,OAAA;AAAA,MACN,WAAA,EAAW,OAAA,KAAY,OAAA,GAAU,WAAA,GAAc,QAAA;AAAA,MAC/C,WAAA,EAAW,cAAc,MAAA,GAAS,MAAA;AAAA,MAClC,IAAA;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,wBAAA,EAA0B,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,wBACpD,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,wBAAA,EACT,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,QAAA,EAAA,EAAQ,wCAAc,GAAA,CAAC,QAAA,EAAA,EAAS,OAAO,EAAA,CAAG,EAAE,CAAA,EAAG,CAAA,GAAK,KAAA,EAAM,CAAA;AAAA,UAC1D,yBACC,GAAA,CAAC,KAAA,EAAA,EAAM,UAAA,EAAW,OAAA,EAAQ,MAAK,SAAA,EAAU,IAAA,EAAM,SAAA,EAC5C,QAAA,EAAA,WAAA,uBAAe,QAAA,EAAA,EAAS,KAAA,EAAO,GAAG,IAAI,CAAA,EAAG,IAAK,KAAA,EACjD,CAAA;AAAA,UAED,0BACC,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,0BAAA,EACV,8BAAC,MAAA,EAAA,EAAM,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,QAAA,EAAA,EAAS,OAAO,EAAA,CAAG,EAAE,CAAA,EAAG,CAAA,GAAK,QAAO,CAAA,EAC5D;AAAA,SAAA,EAEJ,CAAA;AAAA,QACC,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,4BAA4B,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,GAC3D;AAEJ","file":"chunk-EVYKTVBQ.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { Badge } from './badge.js';\nimport { em } from './css-values.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport { Skeleton } from './skeleton.js';\n\nexport type StateBannerTone =\n 'neutral' | 'info' | 'pop' | 'success' | 'warning' | 'danger';\nexport type StateBannerUrgency = 'status' | 'alert';\n\nexport interface StateBannerProps {\n title: string;\n detail?: string;\n /** Optional compact status or count shown beside the title. */\n badge?: string;\n icon?: SafeHtml;\n action?: KerfUiContent;\n tone?: StateBannerTone;\n urgency?: StateBannerUrgency;\n className?: string;\n /** Render the title, badge, and detail as unanimated loading skeletons, keeping the icon and tone. The detail line appears only when `detail` is set, as in the live banner. */\n placeholder?: boolean;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport function StateBanner({\n title,\n detail,\n badge,\n icon,\n action,\n tone = 'info',\n urgency = 'status',\n className = '',\n placeholder = false,\n slot,\n}: StateBannerProps) {\n const badgeTone = tone === 'info' ? 'brand' : tone;\n return (\n <section\n class={`kui-state-banner ${className}`.trim()}\n data-component=\"state-banner\"\n data-tone={tone}\n data-placeholder={placeholder ? 'true' : undefined}\n role={urgency}\n aria-live={urgency === 'alert' ? 'assertive' : 'polite'}\n aria-busy={placeholder ? 'true' : undefined}\n slot={slot}\n >\n {icon && <span class=\"kui-state-banner__icon\">{icon}</span>}\n <div class=\"kui-state-banner__copy\">\n <strong>{placeholder ? <Skeleton width={em(10)} /> : title}</strong>\n {badge && (\n <Badge appearance=\"solid\" size=\"compact\" tone={badgeTone}>\n {placeholder ? <Skeleton width={em(1.75)} /> : badge}\n </Badge>\n )}\n {detail && (\n <span class=\"kui-state-banner__detail\">\n <span>{placeholder ? <Skeleton width={em(16)} /> : detail}</span>\n </span>\n )}\n </div>\n {action && <div class=\"kui-state-banner__action\">{action}</div>}\n </section>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/floating-toolbar.tsx"],"names":[],"mappings":";;;AA4CO,SAAS,eAAA,CAAgB;AAAA,EAC9B,QAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA,GAAW,YAAA;AAAA,EACX,KAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAyB;AACvB,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,qBAAA,EAAwB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAChD,gBAAA,EAAe,kBAAA;AAAA,MACf,eAAA,EAAe,QAAA;AAAA,MACf,IAAA,EAAK,SAAA;AAAA,MACL,YAAA,EAAY,KAAA;AAAA,MACZ,KAAA,EAAO,KAAA,GAAQ,CAAA,6BAAA,EAAgC,KAAK,CAAA,CAAA,GAAK,MAAA;AAAA,MACzD,IAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"chunk-M7QV3IHH.js","sourcesContent":["import type { CssLength } from './css-values.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\n/** Where a {@link FloatingToolbar} floats within its positioned container. */\nexport type FloatingToolbarPosition =\n 'bottom' | 'bottom-start' | 'bottom-end' | 'top' | 'top-start' | 'top-end';\n\nexport interface FloatingToolbarProps {\n /** Toolbar contents — normally one or more `ToolbarControlGroup`s. */\n children: KerfUiContent;\n /** Accessible name for the toolbar (required — it exposes `role=\"toolbar\"`). */\n label: string;\n /**\n * Corner or edge it floats to inside its nearest positioned ancestor.\n * Default: `'bottom-end'`.\n */\n position?: FloatingToolbarPosition;\n /**\n * Distance from the container edges named by `position`. Default:\n * `space('m')` (16px, 8px past a top toolbar's own inset). Omit it inside a\n * `Workbench`, `CollapsiblePanel`, or `ResizableRegion` restore corner: the\n * corner owns the inset there and sets it to zero.\n */\n inset?: CssLength;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A toolbar that floats above the main content of its nearest positioned\n * ancestor — a transparent, forced-dark cluster of controls (e.g. a drawer\n * restore button) that sits over the content but NOT over dialogs or overlays\n * (it is not in the top layer). It is inset from the container edges by\n * `inset` (default `--kui-space-m`, i.e. 8px more than a top toolbar's own\n * inset); pass a typed length to move it. Inside a `Workbench`, `CollapsiblePanel`, or\n * `ResizableRegion` restore corner the corner owns the inset, so the toolbar\n * floats from the corner's own position. While one of those layouts has a\n * side overlay open over the toolbar's region (a Workbench rail overlay, a\n * `wireSidebar` compact overlay, an overlay `CollapsiblePanel` or horizontal\n * `ResizableRegion`), the toolbar is hidden — unfocusable and out of the\n * accessibility tree — until the overlay closes. The app owns the controls\n * and their behavior — wire them with `delegate()` as usual.\n */\nexport function FloatingToolbar({\n children,\n label,\n position = 'bottom-end',\n inset,\n className = '',\n slot,\n}: FloatingToolbarProps) {\n return (\n <div\n class={`kui-floating-toolbar ${className}`.trim()}\n data-component=\"floating-toolbar\"\n data-position={position}\n role=\"toolbar\"\n aria-label={label}\n style={inset ? `--kui-floating-toolbar-inset:${inset}` : undefined}\n slot={slot}\n >\n {children}\n </div>\n );\n}\n"]}