@kerfjs/ui 5.0.0-beta.35 → 5.0.0-beta.36

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 (50) hide show
  1. package/README.md +9 -3
  2. package/ai/component-catalog-v2.json +4 -4
  3. package/ai/component-catalog.json +31 -17
  4. package/ai/public-api-signatures-v1.md +31 -13
  5. package/ai/skill.md +2 -2
  6. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  7. package/dist/catalog.js +2 -2
  8. package/dist/{chunk-MFR2IIFG.js → chunk-2TYUFZUC.js} +3 -1
  9. package/dist/chunk-2TYUFZUC.js.map +1 -0
  10. package/dist/{chunk-OC275HHS.js → chunk-5FJ53EOF.js} +5 -1
  11. package/dist/chunk-5FJ53EOF.js.map +1 -0
  12. package/dist/{chunk-QHCBZTDK.js → chunk-AVZ2IMWG.js} +5 -1
  13. package/dist/chunk-AVZ2IMWG.js.map +1 -0
  14. package/dist/{chunk-KFUUFNTS.js → chunk-EYALJQQD.js} +12 -2
  15. package/dist/chunk-EYALJQQD.js.map +1 -0
  16. package/dist/{chunk-7JQAQWVC.js → chunk-TNXDXSGP.js} +5 -1
  17. package/dist/chunk-TNXDXSGP.js.map +1 -0
  18. package/dist/divider-sides-BzB6rphT.d.ts +6 -0
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +5 -5
  21. package/dist/list-header.d.ts +4 -1
  22. package/dist/list-header.js +1 -1
  23. package/dist/list-inset-control.d.ts +5 -2
  24. package/dist/list-inset-control.js +1 -1
  25. package/dist/list-inset-text.d.ts +6 -3
  26. package/dist/list-inset-text.js +1 -1
  27. package/dist/list.d.ts +7 -3
  28. package/dist/list.js +1 -1
  29. package/dist/row.d.ts +7 -2
  30. package/dist/row.js +1 -1
  31. package/dist/styles/list-header.css +27 -0
  32. package/dist/styles/list-inset-control.css +17 -1
  33. package/dist/styles/list-inset-text.css +27 -11
  34. package/dist/styles/list.css +46 -0
  35. package/dist/styles/row.css +46 -0
  36. package/dist/toolbar.d.ts +1 -1
  37. package/docs/component-contract.md +6 -3
  38. package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
  39. package/docs/design/templates/list-header/inline-action.svg +1 -0
  40. package/docs/design/templates/list-header-dark.svg +1 -1
  41. package/docs/design/templates/list-header.svg +1 -1
  42. package/docs/layout.md +13 -0
  43. package/llms.txt +4 -0
  44. package/package.json +1 -1
  45. package/dist/chunk-7JQAQWVC.js.map +0 -1
  46. package/dist/chunk-KFUUFNTS.js.map +0 -1
  47. package/dist/chunk-MFR2IIFG.js.map +0 -1
  48. package/dist/chunk-OC275HHS.js.map +0 -1
  49. package/dist/chunk-QHCBZTDK.js.map +0 -1
  50. package/dist/divider-sides-267FA7sY.d.ts +0 -4
package/README.md CHANGED
@@ -138,7 +138,12 @@ Use `Row` for horizontal flex composition and `List` for vertical composition.
138
138
  Both accept `hAlign` (`left`, `center`, `right`, `full`) and `vAlign` (`top`,
139
139
  `middle`, `bottom`, `full`), plus their documented short/CSS aliases. `Row`
140
140
  defaults to left/full alignment, the `xs` gap, and `wrap={false}`; List keeps
141
- its existing full/top alignment and zero-gap defaults.
141
+ its existing full/top alignment and zero-gap defaults. Set `textInsets` or
142
+ `controlInsets` with canonical physical sides in `t`/`r`/`b`/`l` order (for
143
+ example, `textInsets="tbl"` or `controlInsets="r"`). Text geometry takes
144
+ precedence where both select the same side. `ListInsetText` and
145
+ `ListInsetControl` inset all four sides by default and accept the same `sides`
146
+ grammar for selective insets.
142
147
 
143
148
  The same property-specific boundary applies beyond spacing: use `flex()` (or a
144
149
  finite keyword) for `Row.flex` and `List.flex`; length builders and intrinsic-size keywords for
@@ -221,8 +226,9 @@ transform is applied. Direction changes take the shortest rotation path; a
221
226
  real controlled content and preserve the button's stable label; ordinary
222
227
  navigation must not display a disclosure arrow. A custom `actionIcon` remains
223
228
  an escape hatch and replaces the default arrow entirely. The header fills its
224
- available inline width, keeping a separate action at the logical end in a 44px
225
- target. Its visible action glyph defaults to 18px through
229
+ available inline width by default; set `inline` to shrink-wrap it beside other
230
+ content and remove its root margin, border, and padding. It keeps a separate
231
+ action at the logical end. Its visible action glyph defaults to 18px through
226
232
  `--kui-list-header-action-icon-size`.
227
233
 
228
234
  ## Machine-readable catalog
@@ -1436,9 +1436,9 @@
1436
1436
  "geometry": {
1437
1437
  "margin": "none",
1438
1438
  "border": "none",
1439
- "padding": "none",
1439
+ "padding": "conditional",
1440
1440
  "notes": [
1441
- "Row adds no margin, border, or padding; it owns only flex participation, alignment, wrapping, and the gap between children."
1441
+ "Row adds no margin or border. textInsets adds the full 17px content inset and controlInsets adds 8px on selected physical sides; text wins when both select a side."
1442
1442
  ]
1443
1443
  }
1444
1444
  },
@@ -1521,9 +1521,9 @@
1521
1521
  "geometry": {
1522
1522
  "margin": "none",
1523
1523
  "border": "conditional",
1524
- "padding": "none",
1524
+ "padding": "conditional",
1525
1525
  "notes": [
1526
- "List adds no margin or padding; dividerSides draws only the selected physical edges without changing box geometry."
1526
+ "List adds no margin. dividerSides draws selected physical edges without changing geometry; textInsets adds the full 17px content inset and controlInsets adds 8px on selected sides, with text winning on overlap."
1527
1527
  ]
1528
1528
  }
1529
1529
  },
@@ -1642,9 +1642,9 @@
1642
1642
  "category": "Structure",
1643
1643
  "kind": "component",
1644
1644
  "source": "kerf",
1645
- "description": "A horizontal flex row with physical-axis alignment, a typed xs gap by default, flex participation, and opt-in wrapping.",
1645
+ "description": "A horizontal flex row with physical-axis alignment, side-selectable text/control insets, a typed xs gap by default, flex participation, and opt-in wrapping.",
1646
1646
  "uses": [],
1647
- "purpose": "Arrange related content horizontally with consistent spacing and explicit left/center/right/full plus top/middle/bottom/full alignment instead of application-owned flex wrappers.",
1647
+ "purpose": "Arrange related content horizontally with consistent spacing, optional physical-side text/control insets, and explicit left/center/right/full plus top/middle/bottom/full alignment instead of application-owned flex wrappers.",
1648
1648
  "publicExports": ["Row"],
