@kerfjs/ui 5.0.0-beta.49 → 5.0.0-beta.50

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 (257) hide show
  1. package/README.md +41 -11
  2. package/ai/catalog-authoring.json +12 -1
  3. package/ai/catalog-authoring.schema.json +49 -1
  4. package/ai/compile-time-contracts-v1.json +14 -0
  5. package/ai/compile-time-contracts-v1.schema.json +1 -0
  6. package/ai/component-catalog-v2-overrides.json +7 -0
  7. package/ai/component-catalog-v2.json +79 -23
  8. package/ai/component-catalog.json +86 -27
  9. package/ai/public-api-signatures-v1.md +217 -169
  10. package/ai/skill.md +23 -9
  11. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  12. package/dist/app-tab.d.ts +3 -1
  13. package/dist/app-tab.js +1 -1
  14. package/dist/badge.d.ts +24 -0
  15. package/dist/badge.js +3 -0
  16. package/dist/badge.js.map +1 -0
  17. package/dist/browser/badge.js +3 -0
  18. package/dist/browser/list-header.js +1 -0
  19. package/dist/browser/state-banner.js +1 -0
  20. package/dist/catalog-resources.d.ts +2 -2
  21. package/dist/catalog.d.ts +24 -125
  22. package/dist/catalog.js +387 -261
  23. package/dist/catalog.js.map +1 -1
  24. package/dist/{chunk-OGTJNHRG.js → chunk-2WMSE4MK.js} +5 -3
  25. package/dist/chunk-2WMSE4MK.js.map +1 -0
  26. package/dist/{chunk-GYGM363P.js → chunk-2YOUUEWR.js} +16 -6
  27. package/dist/chunk-2YOUUEWR.js.map +1 -0
  28. package/dist/{chunk-UDHHKZWO.js → chunk-3V75EQIP.js} +8 -4
  29. package/dist/chunk-3V75EQIP.js.map +1 -0
  30. package/dist/{chunk-W2FK7ZNY.js → chunk-4R777DUZ.js} +10 -2
  31. package/dist/chunk-4R777DUZ.js.map +1 -0
  32. package/dist/{chunk-T7DOWS6T.js → chunk-54HM36IQ.js} +6 -3
  33. package/dist/chunk-54HM36IQ.js.map +1 -0
  34. package/dist/{chunk-DAO2VFTT.js → chunk-5CE64WGC.js} +6 -4
  35. package/dist/chunk-5CE64WGC.js.map +1 -0
  36. package/dist/{chunk-SOK5EUF7.js → chunk-6ZXOQEAN.js} +4 -2
  37. package/dist/chunk-6ZXOQEAN.js.map +1 -0
  38. package/dist/{chunk-OGNE3OFT.js → chunk-AQSKJ6U6.js} +4 -2
  39. package/dist/chunk-AQSKJ6U6.js.map +1 -0
  40. package/dist/{chunk-VDUJZF5G.js → chunk-CMUIXJZM.js} +2 -2
  41. package/dist/{chunk-VDUJZF5G.js.map → chunk-CMUIXJZM.js.map} +1 -1
  42. package/dist/{chunk-OMSRSL3B.js → chunk-COUPLRZG.js} +5 -3
  43. package/dist/chunk-COUPLRZG.js.map +1 -0
  44. package/dist/{chunk-2TYUFZUC.js → chunk-D7GWXIAS.js} +4 -2
  45. package/dist/chunk-D7GWXIAS.js.map +1 -0
  46. package/dist/{chunk-AQFWBG23.js → chunk-DARTMI5Z.js} +5 -3
  47. package/dist/chunk-DARTMI5Z.js.map +1 -0
  48. package/dist/{chunk-V6GQKOX2.js → chunk-DJKWFYAA.js} +5 -3
  49. package/dist/chunk-DJKWFYAA.js.map +1 -0
  50. package/dist/{chunk-6NDBE2OK.js → chunk-E36EVCKG.js} +5 -3
  51. package/dist/chunk-E36EVCKG.js.map +1 -0
  52. package/dist/{chunk-IU4QUY5I.js → chunk-ELRMBQEC.js} +4 -2
  53. package/dist/chunk-ELRMBQEC.js.map +1 -0
  54. package/dist/{chunk-TIGSG6BX.js → chunk-HJKRCKDR.js} +7 -3
  55. package/dist/chunk-HJKRCKDR.js.map +1 -0
  56. package/dist/{chunk-Y6LYKFXY.js → chunk-HMQ2ZDGG.js} +5 -3
  57. package/dist/chunk-HMQ2ZDGG.js.map +1 -0
  58. package/dist/{chunk-WN52USHV.js → chunk-J3EE6XWD.js} +2 -2
  59. package/dist/{chunk-WN52USHV.js.map → chunk-J3EE6XWD.js.map} +1 -1
  60. package/dist/{chunk-CK6P5AUK.js → chunk-KKNK3JUT.js} +7 -4
  61. package/dist/chunk-KKNK3JUT.js.map +1 -0
  62. package/dist/{chunk-ZPWZIVI6.js → chunk-N3GKMPDW.js} +7 -3
  63. package/dist/chunk-N3GKMPDW.js.map +1 -0
  64. package/dist/{chunk-DYBPI5O2.js → chunk-NDUGJ4TU.js} +4 -2
  65. package/dist/chunk-NDUGJ4TU.js.map +1 -0
  66. package/dist/{chunk-WSXUPSID.js → chunk-NN6GYOA2.js} +7 -3
  67. package/dist/chunk-NN6GYOA2.js.map +1 -0
  68. package/dist/{chunk-VXFGMDA7.js → chunk-OQI7RCRP.js} +10 -2
  69. package/dist/chunk-OQI7RCRP.js.map +1 -0
  70. package/dist/{chunk-E34TE2ZI.js → chunk-S6ZTTTV7.js} +5 -3
  71. package/dist/chunk-S6ZTTTV7.js.map +1 -0
  72. package/dist/{chunk-V6HCTCVD.js → chunk-SIU2AC5W.js} +8 -4
  73. package/dist/chunk-SIU2AC5W.js.map +1 -0
  74. package/dist/{chunk-WVLMZ5SG.js → chunk-UMGY5JSP.js} +4 -2
  75. package/dist/chunk-UMGY5JSP.js.map +1 -0
  76. package/dist/{chunk-I4V3UDSA.js → chunk-V6RZWDII.js} +7 -5
  77. package/dist/chunk-V6RZWDII.js.map +1 -0
  78. package/dist/{chunk-CAB6NQ2T.js → chunk-VOCPXGQN.js} +3 -1
  79. package/dist/chunk-VOCPXGQN.js.map +1 -0
  80. package/dist/chunk-XD7DWYXG.js +34 -0
  81. package/dist/chunk-XD7DWYXG.js.map +1 -0
  82. package/dist/{chunk-B6JYRX3P.js → chunk-ZIYOJFZD.js} +43 -4
  83. package/dist/chunk-ZIYOJFZD.js.map +1 -0
  84. package/dist/{chunk-EYALJQQD.js → chunk-ZK5EGVFP.js} +4 -2
  85. package/dist/chunk-ZK5EGVFP.js.map +1 -0
  86. package/dist/{chunk-6WTETUZ6.js → chunk-ZLWQZUGF.js} +8 -2
  87. package/dist/chunk-ZLWQZUGF.js.map +1 -0
  88. package/dist/{chunk-XKFRMGMW.js → chunk-ZNZ2JDBW.js} +3 -1
  89. package/dist/chunk-ZNZ2JDBW.js.map +1 -0
  90. package/dist/{chunk-I45QO2IZ.js → chunk-ZSYLBVWG.js} +6 -4
  91. package/dist/chunk-ZSYLBVWG.js.map +1 -0
  92. package/dist/collapsible-panel.d.ts +3 -1
  93. package/dist/collapsible-panel.js +4 -2
  94. package/dist/collapsible-panel.js.map +1 -1
  95. package/dist/disclosure-arrow.d.ts +3 -1
  96. package/dist/disclosure-arrow.js +1 -1
  97. package/dist/empty-state.d.ts +3 -1
  98. package/dist/empty-state.js +1 -1
  99. package/dist/floating-toolbar.d.ts +3 -1
  100. package/dist/floating-toolbar.js +1 -1
  101. package/dist/grid.d.ts +3 -1
  102. package/dist/grid.js +1 -1
  103. package/dist/index.d.ts +3 -2
  104. package/dist/index.js +33 -32
  105. package/dist/list-action-row.d.ts +3 -1
  106. package/dist/list-action-row.js +1 -1
  107. package/dist/list-header.d.ts +6 -1
  108. package/dist/list-header.js +2 -1
  109. package/dist/list-inset-control.d.ts +3 -1
  110. package/dist/list-inset-control.js +1 -1
  111. package/dist/list-inset-text.d.ts +3 -1
  112. package/dist/list-inset-text.js +1 -1
  113. package/dist/list-item.d.ts +3 -1
  114. package/dist/list-item.js +1 -1
  115. package/dist/list.d.ts +3 -1
  116. package/dist/list.js +1 -1
  117. package/dist/loading-spinner.d.ts +3 -1
  118. package/dist/loading-spinner.js +1 -1
  119. package/dist/lucide-icon.d.ts +3 -1
  120. package/dist/lucide-icon.js +1 -1
  121. package/dist/nav-stack.d.ts +3 -1
  122. package/dist/nav-stack.js +1 -1
  123. package/dist/pane.d.ts +3 -1
  124. package/dist/pane.js +1 -1
  125. package/dist/resizable-region.d.ts +5 -2
  126. package/dist/resizable-region.js +1 -1
  127. package/dist/row.d.ts +3 -1
  128. package/dist/row.js +1 -1
  129. package/dist/segmented-control.d.ts +3 -1
  130. package/dist/segmented-control.js +1 -1
  131. package/dist/select.d.ts +3 -1
  132. package/dist/select.js +1 -1
  133. package/dist/skeleton.d.ts +3 -1
  134. package/dist/skeleton.js +1 -1
  135. package/dist/spacer.d.ts +3 -1
  136. package/dist/spacer.js +1 -1
  137. package/dist/split-view.d.ts +3 -1
  138. package/dist/split-view.js +24 -5
  139. package/dist/split-view.js.map +1 -1
  140. package/dist/state-banner.d.ts +3 -1
  141. package/dist/state-banner.js +2 -1
  142. package/dist/styles/badge.css +86 -0
  143. package/dist/styles/catalog/components/catalog-detail.css +35 -0
  144. package/dist/styles/catalog/components/catalog-example-stack.css +6 -0
  145. package/dist/styles/catalog/components/catalog-example.css +35 -0
  146. package/dist/styles/catalog/components/catalog-resource-footer.css +37 -0
  147. package/dist/styles/catalog/components/catalog-secondary-sections.css +38 -0
  148. package/dist/styles/catalog/components/catalog-section-list.css +22 -0
  149. package/dist/styles/catalog/components/catalog-sidebar.css +82 -0
  150. package/dist/styles/catalog/components/catalog-stage.css +60 -0
  151. package/dist/styles/catalog/components/catalog.css +22 -0
  152. package/dist/styles/catalog.css +10 -587
  153. package/dist/styles/list-header.css +4 -60
  154. package/dist/styles/resizable-region.css +24 -0
  155. package/dist/styles/select.css +0 -3
  156. package/dist/styles/split-view.css +1 -1
  157. package/dist/styles/state-banner.css +0 -27
  158. package/dist/styles/styles.css +1 -0
  159. package/dist/styles/tab-bar.css +6 -1
  160. package/dist/styles/text.css +4 -0
  161. package/dist/styles/token-search-field.css +5 -40
  162. package/dist/styles/toolbar-control-group.css +110 -16
  163. package/dist/styles/toolbar-text.css +4 -0
  164. package/dist/styles/toolbar.css +72 -0
  165. package/dist/styles/webawesome.css +22 -7
  166. package/dist/sunken-panel.d.ts +3 -1
  167. package/dist/sunken-panel.js +1 -1
  168. package/dist/surface-scaffold.d.ts +6 -2
  169. package/dist/surface-scaffold.js +1 -1
  170. package/dist/tab-bar.d.ts +8 -1
  171. package/dist/tab-bar.js +1 -1
  172. package/dist/tab-scaffold.d.ts +3 -1
  173. package/dist/tab-scaffold.js +3 -1
  174. package/dist/tab-scaffold.js.map +1 -1
  175. package/dist/text.d.ts +5 -2
  176. package/dist/text.js +1 -1
  177. package/dist/token-search-field.d.ts +5 -1
  178. package/dist/token-search-field.js +1 -1
  179. package/dist/toolbar-control-group.d.ts +33 -3
  180. package/dist/toolbar-control-group.js +1 -1
  181. package/dist/toolbar-text.d.ts +3 -1
  182. package/dist/toolbar-text.js +1 -1
  183. package/dist/toolbar.d.ts +9 -1
  184. package/dist/toolbar.js +1 -1
  185. package/dist/types-CzgSrFXP.d.ts +64 -0
  186. package/dist/value-table.d.ts +6 -2
  187. package/dist/value-table.js +1 -1
  188. package/dist/wire-resizable-regions.js +1 -1
  189. package/dist/wire-token-search-fields.js +1 -1
  190. package/dist/workbench.d.ts +3 -1
  191. package/dist/workbench.js +3 -1
  192. package/dist/workbench.js.map +1 -1
  193. package/docs/accessibility.md +11 -1
  194. package/docs/catalog.md +25 -7
  195. package/docs/component-contract.md +71 -22
  196. package/docs/component-selection.md +11 -9
  197. package/docs/design-philosophy.md +6 -5
  198. package/docs/recipes.md +5 -5
  199. package/docs/type-contracts.md +1 -0
  200. package/docs/ux-demo.md +4 -4
  201. package/docs/webawesome-theme.md +5 -4
  202. package/llms.txt +30 -10
  203. package/package.json +9 -2
  204. package/ux-demo/recipes/app-shell.css +87 -0
  205. package/ux-demo/recipes/app-shell.tsx +207 -178
  206. package/ux-demo/recipes/collapsible-sidebar.css +83 -0
  207. package/ux-demo/recipes/collapsible-sidebar.tsx +152 -122
  208. package/ux-demo/recipes/compact-toolbar.css +35 -0
  209. package/ux-demo/recipes/compact-toolbar.tsx +104 -100
  210. package/ux-demo/recipes/composer-form.css +19 -0
  211. package/ux-demo/recipes/composer-form.tsx +19 -15
  212. package/ux-demo/recipes/list-detail-dialog.css +42 -0
  213. package/ux-demo/recipes/list-detail-dialog.tsx +127 -125
  214. package/ux-demo/recipes/list-workspace-states.css +30 -0
  215. package/ux-demo/recipes/list-workspace-states.tsx +66 -60
  216. package/ux-demo/recipes/loading-inspector.css +7 -0
  217. package/ux-demo/recipes/loading-inspector.tsx +151 -131
  218. package/ux-demo/recipes/navigation-sidebar.css +12 -0
  219. package/ux-demo/recipes/navigation-sidebar.tsx +116 -105
  220. package/ux-demo/recipes/navigation-stack.css +12 -0
  221. package/ux-demo/recipes/navigation-stack.tsx +47 -37
  222. package/ux-demo/recipes/recipe-root.css +67 -0
  223. package/ux-demo/recipes/recipe-root.tsx +87 -0
  224. package/ux-demo/recipes/workspace-header.css +7 -0
  225. package/ux-demo/recipes/workspace-header.tsx +60 -61
  226. package/dist/chunk-2TYUFZUC.js.map +0 -1
  227. package/dist/chunk-6NDBE2OK.js.map +0 -1
  228. package/dist/chunk-6WTETUZ6.js.map +0 -1
  229. package/dist/chunk-AQFWBG23.js.map +0 -1
  230. package/dist/chunk-B6JYRX3P.js.map +0 -1
  231. package/dist/chunk-CAB6NQ2T.js.map +0 -1
  232. package/dist/chunk-CK6P5AUK.js.map +0 -1
  233. package/dist/chunk-DAO2VFTT.js.map +0 -1
  234. package/dist/chunk-DYBPI5O2.js.map +0 -1
  235. package/dist/chunk-E34TE2ZI.js.map +0 -1
  236. package/dist/chunk-EYALJQQD.js.map +0 -1
  237. package/dist/chunk-GYGM363P.js.map +0 -1
  238. package/dist/chunk-I45QO2IZ.js.map +0 -1
  239. package/dist/chunk-I4V3UDSA.js.map +0 -1
  240. package/dist/chunk-IU4QUY5I.js.map +0 -1
  241. package/dist/chunk-OGNE3OFT.js.map +0 -1
  242. package/dist/chunk-OGTJNHRG.js.map +0 -1
  243. package/dist/chunk-OMSRSL3B.js.map +0 -1
  244. package/dist/chunk-SOK5EUF7.js.map +0 -1
  245. package/dist/chunk-T7DOWS6T.js.map +0 -1
  246. package/dist/chunk-TIGSG6BX.js.map +0 -1
  247. package/dist/chunk-UDHHKZWO.js.map +0 -1
  248. package/dist/chunk-V6GQKOX2.js.map +0 -1
  249. package/dist/chunk-V6HCTCVD.js.map +0 -1
  250. package/dist/chunk-VXFGMDA7.js.map +0 -1
  251. package/dist/chunk-W2FK7ZNY.js.map +0 -1
  252. package/dist/chunk-WSXUPSID.js.map +0 -1
  253. package/dist/chunk-WVLMZ5SG.js.map +0 -1
  254. package/dist/chunk-XKFRMGMW.js.map +0 -1
  255. package/dist/chunk-Y6LYKFXY.js.map +0 -1
  256. package/dist/chunk-ZPWZIVI6.js.map +0 -1
  257. package/ux-demo/recipes/recipes.css +0 -453
