@kerfjs/ui 5.0.0-beta.4 → 5.0.0-beta.41

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 (498) hide show
  1. package/README.md +342 -108
  2. package/ai/application-ui-diagnostic-ids-v1.json +100 -0
  3. package/ai/application-ui-profile-sync.cjs +529 -0
  4. package/ai/application-ui-profile.d.mts +1 -0
  5. package/ai/application-ui-profile.d.ts +102 -0
  6. package/ai/application-ui-profile.defaults.json +41 -0
  7. package/ai/application-ui-profile.mjs +626 -0
  8. package/ai/application-ui-profile.schema.json +130 -0
  9. package/ai/catalog-authoring.json +25 -0
  10. package/ai/catalog-authoring.schema.json +61 -0
  11. package/ai/compile-time-contracts-v1.json +132 -0
  12. package/ai/compile-time-contracts-v1.schema.json +51 -0
  13. package/ai/component-catalog-extension-v2.d.ts +7 -0
  14. package/ai/component-catalog-extension-v2.schema.json +7 -0
  15. package/ai/component-catalog-extension.schema.json +79 -0
  16. package/ai/component-catalog-v2-overrides.json +496 -0
  17. package/ai/component-catalog-v2.d.ts +90 -0
  18. package/ai/component-catalog-v2.json +5678 -0
  19. package/ai/component-catalog-v2.schema.json +298 -0
  20. package/ai/component-catalog.json +2694 -417
  21. package/ai/component-catalog.schema.json +39 -0
  22. package/ai/public-api-signatures-v1.md +1591 -126
  23. package/ai/skill.md +140 -54
  24. package/ai/webawesome-jsx-signatures-v1.md +2 -1
  25. package/analyzer/cli.mjs +49 -0
  26. package/analyzer/index.d.mts +46 -0
  27. package/analyzer/index.mjs +1086 -0
  28. package/analyzer/report.schema.json +66 -0
  29. package/dist/app-tab.d.ts +15 -4
  30. package/dist/app-tab.js +3 -1
  31. package/dist/browser/app-tab.js +1 -0
  32. package/dist/browser/floating-toolbar.js +3 -0
  33. package/dist/browser/list-action-row.js +5 -0
  34. package/dist/browser/list-header.js +7 -0
  35. package/dist/browser/list-inset-control.js +3 -0
  36. package/dist/browser/list-inset-text.js +3 -0
  37. package/dist/browser/list-item.js +5 -0
  38. package/dist/browser/list.js +3 -0
  39. package/dist/browser/pane.js +3 -0
  40. package/dist/browser/row.js +3 -0
  41. package/dist/browser/segmented-control.js +1 -0
  42. package/dist/browser/select.js +1 -0
  43. package/dist/browser/skeleton.js +3 -0
  44. package/dist/browser/spacer.js +3 -0
  45. package/dist/browser/state-banner.js +1 -0
  46. package/dist/browser/sunken-panel.js +3 -0
  47. package/dist/browser/surface-scaffold.js +3 -0
  48. package/dist/browser/text.js +3 -0
  49. package/dist/browser/toolbar-text.js +1 -0
  50. package/dist/browser/value-table.js +1 -0
  51. package/dist/catalog-resources.d.ts +35 -0
  52. package/dist/catalog-resources.js +22 -0
  53. package/dist/catalog-resources.js.map +1 -0
  54. package/dist/catalog.d.ts +151 -0
  55. package/dist/catalog.js +396 -0
  56. package/dist/catalog.js.map +1 -0
  57. package/dist/chunk-2TYUFZUC.js +22 -0
  58. package/dist/chunk-2TYUFZUC.js.map +1 -0
  59. package/dist/chunk-6NDBE2OK.js +32 -0
  60. package/dist/chunk-6NDBE2OK.js.map +1 -0
  61. package/dist/chunk-6WTETUZ6.js +21 -0
  62. package/dist/chunk-6WTETUZ6.js.map +1 -0
  63. package/dist/chunk-AQFWBG23.js +83 -0
  64. package/dist/chunk-AQFWBG23.js.map +1 -0
  65. package/dist/chunk-B6JYRX3P.js +51 -0
  66. package/dist/chunk-B6JYRX3P.js.map +1 -0
  67. package/dist/chunk-C34NZOLJ.js +53 -0
  68. package/dist/chunk-C34NZOLJ.js.map +1 -0
  69. package/dist/chunk-CAB6NQ2T.js +102 -0
  70. package/dist/chunk-CAB6NQ2T.js.map +1 -0
  71. package/dist/chunk-CK6P5AUK.js +136 -0
  72. package/dist/chunk-CK6P5AUK.js.map +1 -0
  73. package/dist/chunk-DAO2VFTT.js +129 -0
  74. package/dist/chunk-DAO2VFTT.js.map +1 -0
  75. package/dist/chunk-DEYOGDE7.js +141 -0
  76. package/dist/chunk-DEYOGDE7.js.map +1 -0
  77. package/dist/chunk-DYBPI5O2.js +25 -0
  78. package/dist/chunk-DYBPI5O2.js.map +1 -0
  79. package/dist/{chunk-TRNBHPNW.js → chunk-E34TE2ZI.js} +12 -8
  80. package/dist/chunk-E34TE2ZI.js.map +1 -0
  81. package/dist/chunk-EYALJQQD.js +25 -0
  82. package/dist/chunk-EYALJQQD.js.map +1 -0
  83. package/dist/chunk-I45QO2IZ.js +88 -0
  84. package/dist/chunk-I45QO2IZ.js.map +1 -0
  85. package/dist/chunk-I4V3UDSA.js +79 -0
  86. package/dist/chunk-I4V3UDSA.js.map +1 -0
  87. package/dist/chunk-OGTJNHRG.js +42 -0
  88. package/dist/chunk-OGTJNHRG.js.map +1 -0
  89. package/dist/chunk-OL4TC3U2.js +156 -0
  90. package/dist/chunk-OL4TC3U2.js.map +1 -0
  91. package/dist/chunk-OMSRSL3B.js +120 -0
  92. package/dist/chunk-OMSRSL3B.js.map +1 -0
  93. package/dist/chunk-R3EBGEAW.js +46 -0
  94. package/dist/chunk-R3EBGEAW.js.map +1 -0
  95. package/dist/chunk-SOK5EUF7.js +25 -0
  96. package/dist/chunk-SOK5EUF7.js.map +1 -0
  97. package/dist/{chunk-7BR3DO2A.js → chunk-SRSJO5QE.js} +13 -4
  98. package/dist/chunk-SRSJO5QE.js.map +1 -0
  99. package/dist/chunk-T7DOWS6T.js +61 -0
  100. package/dist/chunk-T7DOWS6T.js.map +1 -0
  101. package/dist/chunk-TIGSG6BX.js +218 -0
  102. package/dist/chunk-TIGSG6BX.js.map +1 -0
  103. package/dist/chunk-UDHHKZWO.js +41 -0
  104. package/dist/chunk-UDHHKZWO.js.map +1 -0
  105. package/dist/{chunk-MQIZAD4A.js → chunk-UKKSMZYT.js} +76 -22
  106. package/dist/chunk-UKKSMZYT.js.map +1 -0
  107. package/dist/chunk-V6GQKOX2.js +39 -0
  108. package/dist/chunk-V6GQKOX2.js.map +1 -0
  109. package/dist/chunk-V6HCTCVD.js +46 -0
  110. package/dist/chunk-V6HCTCVD.js.map +1 -0
  111. package/dist/chunk-VDUJZF5G.js +515 -0
  112. package/dist/chunk-VDUJZF5G.js.map +1 -0
  113. package/dist/chunk-VXFGMDA7.js +31 -0
  114. package/dist/chunk-VXFGMDA7.js.map +1 -0
  115. package/dist/chunk-WN52USHV.js +115 -0
  116. package/dist/chunk-WN52USHV.js.map +1 -0
  117. package/dist/chunk-WSXUPSID.js +43 -0
  118. package/dist/chunk-WSXUPSID.js.map +1 -0
  119. package/dist/chunk-X5GRDQ7V.js +50 -0
  120. package/dist/chunk-X5GRDQ7V.js.map +1 -0
  121. package/dist/{chunk-56RJXPHG.js → chunk-Y6LYKFXY.js} +1 -1
  122. package/dist/{chunk-56RJXPHG.js.map → chunk-Y6LYKFXY.js.map} +1 -1
  123. package/dist/chunk-ZASJJMGV.js +17 -0
  124. package/dist/chunk-ZASJJMGV.js.map +1 -0
  125. package/dist/chunk-ZPWZIVI6.js +47 -0
  126. package/dist/chunk-ZPWZIVI6.js.map +1 -0
  127. package/dist/collapsible-panel.d.ts +77 -0
  128. package/dist/collapsible-panel.js +84 -0
  129. package/dist/collapsible-panel.js.map +1 -0
  130. package/dist/css-values.d.ts +75 -0
  131. package/dist/css-values.js +3 -0
  132. package/dist/css-values.js.map +1 -0
  133. package/dist/device-class.d.ts +62 -0
  134. package/dist/device-class.js +103 -0
  135. package/dist/device-class.js.map +1 -0
  136. package/dist/disclosure-arrow.js +1 -1
  137. package/dist/divider-sides-BzB6rphT.d.ts +6 -0
  138. package/dist/empty-state.d.ts +3 -2
  139. package/dist/empty-state.js +1 -1
  140. package/dist/flex-alignment-CF8NLj7i.d.ts +4 -0
  141. package/dist/floating-toolbar.d.ts +29 -0
  142. package/dist/floating-toolbar.js +3 -0
  143. package/dist/floating-toolbar.js.map +1 -0
  144. package/dist/index.d.ts +28 -14
  145. package/dist/index.js +34 -23
  146. package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +19 -8
  147. package/dist/list-action-row.js +7 -0
  148. package/dist/list-action-row.js.map +1 -0
  149. package/dist/list-header.d.ts +80 -0
  150. package/dist/list-header.js +9 -0
  151. package/dist/list-header.js.map +1 -0
  152. package/dist/list-inset-control.d.ts +20 -0
  153. package/dist/list-inset-control.js +3 -0
  154. package/dist/list-inset-control.js.map +1 -0
  155. package/dist/list-inset-text.d.ts +29 -0
  156. package/dist/list-inset-text.js +3 -0
  157. package/dist/list-inset-text.js.map +1 -0
  158. package/dist/list-item.d.ts +45 -0
  159. package/dist/list-item.js +7 -0
  160. package/dist/list-item.js.map +1 -0
  161. package/dist/list.d.ts +30 -0
  162. package/dist/list.js +5 -0
  163. package/dist/list.js.map +1 -0
  164. package/dist/loading-spinner.js +1 -1
  165. package/dist/nav-stack.d.ts +41 -0
  166. package/dist/nav-stack.js +6 -0
  167. package/dist/nav-stack.js.map +1 -0
  168. package/dist/pane.d.ts +50 -0
  169. package/dist/pane.js +4 -0
  170. package/dist/pane.js.map +1 -0
  171. package/dist/resizable-region.d.ts +21 -3
  172. package/dist/resizable-region.js +1 -1
  173. package/dist/row.d.ts +28 -0
  174. package/dist/row.js +5 -0
  175. package/dist/row.js.map +1 -0
  176. package/dist/segmented-control.d.ts +11 -8
  177. package/dist/segmented-control.js +3 -1
  178. package/dist/select-register.d.ts +5 -1
  179. package/dist/select-register.js +129 -1
  180. package/dist/select-register.js.map +1 -1
  181. package/dist/select.d.ts +34 -8
  182. package/dist/select.js +3 -1
  183. package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
  184. package/dist/skeleton.d.ts +25 -0
  185. package/dist/skeleton.js +4 -0
  186. package/dist/skeleton.js.map +1 -0
  187. package/dist/spacer.d.ts +16 -0
  188. package/dist/spacer.js +4 -0
  189. package/dist/spacer.js.map +1 -0
  190. package/dist/split-view.d.ts +43 -0
  191. package/dist/split-view.js +82 -0
  192. package/dist/split-view.js.map +1 -0
  193. package/dist/state-banner.d.ts +11 -5
  194. package/dist/state-banner.js +3 -1
  195. package/dist/styles/app-tab.css +26 -0
  196. package/dist/styles/catalog.css +582 -0
  197. package/dist/styles/collapsible-panel.css +212 -0
  198. package/dist/styles/floating-toolbar.css +38 -0
  199. package/dist/styles/foundation.css +80 -0
  200. package/dist/styles/layout.css +2 -20
  201. package/dist/styles/list-action-row.css +224 -0
  202. package/dist/styles/list-header.css +224 -0
  203. package/dist/styles/list-inset-control.css +23 -0
  204. package/dist/styles/list-inset-text.css +30 -0
  205. package/dist/styles/list-item.css +171 -0
  206. package/dist/styles/list.css +118 -0
  207. package/dist/styles/nav-stack.css +141 -0
  208. package/dist/styles/pane.css +62 -0
  209. package/dist/styles/resizable-region.css +158 -0
  210. package/dist/styles/row.css +92 -0
  211. package/dist/styles/segmented-control.css +10 -7
  212. package/dist/styles/select.css +115 -2
  213. package/dist/styles/skeleton.css +31 -0
  214. package/dist/styles/spacer.css +11 -0
  215. package/dist/styles/split-view.css +35 -0
  216. package/dist/styles/state-banner.css +49 -10
  217. package/dist/styles/styles.css +10 -5
  218. package/dist/styles/sunken-panel.css +22 -0
  219. package/dist/styles/surface-scaffold.css +51 -0
  220. package/dist/styles/tab-bar.css +24 -0
  221. package/dist/styles/tab-scaffold.css +85 -0
  222. package/dist/styles/text.css +6 -0
  223. package/dist/styles/token-search-field.css +14 -2
  224. package/dist/styles/toolbar-control-group.css +235 -8
  225. package/dist/styles/toolbar-text.css +65 -2
  226. package/dist/styles/toolbar.css +47 -2
  227. package/dist/styles/webawesome.css +171 -0
  228. package/dist/styles/workbench.css +187 -0
  229. package/dist/sunken-panel.d.ts +20 -0
  230. package/dist/sunken-panel.js +3 -0
  231. package/dist/sunken-panel.js.map +1 -0
  232. package/dist/surface-scaffold.d.ts +26 -0
  233. package/dist/surface-scaffold.js +3 -0
  234. package/dist/surface-scaffold.js.map +1 -0
  235. package/dist/tab-bar.d.ts +24 -6
  236. package/dist/tab-bar.js +1 -1
  237. package/dist/tab-scaffold.d.ts +31 -0
  238. package/dist/tab-scaffold.js +51 -0
  239. package/dist/tab-scaffold.js.map +1 -0
  240. package/dist/text.d.ts +20 -0
  241. package/dist/text.js +3 -0
  242. package/dist/text.js.map +1 -0
  243. package/dist/token-search-field.d.ts +30 -13
  244. package/dist/token-search-field.js +1 -1
  245. package/dist/toolbar-control-group.d.ts +33 -7
  246. package/dist/toolbar-control-group.js +1 -1
  247. package/dist/toolbar-text.d.ts +31 -4
  248. package/dist/toolbar-text.js +3 -1
  249. package/dist/toolbar.d.ts +10 -7
  250. package/dist/toolbar.js +1 -1
  251. package/dist/value-table.d.ts +7 -3
  252. package/dist/value-table.js +3 -1
  253. package/dist/webawesome.d.ts +1 -0
  254. package/dist/wire-catalog.d.ts +57 -0
  255. package/dist/wire-catalog.js +302 -0
  256. package/dist/wire-catalog.js.map +1 -0
  257. package/dist/wire-nav-stack.d.ts +18 -0
  258. package/dist/wire-nav-stack.js +228 -0
  259. package/dist/wire-nav-stack.js.map +1 -0
  260. package/dist/wire-resizable-regions.d.ts +1 -1
  261. package/dist/wire-resizable-regions.js +1 -1
  262. package/dist/wire-sidebar.d.ts +48 -0
  263. package/dist/wire-sidebar.js +147 -0
  264. package/dist/wire-sidebar.js.map +1 -0
  265. package/dist/wire-tab-bars.d.ts +19 -2
  266. package/dist/wire-tab-bars.js +1 -1
  267. package/dist/wire-tab-scaffold.d.ts +11 -0
  268. package/dist/wire-tab-scaffold.js +21 -0
  269. package/dist/wire-tab-scaffold.js.map +1 -0
  270. package/dist/wire-token-search-fields.d.ts +104 -4
  271. package/dist/wire-token-search-fields.js +1 -1
  272. package/dist/workbench.d.ts +44 -0
  273. package/dist/workbench.js +106 -0
  274. package/dist/workbench.js.map +1 -0
  275. package/docs/accessibility.md +155 -20
  276. package/docs/app-layouts.md +61 -0
  277. package/docs/catalog.md +364 -0
  278. package/docs/collapsible-panel.md +142 -0
  279. package/docs/component-contract.md +258 -28
  280. package/docs/component-integration.md +63 -0
  281. package/docs/component-selection.md +219 -57
  282. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  283. package/docs/design/templates/empty-state/filtered.svg +1 -0
  284. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  285. package/docs/design/templates/empty-state/with-action.svg +1 -0
  286. package/docs/design/templates/empty-state-dark.svg +1 -0
  287. package/docs/design/templates/empty-state.svg +1 -0
  288. package/docs/design/templates/list/compact-dark.svg +1 -0
  289. package/docs/design/templates/list/compact.svg +1 -0
  290. package/docs/design/templates/list/stack-dark.svg +1 -0
  291. package/docs/design/templates/list/stack.svg +1 -0
  292. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  293. package/docs/design/templates/list-action-row/default.svg +1 -0
  294. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  295. package/docs/design/templates/list-action-row/selected.svg +1 -0
  296. package/docs/design/templates/list-action-row-dark.svg +1 -0
  297. package/docs/design/templates/list-action-row.svg +1 -0
  298. package/docs/design/templates/list-dark.svg +1 -0
  299. package/docs/design/templates/list-header/action-dark.svg +1 -0
  300. package/docs/design/templates/list-header/action.svg +1 -0
  301. package/docs/design/templates/list-header/count-dark.svg +1 -0
  302. package/docs/design/templates/list-header/count.svg +1 -0
  303. package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
  304. package/docs/design/templates/list-header/inline-action.svg +1 -0
  305. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  306. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  307. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  308. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  309. package/docs/design/templates/list-header-dark.svg +1 -0
  310. package/docs/design/templates/list-header.svg +1 -0
  311. package/docs/design/templates/list-item/default-dark.svg +1 -0
  312. package/docs/design/templates/list-item/default.svg +1 -0
  313. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  314. package/docs/design/templates/list-item/multiline.svg +1 -0
  315. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  316. package/docs/design/templates/list-item/selected.svg +1 -0
  317. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  318. package/docs/design/templates/list-item/trailing.svg +1 -0
  319. package/docs/design/templates/list-item-dark.svg +1 -0
  320. package/docs/design/templates/list-item.svg +1 -0
  321. package/docs/design/templates/list.svg +1 -0
  322. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  323. package/docs/design/templates/segmented-control/equal.svg +1 -0
  324. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  325. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  326. package/docs/design/templates/segmented-control-dark.svg +1 -0
  327. package/docs/design/templates/segmented-control.svg +1 -0
  328. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  329. package/docs/design/templates/skeleton/avatar.svg +1 -0
  330. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  331. package/docs/design/templates/skeleton/block.svg +1 -0
  332. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  333. package/docs/design/templates/skeleton/lines.svg +1 -0
  334. package/docs/design/templates/skeleton-dark.svg +1 -0
  335. package/docs/design/templates/skeleton.svg +1 -0
  336. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  337. package/docs/design/templates/state-banner/danger.svg +1 -0
  338. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  339. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  340. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  341. package/docs/design/templates/state-banner/info.svg +1 -0
  342. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  343. package/docs/design/templates/state-banner/success.svg +1 -0
  344. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  345. package/docs/design/templates/state-banner/warning.svg +1 -0
  346. package/docs/design/templates/state-banner-dark.svg +1 -0
  347. package/docs/design/templates/state-banner.svg +1 -0
  348. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  349. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  350. package/docs/design/templates/tab-bar-dark.svg +1 -0
  351. package/docs/design/templates/tab-bar.svg +1 -0
  352. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  353. package/docs/design/templates/token-search-field/empty.svg +1 -0
  354. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  355. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  356. package/docs/design/templates/token-search-field-dark.svg +1 -0
  357. package/docs/design/templates/token-search-field.svg +1 -0
  358. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  359. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  360. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  361. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  362. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  363. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  364. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  365. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  366. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  367. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  368. package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
  369. package/docs/design/templates/toolbar-control-group.svg +1 -0
  370. package/docs/design/templates/toolbar-dark.svg +1 -0
  371. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  372. package/docs/design/templates/toolbar-text/default.svg +1 -0
  373. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  374. package/docs/design/templates/toolbar-text/large.svg +1 -0
  375. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  376. package/docs/design/templates/toolbar-text/small.svg +1 -0
  377. package/docs/design/templates/toolbar-text-dark.svg +1 -0
  378. package/docs/design/templates/toolbar-text.svg +1 -0
  379. package/docs/design/templates/toolbar.svg +1 -0
  380. package/docs/design/templates/value-table/details-dark.svg +1 -0
  381. package/docs/design/templates/value-table/details.svg +1 -0
  382. package/docs/design/templates/value-table-dark.svg +1 -0
  383. package/docs/design/templates/value-table.svg +1 -0
  384. package/docs/design/templates.md +128 -0
  385. package/docs/design-philosophy.md +33 -11
  386. package/docs/device-class.md +54 -0
  387. package/docs/examples/application-ui-profile.json +60 -0
  388. package/docs/examples/command-palette-adapter.tsx +68 -17
  389. package/docs/examples/component-catalog-extension-v2.json +80 -0
  390. package/docs/examples/component-catalog-extension.json +45 -0
  391. package/docs/layout.md +169 -38
  392. package/docs/nav-stack.md +77 -0
  393. package/docs/recipes.md +64 -16
  394. package/docs/split-view.md +55 -0
  395. package/docs/sunken-panel.md +53 -0
  396. package/docs/surface-scaffold.md +25 -0
  397. package/docs/tab-scaffold.md +52 -0
  398. package/docs/type-contracts.md +127 -0
  399. package/docs/ui-analyzer.md +118 -0
  400. package/docs/ui-doctor.md +91 -0
  401. package/docs/ui-evaluator.md +122 -0
  402. package/docs/ux-demo.md +29 -10
  403. package/docs/webawesome-theme.md +82 -8
  404. package/docs/workbench.md +123 -0
  405. package/doctor/cli.mjs +115 -0
  406. package/doctor/config.schema.json +68 -0
  407. package/doctor/eslint-diagnostics.d.mts +24 -0
  408. package/doctor/eslint-diagnostics.mjs +24 -0
  409. package/doctor/index.d.mts +116 -0
  410. package/doctor/index.mjs +1272 -0
  411. package/doctor/report.schema.json +118 -0
  412. package/evaluator/cli.mjs +89 -0
  413. package/evaluator/index.d.mts +90 -0
  414. package/evaluator/index.mjs +1138 -0
  415. package/evaluator/report.schema.json +152 -0
  416. package/llms.txt +260 -32
  417. package/package.json +205 -38
  418. package/traversal-exclusions.mjs +27 -0
  419. package/ux-demo/recipes/app-shell.tsx +223 -13
  420. package/ux-demo/recipes/collapsible-sidebar.tsx +230 -0
  421. package/ux-demo/recipes/compact-toolbar.tsx +116 -12
  422. package/ux-demo/recipes/composer-form.tsx +120 -19
  423. package/ux-demo/recipes/list-detail-dialog.tsx +205 -0
  424. package/ux-demo/recipes/list-workspace-states.tsx +176 -9
  425. package/ux-demo/recipes/loaders.ts +13 -4
  426. package/ux-demo/recipes/loading-inspector.tsx +191 -0
  427. package/ux-demo/recipes/mount-recipe.ts +31 -5
  428. package/ux-demo/recipes/navigation-sidebar.tsx +123 -11
  429. package/ux-demo/recipes/navigation-stack.tsx +121 -0
  430. package/ux-demo/recipes/recipes.css +125 -16
  431. package/ux-demo/recipes/types.ts +9 -1
  432. package/ux-demo/recipes/workspace-header.tsx +72 -3
  433. package/dist/browser/dialog-header.js +0 -5
  434. package/dist/browser/menu-action-row.js +0 -3
  435. package/dist/browser/menu-header.js +0 -5
  436. package/dist/browser/menu-item.js +0 -3
  437. package/dist/browser/page-header.js +0 -3
  438. package/dist/chunk-2PES33HS.js +0 -13
  439. package/dist/chunk-2PES33HS.js.map +0 -1
  440. package/dist/chunk-55DATV3A.js +0 -10
  441. package/dist/chunk-55DATV3A.js.map +0 -1
  442. package/dist/chunk-7BR3DO2A.js.map +0 -1
  443. package/dist/chunk-7LDCTU7D.js +0 -134
  444. package/dist/chunk-7LDCTU7D.js.map +0 -1
  445. package/dist/chunk-AQNKJRFH.js +0 -79
  446. package/dist/chunk-AQNKJRFH.js.map +0 -1
  447. package/dist/chunk-CTQKI2XL.js +0 -28
  448. package/dist/chunk-CTQKI2XL.js.map +0 -1
  449. package/dist/chunk-DAFFDO33.js +0 -14
  450. package/dist/chunk-DAFFDO33.js.map +0 -1
  451. package/dist/chunk-EGHL5S4P.js +0 -33
  452. package/dist/chunk-EGHL5S4P.js.map +0 -1
  453. package/dist/chunk-GY5WH7TO.js +0 -10
  454. package/dist/chunk-GY5WH7TO.js.map +0 -1
  455. package/dist/chunk-H5AGGVU5.js +0 -75
  456. package/dist/chunk-H5AGGVU5.js.map +0 -1
  457. package/dist/chunk-K3G72I6D.js +0 -24
  458. package/dist/chunk-K3G72I6D.js.map +0 -1
  459. package/dist/chunk-M5JRI6MN.js +0 -27
  460. package/dist/chunk-M5JRI6MN.js.map +0 -1
  461. package/dist/chunk-MBR3TYNL.js +0 -14
  462. package/dist/chunk-MBR3TYNL.js.map +0 -1
  463. package/dist/chunk-MFKMHK5W.js +0 -10
  464. package/dist/chunk-MFKMHK5W.js.map +0 -1
  465. package/dist/chunk-MQIZAD4A.js.map +0 -1
  466. package/dist/chunk-NPPD2A6O.js +0 -40
  467. package/dist/chunk-NPPD2A6O.js.map +0 -1
  468. package/dist/chunk-R6JHHBKQ.js +0 -19
  469. package/dist/chunk-R6JHHBKQ.js.map +0 -1
  470. package/dist/chunk-S3TPM2LP.js +0 -23
  471. package/dist/chunk-S3TPM2LP.js.map +0 -1
  472. package/dist/chunk-TRNBHPNW.js.map +0 -1
  473. package/dist/chunk-VHW5YNIB.js +0 -17
  474. package/dist/chunk-VHW5YNIB.js.map +0 -1
  475. package/dist/chunk-WVPYVDXY.js +0 -15
  476. package/dist/chunk-WVPYVDXY.js.map +0 -1
  477. package/dist/chunk-XZXRLY5Q.js +0 -33
  478. package/dist/chunk-XZXRLY5Q.js.map +0 -1
  479. package/dist/dialog-header.d.ts +0 -15
  480. package/dist/dialog-header.js +0 -5
  481. package/dist/dialog-header.js.map +0 -1
  482. package/dist/menu-action-row.js +0 -4
  483. package/dist/menu-action-row.js.map +0 -1
  484. package/dist/menu-header.d.ts +0 -41
  485. package/dist/menu-header.js +0 -6
  486. package/dist/menu-header.js.map +0 -1
  487. package/dist/menu-item.d.ts +0 -31
  488. package/dist/menu-item.js +0 -4
  489. package/dist/menu-item.js.map +0 -1
  490. package/dist/page-header.d.ts +0 -9
  491. package/dist/page-header.js +0 -3
  492. package/dist/page-header.js.map +0 -1
  493. package/dist/styles/dialog-header.css +0 -87
  494. package/dist/styles/menu-action-row.css +0 -160
  495. package/dist/styles/menu-header.css +0 -143
  496. package/dist/styles/menu-item.css +0 -123
  497. package/dist/styles/page-header.css +0 -33
  498. package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