1649
1649
  "cssValueProps": [
1650
1650
  {
@@ -1674,6 +1674,7 @@
1674
1674
  "Choose physical horizontal distribution and vertical alignment without writing one-off flex CSS.",
1675
1675
  "Use a finite flex keyword or the flex() builder when Row participates in a flexible parent layout.",
1676
1676
  "Allow a bounded group to wrap while retaining the same typed gap and alignment contract."
1677
+ ,"Apply the standard text or control inset to selected physical sides without an application wrapper."
1677
1678
  ],
1678
1679
  "avoidWhen": [
1679
1680
  "Do not use Row when content belongs in a semantic list or when a named-zone component such as Toolbar owns the composition.",
@@ -1703,7 +1704,8 @@
1703
1704
  "named none/2xs/xs/s/m/l/xl token gap",
1704
1705
  "typed CssLength gap",
1705
1706
  "boolean, finite-keyword, or typed CssFlex flex",
1706
- "nowrap or wrapping"
1707
+ "nowrap or wrapping",
1708
+ "top/right/bottom/left text and control inset combinations"
1707
1709
  ],
1708
1710
  "accessibility": [
1709
1711
  "Row adds layout only and no grouping role; children retain responsibility for native or ARIA semantics.",
@@ -1712,9 +1714,9 @@
1712
1714
  "geometry": {
1713
1715
  "margin": "none",
1714
1716
  "border": "none",
1715
- "padding": "none",
1717
+ "padding": "conditional",
1716
1718
  "notes": [
1717
- "Row adds no margin, border, or padding; it owns only flex participation, alignment, wrapping, and the gap between children."
1719
+ "Row adds no margin or border. textInsets adds the full 17px content inset and controlInsets adds 8px on selected physical sides; text wins when both select a side."
1718
1720
  ]
1719
1721
  },
1720
1722
  "delivery": {
@@ -1737,13 +1739,13 @@
1737
1739
  "category": "Navigation",
1738
1740
  "kind": "component",
1739
1741
  "source": "kerf",
1740
- "description": "A vertical stack with physical-axis alignment, optional typed token/length gap, flex growth, vertical scrolling, and independently selectable divider edges.",
1742
+ "description": "A vertical stack with physical-axis alignment, side-selectable text/control insets, optional typed token/length gap, flex growth, vertical scrolling, and independently selectable divider edges.",
1741
1743
  "uses": [
1742
1744
  "list-header",
1743
1745
  "list-action-row",
1744
1746
  "list-item"
1745
1747
  ],
1746
- "purpose": "Standardize vertical component layout and its scroll/divider ownership instead of repeating ad-hoc flex-column wrappers.",
1748
+ "purpose": "Standardize vertical component layout, optional physical-side text/control insets, and scroll/divider ownership instead of repeating ad-hoc flex-column wrappers.",
1747
1749
  "publicExports": [
1748
1750
  "List",
1749
1751
  "px",
@@ -1783,7 +1785,8 @@
1783
1785
  "Arrange component rows or sections in a vertical stretch-aligned stack.",
1784
1786
  "Let one bounded list own vertical scrolling, flex growth, or one or more physical-edge dividers.",
1785
1787
  "Choose a finite gap shorthand such as xs or m, or compose a typed length with @kerfjs/ui/css-values when the spacing scale is insufficient.",
1786
- "Use a finite flex keyword or the flex() builder when List participates in flexible layout."
1788
+ "Use a finite flex keyword or the flex() builder when List participates in flexible layout.",
1789
+ "Apply the standard text or control inset to selected physical sides without an application wrapper."
1787
1790
  ,"Align children horizontally or distribute them vertically with the same physical alignment vocabulary as Row."
1788
1791
  ],
1789
1792
  "avoidWhen": [
@@ -1806,7 +1809,8 @@
1806
1809
  "scrollable",
1807
1810
  "left/center/right/full horizontal alignment",
1808
1811
  "top/middle/bottom/full vertical alignment",
1809
- "top/right/bottom/left divider combinations"
1812
+ "top/right/bottom/left divider combinations",
1813
+ "top/right/bottom/left text and control inset combinations"
1810
1814
  ],
1811
1815
  "accessibility": [
1812
1816
  "List adds layout only and no list role; children retain responsibility for their native or ARIA semantics.",
@@ -1815,9 +1819,9 @@
1815
1819
  "geometry": {
1816
1820
  "margin": "none",
1817
1821
  "border": "conditional",
1818
- "padding": "none",
1822
+ "padding": "conditional",
1819
1823
  "notes": [
1820
- "List adds no margin or padding; dividerSides draws only the selected physical edges without changing box geometry."
1824
+ "List adds no margin. dividerSides draws selected physical edges without changing geometry; textInsets adds the full 17px content inset and controlInsets adds 8px on selected sides, with text winning on overlap."
1821
1825
  ]
1822
1826
  },
1823
1827
  "delivery": {
@@ -1849,12 +1853,12 @@
1849
1853
  "category": "Navigation",
1850
1854
  "kind": "component",
1851
1855
  "source": "kerf",
1852
- "description": "Configurable section headings with semantic count/status indicators, density, group dividers, a logical-end action, disclosure states, and protected native-popover trigger metadata.",
1856
+ "description": "Configurable section headings with full-width or shrink-wrapped inline presentation, semantic count/status indicators, density, group dividers, a logical-end action, disclosure states, and protected native-popover trigger metadata.",
1853
1857
  "uses": [
1854
1858
  "lucide-icon",
1855
1859
  "disclosure-arrow"
1856
1860
  ],
1857
- "purpose": "Fill the available section width while splitting a dormant title and mutually exclusive semantic count or legacy badge from an optional logical-end 44px action with an 18px visual, or render that title cluster as a disclosure button with a default production DisclosureArrow.",
1861
+ "purpose": "Fill the available section width by default, or shrink-wrap without outer geometry when inline, while splitting a dormant title and mutually exclusive semantic count or legacy badge from an optional logical-end action with an 18px visual; disclosure mode renders the title cluster as a button with a default production DisclosureArrow.",
1858
1862
  "publicExports": [
1859
1863
  "ListHeader"
1860
1864
  ],
@@ -1887,6 +1891,7 @@
1887
1891
  "action",
1888
1892
  "toggle",
1889
1893
  "placeholder (loading)",
1894
+ "inline shrink-wrapped presentation",
1890
1895
  "compact density",
1891
1896
  "neutral, accent, pop, or danger indicator tone",
1892
1897
  "before, after, or paired group divider"
@@ -2186,9 +2191,9 @@
2186
2191
  "category": "Structure",
2187
2192
  "kind": "component",
2188
2193
  "source": "kerf",
2189
- "description": "Insets a self-bordered control into a pane/list content region.",
2194
+ "description": "Insets selected physical sides of a self-bordered control in a pane/list content region.",
2190
2195
  "uses": [],
2191
- "purpose": "Insets a self-bordered control into a pane/list content region.",
2196
+ "purpose": "Apply the standard 8px outer margin to all physical sides of a self-bordered control by default, or only the sides selected with the canonical Sides contract.",
2192
2197
  "publicExports": [
2193
2198
  "ListInsetControl"
2194
2199
  ],
@@ -2207,6 +2212,10 @@
2207
2212
  "appOwns": [
2208
2213
  "the wrapped control and its behavior"
2209
2214
  ],
2215
+ "variants": [
2216
+ "all-side inset by default",
2217
+ "top/right/bottom/left inset combinations"
2218
+ ],
2210
2219
  "accessibility": [
2211
2220
  "A layout wrapper only; it adds no role or name — the wrapped control keeps its own."
2212
2221
  ],
@@ -2241,9 +2250,9 @@
2241
2250
  "category": "Structure",
2242
2251
  "kind": "component",
2243
2252
  "source": "kerf",
2244
- "description": "Gives bare text the content-item geometry so it lines up with bordered items.",
2253
+ "description": "Gives selected physical sides of bare text the content-item geometry so it lines up with bordered items.",
2245
2254
  "uses": [],
2246
- "purpose": "Gives bare text the content-item geometry so it lines up with bordered items.",
2255
+ "purpose": "Apply the full 8px margin + 1px transparent border + 8px padding to all physical sides of bare text by default, or only the sides selected with the canonical Sides contract.",
2247
2256
  "publicExports": [
2248
2257
  "ListInsetText"
2249
2258
  ],
@@ -2262,6 +2271,11 @@
2262
2271
  "appOwns": [
2263
2272
  "the text content"
2264
2273
  ],
2274
+ "variants": [
2275
+ "all-side inset by default",
2276
+ "top/right/bottom/left inset combinations",
2277
+ "deprecated horizontalOnly compatibility alias for sides=\"rl\""
2278
+ ],
2265
2279
  "accessibility": [
2266
2280
  "A layout wrapper only; it adds no role or name."
2267
2281
  ],
@@ -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.35` and `kerfjs@5.0.0-beta.35`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
3
+ Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.36` and `kerfjs@5.0.0-beta.36`. 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
 
@@ -105,7 +105,7 @@ export { DisclosureArrow, type DisclosureArrowProps, type DisclosureDirection };
105
105
 
106
106
  ```ts
107
107
  import * as kerfjs from 'kerfjs';
108
- import { D as DividerSides } from './divider-sides-267FA7sY.js';
108
+ import { D as DividerSides } from './divider-sides-BzB6rphT.js';
109
109
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
110
110
 
111
111
  interface ToolbarProps {
@@ -257,6 +257,7 @@ type ListHeaderRootAttributes = Readonly<Record<`data-${string}`, string | undef
257
257
  'data-has-count'?: never;
258
258
  'data-density'?: never;
259
259
  'data-divider'?: never;
260
+ 'data-inline'?: never;
260
261
  'data-indicator-tone'?: never;
261
262
  'data-toggle'?: never;
262
263
  }>;
@@ -271,6 +272,8 @@ interface ListHeaderBaseProps {
271
272
  label: string;
272
273
  density?: 'standard' | 'compact';
273
274
  divider?: 'none' | 'before' | 'after' | 'both';
275
+ /** Shrink-wrap the header without its default outer margin, border, or padding. */
276
+ inline?: boolean;
274
277
  indicatorTone?: 'neutral' | 'accent' | 'pop' | 'danger';
275
278
  /** Render as an unanimated loading skeleton: keep the label and action affordance, disable interaction. */
276
279
  placeholder?: boolean;
@@ -322,7 +325,7 @@ type ListHeaderIndicatorProps = {
322
325
  status?: SafeHtml;
323
326
  };
324
327
  type ListHeaderProps = ListHeaderBaseProps & ListHeaderIndicatorProps & ListHeaderModeProps;
325
- declare function ListHeader({ label, count, countLabel, badge, status, density, divider, indicatorTone, action, actionLabel, actionIcon, actionDisabled, disabledReason, expanded, toggle, placeholder, rootAttributes, triggerAttributes, }: ListHeaderProps): SafeHtml;
328
+ declare function ListHeader({ label, count, countLabel, badge, status, density, divider, inline, indicatorTone, action, actionLabel, actionIcon, actionDisabled, disabledReason, expanded, toggle, placeholder, rootAttributes, triggerAttributes, }: ListHeaderProps): SafeHtml;
326
329
 
327
330
  export { ListHeader, type ListHeaderProps };
328
331
  ```
@@ -332,7 +335,7 @@ export { ListHeader, type ListHeaderProps };
332
335
  ```ts
333
336
  import * as kerfjs from 'kerfjs';
334
337
  import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
335
- import { D as DividerSides } from './divider-sides-267FA7sY.js';
338
+ import { D as DividerSides, S as Sides } from './divider-sides-BzB6rphT.js';
336
339
  import { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-CF8NLj7i.js';
337
340
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
338
341
 
@@ -350,12 +353,16 @@ interface ListProps {
350
353
  scrollable?: boolean;
351
354
  /** Physical divider edges in canonical top/right/bottom/left order. */
352
355
  dividerSides?: DividerSides;
356
+ /** Physical sides that receive the standard 17px text inset. */
357
+ textInsets?: Sides;
358
+ /** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */
359
+ controlInsets?: Sides;
353
360
  className?: string;
354
361
  }
355
362
  /** A stretch-aligned vertical stack with optional gap, flex, scroll, and dividers. */
356
- declare function List({ children, gap, flex, hAlign, vAlign, scrollable, dividerSides, className, }: ListProps): kerfjs.SafeHtml;
363
+ declare function List({ children, gap, flex, hAlign, vAlign, scrollable, dividerSides, textInsets, controlInsets, className, }: ListProps): kerfjs.SafeHtml;
357
364
 
358
- export { CssFlex, CssFlexKeyword, CssLength, DividerSides, HorizontalAlignment, List, type ListProps, UiSpaceName, VerticalAlignment };
365
+ export { CssFlex, CssFlexKeyword, CssLength, DividerSides, HorizontalAlignment, List, type ListProps, Sides, UiSpaceName, VerticalAlignment };
359
366
  ```
360
367
 
361
368
  ## `@kerfjs/ui/list-action-row`
@@ -478,11 +485,14 @@ export { ListItem, type ListItemProps };
478
485
 
479
486
  ```ts
480
487
  import * as kerfjs from 'kerfjs';
488
+ import { S as Sides } from './divider-sides-BzB6rphT.js';
481
489
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
482
490
 
483
491
  interface ListInsetControlProps {
484
492
  /** Control(s) that own their own border and padding (e.g. an input, a `wa-*`). */
485
493
  children: KerfUiContent;
494
+ /** Physical inset sides in canonical top/right/bottom/left order. Defaults to all sides. */
495
+ sides?: Sides;
486
496
  className?: string;
487
497
  }
488
498
  /**
@@ -491,22 +501,25 @@ interface ListInsetControlProps {
491
501
  * Use it for controls that carry their own border and padding but no outer margin
492
502
  * — the wrapper adds only the alignment margin and layout, not a second inset.
493
503
  */
494
- declare function ListInsetControl({ children, className, }: ListInsetControlProps): kerfjs.SafeHtml;
504
+ declare function ListInsetControl({ children, sides, className, }: ListInsetControlProps): kerfjs.SafeHtml;
495
505
 
496
- export { ListInsetControl, type ListInsetControlProps };
506
+ export { ListInsetControl, type ListInsetControlProps, Sides };
497
507
  ```
498
508
 
499
509
  ## `@kerfjs/ui/list-inset-text`
500
510
 
501
511
  ```ts
502
512
  import * as kerfjs from 'kerfjs';
513
+ import { S as Sides } from './divider-sides-BzB6rphT.js';
503
514
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
504
515
 
505
516
  interface ListInsetTextProps {
506
517
  /** Text (or inline content) that carries no margin, border, or padding of its own. */
507
518
  children: KerfUiContent | string;
519
+ /** Physical inset sides in canonical top/right/bottom/left order. Defaults to all sides. */
520
+ sides?: Sides;
508
521
  /**
509
- * Keep only the horizontal geometry (inline margin, left/right border, and
522
+ * @deprecated Pass `sides="rl"` instead. Keep only the horizontal geometry (inline margin, left/right border, and
510
523
  * left/right padding) and drop the vertical margin, border, and padding. Use it
511
524
  * when the text edge must still align with bordered items but the line should not
512
525
  * add its own vertical box space — tight text layout inside a content region.
@@ -522,9 +535,9 @@ interface ListInsetTextProps {
522
535
  * Pass `horizontalOnly` to keep the horizontal inset but drop the vertical box
523
536
  * space for tight text layout.
524
537
  */
525
- declare function ListInsetText({ children, horizontalOnly, className, }: ListInsetTextProps): kerfjs.SafeHtml;
538
+ declare function ListInsetText({ children, sides, horizontalOnly, className, }: ListInsetTextProps): kerfjs.SafeHtml;
526
539
 
527
- export { ListInsetText, type ListInsetTextProps };
540
+ export { ListInsetText, type ListInsetTextProps, Sides };
528
541
  ```
529
542
 
530
543
  ## `@kerfjs/ui/value-table`
@@ -1996,6 +2009,7 @@ export { DialogSurface, type DialogSurfacePresentation, type DialogSurfaceProps,
1996
2009
  ```ts
1997
2010
  import * as kerfjs from 'kerfjs';
1998
2011
  import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
2012
+ import { S as Sides } from './divider-sides-BzB6rphT.js';
1999
2013
  import { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-CF8NLj7i.js';
2000
2014
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2001
2015
 
@@ -2011,10 +2025,14 @@ interface RowProps {
2011
2025
  flex?: boolean | CssFlexKeyword | CssFlex;
2012
2026
  /** Allow children to wrap onto additional lines. */
2013
2027
  wrap?: boolean;
2028
+ /** Physical sides that receive the standard 17px text inset. */
2029
+ textInsets?: Sides;
2030
+ /** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */
2031
+ controlInsets?: Sides;
2014
2032
  className?: string;
2015
2033
  }
2016
2034
  /** A horizontal flex row with explicit physical-axis alignment and spacing. */
2017
- declare function Row({ children, hAlign, vAlign, gap, flex, wrap, className, }: RowProps): kerfjs.SafeHtml;
2035
+ declare function Row({ children, hAlign, vAlign, gap, flex, wrap, textInsets, controlInsets, className, }: RowProps): kerfjs.SafeHtml;
2018
2036
 
2019
- export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, Row, type RowProps, UiSpaceName, VerticalAlignment };
2037
+ export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, Row, type RowProps, Sides, UiSpaceName, VerticalAlignment };
2020
2038
  ```
package/ai/skill.md CHANGED
@@ -128,9 +128,9 @@ Hard rules:
128
128
  12. Demo work uses public production component subpaths and their browser-selected CSS. Give every public visual component its own category-grouped catalog route; list themed third-party components under a clearly labeled collapsible ecosystem section, with a focused route for each. For the complete focused/composition decision, `CatalogExample` / `CatalogExampleStack` row/group nesting, exact specimen selection, geometry-overlay legend and exclusions, skip-marker behavior, and metadata ownership, follow the single [Catalog demo authoring contract](../docs/catalog.md#catalog-demo-authoring-contract), discovered machine-readably through [`catalog-authoring.json`](./catalog-authoring.json). Never infer structure from private `kui-catalog-*` classes. Project each component's deterministic repository-relative demo source and existing documentation path so the detail can expose `View demo source` and `Read guidance` links without a runtime export; also derive first-party component implementation paths from their canonical browser imports, and label Web Awesome documentation as Kerf integration guidance. Declare direct `uses` relationships so `Used by` stays derivable, and theme shell chrome through the same semantic tokens as the stage instead of drawing a substitute. Enable `wireCatalog({ revealSelection: true })` for long desktop sidebars so controlled selections remain visible without moving focus; keep its default compact media guard unless compact scrolling is an explicit product behavior, and use `revealCatalogEntry` for an initial deep link.
129
129
  13. The Web Awesome theme makes Tooltip and Popover arrowless by default. Keep that default unless a pointer materially clarifies the anchor; opt back in with `--wa-tooltip-arrow-size`, `--kui-wa-popover-arrow-size`, or a popover's public `--arrow-size`, and use `without-arrow` when local no-arrow intent should survive theme changes. Its non-field chrome uses `--kui-wa-control-inset` (8px controls/items), `--kui-wa-surface-margin` / `--kui-wa-surface-inset` (8px around/inside Accordion, Card, Details, Callout, and Include), and `--kui-wa-container-inset` (16px Tab Panel content); Dialog maps its body to the 8px surface tier and its footer to the 16px container tier independently of `--spacing`. Override those tiers instead of restyling individual parts. When a dialog provides another dismissal affordance, put `hide-actions` on the `wa-dialog` host to hide its directly exported `header-actions` part; never chain `::part()` selectors through internal parts. Checkbox and Radio Group option regions, the Color Picker trigger, and Slider's complete interactive region receive the shared 8px logical inline outer inset because those controls have no bordered field shell. Known Date field captions and bordered text-like field hints align with values at the 9px border-plus-padding inset. OTP Input's label uses the same uppercase xs/650 treatment as other field labels, and both its label and hint use that 9px inset.
130
130
  14. Treat the complete Web Awesome catalog as support coverage, not a recommendation list. Its UX sidebar marks superseded and exceptional entries `Discouraged`. Consider Popup when it replaces custom anchored positioning. Prefer Kerf `Select` over direct Dropdown/Dropdown Item/Select/Option composition, `SegmentedControl` over Button Group, `TabBar` or `SegmentedControl` over Web Awesome Tabs, `LucideIcon` over Web Awesome Icon, and `ResizableRegion` over Split Panel. Use Tree/Tree Item, Animated Image, and Comparison only for a specific required behavior; avoid Zoomable Frame.
131
- 15. Build sidebars, main areas, inspectors, and dialogs from `@kerfjs/ui/layout.css`: an unpadded `.kui-pane`, optional `.kui-pane__toolbar`, one scrolling `.kui-pane__content`, and optional `.kui-pane__footer`. Use `Row` instead of a hand-written flex-row wrapper and `List` instead of a hand-written flex-column wrapper when children need shared physical-axis alignment and typed spacing. `Row` defaults to left/full with an `xs` gap and no wrapping; `List` retains full/top and zero-gap defaults. Use `List` when rows or sections also need flex growth, one vertical scroll owner, or physical-edge dividers; `dividerSides` uses canonical `t`/`r`/`b`/`l` order. A dialog body is generally a `List`: set `DialogSurface bodyInset="none"` when its list children own geometry, and wrap bare dialog prose in `ListInsetText` so it aligns with bordered siblings without a second inset. Add `.kui-content` for 24px major vertical separation and `.kui-content-item` for a child-owned 8px inline margin, 1px transparent-or-visible border, 8px padding, and 12px radius. Use the pill modifier for 22px. Do not pad pane shells, duplicate item geometry in wrappers, or create nested scroll owners.
131
+ 15. Build sidebars, main areas, inspectors, and dialogs from `@kerfjs/ui/layout.css`: an unpadded `.kui-pane`, optional `.kui-pane__toolbar`, one scrolling `.kui-pane__content`, and optional `.kui-pane__footer`. Use `Row` instead of a hand-written flex-row wrapper and `List` instead of a hand-written flex-column wrapper when children need shared physical-axis alignment and typed spacing. `Row` defaults to left/full with an `xs` gap and no wrapping; `List` retains full/top and zero-gap defaults. Use `List` when rows or sections also need flex growth, one vertical scroll owner, or physical-edge dividers. `dividerSides`, `textInsets`, and `controlInsets` use canonical physical `t`/`r`/`b`/`l` order; text geometry wins where text and control selections overlap. `ListInsetText` and `ListInsetControl` inset all four sides by default and accept the same `sides` grammar for selective edges. A dialog body is generally a `List`: set `DialogSurface bodyInset="none"` when its list children own geometry, and wrap bare dialog prose in `ListInsetText` so it aligns with bordered siblings without a second inset. Add `.kui-content` for 24px major vertical separation and `.kui-content-item` for a child-owned 8px inline margin, 1px transparent-or-visible border, 8px padding, and 12px radius. Use the pill modifier for 22px. Do not pad pane shells, duplicate item geometry in wrappers, or create nested scroll owners.
132
132
  16. Keep a visible collapsible pane's collapse control in its own toolbar. When hidden, move its restore control into the adjacent main toolbar on the corresponding logical edge: leading for an inline-start sidebar and trailing for an inline-end inspector. Collapse the pane completely; do not preserve an empty icon-only rail.
133
- 17. The only direct children of a `Toolbar` zone (`leading`/`center`/`trailing`) are `ToolbarText` (identity/title text) and `ToolbarControlGroup`; never drop bare buttons, inputs, links, or arbitrary markup straight into a zone. Put identity/title text directly in the zone as `ToolbarText`; wrap interactive controls and icon tiles in `ToolbarControlGroup`. `SegmentedControl`, `Select`, a collapsible `TokenSearchField`, and Web Awesome controls all live inside a group. For an ordinary icon/action control inside a group, use a plain `<button>` (the group styles `> button` fully) — that is the default; reach for `wa-button` only when you need a Web Awesome feature, chiefly a `wa-dropdown` popup trigger. A popup menu in a toolbar is a `single` group wrapping a `wa-dropdown` whose `slot="trigger"` `wa-button` is the toolbar button and whose `wa-dropdown-item`s are the menu, with the dropdown kept under `data-morph-skip-children`. For a compact mixed group, keep the standard item padding and raised selected chrome; the selected item paints over the outer border without an internal separator. For an avatar control, set `content="avatar"` and `avatarImage` on the group instead of inserting an `img`: a lone control paints the contained image on the outer group and a multi-button group paints it only on the pressed selection highlight. Compose panel/dialog/page headings with a direct extra-large `ToolbarText`, optional grouped icon, grouped trailing controls, and app-owned supporting copy below. A group remains 44px outside (`calc(2px + remify(42px))`) when its border/background are transparent; use 8px between groups and inside items. Split dormant and interactive regions: `ListHeader` fills the available inline width and keeps its label and mutually exclusive semantic count or non-count `badge` together, with an independent logical-end 44px action unless disclosure mode makes the title cluster the button. Its action visual defaults to 18px through `--kui-list-header-action-icon-size`; never shrink the target to match it. Pass every non-negative safe-integer section quantity through `count` with a localized full spoken `countLabel`; never concatenate it into `label` or put a number in `badge`. `ListItem.trailing` is dormant; use `ListActionRow` when primary and trailing actions need sibling 44px native buttons. Its `label`, `icon`, and `trailingActionIcon` slots are also dormant and cannot contain controls. Let panes relocate at narrow widths instead of shrinking targets.
133
+ 17. The only direct children of a `Toolbar` zone (`leading`/`center`/`trailing`) are `ToolbarText` (identity/title text) and `ToolbarControlGroup`; never drop bare buttons, inputs, links, or arbitrary markup straight into a zone. Put identity/title text directly in the zone as `ToolbarText`; wrap interactive controls and icon tiles in `ToolbarControlGroup`. `SegmentedControl`, `Select`, a collapsible `TokenSearchField`, and Web Awesome controls all live inside a group. For an ordinary icon/action control inside a group, use a plain `<button>` (the group styles `> button` fully) — that is the default; reach for `wa-button` only when you need a Web Awesome feature, chiefly a `wa-dropdown` popup trigger. A popup menu in a toolbar is a `single` group wrapping a `wa-dropdown` whose `slot="trigger"` `wa-button` is the toolbar button and whose `wa-dropdown-item`s are the menu, with the dropdown kept under `data-morph-skip-children`. For a compact mixed group, keep the standard item padding and raised selected chrome; the selected item paints over the outer border without an internal separator. For an avatar control, set `content="avatar"` and `avatarImage` on the group instead of inserting an `img`: a lone control paints the contained image on the outer group and a multi-button group paints it only on the pressed selection highlight. Compose panel/dialog/page headings with a direct extra-large `ToolbarText`, optional grouped icon, grouped trailing controls, and app-owned supporting copy below. A group remains 44px outside (`calc(2px + remify(42px))`) when its border/background are transparent; use 8px between groups and inside items. Split dormant and interactive regions: `ListHeader` fills the available inline width by default; set `inline` only when it should shrink-wrap in surrounding content without outer margin, border, or padding. It keeps its label and mutually exclusive semantic count or non-count `badge` together, with an independent logical-end action unless disclosure mode makes the title cluster the button. Its action visual defaults to 18px through `--kui-list-header-action-icon-size`; never shrink the target to match it. Pass every non-negative safe-integer section quantity through `count` with a localized full spoken `countLabel`; never concatenate it into `label` or put a number in `badge`. `ListItem.trailing` is dormant; use `ListActionRow` when primary and trailing actions need sibling native buttons. Its `label`, `icon`, and `trailingActionIcon` slots are also dormant and cannot contain controls. Let panes relocate at narrow widths instead of shrinking targets.
134
134
  18. When a recurring concept has no matching export or production recipe, keep its semantics in a thin application adapter while reusing the public layout vocabulary. The composer recipe uses one visible form surface, toolbar title/supporting-copy ids, shared 8px field/action gutters, 24px major rhythm, and a conditional StateBanner as its only nested semantic surface; do not turn every section into a card or double-inset intrinsically bordered controls. The application-local `../docs/examples/command-palette-adapter.tsx` is reference source for one such missing concept, not an `@kerfjs/ui` runtime export or catalog recipe. The application owns its registration, ranking, history, permissions, availability, shortcut policy, focus policy, dispatch, and copy. If a missing concept recurs across products, open an upstream component or recipe request.
135
135
  19. Compose `ValueTable` from typed `ValueTableRow` entries instead of handwritten `dt`/`dd` wrappers. Pass `icon` for the optional 24px leading visual; the row owns 8px of root-scaled top and bottom padding, the 8px iconless or 40px icon-bearing separator start, and the common 8px right inset.
136
136
  20. Use the standard direct `Toolbar` composition for a panel, dialog, or page heading, not a private wrapper or custom heading row. Put an optional icon in a `ToolbarControlGroup`, the title directly in the leading zone as extra-large `ToolbarText`, and actions in a trailing group. Set `headingLevel` for page/section landmarks. Supporting copy stays below the toolbar as app-owned content. The app owns modal behavior, focus, dismissal, command policy, ids, and action handling.
@@ -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.35` 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.
3
+ Generated from the emitted `@kerfjs/ui@5.0.0-beta.36` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
4
4
 
5
5
  ```ts
6
6
  import { KerfCustomElement } from 'kerfjs/jsx-runtime';
package/dist/catalog.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { ToolbarControlGroup } from './chunk-B6JYRX3P.js';
2
2
  import { Toolbar } from './chunk-VXFGMDA7.js';
3
3
  import { Pane } from './chunk-I4V3UDSA.js';
4
- import { ListHeader } from './chunk-OC275HHS.js';
4
+ import { ListHeader } from './chunk-5FJ53EOF.js';
5
5
  import { ListItem } from './chunk-I45QO2IZ.js';
6
- import { List } from './chunk-7JQAQWVC.js';
6
+ import { List } from './chunk-TNXDXSGP.js';
7
7
 
8
8
  import { filterDataAttributes } from './chunk-SRSJO5QE.js';
9
9
 
@@ -3,6 +3,7 @@ import { jsx } from 'kerfjs/jsx-runtime';
3
3
  // src/list-inset-control.tsx
4
4
  function ListInsetControl({
5
5
  children,
6
+ sides = "trbl",
6
7
  className = ""
7
8
  }) {
8
9
  return /* @__PURE__ */ jsx(
@@ -10,6 +11,7 @@ function ListInsetControl({
10
11
  {
11
12
  class: `kui-list-inset-control ${className}`.trim(),
12
13
  "data-component": "list-inset-control",
14
+ "data-sides": sides,
13
15
  children
14
16
  }
15
17
  );
@@ -17,4 +19,4 @@ function ListInsetControl({
17
19
 
18
20
  export { ListInsetControl };
19
21
 
20
- //# sourceMappingURL=chunk-MFR2IIFG.js.map
22
+ //# sourceMappingURL=chunk-2TYUFZUC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/list-inset-control.tsx"],"names":[],"mappings":";;;AAiBO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,QAAA;AAAA,EACA,KAAA,GAAQ,MAAA;AAAA,EACR,SAAA,GAAY;AACd,CAAA,EAA0B;AACxB,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,uBAAA,EAA0B,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAClD,gBAAA,EAAe,oBAAA;AAAA,MACf,YAAA,EAAY,KAAA;AAAA,MAEX;AAAA;AAAA,GACH;AAEJ","file":"chunk-2TYUFZUC.js","sourcesContent":["import type { Sides } from './divider-sides.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport interface ListInsetControlProps {\n /** Control(s) that own their own border and padding (e.g. an input, a `wa-*`). */\n children: KerfUiContent;\n /** Physical inset sides in canonical top/right/bottom/left order. Defaults to all sides. */\n sides?: Sides;\n className?: string;\n}\n\n/**\n * Insets a control into a pane/list content region: an 8px inline margin (so its\n * edges line up with `.kui-content` items) and a stretch flex row with an 8px gap.\n * Use it for controls that carry their own border and padding but no outer margin\n * — the wrapper adds only the alignment margin and layout, not a second inset.\n */\nexport function ListInsetControl({\n children,\n sides = 'trbl',\n className = '',\n}: ListInsetControlProps) {\n return (\n <div\n class={`kui-list-inset-control ${className}`.trim()}\n data-component=\"list-inset-control\"\n data-sides={sides}\n >\n {children}\n </div>\n );\n}\n\nexport type { Sides } from './divider-sides.js';\n"]}
@@ -11,6 +11,7 @@ var PROTECTED_ROOT_DATA_ATTRIBUTES = /* @__PURE__ */ new Set([
11
11
  "data-has-count",
12
12
  "data-density",
13
13
  "data-divider",
14
+ "data-inline",
14
15
  "data-indicator-tone",
15
16
  "data-toggle"
16
17
  ]);
@@ -23,6 +24,7 @@ function ListHeader({
23
24
  status,
24
25
  density = "standard",
25
26
  divider = "none",
27
+ inline = false,
26
28
  indicatorTone = "neutral",
27
29
  action,
28
30
  actionLabel,
@@ -61,6 +63,7 @@ function ListHeader({
61
63
  "data-has-count": String(normalizedCount !== void 0),
62
64
  "data-density": density,
63
65
  "data-divider": divider,
66
+ "data-inline": String(inline),
64
67
  "data-indicator-tone": indicatorTone,
65
68
  "data-toggle": "true",
66
69
  "data-placeholder": placeholder ? "true" : void 0,
@@ -96,6 +99,7 @@ function ListHeader({
96
99
  "data-has-count": String(normalizedCount !== void 0),
97
100
  "data-density": density,
98
101
  "data-divider": divider,
102
+ "data-inline": String(inline),
99
103
  "data-indicator-tone": indicatorTone,
100
104
  "data-toggle": "false",
101
105
  "data-placeholder": placeholder ? "true" : void 0,
@@ -125,4 +129,4 @@ function ListHeader({
125
129
 
126
130
  export { ListHeader };
127
131
 
128
- //# sourceMappingURL=chunk-OC275HHS.js.map
132
+ //# sourceMappingURL=chunk-5FJ53EOF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/list-header.tsx"],"names":[],"mappings":"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","file":"chunk-5FJ53EOF.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { em } from './css-values.js';\nimport { DisclosureArrow } from './disclosure-arrow.js';\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from './extension-attributes.js';\nimport { Skeleton } from './skeleton.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-has-badge',\n 'data-has-count',\n 'data-density',\n 'data-divider',\n 'data-inline',\n 'data-indicator-tone',\n 'data-toggle',\n]);\nconst PROTECTED_TRIGGER_DATA_ATTRIBUTES = new Set(['data-action']);\n\ntype ListHeaderRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-has-badge'?: never;\n 'data-has-count'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-inline'?: never;\n 'data-indicator-tone'?: never;\n 'data-toggle'?: never;\n }\n>;\n\ntype ListHeaderTriggerAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-action'?: 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\ninterface ListHeaderBaseProps {\n label: string;\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Shrink-wrap the header without its default outer margin, border, or padding. */\n inline?: boolean;\n indicatorTone?: 'neutral' | 'accent' | 'pop' | 'danger';\n /** Render as an unanimated loading skeleton: keep the label and action affordance, disable interaction. */\n placeholder?: boolean;\n rootAttributes?: ListHeaderRootAttributes;\n triggerAttributes?: ListHeaderTriggerAttributes;\n}\n\ntype ListHeaderModeProps =\n | {\n /** Render the title as a controlled disclosure trigger. */\n toggle: true;\n action: string;\n expanded: boolean;\n actionIcon?: SafeHtml;\n actionLabel?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a separately named trailing action. */\n toggle?: false;\n action: string;\n actionLabel: string;\n actionIcon: SafeHtml;\n expanded?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a passive section heading. */\n toggle?: false;\n action?: never;\n actionLabel?: never;\n actionIcon?: never;\n expanded?: never;\n actionDisabled?: never;\n disabledReason?: never;\n };\n\ntype ListHeaderIndicatorProps =\n | { count: number; countLabel: string; badge?: never; status?: never }\n | { count?: never; countLabel?: never; badge: SafeHtml; status?: never }\n | { count?: never; countLabel?: never; badge?: never; status?: SafeHtml };\n\nexport type ListHeaderProps = ListHeaderBaseProps &\n ListHeaderIndicatorProps &\n ListHeaderModeProps;\n\nexport function ListHeader({\n label,\n count,\n countLabel,\n badge,\n status,\n density = 'standard',\n divider = 'none',\n inline = false,\n indicatorTone = 'neutral',\n action,\n actionLabel,\n actionIcon,\n actionDisabled = false,\n disabledReason,\n expanded,\n toggle = false,\n placeholder = false,\n rootAttributes = {},\n triggerAttributes = {},\n}: ListHeaderProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTriggerAttributes = filterControlAttributes(\n triggerAttributes,\n PROTECTED_TRIGGER_DATA_ATTRIBUTES,\n );\n const normalizedCount =\n typeof count === 'number' && Number.isSafeInteger(count) && count >= 0\n ? count\n : undefined;\n const normalizedCountLabel =\n normalizedCount === undefined\n ? undefined\n : typeof countLabel === 'string' && countLabel.trim()\n ? countLabel\n : String(normalizedCount);\n const renderedBadge =\n normalizedCount === undefined ? (status ?? badge) : undefined;\n const renderedActionIcon =\n actionIcon ??\n (toggle ? <DisclosureArrow open={Boolean(expanded)} /> : undefined);\n const accessibleLabel =\n normalizedCount === undefined\n ? undefined\n : `${label}, ${normalizedCountLabel}`;\n const indicator = placeholder ? (\n (normalizedCount !== undefined || renderedBadge) && (\n <span class=\"kui-list-header__badge\">\n <Skeleton width={em(1.75)} />\n </span>\n )\n ) : normalizedCount === undefined ? (\n renderedBadge && <span class=\"kui-list-header__badge\">{renderedBadge}</span>\n ) : (\n <span class=\"kui-list-header__count\" aria-hidden=\"true\">\n {normalizedCount}\n </span>\n );\n const busy = placeholder ? ('true' as const) : undefined;\n if (toggle) {\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-indicator-tone={indicatorTone}\n data-toggle=\"true\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n >\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__title kui-list-header__toggle\"\n data-action={placeholder ? undefined : action}\n title={actionDisabled ? disabledReason : undefined}\n disabled={actionDisabled || placeholder || undefined}\n aria-label={accessibleLabel}\n aria-expanded={String(Boolean(expanded))}\n >\n <span class=\"kui-list-header__label\">{label}</span>\n {indicator}\n {renderedActionIcon && (\n <span class=\"kui-list-header__action-layer\">\n {renderedActionIcon}\n </span>\n )}\n </button>\n </header>\n );\n }\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-indicator-tone={indicatorTone}\n data-toggle=\"false\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n >\n <div class=\"kui-list-header__title\">\n <h2 class=\"kui-list-header__label\" aria-label={accessibleLabel}>\n {label}\n </h2>\n {indicator}\n </div>\n {action && (\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__action\"\n data-action={placeholder ? undefined : action}\n aria-label={actionLabel}\n title={actionDisabled ? disabledReason : actionLabel}\n disabled={actionDisabled || placeholder || undefined}\n >\n {renderedActionIcon}\n </button>\n )}\n </header>\n );\n}\n"]}
@@ -18,6 +18,8 @@ function Row({
18
18
  gap = "xs",
19
19
  flex = false,
20
20
  wrap = false,
21
+ textInsets = "",
22
+ controlInsets = "",
21
23
  className = ""
22
24
  }) {
23
25
  const gapValue = spaceNames.includes(gap) ? space(gap) : gap;
@@ -35,6 +37,8 @@ function Row({
35
37
  "data-v-align": verticalAlignment(vAlign),
36
38
  "data-flex": String(Boolean(flex)),
37
39
  "data-wrap": String(wrap),
40
+ "text-insets": textInsets || void 0,
41
+ "control-insets": controlInsets || void 0,
38
42
  style,
39
43
  children
40
44
  }
@@ -43,4 +47,4 @@ function Row({
43
47
 
44
48
  export { Row };
45
49
 
46
- //# sourceMappingURL=chunk-QHCBZTDK.js.map
50
+ //# sourceMappingURL=chunk-AVZ2IMWG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/row.tsx"],"names":[],"mappings":";;;;AAgBA,IAAM,UAAA,GAAqC;AAAA,EACzC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA;AACF,CAAA;AAsBO,SAAS,GAAA,CAAI;AAAA,EAClB,QAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,MAAA,GAAS,MAAA;AAAA,EACT,GAAA,GAAM,IAAA;AAAA,EACN,IAAA,GAAO,KAAA;AAAA,EACP,IAAA,GAAO,KAAA;AAAA,EACP,UAAA,GAAa,EAAA;AAAA,EACb,aAAA,GAAgB,EAAA;AAAA,EAChB,SAAA,GAAY;AACd,CAAA,EAAa;AACX,EAAA,MAAM,WAAW,UAAA,CAAW,QAAA,CAAS,GAAkB,CAAA,GACnD,KAAA,CAAM,GAAkB,CAAA,GACxB,GAAA;AACJ,EAAA,MAAM,SAAA,GAAY,IAAA,KAAS,IAAA,GAAO,UAAA,GAAa,IAAA,IAAQ,MAAA;AACvD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,kBAAkB,QAAQ,CAAA,CAAA;AAAA,IAC1B,SAAA,GAAY,CAAA,gBAAA,EAAmB,SAAS,CAAA,CAAA,GAAK;AAAA,GAC/C,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEX,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,QAAA,EAAW,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACnC,gBAAA,EAAe,KAAA;AAAA,MACf,cAAA,EAAc,oBAAoB,MAAM,CAAA;AAAA,MACxC,cAAA,EAAc,kBAAkB,MAAM,CAAA;AAAA,MACtC,WAAA,EAAW,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,MAC/B,WAAA,EAAW,OAAO,IAAI,CAAA;AAAA,MACtB,eAAa,UAAA,IAAc,MAAA;AAAA,MAC3B,kBAAgB,aAAA,IAAiB,MAAA;AAAA,MACjC,KAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"chunk-AVZ2IMWG.js","sourcesContent":["import {\n type CssFlex,\n type CssFlexKeyword,\n type CssLength,\n space,\n type UiSpaceName,\n} from './css-values.js';\nimport type { Sides } from './divider-sides.js';\nimport {\n type HorizontalAlignment,\n horizontalAlignment,\n type VerticalAlignment,\n verticalAlignment,\n} from './flex-alignment.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nconst spaceNames: readonly UiSpaceName[] = [\n 'none',\n '2xs',\n 'xs',\n 's',\n 'm',\n 'l',\n 'xl',\n];\n\nexport interface RowProps {\n children?: KerfUiContent;\n /** Horizontal distribution. Defaults to left. */\n hAlign?: HorizontalAlignment;\n /** Vertical alignment and wrapped-line distribution. Defaults to full. */\n vAlign?: VerticalAlignment;\n /** A named UI spacing token or typed CSS length. Defaults to xs. */\n gap?: UiSpaceName | CssLength;\n /** Allow this row to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */\n flex?: boolean | CssFlexKeyword | CssFlex;\n /** Allow children to wrap onto additional lines. */\n wrap?: boolean;\n /** Physical sides that receive the standard 17px text inset. */\n textInsets?: Sides;\n /** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */\n controlInsets?: Sides;\n className?: string;\n}\n\n/** A horizontal flex row with explicit physical-axis alignment and spacing. */\nexport function Row({\n children,\n hAlign = 'left',\n vAlign = 'full',\n gap = 'xs',\n flex = false,\n wrap = false,\n textInsets = '',\n controlInsets = '',\n className = '',\n}: RowProps) {\n const gapValue = spaceNames.includes(gap as UiSpaceName)\n ? space(gap as UiSpaceName)\n : gap;\n const flexValue = flex === true ? '1 1 auto' : flex || undefined;\n const style = [\n `--_kui-row-gap:${gapValue}`,\n flexValue ? `--_kui-row-flex:${flexValue}` : '',\n ]\n .filter(Boolean)\n .join(';');\n\n return (\n <div\n class={`kui-row ${className}`.trim()}\n data-component=\"row\"\n data-h-align={horizontalAlignment(hAlign)}\n data-v-align={verticalAlignment(vAlign)}\n data-flex={String(Boolean(flex))}\n data-wrap={String(wrap)}\n text-insets={textInsets || undefined}\n control-insets={controlInsets || undefined}\n style={style}\n >\n {children}\n </div>\n );\n}\n\nexport type {\n CssFlex,\n CssFlexKeyword,\n CssLength,\n UiSpaceName,\n} from './css-values.js';\nexport type { Sides } from './divider-sides.js';\nexport type {\n HorizontalAlignment,\n VerticalAlignment,\n} from './flex-alignment.js';\n"]}
@@ -3,13 +3,23 @@ import { jsx } from 'kerfjs/jsx-runtime';
3
3
  // src/list-inset-text.tsx
4
4
  function ListInsetText({
5
5
  children,
6
+ sides,
6
7
  horizontalOnly = false,
7
8
  className = ""
8
9
  }) {
10
+ const resolvedSides = sides ?? (horizontalOnly ? "rl" : "trbl");
9
11
  const cls = `kui-list-inset-text${horizontalOnly ? " kui-list-inset-text--horizontal" : ""} ${className}`.trim();
10
- return /* @__PURE__ */ jsx("div", { class: cls, "data-component": "list-inset-text", children });
12
+ return /* @__PURE__ */ jsx(
13
+ "div",
14
+ {
15
+ class: cls,
16
+ "data-component": "list-inset-text",
17
+ "data-sides": resolvedSides,
18
+ children
19
+ }
20
+ );
11
21
  }
12
22
 
13
23
  export { ListInsetText };
14
24
 
15
- //# sourceMappingURL=chunk-KFUUFNTS.js.map
25
+ //# sourceMappingURL=chunk-EYALJQQD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/list-inset-text.tsx"],"names":[],"mappings":";;;AA0BO,SAAS,aAAA,CAAc;AAAA,EAC5B,QAAA;AAAA,EACA,KAAA;AAAA,EACA,cAAA,GAAiB,KAAA;AAAA,EACjB,SAAA,GAAY;AACd,CAAA,EAAuB;AACrB,EAAA,MAAM,aAAA,GAAgB,KAAA,KAAU,cAAA,GAAiB,IAAA,GAAO,MAAA,CAAA;AACxD,EAAA,MAAM,GAAA,GACJ,sBAAsB,cAAA,GAAiB,kCAAA,GAAqC,EAAE,CAAA,CAAA,EAAI,SAAS,GAAG,IAAA,EAAK;AACrG,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,GAAA;AAAA,MACP,gBAAA,EAAe,iBAAA;AAAA,MACf,YAAA,EAAY,aAAA;AAAA,MAEX;AAAA;AAAA,GACH;AAEJ","file":"chunk-EYALJQQD.js","sourcesContent":["import type { Sides } from './divider-sides.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport interface ListInsetTextProps {\n /** Text (or inline content) that carries no margin, border, or padding of its own. */\n children: KerfUiContent | string;\n /** Physical inset sides in canonical top/right/bottom/left order. Defaults to all sides. */\n sides?: Sides;\n /**\n * @deprecated Pass `sides=\"rl\"` instead. Keep only the horizontal geometry (inline margin, left/right border, and\n * left/right padding) and drop the vertical margin, border, and padding. Use it\n * when the text edge must still align with bordered items but the line should not\n * add its own vertical box space — tight text layout inside a content region.\n */\n horizontalOnly?: boolean;\n className?: string;\n}\n\n/**\n * Gives bare text the content-item geometry — an 8px inline margin, a 1px\n * transparent border, and 8px padding — so a plain string lines up with\n * bordered `.kui-content` items (its text edge lands at the same 17px inset).\n * Use it for text elements that have no margin, border, or padding of their own.\n * Pass `horizontalOnly` to keep the horizontal inset but drop the vertical box\n * space for tight text layout.\n */\nexport function ListInsetText({\n children,\n sides,\n horizontalOnly = false,\n className = '',\n}: ListInsetTextProps) {\n const resolvedSides = sides ?? (horizontalOnly ? 'rl' : 'trbl');\n const cls =\n `kui-list-inset-text${horizontalOnly ? ' kui-list-inset-text--horizontal' : ''} ${className}`.trim();\n return (\n <div\n class={cls}\n data-component=\"list-inset-text\"\n data-sides={resolvedSides}\n >\n {children}\n </div>\n );\n}\n\nexport type { Sides } from './divider-sides.js';\n"]}
@@ -19,6 +19,8 @@ function List({
19
19
  vAlign = "top",
20
20
  scrollable = false,
21
21
  dividerSides = "",
22
+ textInsets = "",
23
+ controlInsets = "",
22
24
  className = ""
23
25
  }) {
24
26
  const gapValue = gap === true ? "var(--kui-list-gap)" : spaceNames.includes(gap) ? space(gap) : gap || void 0;
@@ -38,6 +40,8 @@ function List({
38
40
  "data-v-align": verticalAlignment(vAlign),
39
41
  "data-scrollable": String(scrollable),
40
42
  "divider-sides": dividerSides || void 0,
43
+ "text-insets": textInsets || void 0,
44
+ "control-insets": controlInsets || void 0,
41
45
  style: style || void 0,
42
46
  children
43
47
  }
@@ -46,4 +50,4 @@ function List({
46
50
 
47
51
  export { List };
48
52
 
49
- //# sourceMappingURL=chunk-7JQAQWVC.js.map
53
+ //# sourceMappingURL=chunk-TNXDXSGP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/list.tsx"],"names":[],"mappings":";;;;AAgBA,IAAM,UAAA,GAAqC;AAAA,EACzC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA,GAAA;AAAA,EACA;AACF,CAAA;AAwBO,SAAS,IAAA,CAAK;AAAA,EACnB,QAAA;AAAA,EACA,GAAA,GAAM,KAAA;AAAA,EACN,IAAA,GAAO,KAAA;AAAA,EACP,MAAA,GAAS,MAAA;AAAA,EACT,MAAA,GAAS,KAAA;AAAA,EACT,UAAA,GAAa,KAAA;AAAA,EACb,YAAA,GAAe,EAAA;AAAA,EACf,UAAA,GAAa,EAAA;AAAA,EACb,aAAA,GAAgB,EAAA;AAAA,EAChB,SAAA,GAAY;AACd,CAAA,EAAc;AACZ,EAAA,MAAM,QAAA,GACJ,GAAA,KAAQ,IAAA,GACJ,qBAAA,GACA,UAAA,CAAW,QAAA,CAAS,GAAkB,CAAA,GACpC,KAAA,CAAM,GAAkB,CAAA,GACxB,GAAA,IAAO,MAAA;AACf,EAAA,MAAM,SAAA,GAAY,IAAA,KAAS,IAAA,GAAO,UAAA,GAAa,IAAA,IAAQ,MAAA;AACvD,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,QAAA,GAAW,CAAA,gBAAA,EAAmB,QAAQ,CAAA,CAAA,GAAK,EAAA;AAAA,IAC3C,SAAA,GAAY,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,GAAK;AAAA,GAChD,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEX,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,SAAA,EAAY,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACpC,gBAAA,EAAe,MAAA;AAAA,MACf,UAAA,EAAU,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAA;AAAA,MAC7B,WAAA,EAAW,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,MAC/B,cAAA,EAAc,oBAAoB,MAAM,CAAA;AAAA,MACxC,cAAA,EAAc,kBAAkB,MAAM,CAAA;AAAA,MACtC,iBAAA,EAAiB,OAAO,UAAU,CAAA;AAAA,MAClC,iBAAe,YAAA,IAAgB,MAAA;AAAA,MAC/B,eAAa,UAAA,IAAc,MAAA;AAAA,MAC3B,kBAAgB,aAAA,IAAiB,MAAA;AAAA,MACjC,OAAO,KAAA,IAAS,MAAA;AAAA,MAEf;AAAA;AAAA,GACH;AAEJ","file":"chunk-TNXDXSGP.js","sourcesContent":["import {\n type CssFlex,\n type CssFlexKeyword,\n type CssLength,\n space,\n type UiSpaceName,\n} from './css-values.js';\nimport type { DividerSides, Sides } from './divider-sides.js';\nimport {\n type HorizontalAlignment,\n horizontalAlignment,\n type VerticalAlignment,\n verticalAlignment,\n} from './flex-alignment.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nconst spaceNames: readonly UiSpaceName[] = [\n 'none',\n '2xs',\n 'xs',\n 's',\n 'm',\n 'l',\n 'xl',\n];\n\nexport interface ListProps {\n children?: KerfUiContent;\n /** Use the standard item gap, a named UI spacing token, or a typed CSS length. Defaults to no gap. */\n gap?: boolean | UiSpaceName | CssLength;\n /** Allow this list to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */\n flex?: boolean | CssFlexKeyword | CssFlex;\n /** Horizontal alignment. Defaults to full to preserve stretch-aligned list children. */\n hAlign?: HorizontalAlignment;\n /** Vertical distribution. Defaults to top. */\n vAlign?: VerticalAlignment;\n /** Own vertical scrolling and overscroll containment. */\n scrollable?: boolean;\n /** Physical divider edges in canonical top/right/bottom/left order. */\n dividerSides?: DividerSides;\n /** Physical sides that receive the standard 17px text inset. */\n textInsets?: Sides;\n /** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */\n controlInsets?: Sides;\n className?: string;\n}\n\n/** A stretch-aligned vertical stack with optional gap, flex, scroll, and dividers. */\nexport function List({\n children,\n gap = false,\n flex = false,\n hAlign = 'full',\n vAlign = 'top',\n scrollable = false,\n dividerSides = '',\n textInsets = '',\n controlInsets = '',\n className = '',\n}: ListProps) {\n const gapValue =\n gap === true\n ? 'var(--kui-list-gap)'\n : spaceNames.includes(gap as UiSpaceName)\n ? space(gap as UiSpaceName)\n : gap || undefined;\n const flexValue = flex === true ? '1 1 auto' : flex || undefined;\n const style = [\n gapValue ? `--_kui-list-gap:${gapValue}` : '',\n flexValue ? `--_kui-list-flex:${flexValue}` : '',\n ]\n .filter(Boolean)\n .join(';');\n\n return (\n <div\n class={`kui-list ${className}`.trim()}\n data-component=\"list\"\n data-gap={String(Boolean(gap))}\n data-flex={String(Boolean(flex))}\n data-h-align={horizontalAlignment(hAlign)}\n data-v-align={verticalAlignment(vAlign)}\n data-scrollable={String(scrollable)}\n divider-sides={dividerSides || undefined}\n text-insets={textInsets || undefined}\n control-insets={controlInsets || undefined}\n style={style || undefined}\n >\n {children}\n </div>\n );\n}\n\nexport type {\n CssFlex,\n CssFlexKeyword,\n CssLength,\n UiSpaceName,\n} from './css-values.js';\nexport type { DividerSides, Sides } from './divider-sides.js';\nexport type {\n HorizontalAlignment,\n VerticalAlignment,\n} from './flex-alignment.js';\n"]}