package/README.md CHANGED
@@ -101,6 +101,14 @@ components, or a generic `slots` object. The v2 composition catalog publishes
101
101
  sound prop bindings as `zone.jsx.prop`, allowing ESLint to validate statically
102
102
  visible content and cardinality without guessing from zone names.
103
103
 
104
+ Stable single-root visual components also accept the explicit native
105
+ `slot?: string` prop, so their returned root can participate directly in a web
106
+ component's named slot and keep that assignment through Kerf rerenders. This is
107
+ a narrow interop attribute, not general native-attribute spreading. The
108
+ multi-root `ResizableRegion` and `CollapsiblePanel` intentionally omit it
109
+ because neither has one unambiguous returned root; `CollapsiblePanelToggle`
110
+ supports it as a normal single-root control.
111
+
104
112
  `ListItem.rootAttributes`, `ListHeader.rootAttributes`,
105
113
  `ListActionRow.rootAttributes`, `AppTab.rootAttributes`,
106
114
  `CatalogExample.rootAttributes`, and `CatalogExampleStack.rootAttributes` carry typed
@@ -165,9 +173,10 @@ interchangeable. `ListItem` and `ListActionRow` deliberately expose no raw
165
173
  | Component | Browser import (includes reachable CSS) | Manual CSS export |