package/README.md CHANGED
@@ -4,11 +4,27 @@ Accessible, composable UI primitives for [kerf](https://github.com/brianwestphal
4
4
 
5
5
  Start interface work with the [need-first component selection matrix](./docs/component-selection.md). It distinguishes direct reuse, composition, thin application adapters, and genuinely custom semantics, with imports, required wiring, application ownership, alternatives, and recipes for every public primitive.
6
6
 
7
+ When adding a first-party public component, follow the
8
+ [component integration workflow](./docs/component-integration.md). The catalog
9
+ entry drives one validator across package, build, barrel, CSS, demo, route, and
10
+ AI signature projections, with a non-mutating dry-run report.
11
+
12
+ Browser verification always builds current source: both `npm run test:e2e`
13
+ and direct focused Playwright commands run the catalog/conformance preflights
14
+ and production build before preview. See the [UX catalog contract](./docs/ux-demo.md).
15
+
16
+ When authoring a component gallery, follow the single
17
+ [Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract)
18
+ for focused-versus-composition modes, helper nesting, specimen selection,
19
+ geometry inspection, and metadata ownership. AI tools can discover that
20
+ contract and its public imports through the shipped
21
+ [`catalog-authoring.json`](./ai/catalog-authoring.json) artifact.
22
+
7
23
  For connective application patterns, use the seven [production composition
8
24
  recipes](./docs/recipes.md). Each has a stable catalog route, runnable state,
9
25
  public-subpath source, semantic layout ownership, and explicit application
10
26
  customization boundaries. The composer recipe demonstrates one coherent form
11
- surface with `DialogHeader` hierarchy and field/action controls aligned to the
27
+ surface with a `Toolbar`/`ToolbarText` heading and field/action controls aligned to the
12
28
  shared 8px gutter; only persistent feedback adds a nested semantic
13
29
  `StateBanner` surface.
14
30
 
@@ -23,60 +39,80 @@ npm install kerfjs @kerfjs/ui
23
39
  ```
24
40
 
25
41
  ```tsx
26
- import { MenuItem } from '@kerfjs/ui/menu-item';
27
- import { MenuHeader } from '@kerfjs/ui/menu-header';
28
- import { MenuActionRow } from '@kerfjs/ui/menu-action-row';
29
- import { Toolbar } from '@kerfjs/ui/toolbar';
30
- import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
31
- import { ToolbarText } from '@kerfjs/ui/toolbar-text';
32
-
33
- mount(root, () => <>
34
- <Toolbar label="Document" leading={<ToolbarControlGroup appearance="borderless" single><ToolbarText text="Notes" /></ToolbarControlGroup>} />
35
- <section>
36
- <MenuHeader
37
- label="Workspace"
38
- action="show-workspace-actions"
39
- actionLabel="Workspace actions"
40
- rootAttributes={{ 'data-section-id': 'workspace' }}
41
- triggerAttributes={{
42
- popoverTarget: 'workspace-actions',
43
- popoverTargetAction: 'toggle',
44
- 'aria-controls': 'workspace-actions',
45
- 'aria-haspopup': 'dialog',
46
- }}
47
- />
48
- <MenuItem
49
- action="open-notes"
50
- label="Notes"
51
- selected
52
- rootAttributes={{ 'data-command-color': 'blue', 'data-drop-status': 'ready' }}
42
+ import { ListItem } from "@kerfjs/ui/list-item";
43
+ import { ListHeader } from "@kerfjs/ui/list-header";
44
+ import { ListActionRow } from "@kerfjs/ui/list-action-row";
45
+ import { Toolbar } from "@kerfjs/ui/toolbar";
46
+ import { ToolbarControlGroup } from "@kerfjs/ui/toolbar-control-group";
47
+ import { ToolbarText } from "@kerfjs/ui/toolbar-text";
48
+
49
+ mount(root, () => (
50
+ <>
51
+ <Toolbar
52
+ label="Document"
53
+ leading={<ToolbarText text="Notes" />}
53
54
  />
54
- <MenuActionRow
55
- action="open-file"
56
- itemId="src/main.ts"
57
- label="src/main.ts"
58
- trailingAction="open-file-actions"
59
- trailingActionLabel="Actions for src/main.ts"
60
- trailingActionIcon={moreIcon}
61
- />
62
- <div id="workspace-actions" popover="auto">Application-owned actions</div>
63
- </section>
64
- </>);
55
+ <section>
56
+ <ListHeader
57
+ label="Workspace"
58
+ action="show-workspace-actions"
59
+ actionLabel="Workspace actions"
60
+ rootAttributes={{ "data-section-id": "workspace" }}
61
+ triggerAttributes={{
62
+ popoverTarget: "workspace-actions",
63
+ popoverTargetAction: "toggle",
64
+ "aria-controls": "workspace-actions",
65
+ "aria-haspopup": "dialog",
66
+ }}
67
+ />
68
+ <ListItem
69
+ action="open-notes"
70
+ label="Notes"
71
+ selected
72
+ rootAttributes={{
73
+ "data-command-color": "blue",
74
+ "data-drop-status": "ready",
75
+ }}
76
+ />
77
+ <ListActionRow
78
+ action="open-file"
79
+ itemId="src/main.ts"
80
+ label="src/main.ts"
81
+ trailingAction="open-file-actions"
82
+ trailingActionLabel="Actions for src/main.ts"
83
+ trailingActionIcon={moreIcon}
84
+ />
85
+ <div id="workspace-actions" popover="auto">
86
+ Application-owned actions
87
+ </div>
88
+ </section>
89
+ </>
90
+ ));
65
91
  ```
66
92
 
67
93
  Components return Kerf `SafeHtml`. They do not own application state or attach transient listeners. Actions are stable `data-action` hooks; the application wires them once with `delegate()` or `delegateActions()` and retains the disposer.
68
94
 
69
- `MenuItem.rootAttributes`, `MenuHeader.rootAttributes`,
70
- `MenuActionRow.rootAttributes`, and `AppTab.rootAttributes` carry typed
95
+ Component content positions use one convention: `children` is the homogeneous
96
+ primary region, while semantic positions and replacement content use explicit
97
+ named `SafeHtml` props such as `header`, `footer`, `leading`, `trailing`,
98
+ `icon`, and `action`. These named `SafeHtml` prop slots are ordinary typed
99
+ function-component props—not native `<slot>` elements, wrapper slot
100
+ components, or a generic `slots` object. The v2 composition catalog publishes
101
+ sound prop bindings as `zone.jsx.prop`, allowing ESLint to validate statically
102
+ visible content and cardinality without guessing from zone names.
103
+
104
+ `ListItem.rootAttributes`, `ListHeader.rootAttributes`,
105
+ `ListActionRow.rootAttributes`, `AppTab.rootAttributes`,
106
+ `CatalogExample.rootAttributes`, and `CatalogExampleStack.rootAttributes` carry typed
71
107
  application `data-*` metadata without
72
- teaching the package domain fields. `MenuHeader.triggerAttributes` and
73
- `MenuActionRow.trailingActionAttributes` additionally support native popover
108
+ teaching the package domain fields. `ListHeader.triggerAttributes` and
109
+ `ListActionRow.trailingActionAttributes` additionally support native popover
74
110
  target and relationship attributes. Roles and component-owned action, selection,
75
- disclosure, naming, disabled, and icon semantics remain protected props; an
111
+ disclosure, naming, disabled, icon, and catalog-structure semantics remain protected props; an
76
112
  isolated `role="menuitem"` is not an extension shortcut.
77
113
  The slots are also filtered at runtime, so structurally widened objects and
78
114
  JavaScript callers cannot bypass those protections with case-variant names.
79
- `MenuItem.trailing` is dormant metadata. Use `MenuActionRow` when a row needs
115
+ `ListItem.trailing` is dormant metadata. Use `ListActionRow` when a row needs
80
116
  sibling primary and trailing native-button actions with independent names,
81
117
  disabled states, focus, and click ownership. Its `label`, `icon`, and
82
118
  `trailingActionIcon` slots are dormant content and must not contain controls.
@@ -90,40 +126,93 @@ Do not concatenate a count into `label` or pass a numeric `badge`; the mutually
90
126
  exclusive legacy `badge` slot remains available for non-count `SafeHtml` such
91
127
  as a `New` marker.
92
128
 
129
+ `Row.gap`, `List.gap`, and `Spacer` dimensions accept a direct spacing name such as
130
+ `gap="xs"` or `gap="m"`, or a branded `CssLength`. Import `space`, `rem`, `em`,
131
+ `px`, `pct`, `lengthVar`, `plus`, and `calc` from the CSS-free
132
+ `@kerfjs/ui/css-values` subpath when a named step is not enough. `plus` returns
133
+ an incomplete expression, so wrap it with `calc` before passing it to a prop.
134
+ Raw CSS strings are deliberately rejected; the opaque brands catch authoring
135
+ mistakes but are not sanitizers.
136
+
137
+ Use `Row` for horizontal flex composition and `List` for vertical composition.
138
+ Both accept `hAlign` (`left`, `center`, `right`, `full`) and `vAlign` (`top`,
139
+ `middle`, `bottom`, `full`), plus their documented short/CSS aliases. `Row`
140
+ defaults to left/full alignment, the `xs` gap, and `wrap={false}`; List keeps
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.
147
+
148
+ The same property-specific boundary applies beyond spacing: use `flex()` (or a
149
+ finite keyword) for `Row.flex` and `List.flex`; length builders and intrinsic-size keywords for
150
+ `Skeleton.width`/`height`; length builders for `Skeleton.radius`; and
151
+ `uiColor()` or `colorVar()` for `SelectChoice.color`. These grammars are not
152
+ interchangeable. `ListItem` and `ListActionRow` deliberately expose no raw
153
+ `style` declarations; use `className`, public tokens, and component props.
154
+
93
155
  ## Component subpaths
94
156
 
95
- | Component | Browser import (includes reachable CSS) | Manual CSS export |
96
- | --- | --- | --- |
97
- | `LucideIcon` | `@kerfjs/ui/lucide-icon` | `@kerfjs/ui/lucide-icon.css` |
98
- | `DisclosureArrow` | `@kerfjs/ui/disclosure-arrow` | `@kerfjs/ui/disclosure-arrow.css` |
99
- | `Toolbar` | `@kerfjs/ui/toolbar` | `@kerfjs/ui/toolbar.css` |
100
- | `ToolbarControlGroup` | `@kerfjs/ui/toolbar-control-group` | `@kerfjs/ui/toolbar-control-group.css` |
101
- | `ToolbarText` | `@kerfjs/ui/toolbar-text` | `@kerfjs/ui/toolbar-text.css` |
102
- | `MenuActionRow` | `@kerfjs/ui/menu-action-row` | `@kerfjs/ui/menu-action-row.css` |
103
- | `MenuItem` | `@kerfjs/ui/menu-item` | `@kerfjs/ui/menu-item.css` |
104
- | `MenuHeader` | `@kerfjs/ui/menu-header` | `@kerfjs/ui/menu-header.css` |
105
- | Pane, content, and navigation composition | — | `@kerfjs/ui/layout.css` |
106
- | `ResizableRegion` | `@kerfjs/ui/resizable-region` | `@kerfjs/ui/resizable-region.css` |
107
- | `wireResizableRegions` | `@kerfjs/ui/wire-resizable-regions` | — |
108
- | `AppTab` | `@kerfjs/ui/app-tab` | `@kerfjs/ui/app-tab.css` |
109
- | `TabBar` | `@kerfjs/ui/tab-bar` | `@kerfjs/ui/tab-bar.css` |
110
- | `wireTabBars`, `reorderTabs` | `@kerfjs/ui/wire-tab-bars` | — |
111
- | `PageHeader` | `@kerfjs/ui/page-header` | `@kerfjs/ui/page-header.css` |
112
- | `LoadingSpinner` | `@kerfjs/ui/loading-spinner` | `@kerfjs/ui/loading-spinner.css` |
113
- | `Select` | `@kerfjs/ui/select` | `@kerfjs/ui/select.css` |
114
- | `SegmentedControl` | `@kerfjs/ui/segmented-control` | `@kerfjs/ui/segmented-control.css` |
115
- | `TokenSearchField`, `readTokenSearchField`, `placeTokenSearchCaret` | `@kerfjs/ui/token-search-field` | `@kerfjs/ui/token-search-field.css` |
116
- | `wireTokenSearchFields` | `@kerfjs/ui/wire-token-search-fields` | — |
117
- | `StateBanner` | `@kerfjs/ui/state-banner` | `@kerfjs/ui/state-banner.css` |
118
- | `EmptyState` | `@kerfjs/ui/empty-state` | `@kerfjs/ui/empty-state.css` |
119
- | `DialogHeader` | `@kerfjs/ui/dialog-header` | `@kerfjs/ui/dialog-header.css` |
120
- | `ValueTable`, `ValueTableRow` | `@kerfjs/ui/value-table` | `@kerfjs/ui/value-table.css` |
121
-
122
- `DialogHeader` puts its 24px icon in a 34px circular background and aligns that
123
- identity group with its automatically grouped action children in a real top
124
- toolbar. Its optional summary stays on a separate row below the title. Pass a
125
- localized `actionsLabel` when the action group needs an accessible name; new
126
- callers pass action children directly rather than pre-wrapping groups.
157
+ | Component | Browser import (includes reachable CSS) | Manual CSS export |
158
+ | ------------------------------------------------------------------- | --------------------------------------- | -------------------------------------- |
159
+ | `LucideIcon` | `@kerfjs/ui/lucide-icon` | `@kerfjs/ui/lucide-icon.css` |
160
+ | `DisclosureArrow` | `@kerfjs/ui/disclosure-arrow` | `@kerfjs/ui/disclosure-arrow.css` |
161
+ | `Toolbar` | `@kerfjs/ui/toolbar` | `@kerfjs/ui/toolbar.css` |
162
+ | `ToolbarControlGroup` | `@kerfjs/ui/toolbar-control-group` | `@kerfjs/ui/toolbar-control-group.css` |
163
+ | `DialogSurface`, `PopupSurface` | `@kerfjs/ui/surface-scaffold` | `@kerfjs/ui/surface-scaffold.css` |
164
+ | `FloatingToolbar` | `@kerfjs/ui/floating-toolbar` | `@kerfjs/ui/floating-toolbar.css` |
165
+ | `ToolbarText` | `@kerfjs/ui/toolbar-text` | `@kerfjs/ui/toolbar-text.css` |
166
+ | `Text` | `@kerfjs/ui/text` | `@kerfjs/ui/text.css` |
167
+ | `List` | `@kerfjs/ui/list` | `@kerfjs/ui/list.css` |
168
+ | `Row` | `@kerfjs/ui/row` | `@kerfjs/ui/row.css` |
169
+ | `Spacer` | `@kerfjs/ui/spacer` | `@kerfjs/ui/spacer.css` |
170
+ | Typed CSS dimension builders | `@kerfjs/ui/css-values` | — |
171
+ | `ListActionRow` | `@kerfjs/ui/list-action-row` | `@kerfjs/ui/list-action-row.css` |
172
+ | `ListItem` | `@kerfjs/ui/list-item` | `@kerfjs/ui/list-item.css` |
173
+ | `ListHeader` | `@kerfjs/ui/list-header` | `@kerfjs/ui/list-header.css` |
174
+ | `ListInsetControl` | `@kerfjs/ui/list-inset-control` | `@kerfjs/ui/list-inset-control.css` |
175
+ | `ListInsetText` | `@kerfjs/ui/list-inset-text` | `@kerfjs/ui/list-inset-text.css` |
176
+ | `Pane` | `@kerfjs/ui/pane` | `@kerfjs/ui/pane.css` |
177
+ | `NavStack` | `@kerfjs/ui/nav-stack` | `@kerfjs/ui/nav-stack.css` |
178
+ | `wireNavStack` | `@kerfjs/ui/wire-nav-stack` | — |
179
+ | `SplitView` | `@kerfjs/ui/split-view` | `@kerfjs/ui/split-view.css` |
180
+ | `TabScaffold` | `@kerfjs/ui/tab-scaffold` | `@kerfjs/ui/tab-scaffold.css` |
181
+ | `wireTabScaffold` | `@kerfjs/ui/wire-tab-scaffold` | — |
182
+ | `Workbench` | `@kerfjs/ui/workbench` | `@kerfjs/ui/workbench.css` |
183
+ | `CollapsiblePanel`, `CollapsiblePanelToggle` | `@kerfjs/ui/collapsible-panel` | `@kerfjs/ui/collapsible-panel.css` |
184
+ | `wireSidebar` | `@kerfjs/ui/wire-sidebar` | — |
185
+ | Content and navigation composition | — | `@kerfjs/ui/layout.css` |
186
+ | `ResizableRegion` | `@kerfjs/ui/resizable-region` | `@kerfjs/ui/resizable-region.css` |
187
+ | `wireResizableRegions` | `@kerfjs/ui/wire-resizable-regions` | — |
188
+ | `AppTab` | `@kerfjs/ui/app-tab` | `@kerfjs/ui/app-tab.css` |
189
+ | `TabBar` | `@kerfjs/ui/tab-bar` | `@kerfjs/ui/tab-bar.css` |
190
+ | `wireTabBars`, `reorderTabs` | `@kerfjs/ui/wire-tab-bars` | — |
191
+ | `LoadingSpinner` | `@kerfjs/ui/loading-spinner` | `@kerfjs/ui/loading-spinner.css` |
192
+ | `Skeleton` | `@kerfjs/ui/skeleton` | `@kerfjs/ui/skeleton.css` |
193
+ | `SunkenPanel` | `@kerfjs/ui/sunken-panel` | `@kerfjs/ui/sunken-panel.css` |
194
+ | `Select` | `@kerfjs/ui/select` | `@kerfjs/ui/select.css` |
195
+ | `SegmentedControl` | `@kerfjs/ui/segmented-control` | `@kerfjs/ui/segmented-control.css` |
196
+ | `TokenSearchField`, `readTokenSearchField`, `placeTokenSearchCaret` | `@kerfjs/ui/token-search-field` | `@kerfjs/ui/token-search-field.css` |
197
+ | `wireTokenSearchFields` | `@kerfjs/ui/wire-token-search-fields` | — |
198
+ | `StateBanner` | `@kerfjs/ui/state-banner` | `@kerfjs/ui/state-banner.css` |
199
+ | `EmptyState` | `@kerfjs/ui/empty-state` | `@kerfjs/ui/empty-state.css` |
200
+ | `ValueTable`, `ValueTableRow` | `@kerfjs/ui/value-table` | `@kerfjs/ui/value-table.css` |
201
+
202
+ Opt-in application layouts keep JavaScript and CSS explicit. Import each
203
+ layout from its component subpath, load the matching manual CSS export, and
204
+ add its wire subpath when the layout has interactive behavior. The catalog
205
+ entries for `nav-stack`, `split-view`, `tab-scaffold`, `workbench`, and
206
+ `collapsible-panel` document their selection rules, ownership boundaries,
207
+ public classes, tokens, and focused demos. See
208
+ [`docs/app-layouts.md`](./docs/app-layouts.md) for the layout decision matrix.
209
+
210
+ Compose panel, dialog, and page headings directly with `Toolbar`: put an optional
211
+ icon in a `ToolbarControlGroup`, use a direct extra-large `ToolbarText` for the
212
+ title, and put actions in the trailing zone inside their own control group. Set
213
+ `headingLevel` for page or section headings. Supporting copy is app-owned content
214
+ below the toolbar and should be connected to its host with `aria-describedby`
215
+ when it adds useful context.
127
216
 
128
217
  `DisclosureArrow` defaults to an 18px root-scaled decorative visual. Override
129
218
  `--kui-disclosure-arrow-size` at the narrowest useful scope when a consumer
@@ -134,14 +223,15 @@ scale of `.5` through `--kui-disclosure-icon-scale`. Author replacement
134
223
  transform is applied. Direction changes take the shortest rotation path; a
135
224
  180-degree closed-to-open tie uses counterclockwise rotation.
136
225
 
137
- `MenuHeader` supplies that production `DisclosureArrow` automatically when
226
+ `ListHeader` supplies that production `DisclosureArrow` automatically when
138
227
  `toggle` is true and `actionIcon` is omitted. Keep `expanded` synchronized with
139
228
  real controlled content and preserve the button's stable label; ordinary
140
229
  navigation must not display a disclosure arrow. A custom `actionIcon` remains
141
230
  an escape hatch and replaces the default arrow entirely. The header fills its
142
- available inline width, keeping a separate action at the logical end in a 44px
143
- target. Its visible action glyph defaults to 18px through
144
- `--kui-menu-header-action-icon-size`.
231
+ available inline width by default; set `inline` to shrink-wrap it beside other
232
+ content and remove its root margin, border, and padding. It keeps a separate
233
+ action at the logical end. Its visible action glyph defaults to 18px through
234
+ `--kui-list-header-action-icon-size`.
145
235
 
146
236
  ## Machine-readable catalog
147
237
 
@@ -152,7 +242,124 @@ delivery and side effects, companion wiring, application-owned policy,
152
242
  variants, accessibility obligations, public CSS hooks, routes, and current
153
243
  documentation/recipe links. The adjacent
154
244
  [`component-catalog.schema.json`](./ai/component-catalog.schema.json) describes
155
- the versioned format.
245
+ the versioned format. Every visual entry also declares who owns its margin,
246
+ border, and padding, so a generator can fit it into Kerf's alignment model
247
+ without guessing from a screenshot or private CSS.
248
+
249
+ Catalog demo authoring is deliberately separate from the entry inventory. Load
250
+ [`catalog-authoring.json`](./ai/catalog-authoring.json) to discover the
251
+ authoritative [Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract),
252
+ the exact API-signature context, public imports/helpers, and sanctioned metadata
253
+ slot. Keeping this as a companion artifact prevents per-entry selection facts
254
+ from duplicating presentation rules.
255
+
256
+ Tools that evaluate composition may additionally load
257
+ [`component-catalog-v2.json`](./ai/component-catalog-v2.json). It is a
258
+ deterministic, package-qualified projection of every v1 entry with formal
259
+ parent/context, zone/cardinality, child, state ownership, wiring, responsive,
260
+ layout, accessibility, public-boundary, and stable-diagnostic fields. V1
261
+ remains the selection and delivery compatibility surface. V2 defaults are
262
+ deliberately permissive; only documented objective rules receive an
263
+ authoritative override and enforceable diagnostic. The adjacent schema and
264
+ [`component-catalog-v2.d.ts`](./ai/component-catalog-v2.d.ts) types describe
265
+ the same contract.
266
+
267
+ Applications and downstream design systems should publish the same facts for
268
+ their own components. Start from the reusable
269
+ [`component-catalog-extension.schema.json`](./ai/component-catalog-extension.schema.json)
270
+ and the checked
271
+ [`component-catalog-extension.json`](./docs/examples/component-catalog-extension.json)
272
+ example. Give each app-owned component or composition a stable id, selection
273
+ guidance, public hooks, and explicit geometry ownership; then concatenate its
274
+ `entries` with Kerf's shipped `entries` in the AI context. Keep package/source
275
+ identity alongside each input when ids could collide. This makes a combined
276
+ tool reason about both sides of a composition using one vocabulary without
277
+ pretending app-local components are `@kerfjs/ui` exports.
278
+
279
+ Composition-aware consumers use
280
+ [`component-catalog-extension-v2.schema.json`](./ai/component-catalog-extension-v2.schema.json),
281
+ its shipped TypeScript types, and the checked
282
+ [`component-catalog-extension-v2.json`](./docs/examples/component-catalog-extension-v2.json)
283
+ example. Preserve each catalog's package and qualify every identity and
284
+ cross-catalog reference as `package:id`; never merge entries by bare id.
285
+
286
+ [`compile-time-contracts-v1.json`](./ai/compile-time-contracts-v1.json) is the
287
+ matching declaration contract: stable `KUI-T###` ids identify the invalid prop,
288
+ state, identity, accessibility, and protected-attribute combinations TypeScript
289
+ rejects. The package gate compiles one positive/negative consumer fixture against
290
+ both source and declarations extracted from the real packed tarball. The
291
+ [compile-time contract guide](./docs/type-contracts.md) documents migrations and
292
+ the dynamic DOM/children relationships that remain runtime or catalog checks.
293
+ Packages scaffolded by `create-kerf-component` maintain this v2 input from
294
+ `kerf.components.json`: `npm run catalog:generate` emits the catalog and
295
+ `npm run catalog:check` verifies source files, named public exports, explicit
296
+ author decisions, and byte-for-byte drift. Tools index the generated consumer
297
+ entries and this catalog by full key, reject duplicate full keys, search the
298
+ consumer package first, and retain package identity across every reference.
299
+ They must not infer missing semantics or geometry from rendered appearance.
300
+
301
+ ### Application UI profile
302
+
303
+ Applications can check in `.kerf-ui-profile.json` so tools do not have to infer
304
+ project-wide UI policy. Start from the shipped
305
+ [`application-ui-profile.defaults.json`](./ai/application-ui-profile.defaults.json)
306
+ and the checked
307
+ [`application-ui-profile.json`](./docs/examples/application-ui-profile.json)
308
+ workspace example. The versioned
309
+ [`application-ui-profile.schema.json`](./ai/application-ui-profile.schema.json)
310
+ and [`application-ui-profile.d.ts`](./ai/application-ui-profile.d.ts) cover
311
+ catalog locations, concept preferences, allowed theme/density choices, semantic
312
+ token overrides, layout/responsive conventions, and narrow rule exceptions.
313
+ Profiles contain policy only—never product records, user data, or broad styling
314
+ waivers.
315
+
316
+ Catalog declarations always provide a v2 `composition` location. Consumer
317
+ packages generated with composition-only metadata omit `selection`;
318
+ `@kerfjs/ui` continues to require its v1 selection catalog.
319
+
320
+ Node-based AI and static-analysis tools may import the shipped discovery API
321
+ from `@kerfjs/ui/ai/application-ui-profile.mjs`. It discovers package defaults,
322
+ then the workspace profile, then directory profiles from parent to child;
323
+ `mergeApplicationUiProfiles()` applies later scalar/map values, replaces a
324
+ catalog by package and an exception by id, and preserves source provenance.
325
+ `loadApplicationUiProfile()` resolves catalogs and returns diagnostics with the
326
+ originating file plus JSON path. Unknown/stale components, tokens, rules, and
327
+ catalog locations are errors. Every layer is checked against its then-effective
328
+ catalogs, including parent references and catalog paths later overridden by a
329
+ child profile. Synchronous integrations can require the shipped
330
+ `application-ui-profile-sync.cjs` projection and call
331
+ `loadApplicationUiProfileSync()` with already-discovered layers. Consumers that define additional stable
332
+ diagnostics pass their ids through the additive `knownRules` option; those ids
333
+ are merged with catalog diagnostics before exception validation.
334
+
335
+ ### Static CSS and layout ownership analysis
336
+
337
+ Run `kerf-ui-analyze --root . src` (or import
338
+ `@kerfjs/ui/analyzer`) to evaluate cross-file integration facts against the
339
+ composition catalogs and application profile. It catches provable private
340
+ selector reach-through, unknown tokens, competing geometry owners, nested
341
+ scroll owners, and cataloged CSS-value violations in JavaScript/TypeScript
342
+ component calls and JSX. It reports forced dimensions, repeated insets,
343
+ exceptional spacing shorthands, and dynamic classes separately as review
344
+ findings. Text, versioned JSON,
345
+ and SARIF outputs carry stable `KUI-L###` ids, repository-relative locations,
346
+ evidence, and ownership chains. See the [analyzer guide](./docs/ui-analyzer.md).
347
+
348
+ ### Browser-backed integration evaluation
349
+
350
+ Run `kerf-ui-evaluate --url <running-app>` (or import
351
+ `@kerfjs/ui/evaluator`) after the static analyzer. Its Playwright-backed
352
+ wide/intermediate/narrow/200%-zoom, light/dark, and reduced-motion matrix checks
353
+ rendered overflow, clipping, reachability, focus/keyboard behavior, accessible
354
+ names, contrast, hit targets, scrolling, alignment, and cataloged runtime
355
+ geometry. The versioned report carries stable `KUI-B###` diagnostics, focused
356
+ DOM/computed-style evidence, hashed screenshot artifacts, explicit timeout and
357
+ retention policy, and a separate unscored human-visual rubric. See the
358
+ [browser evaluator guide](./docs/ui-evaluator.md).
359
+
360
+ ### Unified repair-loop doctor
361
+
362
+ Use `kerf-ui-doctor` for the supported application repair loop across profile/catalog validation, TypeScript, the Kerf UI ESLint preset, static layout analysis, and an optional explicitly authorized browser evaluation. Its isolated Kerf lint pass preserves each file's applicable core-rule and suppression settings without executing consumer plugin rules. It emits one portable versioned JSON report with deterministic exit codes, exact suppressions, monorepo package selection, changed/full modes, caching, and local-path redaction. See the [UI doctor guide](./docs/ui-doctor.md).
156
363
 
157
364
  For code generation, pair catalog selection guidance with the checked-in
158
365
  [`public-api-signatures-v1.md`](./ai/public-api-signatures-v1.md) declaration
@@ -188,9 +395,10 @@ that convenience import, also import `@kerfjs/ui/styles.css`, which deliberately
188
395
  contains the complete layer. Non-browser/SSR tools resolve the pure `import`
189
396
  condition automatically; `@kerfjs/ui/unstyled` is the explicit CSS-free root
190
397
  entry for a browser build with a custom styling pipeline. The exported
191
- `foundation.css` and component CSS paths remain available for fully manual
192
- delivery. Load application overrides after package styles, or scope `--kui-*`
193
- variables directly on a component instance.
398
+ `@kerfjs/ui/foundation.css` and component CSS paths remain available for fully
399
+ manual delivery. Its complete supported `--kui-*` token surface is cataloged
400
+ under the `foundation` entry. Load application overrides after package styles,
401
+ or scope variables directly on a component instance.
194
402
 
195
403
  ## Pane and content geometry
196
404
 
@@ -204,9 +412,9 @@ Add `.kui-content` to make its major children a vertical stack with 24px gaps.
204
412
  <div class="kui-pane__toolbar"><Toolbar label="Workspace" ... /></div>
205
413
  <nav class="kui-pane__content kui-content">
206
414
  <section>
207
- <MenuHeader label="Workspace" count={3} countLabel="3 workspaces" />
208
- <MenuItem action="open" label="Inbox" icon={inboxIcon} />
209
- <MenuItem action="open" label="Drafts" />
415
+ <ListHeader label="Workspace" count={3} countLabel="3 workspaces" />
416
+ <ListItem action="open" label="Inbox" icon={inboxIcon} />
417
+ <ListItem action="open" label="Drafts" />
210
418
  </section>
211
419
  <div class="kui-content-item">Workspace details</div>
212
420
  </nav>
@@ -216,7 +424,7 @@ Add `.kui-content` to make its major children a vertical stack with 24px gaps.
216
424
  Ordinary children use `.kui-content-item`: 8px inline margin, a real 1px border
217
425
  (transparent by default), 8px padding, and 12px rounded corners. The pill
218
426
  modifier uses a 22px radius. A component can expose a transparent border or
219
- background without changing layout. `MenuHeader` follows the same rule while
427
+ background without changing layout. `ListHeader` follows the same rule while
220
428
  keeping its dormant title and count-or-badge cluster separate from its optional
221
429
  44px action.
222
430
 
@@ -236,10 +444,10 @@ Apps using Web Awesome's free components can opt into the same visual universe
236
444
  with one CSS import:
237
445
 
238
446
  ```ts
239
- import type {} from '@kerfjs/ui/webawesome';
240
- import '@kerfjs/ui/webawesome.css';
241
- import '@awesome.me/webawesome/dist/components/button/button.js';
242
- import '@awesome.me/webawesome/dist/components/input/input.js';
447
+ import type {} from "@kerfjs/ui/webawesome";
448
+ import "@kerfjs/ui/webawesome.css";
449
+ import "@awesome.me/webawesome/dist/components/button/button.js";
450
+ import "@awesome.me/webawesome/dist/components/input/input.js";
243
451
  ```
244
452
 
245
453
  The type-only `@kerfjs/ui/webawesome` import adds Kerf JSX intrinsic-element
@@ -250,6 +458,9 @@ Awesome modules the application renders.
250
458
  `webawesome.css` includes Web Awesome's native/base theme and then applies the
251
459
  Hot Sheet 2 palette, surfaces, status colors, focus treatment, form geometry,
252
460
  radii, tooltips, and shadows through Web Awesome's public `--wa-*` contract.
461
+ On `wa-dialog`, the optional `hide-actions` class hides the exported
462
+ `header-actions` shadow part for compositions that provide another dismissal
463
+ affordance.
253
464
  Those tokens flow into all free component families. Every free Web Awesome 3.12
254
465
  component has an individual UX-catalog route under the collapsible ecosystem
255
466
  section, but the theme entry does not import or register component JavaScript,
@@ -265,13 +476,15 @@ classes for explicit appearance boundaries:
265
476
  ```css
266
477
  :root {
267
478
  --wa-color-brand-fill-loud: #7540a8;
268
- --wa-form-control-border-radius: .5rem;
479
+ --wa-form-control-border-radius: 0.5rem;
269
480
  }
270
481
  ```
271
482
 
272
483
  `foundation.css` follows Hot Sheet 2's Web Awesome-compatible semantic palette.
273
- Brand, neutral, success, warning, and danger each expose fill, border, and
274
- foreground roles through `--kui-color-*`; stateful components also expose
484
+ Brand, pop, neutral, success, warning, and danger each expose fill, border, and
485
+ foreground roles through `--kui-color-*`. Pop is attractive, non-status emphasis
486
+ for featured, novel, or celebratory content; it never substitutes for success,
487
+ warning, or danger. Stateful components also expose
275
488
  component variables such as `--kui-state-banner-background`. Override the
276
489
  foundation for an application theme, a tone variable for one semantic state, or
277
490
  a component variable on one instance without replacing component selectors.
@@ -280,8 +493,8 @@ needs a selector, the component catalog's `publicClasses` arrays define the
280
493
  exact stable anatomy: public-class-to-public-class selectors are supported;
281
494
  descendant tag, id, attribute-only, and unlisted-class selectors are not.
282
495
 
283
- `StateBanner` has opinionated `neutral`, `info`, `success`, `warning`, and
284
- `danger` palettes. Override an individual banner with
496
+ `StateBanner` has opinionated `neutral`, `info`, `pop`, `success`, `warning`,
497
+ and `danger` palettes. Override an individual banner with
285
498
  `--kui-state-banner-background`, `--kui-state-banner-border`,
286
499
  `--kui-state-banner-foreground`, `--kui-state-banner-detail`,
287
500
  `--kui-state-banner-action-background`, and
@@ -305,8 +518,8 @@ standalone `filled`/`outlined` appearance with `shape="rounded"` or
305
518
  appearance="toolbar"
306
519
  shape="pill"
307
520
  choices={[
308
- { value: 'list', label: 'List' },
309
- { value: 'columns', label: 'Columns' },
521
+ { value: "list", label: "List" },
522
+ { value: "columns", label: "Columns" },
310
523
  ]}
311
524
  />
312
525
  ```
@@ -326,8 +539,14 @@ after browser input to recover text plus token offsets, and
326
539
  Call `wireTokenSearchFields()` once at a stable root to make Enter submit through
327
540
  `onSubmit` without inserting a contenteditable line break and to preserve focus
328
541
  plus the text-relative caret when keyboard deletion of a chip causes controlled
329
- rendering to replace the editor. Text still wraps visually when it reaches the
330
- field edge.
542
+ rendering to replace the editor. A select-all deletion is normalized to a truly
543
+ empty editor even when the browser leaves an atomic chip or line break behind;
544
+ replacement typing consumes that intent so a later Backspace/Delete remains an
545
+ ordinary character edit.
546
+ Managed deletion keeps a collapsible replacement editor open and focused before
547
+ the next keystroke; applications must persist both query and tokens from the DOM
548
+ read. Genuine outside focus and Escape still collapse an empty field.
549
+ Text still wraps visually when it reaches the field edge.
331
550
  Clear actions should empty the editor's `textContent` before clearing app state.
332
551
  The leading icon, first text line, clear action, and trailing slot share one
333
552
  fixed alignment row; when text wraps, those controls stay pinned to that first
@@ -359,15 +578,25 @@ close button retains all close interaction.
359
578
  `Select` uses Web Awesome but does not register anything by itself. Install the optional peer, import the shared theme if desired, and explicitly import the registration entry in the application:
360
579
 
361
580
  ```ts
362
- import '@kerfjs/ui/webawesome.css';
363
- import '@kerfjs/ui/select/register';
581
+ import "@kerfjs/ui/webawesome.css";
582
+ import "@kerfjs/ui/select/register";
364
583
  ```
365
584
 
366
585
  That boundary keeps Web Awesome and its custom-element side effects out of bundles that use unrelated components. Automated consumer-bundle tests enforce it.
586
+ Use `label` for a visible label or `ariaLabel` for a visually hidden name. A
587
+ nonempty visible label takes precedence when both are supplied. Kerf names the
588
+ actual shadow combobox without adding visible label spacing; this also works
589
+ with `renderSelected`, and needs no application shadow-DOM patch. Use `hint`
590
+ for persistent supporting text below the control and `placeholderText` for the
591
+ empty value inside the closed control. Loading placeholders preserve the hint.
592
+
367
593
  `Select` also owns the Kerf/Web Awesome reconciliation boundary: option icons
368
594
  keep stable slotted elements across rerenders, and `renderSelected` content is
369
595
  replaced when the controlled value changes. Consumers do not need to add
370
- `data-key` or `data-morph-skip` workarounds around choice icons.
596
+ `data-key` or `data-morph-skip` workarounds around choice icons. Icon-bearing
597
+ options retain the standard icon-to-label gap. When a compact Select is wrapped
598
+ in a `ToolbarControlGroup`, use `focusRingOwner="group"`; the group paints the
599
+ focus ring with its configured pill or rounded geometry.
371
600
 
372
601
  For application choices and panes, prefer Kerf's purpose-built primitives:
373
602
  `Select` over direct Web Awesome selection/dropdown composition,
@@ -376,7 +605,11 @@ Awesome Tabs, `LucideIcon` over Web Awesome Icon, and `ResizableRegion` over
376
605
  Split Panel. `ResizableRegion` includes Hot Sheet 2's 1px separator and
377
606
  hover/focus grip. Its optional `handleIcon` replaces only the decorative glyph;
378
607
  the component and `wireResizableRegions()` retain separator semantics and
379
- pointer/keyboard behavior. Consider Web Awesome Popup when its anchored-positioning
608
+ pointer/keyboard behavior. Typed policies cover separator visibility,
609
+ instant-track/composited-content collapse, popup-safe overflow,
610
+ inline/overlay/hidden responsive presentation, and safe-area restore controls;
611
+ the same policies are available on `Workbench` and `CollapsiblePanel`. Consider
612
+ Web Awesome Popup when its anchored-positioning
380
613
  engine removes custom placement code; treat Tree, Animated Image, Comparison,
381
614
  Zoomable Frame, and the displaced alternatives above as exceptional rather
382
615
  than default patterns. The detailed rationale lives in the theme contract.
@@ -395,8 +628,9 @@ than default patterns. The detailed rationale lives in the theme contract.
395
628
 
396
629
  Run `npm run dev` from this directory for the category-grouped master/detail catalog. Every public visual component has a focused route; all 70 free Web Awesome 3.12 components have focused routes under the collapsible ecosystem section. Every detail visibly links its first-party demo source and existing guidance while showing the repository-relative paths; first-party components also link their implementation source, and Web Awesome entries label local guidance as Kerf integration guidance. One grouped `Related components` selector contains derived `Uses` / `Used by` navigation across both sets. Run `npm run check` for static/unit/bundle gates and `npm run test:e2e` for the real-browser suite.
397
630
 
398
- Run `npm run format:css` after editing styles. The normal `npm run check` gate
399
- uses Prettier to reject unformatted CSS in `src/` and `ux-demo/`.
631
+ Run `npm run format` after editing source or structured content. The narrower
632
+ `npm run format:css` command remains available for style-only work. The normal
633
+ `npm run lint` and `npm run check` gates use Prettier to reject formatting drift.
400
634
 
401
635
  For dimensions that should scale with the root font size, author pixels with
402
636
  `remify()`: `gap: remify(17px)` builds to `gap: 1.0625rem` using a fixed 16px