166
174
  | ------------------------------------------------------------------- | --------------------------------------- | -------------------------------------- |
167
175
  | `LucideIcon` | `@kerfjs/ui/lucide-icon` | `@kerfjs/ui/lucide-icon.css` |
176
+ | `Badge` | `@kerfjs/ui/badge` | `@kerfjs/ui/badge.css` |
168
177
  | `DisclosureArrow` | `@kerfjs/ui/disclosure-arrow` | `@kerfjs/ui/disclosure-arrow.css` |
169
178
  | `Toolbar` | `@kerfjs/ui/toolbar` | `@kerfjs/ui/toolbar.css` |
170
- | `ToolbarControlGroup` | `@kerfjs/ui/toolbar-control-group` | `@kerfjs/ui/toolbar-control-group.css` |
179
+ | `ToolbarControlGroup`, `ToolbarActionLink` | `@kerfjs/ui/toolbar-control-group` | `@kerfjs/ui/toolbar-control-group.css` |
171
180
  | `DialogSurface`, `PopupSurface` | `@kerfjs/ui/surface-scaffold` | `@kerfjs/ui/surface-scaffold.css` |
172
181
  | `FloatingToolbar` | `@kerfjs/ui/floating-toolbar` | `@kerfjs/ui/floating-toolbar.css` |
173
182
  | `ToolbarText` | `@kerfjs/ui/toolbar-text` | `@kerfjs/ui/toolbar-text.css` |
@@ -258,9 +267,10 @@ without guessing from a screenshot or private CSS.
258
267
  Catalog demo authoring is deliberately separate from the entry inventory. Load
259
268
  [`catalog-authoring.json`](./ai/catalog-authoring.json) to discover the
260
269
  authoritative [Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract),
261
- the exact API-signature context, public imports/helpers, and sanctioned metadata
262
- slot. Keeping this as a companion artifact prevents per-entry selection facts
263
- from duplicating presentation rules.
270
+ the exact API-signature context, public imports/helpers, sanctioned metadata
271
+ slot, three-kind taxonomy, and functional-group/importance ordering policy.
272
+ Keeping this as a companion artifact prevents per-entry selection facts from
273
+ duplicating presentation rules.
264
274
 
265
275
  Tools that evaluate composition may additionally load
266
276
  [`component-catalog-v2.json`](./ai/component-catalog-v2.json). It is a
@@ -398,6 +408,19 @@ roots therefore do not need a transitive stylesheet list, and removing the last
398
408
  component import also removes its reachable CSS. This is component-level CSS
399
409
  tree shaking; variants within an imported component remain together.
400
410
 
411
+ When one public subpath groups several visual components, its source is a
412
+ folder: one component per file and one owned stylesheet per visual component.
413
+ The public JavaScript/TypeScript compatibility entrypoint only re-exports those
414
+ modules, and its CSS compatibility entrypoint only imports the owner
415
+ stylesheets. Do not accumulate multiple visual owners in either compatibility
416
+ file.
417
+
418
+ `npm run check:css-ownership` keeps that boundary honest: application CSS may
419
+ style only application-owned structure, never package component classes or
420
+ Web Awesome descendants. The UX catalog's `style.css` contains document-shell
421
+ mechanics only, recipes use component-owned styles, and `catalog.css` remains a
422
+ minimal compatibility entrypoint.
423
+
401
424
  The root `@kerfjs/ui` barrel stays JavaScript-only because making a side-effectful
402
425
  CSS barrel tree-shakable is not portable across bundlers. If an application uses
403
426
  that convenience import, also import `@kerfjs/ui/styles.css`, which deliberately
@@ -478,8 +501,8 @@ Tooltip and Popover surfaces omit pointer arrows by default. Override
478
501
  `--wa-tooltip-arrow-size` and `--kui-wa-popover-arrow-size`, or a single
479
502
  popover's public `--arrow-size`, when an arrow communicates useful context.
480
503
 
481
- Load application CSS afterward to override semantic values globally, or scope
482
- them to a subtree. Use Web Awesome's `.wa-light`, `.wa-dark`, and `.wa-invert`
504
+ Configure semantic values globally at the application root, or scope variables
505
+ to a self-owned subtree. Use Web Awesome's `.wa-light`, `.wa-dark`, and `.wa-invert`
483
506
  classes for explicit appearance boundaries:
484
507
 
485
508
  ```css
@@ -497,10 +520,11 @@ warning, or danger. Stateful components also expose
497
520
  component variables such as `--kui-state-banner-background`. Override the
498
521
  foundation for an application theme, a tone variable for one semantic state, or
499
522
  a component variable on one instance without replacing component selectors.
500
- Prefer an equivalent prop or token. When composition-specific layout still
501
- needs a selector, the component catalog's `publicClasses` arrays define the
502
- exact stable anatomy: public-class-to-public-class selectors are supported;
503
- descendant tag, id, attribute-only, and unlisted-class selectors are not.
523
+ Prefer an equivalent prop or token. The component catalog's `publicClasses`
524
+ arrays support diagnostics, tooling, browser assertions, and package-owned
525
+ composition; they are not an application styling API. Application-owned CSS may
526
+ style new structure rendered by its own component, but it must not select a
527
+ nested Kerf or Web Awesome component. Add missing configuration to the owner.
504
528
 
505
529
  `StateBanner` has opinionated `neutral`, `info`, `pop`, `success`, `warning`,
506
530
  and `danger` palettes. Override an individual banner with
@@ -578,6 +602,11 @@ drag, the scroll strip automatically moves toward either edge with speed based
578
602
  on pointer proximity, exposing earlier or later drop targets. Apply the reported
579
603
  change with `reorderTabs()` or application-specific state logic. The application
580
604
  still owns selection, closing, routing, and persistence.
605
+ For a tab-local action immediately after the final tab plus a workspace action
606
+ at the opposite edge, set `trailingPlacement="adjacent"`, pass the local action
607
+ through `trailing`, and pass the workspace action through `end`. TabBar owns the
608
+ flex geometry: the tab strip shrinks and scrolls while both action regions stay
609
+ visible. Do not recreate that split with descendant CSS overrides.
581
610
  Use `AppTab.rootAttributes` for domain `data-*` metadata and `closeIcon` for a
582
611
  decorative replacement glyph. The runtime rejects roles and case variants of
583
612
  the component- or wiring-owned action, tab identity, selection, drag, drop, and
@@ -616,7 +645,8 @@ hover/focus grip. Its optional `handleIcon` replaces only the decorative glyph;
616
645
  the component and `wireResizableRegions()` retain separator semantics and
617
646
  pointer/keyboard behavior. Typed policies cover separator visibility,
618
647
  instant-track/composited-content collapse, popup-safe overflow,
619
- inline/overlay/hidden responsive presentation, and safe-area restore controls;
648
+ inline/overlay/hidden responsive presentation, `responsiveFillAt` single-track
649
+ replacement, and safe-area restore controls;
620
650
  the same policies are available on `Workbench` and `CollapsiblePanel`. Consider
621
651
  Web Awesome Popup when its anchored-positioning
622
652
  engine removes custom placement code; treat Tree, Animated Image, Comparison,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./catalog-authoring.schema.json",
3
- "schemaVersion": 1,
3
+ "schemaVersion": 2,
4
4
  "package": "@kerfjs/ui",
5
5
  "scope": "catalog-demo-authoring",
6
6
  "authoritativeGuide": "docs/catalog.md#catalog-demo-authoring-contract",
@@ -17,6 +17,17 @@
17
17
  "wireCatalogGeometryOverlay",
18
18
  "revealCatalogEntry"
19
19
  ],
20
+ "taxonomy": {
21
+ "kinds": ["component", "composition", "recipe"],
22
+ "organization": {
23
+ "grouping": "functional-category",
24
+ "categoryOrder": "importance-descending",
25
+ "withinCategoryKindOrder": ["component", "composition"],
26
+ "withinKindOrder": ["importance-descending", "name-ascending"],
27
+ "recipes": "after-all-functional-groups"
28
+ },
29
+ "compositionTag": "Composition"
30
+ },
20
31
  "metadata": {
21
32
  "slot": "rootAttributes",
22
33
  "demo": "data-demo",
@@ -11,11 +11,12 @@
11
11
  "apiSignatures",
12
12
  "imports",
13
13
  "helpers",
14
+ "taxonomy",
14
15
  "metadata"
15
16
  ],
16
17
  "properties": {
17
18
  "$schema": { "type": "string" },
18
- "schemaVersion": { "const": 1 },
19
+ "schemaVersion": { "const": 2 },
19
20
  "package": { "const": "@kerfjs/ui" },
20
21
  "scope": { "const": "catalog-demo-authoring" },
21
22
  "authoritativeGuide": { "type": "string", "minLength": 1 },
@@ -44,6 +45,53 @@
44
45
  "minItems": 6,
45
46
  "uniqueItems": true
46
47
  },
48
+ "taxonomy": {
49
+ "type": "object",
50
+ "required": ["kinds", "organization", "compositionTag"],
51
+ "properties": {
52
+ "kinds": {
53
+ "type": "array",
54
+ "items": { "enum": ["component", "composition", "recipe"] },
55
+ "minItems": 3,
56
+ "maxItems": 3,
57
+ "uniqueItems": true
58
+ },
59
+ "organization": {
60
+ "type": "object",
61
+ "required": [
62
+ "grouping",
63
+ "categoryOrder",
64
+ "withinCategoryKindOrder",
65
+ "withinKindOrder",
66
+ "recipes"
67
+ ],
68
+ "properties": {
69
+ "grouping": { "const": "functional-category" },
70
+ "categoryOrder": { "const": "importance-descending" },
71
+ "withinCategoryKindOrder": {
72
+ "type": "array",
73
+ "items": { "enum": ["component", "composition"] },
74
+ "minItems": 2,
75
+ "maxItems": 2,
76
+ "uniqueItems": true
77
+ },
78
+ "withinKindOrder": {
79
+ "type": "array",
80
+ "items": {
81
+ "enum": ["importance-descending", "name-ascending"]
82
+ },
83
+ "minItems": 2,
84
+ "maxItems": 2,
85
+ "uniqueItems": true
86
+ },
87
+ "recipes": { "const": "after-all-functional-groups" }
88
+ },
89
+ "additionalProperties": false
90
+ },
91
+ "compositionTag": { "const": "Composition" }
92
+ },
93
+ "additionalProperties": false
94
+ },
47
95
  "metadata": {
48
96
  "type": "object",
49
97
  "required": ["slot", "demo", "geometryOverlaySkip"],
@@ -127,6 +127,20 @@
127
127
  ],
128
128
  "kind": "property-specific-css-value",
129
129
  "summary": "List flex, Skeleton dimensions, and Select icon colors use separate typed CSS grammars; row declaration-string props are absent rather than sharing a generic CSS escape hatch."
130
+ },
131
+ {
132
+ "id": "KUI-T014",
133
+ "publicImport": "@kerfjs/ui",
134
+ "symbols": [
135
+ "BadgeProps",
136
+ "CatalogProps",
137
+ "CollapsiblePanelToggleProps",
138
+ "SelectProps",
139
+ "SkeletonProps",
140
+ "TextProps"
141
+ ],
142
+ "kind": "explicit-native-attribute",
143
+ "summary": "Stable single-root visual components accept an explicit native slot attribute; multi-root components and arbitrary native attribute spreading remain excluded."
130
144
  }
131
145
  ]
132
146
  }
@@ -35,6 +35,7 @@
35
35
  "controlled-callback",
36
36
  "discriminated-union",
37
37
  "finite-vocabulary",
38
+ "explicit-native-attribute",
38
39
  "literal-identity",
39
40
  "property-specific-css-value",
40
41
  "protected-attributes",
@@ -166,6 +166,13 @@
166
166
  "accepts": ["toolbar-control-group"],
167
167
  "cardinality": { "min": 0, "max": 1 },
168
168
  "exclusiveWith": []
169
+ },
170
+ {
171
+ "id": "end",
172
+ "jsx": { "prop": "end" },
173
+ "accepts": ["toolbar-control-group"],
174
+ "cardinality": { "min": 0, "max": 1 },
175
+ "exclusiveWith": []
169
176
  }
170
177
  ],
171
178
  "state": [
@@ -7,6 +7,54 @@
7
7
  "identity": "package:id"
8
8
  },
9
9
  "entries": [
10
+ {
11
+ "key": "@kerfjs/ui:badge",
12
+ "package": "@kerfjs/ui",
13
+ "id": "badge",
14
+ "name": "Badge",
15
+ "kind": "component",
16
+ "source": "kerf",
17
+ "parents": { "mode": "any", "entries": [] },
18
+ "contexts": ["application-ui"],
19
+ "zones": [],
20
+ "children": { "mode": "any", "concepts": [], "requiredConcepts": [] },
21
+ "state": [
22
+ { "id": "metadata text", "owner": "application", "required": false },
23
+ {
24
+ "id": "semantic tone mapping",
25
+ "owner": "application",
26
+ "required": false
27
+ },
28
+ {
29
+ "id": "accessible label for abbreviated content",
30
+ "owner": "application",
31
+ "required": false
32
+ }
33
+ ],
34
+ "wiring": { "required": false, "helpers": [], "obligations": [] },
35
+ "responsive": { "owner": "not-applicable", "behaviors": [] },
36
+ "layout": {
37
+ "roles": ["foundation"],
38
+ "geometry": { "margin": "none", "border": "self", "padding": "self" }
39
+ },
40
+ "accessibility": {
41
+ "obligations": [
42
+ "Badge is non-interactive. Supply label when visible content is abbreviated, and ariaHidden when it repeats an accessible name owned by the surrounding component.",
43
+ "Keep meaningful text visible because tone is supplementary."
44
+ ]
45
+ },
46
+ "cssValueProps": [],
47
+ "boundaries": {
48
+ "rootClass": "kui-badge",
49
+ "publicClasses": ["kui-badge"],
50
+ "publicTokens": []
51
+ },
52
+ "diagnostics": [],
53
+ "provenance": {
54
+ "selection": "ai/component-catalog.json",
55
+ "composition": "generated-permissive-default"
56
+ }
57
+ },
10
58
  {
11
59
  "key": "@kerfjs/ui:lucide-icon",
12
60
  "package": "@kerfjs/ui",
@@ -596,7 +644,6 @@
596
644
  "publicClasses": [
597
645
  "kui-split-view",
598
646
  "kui-split-view__list",
599
- "kui-resizable-region",
600
647
  "kui-split-view__detail",
601
648
  "kui-split-view--compact"
602
649
  ],
@@ -1062,6 +1109,11 @@
1062
1109
  },
1063
1110
  "state": [
1064
1111
  { "id": "actions", "owner": "application", "required": false },
1112
+ {
1113
+ "id": "link destination and copy",
1114
+ "owner": "application",
1115
+ "required": false
1116
+ },
1065
1117
  { "id": "pressed state", "owner": "application", "required": false },
1066
1118
  { "id": "expanded state", "owner": "application", "required": false },
1067
1119
  { "id": "avatar image URL", "owner": "application", "required": false }
@@ -1079,8 +1131,11 @@
1079
1131
  },
1080
1132
  "cssValueProps": [],
1081
1133
  "boundaries": {
1082
- "rootClass": "kui-toolbar-control-group",
1083
- "publicClasses": ["kui-toolbar-control-group"],
1134
+ "rootClass": "kui-toolbar-action-link",
1135
+ "publicClasses": [
1136
+ "kui-toolbar-action-link",
1137
+ "kui-toolbar-control-group"
1138
+ ],
1084
1139
  "publicTokens": [
1085
1140
  "--kui-color-brand-on-quiet",
1086
1141
  "--kui-color-pop-border-normal",
@@ -1317,7 +1372,7 @@
1317
1372
  "key": "@kerfjs/ui:headers",
1318
1373
  "package": "@kerfjs/ui",
1319
1374
  "id": "headers",
1320
- "name": "Header composition",
1375
+ "name": "Headers",
1321
1376
  "kind": "composition",
1322
1377
  "source": "kerf",
1323
1378
  "parents": { "mode": "any", "entries": [] },
@@ -1786,16 +1841,12 @@
1786
1841
  "kui-list-header",
1787
1842
  "kui-list-header__action",
1788
1843
  "kui-list-header__action-layer",
1789
- "kui-list-header__badge",
1790
- "kui-list-header__count",
1791
1844
  "kui-list-header__label",
1792
1845
  "kui-list-header__title",
1793
1846
  "kui-list-header__toggle"
1794
1847
  ],
1795
1848
  "publicTokens": [
1796
1849
  "--kui-color-neutral-border-quiet",
1797
- "--kui-color-neutral-fill-quiet",
1798
- "--kui-color-neutral-on-quiet",
1799
1850
  "--kui-focus-ring",
1800
1851
  "--kui-font-xs",
1801
1852
  "--kui-list-header-action-icon-size",
@@ -1803,15 +1854,8 @@
1803
1854
  "--kui-layout-inline-margin",
1804
1855
  "--kui-layout-item-gap",
1805
1856
  "--kui-layout-item-padding",
1806
- "--kui-layout-pill-radius",
1807
- "--kui-list-header-count-font-size",
1808
1857
  "--kui-list-header-hover-background",
1809
- "--kui-list-group-divider-color",
1810
- "--kui-color-brand-on-normal",
1811
- "--kui-color-pop-fill-normal",
1812
- "--kui-color-pop-on-normal",
1813
- "--kui-color-danger-fill-normal",
1814
- "--kui-color-danger-on-normal"
1858
+ "--kui-list-group-divider-color"
1815
1859
  ]
1816
1860
  },
1817
1861
  "diagnostics": [
@@ -2087,7 +2131,7 @@
2087
2131
  "key": "@kerfjs/ui:application-tabs",
2088
2132
  "package": "@kerfjs/ui",
2089
2133
  "id": "application-tabs",
2090
- "name": "Application tabs composition",
2134
+ "name": "Application tabs",
2091
2135
  "kind": "composition",
2092
2136
  "source": "kerf",
2093
2137
  "parents": { "mode": "any", "entries": [] },
@@ -2258,6 +2302,13 @@
2258
2302
  "accepts": ["toolbar-control-group"],
2259
2303
  "cardinality": { "min": 0, "max": 1 },
2260
2304
  "exclusiveWith": []
2305
+ },
2306
+ {
2307
+ "id": "end",
2308
+ "jsx": { "prop": "end" },
2309
+ "accepts": ["toolbar-control-group"],
2310
+ "cardinality": { "min": 0, "max": 1 },
2311
+ "exclusiveWith": []
2261
2312
  }
2262
2313
  ],
2263
2314
  "children": {
@@ -2279,7 +2330,14 @@
2279
2330
  "responsive": { "owner": "not-applicable", "behaviors": [] },
2280
2331
  "layout": {
2281
2332
  "roles": ["navigation"],
2282
- "geometry": { "margin": "none", "border": "self", "padding": "self" }
2333
+ "geometry": {
2334
+ "margin": "none",
2335
+ "border": "self",
2336
+ "padding": "self",
2337
+ "notes": [
2338
+ "TabBar owns inline flex allocation: tabs shrink and scroll, an adjacent trailing action follows the tab strip, and the end action stays pinned at the far edge; leading, trailing, and end actions do not shrink."
2339
+ ]
2340
+ }
2283
2341
  },
2284
2342
  "accessibility": {
2285
2343
  "obligations": [
@@ -2294,7 +2352,8 @@
2294
2352
  "kui-tab-bar",
2295
2353
  "kui-tab-bar__leading",
2296
2354
  "kui-tab-bar__tabs",
2297
- "kui-tab-bar__trailing"
2355
+ "kui-tab-bar__trailing",
2356
+ "kui-tab-bar__end"
2298
2357
  ],
2299
2358
  "publicTokens": ["--kui-tab-bar-background", "--kui-tab-bar-border"]
2300
2359
  },
@@ -2638,7 +2697,7 @@
2638
2697
  "key": "@kerfjs/ui:feedback",
2639
2698
  "package": "@kerfjs/ui",
2640
2699
  "id": "feedback",
2641
- "name": "Feedback composition",
2700
+ "name": "Feedback",
2642
2701
  "kind": "composition",
2643
2702
  "source": "kerf",
2644
2703
  "parents": { "mode": "any", "entries": [] },
@@ -2724,7 +2783,6 @@
2724
2783
  "publicClasses": [
2725
2784
  "kui-state-banner",
2726
2785
  "kui-state-banner__action",
2727
- "kui-state-banner__badge",
2728
2786
  "kui-state-banner__copy",
2729
2787
  "kui-state-banner__detail",
2730
2788
  "kui-state-banner__icon"
@@ -2756,8 +2814,6 @@
2756
2814
  "--kui-state-banner-action-background",
2757
2815
  "--kui-state-banner-action-hover-background",
2758
2816
  "--kui-state-banner-background",
2759
- "--kui-state-banner-badge-background",
2760
- "--kui-state-banner-badge-foreground",
2761
2817
  "--kui-state-banner-border",
2762
2818
  "--kui-state-banner-danger-background",
2763
2819
  "--kui-state-banner-danger-border",