@kerfjs/ui 4.4.1 → 4.5.0-beta.1

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 (499) hide show
  1. package/README.md +425 -42
  2. package/ai/application-ui-diagnostic-ids-v1.json +92 -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 +102 -0
  12. package/ai/compile-time-contracts-v1.schema.json +49 -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 +319 -0
  17. package/ai/component-catalog-v2.d.ts +67 -0
  18. package/ai/component-catalog-v2.json +4675 -0
  19. package/ai/component-catalog-v2.schema.json +246 -0
  20. package/ai/component-catalog.json +5826 -0
  21. package/ai/component-catalog.schema.json +95 -0
  22. package/ai/public-api-signatures-v1.md +1719 -0
  23. package/ai/skill.md +129 -21
  24. package/ai/webawesome-jsx-signatures-v1.md +106 -0
  25. package/analyzer/cli.mjs +46 -0
  26. package/analyzer/index.d.mts +45 -0
  27. package/analyzer/index.mjs +737 -0
  28. package/analyzer/report.schema.json +66 -0
  29. package/dist/app-tab.d.ts +14 -2
  30. package/dist/app-tab.js +3 -1
  31. package/dist/browser/app-tab.js +3 -2
  32. package/dist/browser/disclosure-arrow.js +4 -0
  33. package/dist/browser/empty-state.js +3 -3
  34. package/dist/browser/floating-toolbar.js +3 -0
  35. package/dist/browser/list-action-row.js +4 -0
  36. package/dist/browser/list-header.js +6 -0
  37. package/dist/browser/list-inset-control.js +3 -0
  38. package/dist/browser/list-inset-text.js +3 -0
  39. package/dist/browser/list-item.js +4 -0
  40. package/dist/browser/list.js +3 -0
  41. package/dist/browser/loading-spinner.js +2 -2
  42. package/dist/browser/lucide-icon.js +2 -2
  43. package/dist/browser/pane.js +3 -0
  44. package/dist/browser/panel-header.js +7 -0
  45. package/dist/browser/resizable-region.js +2 -2
  46. package/dist/browser/segmented-control.js +3 -2
  47. package/dist/browser/select.js +4 -3
  48. package/dist/browser/skeleton.js +3 -0
  49. package/dist/browser/state-banner.js +3 -2
  50. package/dist/browser/sunken-panel.js +3 -0
  51. package/dist/browser/tab-bar.js +2 -2
  52. package/dist/browser/token-search-field.js +4 -0
  53. package/dist/browser/toolbar-control-group.js +2 -2
  54. package/dist/browser/toolbar-text.js +3 -2
  55. package/dist/browser/toolbar.js +2 -2
  56. package/dist/browser/value-table.js +3 -2
  57. package/dist/catalog-resources.d.ts +34 -0
  58. package/dist/catalog-resources.js +22 -0
  59. package/dist/catalog-resources.js.map +1 -0
  60. package/dist/catalog.d.ts +150 -0
  61. package/dist/catalog.js +377 -0
  62. package/dist/catalog.js.map +1 -0
  63. package/dist/chunk-5VTB2BKP.js +35 -0
  64. package/dist/chunk-5VTB2BKP.js.map +1 -0
  65. package/dist/chunk-6WTETUZ6.js +21 -0
  66. package/dist/chunk-6WTETUZ6.js.map +1 -0
  67. package/dist/chunk-7KEUJIIC.js +218 -0
  68. package/dist/chunk-7KEUJIIC.js.map +1 -0
  69. package/dist/chunk-7XRDUG4Y.js +58 -0
  70. package/dist/chunk-7XRDUG4Y.js.map +1 -0
  71. package/dist/chunk-B3A3IVO5.js +83 -0
  72. package/dist/chunk-B3A3IVO5.js.map +1 -0
  73. package/dist/chunk-DPDBVKNA.js +113 -0
  74. package/dist/chunk-DPDBVKNA.js.map +1 -0
  75. package/dist/chunk-FEAMR7S4.js +68 -0
  76. package/dist/chunk-FEAMR7S4.js.map +1 -0
  77. package/dist/chunk-FEY65TBV.js +15 -0
  78. package/dist/chunk-FEY65TBV.js.map +1 -0
  79. package/dist/{chunk-TRNBHPNW.js → chunk-IJBSZ4NX.js} +11 -8
  80. package/dist/chunk-IJBSZ4NX.js.map +1 -0
  81. package/dist/chunk-J5BFYY7Q.js +35 -0
  82. package/dist/chunk-J5BFYY7Q.js.map +1 -0
  83. package/dist/chunk-JRKSK2HX.js +79 -0
  84. package/dist/chunk-JRKSK2HX.js.map +1 -0
  85. package/dist/chunk-KWWR5VMS.js +45 -0
  86. package/dist/chunk-KWWR5VMS.js.map +1 -0
  87. package/dist/chunk-LPOMRC4C.js +25 -0
  88. package/dist/chunk-LPOMRC4C.js.map +1 -0
  89. package/dist/chunk-M7JBER5U.js +41 -0
  90. package/dist/chunk-M7JBER5U.js.map +1 -0
  91. package/dist/chunk-NENBUYX5.js +79 -0
  92. package/dist/chunk-NENBUYX5.js.map +1 -0
  93. package/dist/chunk-NWSEP5RT.js +117 -0
  94. package/dist/chunk-NWSEP5RT.js.map +1 -0
  95. package/dist/chunk-OJWWHFH3.js +426 -0
  96. package/dist/chunk-OJWWHFH3.js.map +1 -0
  97. package/dist/chunk-PSKN344N.js +114 -0
  98. package/dist/chunk-PSKN344N.js.map +1 -0
  99. package/dist/chunk-PX3YSS5C.js +32 -0
  100. package/dist/chunk-PX3YSS5C.js.map +1 -0
  101. package/dist/chunk-QO55FN2Y.js +20 -0
  102. package/dist/chunk-QO55FN2Y.js.map +1 -0
  103. package/dist/chunk-R7ZWUN64.js +38 -0
  104. package/dist/chunk-R7ZWUN64.js.map +1 -0
  105. package/dist/chunk-RKVQEH4J.js +61 -0
  106. package/dist/chunk-RKVQEH4J.js.map +1 -0
  107. package/dist/chunk-SRSJO5QE.js +40 -0
  108. package/dist/chunk-SRSJO5QE.js.map +1 -0
  109. package/dist/chunk-SYDMYBPG.js +31 -0
  110. package/dist/chunk-SYDMYBPG.js.map +1 -0
  111. package/dist/chunk-TB6DY7H5.js +25 -0
  112. package/dist/chunk-TB6DY7H5.js.map +1 -0
  113. package/dist/chunk-UFZKLBCF.js +108 -0
  114. package/dist/chunk-UFZKLBCF.js.map +1 -0
  115. package/dist/{chunk-MQIZAD4A.js → chunk-UKKSMZYT.js} +76 -22
  116. package/dist/chunk-UKKSMZYT.js.map +1 -0
  117. package/dist/chunk-W5L2JSBY.js +40 -0
  118. package/dist/chunk-W5L2JSBY.js.map +1 -0
  119. package/dist/chunk-Y45PPBDV.js +105 -0
  120. package/dist/chunk-Y45PPBDV.js.map +1 -0
  121. package/dist/chunk-Y6LYKFXY.js +43 -0
  122. package/dist/chunk-Y6LYKFXY.js.map +1 -0
  123. package/dist/collapsible-panel.d.ts +66 -0
  124. package/dist/collapsible-panel.js +63 -0
  125. package/dist/collapsible-panel.js.map +1 -0
  126. package/dist/device-class.d.ts +62 -0
  127. package/dist/device-class.js +103 -0
  128. package/dist/device-class.js.map +1 -0
  129. package/dist/disclosure-arrow.d.ts +14 -0
  130. package/dist/disclosure-arrow.js +4 -0
  131. package/dist/disclosure-arrow.js.map +1 -0
  132. package/dist/divider-sides-267FA7sY.d.ts +4 -0
  133. package/dist/empty-state.d.ts +1 -1
  134. package/dist/empty-state.js +1 -1
  135. package/dist/floating-toolbar.d.ts +28 -0
  136. package/dist/floating-toolbar.js +3 -0
  137. package/dist/floating-toolbar.js.map +1 -0
  138. package/dist/index.d.ts +20 -9
  139. package/dist/index.js +29 -18
  140. package/dist/list-action-row.d.ts +52 -0
  141. package/dist/list-action-row.js +5 -0
  142. package/dist/list-action-row.js.map +1 -0
  143. package/dist/list-header.d.ts +64 -0
  144. package/dist/list-header.js +7 -0
  145. package/dist/list-header.js.map +1 -0
  146. package/dist/list-inset-control.d.ts +16 -0
  147. package/dist/list-inset-control.js +3 -0
  148. package/dist/list-inset-control.js.map +1 -0
  149. package/dist/list-inset-text.d.ts +25 -0
  150. package/dist/list-inset-text.js +3 -0
  151. package/dist/list-inset-text.js.map +1 -0
  152. package/dist/list-item.d.ts +33 -0
  153. package/dist/list-item.js +5 -0
  154. package/dist/list-item.js.map +1 -0
  155. package/dist/list.d.ts +19 -0
  156. package/dist/list.js +3 -0
  157. package/dist/list.js.map +1 -0
  158. package/dist/loading-spinner.js +1 -1
  159. package/dist/nav-stack.d.ts +38 -0
  160. package/dist/nav-stack.js +5 -0
  161. package/dist/nav-stack.js.map +1 -0
  162. package/dist/pane.d.ts +49 -0
  163. package/dist/pane.js +4 -0
  164. package/dist/pane.js.map +1 -0
  165. package/dist/panel-header.d.ts +42 -0
  166. package/dist/panel-header.js +7 -0
  167. package/dist/panel-header.js.map +1 -0
  168. package/dist/resizable-region.d.ts +3 -1
  169. package/dist/resizable-region.js +1 -1
  170. package/dist/segmented-control.d.ts +8 -6
  171. package/dist/segmented-control.js +2 -1
  172. package/dist/select-register.d.ts +5 -1
  173. package/dist/select-register.js +3 -0
  174. package/dist/select-register.js.map +1 -1
  175. package/dist/select.d.ts +15 -6
  176. package/dist/select.js +2 -1
  177. package/dist/skeleton.d.ts +24 -0
  178. package/dist/skeleton.js +3 -0
  179. package/dist/skeleton.js.map +1 -0
  180. package/dist/split-view.d.ts +42 -0
  181. package/dist/split-view.js +81 -0
  182. package/dist/split-view.js.map +1 -0
  183. package/dist/state-banner.d.ts +8 -3
  184. package/dist/state-banner.js +2 -1
  185. package/dist/styles/app-tab.css +152 -0
  186. package/dist/styles/catalog.css +575 -0
  187. package/dist/styles/collapsible-panel.css +146 -0
  188. package/dist/styles/disclosure-arrow.css +23 -0
  189. package/dist/styles/empty-state.css +47 -0
  190. package/dist/styles/floating-toolbar.css +38 -0
  191. package/dist/styles/foundation.css +362 -0
  192. package/dist/styles/layout.css +55 -0
  193. package/dist/styles/list-action-row.css +160 -0
  194. package/dist/styles/list-header.css +160 -0
  195. package/dist/styles/list-inset-control.css +7 -0
  196. package/dist/styles/list-inset-text.css +14 -0
  197. package/dist/styles/list-item.css +123 -0
  198. package/dist/styles/list.css +43 -0
  199. package/dist/styles/loading-spinner.css +21 -0
  200. package/dist/styles/lucide-icon.css +6 -0
  201. package/dist/styles/nav-stack.css +111 -0
  202. package/dist/styles/pane.css +62 -0
  203. package/dist/styles/panel-header.css +64 -0
  204. package/dist/styles/resizable-region.css +111 -0
  205. package/{src → dist/styles}/segmented-control.css +58 -31
  206. package/dist/styles/select.css +140 -0
  207. package/dist/styles/skeleton.css +31 -0
  208. package/dist/styles/split-view.css +35 -0
  209. package/dist/styles/state-banner.css +198 -0
  210. package/dist/styles/styles.css +24 -0
  211. package/dist/styles/sunken-panel.css +22 -0
  212. package/dist/styles/tab-bar.css +45 -0
  213. package/dist/styles/tab-scaffold.css +84 -0
  214. package/dist/styles/token-search-field.css +289 -0
  215. package/dist/styles/toolbar-control-group.css +225 -0
  216. package/dist/styles/toolbar-text.css +92 -0
  217. package/dist/styles/toolbar.css +97 -0
  218. package/dist/styles/value-table.css +75 -0
  219. package/dist/styles/webawesome.css +399 -0
  220. package/dist/styles/workbench.css +94 -0
  221. package/dist/sunken-panel.d.ts +19 -0
  222. package/dist/sunken-panel.js +3 -0
  223. package/dist/sunken-panel.js.map +1 -0
  224. package/dist/tab-bar.d.ts +10 -2
  225. package/dist/tab-bar.js +1 -1
  226. package/dist/tab-scaffold.d.ts +30 -0
  227. package/dist/tab-scaffold.js +51 -0
  228. package/dist/tab-scaffold.js.map +1 -0
  229. package/dist/token-search-field.d.ts +59 -0
  230. package/dist/token-search-field.js +4 -0
  231. package/dist/token-search-field.js.map +1 -0
  232. package/dist/toolbar-control-group.d.ts +11 -5
  233. package/dist/toolbar-control-group.js +1 -1
  234. package/dist/toolbar-text.d.ts +31 -4
  235. package/dist/toolbar-text.js +2 -1
  236. package/dist/toolbar.d.ts +5 -3
  237. package/dist/toolbar.js +1 -1
  238. package/dist/value-table.d.ts +13 -3
  239. package/dist/value-table.js +2 -1
  240. package/dist/webawesome.d.ts +100 -0
  241. package/dist/webawesome.js +3 -0
  242. package/dist/webawesome.js.map +1 -0
  243. package/dist/wire-catalog.d.ts +57 -0
  244. package/dist/wire-catalog.js +302 -0
  245. package/dist/wire-catalog.js.map +1 -0
  246. package/dist/wire-nav-stack.d.ts +15 -0
  247. package/dist/wire-nav-stack.js +103 -0
  248. package/dist/wire-nav-stack.js.map +1 -0
  249. package/dist/wire-resizable-regions.d.ts +1 -1
  250. package/dist/wire-resizable-regions.js +1 -1
  251. package/dist/wire-sidebar.d.ts +43 -0
  252. package/dist/wire-sidebar.js +128 -0
  253. package/dist/wire-sidebar.js.map +1 -0
  254. package/dist/wire-tab-bars.d.ts +18 -2
  255. package/dist/wire-tab-bars.js +1 -1
  256. package/dist/wire-tab-scaffold.d.ts +11 -0
  257. package/dist/wire-tab-scaffold.js +21 -0
  258. package/dist/wire-tab-scaffold.js.map +1 -0
  259. package/dist/wire-token-search-fields.d.ts +111 -0
  260. package/dist/wire-token-search-fields.js +5 -0
  261. package/dist/wire-token-search-fields.js.map +1 -0
  262. package/dist/workbench.d.ts +33 -0
  263. package/dist/workbench.js +64 -0
  264. package/dist/workbench.js.map +1 -0
  265. package/docs/accessibility.md +124 -4
  266. package/docs/app-layouts.md +61 -0
  267. package/docs/catalog.md +364 -0
  268. package/docs/collapsible-panel.md +129 -0
  269. package/docs/component-contract.md +312 -5
  270. package/docs/component-selection.md +219 -0
  271. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  272. package/docs/design/templates/empty-state/filtered.svg +1 -0
  273. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  274. package/docs/design/templates/empty-state/with-action.svg +1 -0
  275. package/docs/design/templates/empty-state-dark.svg +1 -0
  276. package/docs/design/templates/empty-state.svg +1 -0
  277. package/docs/design/templates/list/compact-dark.svg +1 -0
  278. package/docs/design/templates/list/compact.svg +1 -0
  279. package/docs/design/templates/list/stack-dark.svg +1 -0
  280. package/docs/design/templates/list/stack.svg +1 -0
  281. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  282. package/docs/design/templates/list-action-row/default.svg +1 -0
  283. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  284. package/docs/design/templates/list-action-row/selected.svg +1 -0
  285. package/docs/design/templates/list-action-row-dark.svg +1 -0
  286. package/docs/design/templates/list-action-row.svg +1 -0
  287. package/docs/design/templates/list-dark.svg +1 -0
  288. package/docs/design/templates/list-header/action-dark.svg +1 -0
  289. package/docs/design/templates/list-header/action.svg +1 -0
  290. package/docs/design/templates/list-header/count-dark.svg +1 -0
  291. package/docs/design/templates/list-header/count.svg +1 -0
  292. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  293. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  294. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  295. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  296. package/docs/design/templates/list-header-dark.svg +1 -0
  297. package/docs/design/templates/list-header.svg +1 -0
  298. package/docs/design/templates/list-item/default-dark.svg +1 -0
  299. package/docs/design/templates/list-item/default.svg +1 -0
  300. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  301. package/docs/design/templates/list-item/multiline.svg +1 -0
  302. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  303. package/docs/design/templates/list-item/selected.svg +1 -0
  304. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  305. package/docs/design/templates/list-item/trailing.svg +1 -0
  306. package/docs/design/templates/list-item-dark.svg +1 -0
  307. package/docs/design/templates/list-item.svg +1 -0
  308. package/docs/design/templates/list.svg +1 -0
  309. package/docs/design/templates/panel-header/icon-actions-dark.svg +1 -0
  310. package/docs/design/templates/panel-header/icon-actions.svg +1 -0
  311. package/docs/design/templates/panel-header/icon-summary-actions-dark.svg +1 -0
  312. package/docs/design/templates/panel-header/icon-summary-actions.svg +1 -0
  313. package/docs/design/templates/panel-header/no-icon-dark.svg +1 -0
  314. package/docs/design/templates/panel-header/no-icon.svg +1 -0
  315. package/docs/design/templates/panel-header/page-heading-dark.svg +1 -0
  316. package/docs/design/templates/panel-header/page-heading.svg +1 -0
  317. package/docs/design/templates/panel-header/title-only-dark.svg +1 -0
  318. package/docs/design/templates/panel-header/title-only.svg +1 -0
  319. package/docs/design/templates/panel-header-dark.svg +1 -0
  320. package/docs/design/templates/panel-header.svg +1 -0
  321. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  322. package/docs/design/templates/segmented-control/equal.svg +1 -0
  323. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  324. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  325. package/docs/design/templates/segmented-control-dark.svg +1 -0
  326. package/docs/design/templates/segmented-control.svg +1 -0
  327. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  328. package/docs/design/templates/skeleton/avatar.svg +1 -0
  329. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  330. package/docs/design/templates/skeleton/block.svg +1 -0
  331. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  332. package/docs/design/templates/skeleton/lines.svg +1 -0
  333. package/docs/design/templates/skeleton-dark.svg +1 -0
  334. package/docs/design/templates/skeleton.svg +1 -0
  335. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  336. package/docs/design/templates/state-banner/danger.svg +1 -0
  337. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  338. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  339. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  340. package/docs/design/templates/state-banner/info.svg +1 -0
  341. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  342. package/docs/design/templates/state-banner/success.svg +1 -0
  343. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  344. package/docs/design/templates/state-banner/warning.svg +1 -0
  345. package/docs/design/templates/state-banner-dark.svg +1 -0
  346. package/docs/design/templates/state-banner.svg +1 -0
  347. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  348. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  349. package/docs/design/templates/tab-bar-dark.svg +1 -0
  350. package/docs/design/templates/tab-bar.svg +1 -0
  351. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  352. package/docs/design/templates/token-search-field/empty.svg +1 -0
  353. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  354. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  355. package/docs/design/templates/token-search-field-dark.svg +1 -0
  356. package/docs/design/templates/token-search-field.svg +1 -0
  357. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  358. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  359. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  360. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  361. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  362. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  363. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  364. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  365. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  366. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  367. package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
  368. package/docs/design/templates/toolbar-control-group.svg +1 -0
  369. package/docs/design/templates/toolbar-dark.svg +1 -0
  370. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  371. package/docs/design/templates/toolbar-text/default.svg +1 -0
  372. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  373. package/docs/design/templates/toolbar-text/large.svg +1 -0
  374. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  375. package/docs/design/templates/toolbar-text/small.svg +1 -0
  376. package/docs/design/templates/toolbar-text-dark.svg +1 -0
  377. package/docs/design/templates/toolbar-text.svg +1 -0
  378. package/docs/design/templates/toolbar.svg +1 -0
  379. package/docs/design/templates/value-table/details-dark.svg +1 -0
  380. package/docs/design/templates/value-table/details.svg +1 -0
  381. package/docs/design/templates/value-table-dark.svg +1 -0
  382. package/docs/design/templates/value-table.svg +1 -0
  383. package/docs/design/templates.md +130 -0
  384. package/docs/design-philosophy.md +59 -1
  385. package/docs/device-class.md +54 -0
  386. package/docs/examples/application-ui-profile.json +60 -0
  387. package/docs/examples/command-palette-adapter.tsx +120 -0
  388. package/docs/examples/component-catalog-extension-v2.json +81 -0
  389. package/docs/examples/component-catalog-extension.json +45 -0
  390. package/docs/layout.md +150 -0
  391. package/docs/nav-stack.md +56 -0
  392. package/docs/recipes.md +167 -0
  393. package/docs/split-view.md +49 -0
  394. package/docs/sunken-panel.md +53 -0
  395. package/docs/tab-scaffold.md +50 -0
  396. package/docs/type-contracts.md +102 -0
  397. package/docs/ui-analyzer.md +86 -0
  398. package/docs/ui-doctor.md +84 -0
  399. package/docs/ui-evaluator.md +122 -0
  400. package/docs/ux-demo.md +23 -9
  401. package/docs/webawesome-theme.md +87 -7
  402. package/docs/workbench.md +73 -0
  403. package/doctor/cli.mjs +115 -0
  404. package/doctor/config.schema.json +68 -0
  405. package/doctor/eslint-diagnostics.d.mts +8 -0
  406. package/doctor/eslint-diagnostics.mjs +7 -0
  407. package/doctor/index.d.mts +116 -0
  408. package/doctor/index.mjs +1257 -0
  409. package/doctor/report.schema.json +118 -0
  410. package/evaluator/cli.mjs +89 -0
  411. package/evaluator/index.d.mts +90 -0
  412. package/evaluator/index.mjs +1138 -0
  413. package/evaluator/report.schema.json +152 -0
  414. package/llms.txt +197 -14
  415. package/package.json +228 -46
  416. package/traversal-exclusions.mjs +27 -0
  417. package/ux-demo/recipes/app-shell.tsx +228 -0
  418. package/ux-demo/recipes/collapsible-sidebar.tsx +223 -0
  419. package/ux-demo/recipes/compact-toolbar.tsx +145 -0
  420. package/ux-demo/recipes/composer-form.tsx +151 -0
  421. package/ux-demo/recipes/list-detail-dialog.tsx +181 -0
  422. package/ux-demo/recipes/list-workspace-states.tsx +183 -0
  423. package/ux-demo/recipes/loaders.ts +36 -0
  424. package/ux-demo/recipes/loading-inspector.tsx +164 -0
  425. package/ux-demo/recipes/mount-recipe.ts +64 -0
  426. package/ux-demo/recipes/navigation-sidebar.tsx +137 -0
  427. package/ux-demo/recipes/navigation-stack.tsx +118 -0
  428. package/ux-demo/recipes/recipes.css +448 -0
  429. package/ux-demo/recipes/types.ts +19 -0
  430. package/ux-demo/recipes/workspace-header.tsx +67 -0
  431. package/dist/browser/dialog-header.js +0 -3
  432. package/dist/browser/menu-header.js +0 -3
  433. package/dist/browser/menu-item.js +0 -3
  434. package/dist/browser/page-header.js +0 -3
  435. package/dist/chunk-2PES33HS.js +0 -13
  436. package/dist/chunk-2PES33HS.js.map +0 -1
  437. package/dist/chunk-3O7ZEUW2.js +0 -27
  438. package/dist/chunk-3O7ZEUW2.js.map +0 -1
  439. package/dist/chunk-4HHCYSGT.js +0 -79
  440. package/dist/chunk-4HHCYSGT.js.map +0 -1
  441. package/dist/chunk-55DATV3A.js +0 -10
  442. package/dist/chunk-55DATV3A.js.map +0 -1
  443. package/dist/chunk-723YNJBH.js +0 -17
  444. package/dist/chunk-723YNJBH.js.map +0 -1
  445. package/dist/chunk-DAFFDO33.js +0 -14
  446. package/dist/chunk-DAFFDO33.js.map +0 -1
  447. package/dist/chunk-GY5WH7TO.js +0 -10
  448. package/dist/chunk-GY5WH7TO.js.map +0 -1
  449. package/dist/chunk-MBR3TYNL.js +0 -14
  450. package/dist/chunk-MBR3TYNL.js.map +0 -1
  451. package/dist/chunk-MFKMHK5W.js +0 -10
  452. package/dist/chunk-MFKMHK5W.js.map +0 -1
  453. package/dist/chunk-MQIZAD4A.js.map +0 -1
  454. package/dist/chunk-NHXX4JI5.js +0 -28
  455. package/dist/chunk-NHXX4JI5.js.map +0 -1
  456. package/dist/chunk-OPCJRCYO.js +0 -19
  457. package/dist/chunk-OPCJRCYO.js.map +0 -1
  458. package/dist/chunk-T5XNMVOI.js +0 -24
  459. package/dist/chunk-T5XNMVOI.js.map +0 -1
  460. package/dist/chunk-TRNBHPNW.js.map +0 -1
  461. package/dist/chunk-VHW5YNIB.js +0 -17
  462. package/dist/chunk-VHW5YNIB.js.map +0 -1
  463. package/dist/chunk-VKH2JLDZ.js +0 -10
  464. package/dist/chunk-VKH2JLDZ.js.map +0 -1
  465. package/dist/chunk-WVPYVDXY.js +0 -15
  466. package/dist/chunk-WVPYVDXY.js.map +0 -1
  467. package/dist/chunk-WY4CAEPG.js +0 -14
  468. package/dist/chunk-WY4CAEPG.js.map +0 -1
  469. package/dist/dialog-header.d.ts +0 -14
  470. package/dist/dialog-header.js +0 -3
  471. package/dist/dialog-header.js.map +0 -1
  472. package/dist/menu-header.d.ts +0 -15
  473. package/dist/menu-header.js +0 -3
  474. package/dist/menu-header.js.map +0 -1
  475. package/dist/menu-item.d.ts +0 -22
  476. package/dist/menu-item.js +0 -3
  477. package/dist/menu-item.js.map +0 -1
  478. package/dist/page-header.d.ts +0 -9
  479. package/dist/page-header.js +0 -3
  480. package/dist/page-header.js.map +0 -1
  481. package/src/app-tab.css +0 -20
  482. package/src/dialog-header.css +0 -9
  483. package/src/empty-state.css +0 -6
  484. package/src/foundation.css +0 -106
  485. package/src/loading-spinner.css +0 -4
  486. package/src/lucide-icon.css +0 -1
  487. package/src/menu-header.css +0 -13
  488. package/src/menu-item.css +0 -12
  489. package/src/page-header.css +0 -3
  490. package/src/resizable-region.css +0 -19
  491. package/src/select.css +0 -18
  492. package/src/state-banner.css +0 -31
  493. package/src/styles.css +0 -18
  494. package/src/tab-bar.css +0 -4
  495. package/src/toolbar-control-group.css +0 -25
  496. package/src/toolbar-text.css +0 -4
  497. package/src/toolbar.css +0 -9
  498. package/src/value-table.css +0 -5
  499. package/src/webawesome.css +0 -178
@@ -0,0 +1,152 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://raw.githubusercontent.com/brianwestphal/kerf/main/ui/evaluator/report.schema.json",
4
+ "title": "Kerf UI browser evaluation report",
5
+ "type": "object",
6
+ "required": [
7
+ "schemaVersion",
8
+ "tool",
9
+ "target",
10
+ "recordedAt",
11
+ "profileFiles",
12
+ "contexts",
13
+ "diagnostics",
14
+ "summary",
15
+ "artifacts",
16
+ "subjectiveReview"
17
+ ],
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "schemaVersion": { "const": 1 },
21
+ "tool": {
22
+ "type": "object",
23
+ "required": ["name", "reportVersion"],
24
+ "additionalProperties": false,
25
+ "properties": {
26
+ "name": { "const": "@kerfjs/ui/evaluator" },
27
+ "reportVersion": { "const": 1 }
28
+ }
29
+ },
30
+ "target": {
31
+ "type": "object",
32
+ "required": ["url"],
33
+ "additionalProperties": false,
34
+ "properties": { "url": { "type": "string", "minLength": 1 } }
35
+ },
36
+ "recordedAt": { "type": "string", "format": "date-time" },
37
+ "profileFiles": { "$ref": "#/$defs/stringList" },
38
+ "contexts": {
39
+ "type": "array",
40
+ "minItems": 1,
41
+ "items": { "$ref": "#/$defs/context" }
42
+ },
43
+ "diagnostics": {
44
+ "type": "array",
45
+ "items": { "$ref": "#/$defs/diagnostic" }
46
+ },
47
+ "summary": { "$ref": "#/$defs/summary" },
48
+ "artifacts": {
49
+ "type": "object",
50
+ "required": ["retention", "files"],
51
+ "additionalProperties": false,
52
+ "properties": {
53
+ "retention": { "enum": ["always", "on-failure", "never"] },
54
+ "files": {
55
+ "type": "array",
56
+ "items": {
57
+ "type": "object",
58
+ "required": ["path", "sha256"],
59
+ "additionalProperties": false,
60
+ "properties": {
61
+ "path": { "type": "string", "minLength": 1 },
62
+ "sha256": {
63
+ "type": "string",
64
+ "pattern": "^[a-f0-9]{64}$"
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+ },
71
+ "subjectiveReview": {
72
+ "type": "object",
73
+ "required": ["status", "rubric", "ratings", "note"],
74
+ "additionalProperties": false,
75
+ "properties": {
76
+ "status": { "const": "not-recorded" },
77
+ "rubric": {
78
+ "type": "array",
79
+ "minItems": 6,
80
+ "items": {
81
+ "type": "object",
82
+ "required": ["id", "prompt"],
83
+ "additionalProperties": false,
84
+ "properties": {
85
+ "id": { "type": "string", "minLength": 1 },
86
+ "prompt": { "type": "string", "minLength": 1 }
87
+ }
88
+ }
89
+ },
90
+ "ratings": { "type": "array", "maxItems": 0 },
91
+ "note": { "type": "string", "minLength": 1 }
92
+ }
93
+ }
94
+ },
95
+ "$defs": {
96
+ "stringList": {
97
+ "type": "array",
98
+ "items": { "type": "string", "minLength": 1 },
99
+ "uniqueItems": true
100
+ },
101
+ "summary": {
102
+ "type": "object",
103
+ "required": ["errors", "warnings", "passed"],
104
+ "additionalProperties": false,
105
+ "properties": {
106
+ "errors": { "type": "integer", "minimum": 0 },
107
+ "warnings": { "type": "integer", "minimum": 0 },
108
+ "passed": { "type": "boolean" }
109
+ }
110
+ },
111
+ "context": {
112
+ "type": "object",
113
+ "required": [
114
+ "id",
115
+ "browser",
116
+ "width",
117
+ "height",
118
+ "zoom",
119
+ "colorScheme",
120
+ "reducedMotion",
121
+ "evidence",
122
+ "summary"
123
+ ],
124
+ "additionalProperties": false,
125
+ "properties": {
126
+ "id": { "type": "string", "minLength": 1 },
127
+ "browser": { "enum": ["chromium", "firefox", "webkit"] },
128
+ "width": { "type": "integer", "minimum": 1 },
129
+ "height": { "type": "integer", "minimum": 1 },
130
+ "zoom": { "type": "number", "minimum": 1 },
131
+ "colorScheme": { "enum": ["light", "dark"] },
132
+ "reducedMotion": { "enum": ["reduce", "no-preference"] },
133
+ "evidence": { "type": "object" },
134
+ "summary": { "$ref": "#/$defs/summary" }
135
+ }
136
+ },
137
+ "diagnostic": {
138
+ "type": "object",
139
+ "required": ["code", "severity", "context", "message"],
140
+ "additionalProperties": false,
141
+ "properties": {
142
+ "code": { "type": "string", "pattern": "^KUI-B[0-9]{3}$" },
143
+ "severity": { "enum": ["error", "warning"] },
144
+ "context": { "type": "string", "minLength": 1 },
145
+ "message": { "type": "string", "minLength": 1 },
146
+ "repair": { "type": "string", "minLength": 1 },
147
+ "selector": { "type": "string", "minLength": 1 },
148
+ "evidence": {}
149
+ }
150
+ }
151
+ }
152
+ }
package/llms.txt CHANGED
@@ -1,22 +1,205 @@
1
1
  # @kerfjs/ui
2
2
 
3
- Accessible, production-backed UI primitives for kerf applications.
3
+ > Accessible, production-backed UI primitives for [kerf](https://github.com/brianwestphal/kerf)
4
+ > applications. Components are plain functions returning `SafeHtml`; the app owns
5
+ > state and wires stable `data-action` hooks once. This file orients an LLM to
6
+ > generate correct, good-looking kerf UI — it is not a catalog to browse.
4
7
 
5
- - [Package guide](./README.md)
6
- - [AI skill](./ai/skill.md)
7
- - [Component contract](./docs/component-contract.md)
8
- - [Web Awesome theme contract](./docs/webawesome-theme.md)
9
- - [Accessibility and keyboard contracts](./docs/accessibility.md)
10
- - [Design philosophy](./docs/design-philosophy.md)
11
- - [Apple HIG translation](./docs/apple-hig.md)
12
- - [UX catalog](./docs/ux-demo.md)
8
+ ```bash
9
+ npm install kerfjs @kerfjs/ui # kerfjs is a peer; Web Awesome is an optional peer
10
+ ```
13
11
 
14
- The UX catalog is a category-grouped master/detail review surface with a focused route for every public visual component plus composition demos. Its collapsible ecosystem section also lists all 70 free Web Awesome 3.12 components, each with a focused themed route. Related entries use one grouped `Uses` / `Used by` selector across both sets; the shell, display preferences, and selected component share one semantic theme.
12
+ Import each component from its own subpath (`@kerfjs/ui/list-item`, `@kerfjs/ui/toolbar`,
13
+ …); the browser build pulls that component's reachable CSS automatically, so do not
14
+ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
15
15
 
16
- Public components: `LucideIcon`, `Toolbar`, `ToolbarControlGroup`, `ToolbarText`, `SegmentedControl`, `MenuItem`, `MenuHeader`, `ResizableRegion`, `wireResizableRegions`, `AppTab`, `TabBar`, `wireTabBars`, `reorderTabs`, `PageHeader`, `LoadingSpinner`, `Select`, `StateBanner`, `EmptyState`, `DialogHeader`, and `ValueTable`. `SegmentedControl` is controlled and supports toolbar, rounded-rectangle, and pill presentations with native pressed buttons in sequential Tab order. Semantic state palettes are opinionated, Web Awesome-compatible, and overridable globally, by tone, or per instance.
16
+ ## How to build a screen (retrieval order)
17
17
 
18
- Import visual components from explicit JavaScript subpaths. A CSS-aware browser bundler selects generated wrappers that bring in the foundation, the component CSS, and styles for reachable UI subcomponents; unrelated CSS stays out. The root barrel and `@kerfjs/ui/unstyled` are CSS-free; use `styles.css` with the root barrel only when the complete layer is intentional. Manual CSS exports remain available for custom pipelines, and application overrides follow package styles in the cascade. `@kerfjs/ui/webawesome.css` is an optional CSS-only theme for Web Awesome's free components; it includes Web Awesome's base stylesheet, registers no elements, and remains overridable through public `--wa-*` tokens. CSS, its generated browser wrappers, and `@kerfjs/ui/select/register` are the declared side effects. `kerfjs` is an external peer. The Web Awesome peer is optional and needed for its components. `wireTabBars` includes proximity-based horizontal edge autoscroll during same-bar drag reordering.
18
+ 1. **Pick the component from the interface need**, not by appearance — read
19
+ [component-selection.md](./docs/component-selection.md) (the problem→component
20
+ matrix, with imports, wiring, ownership, and alternatives).
21
+ 2. **Get exact signatures before emitting code** — read
22
+ [public-api-signatures-v1.md](./ai/public-api-signatures-v1.md) (real prop names,
23
+ callback shapes, disposer return types).
24
+ 3. **For exhaustive, structured facts** (ids, exports, variants, `publicClasses`,
25
+ relationships, side effects, and geometry ownership) load the
26
+ [Machine-readable component catalog](./ai/component-catalog.json) — the
27
+ canonical checked-in source; its schema is alongside it. Also load the
28
+ consuming application's catalog extension when present; generate one from the
29
+ [Consumer catalog extension schema](./ai/component-catalog-extension.schema.json)
30
+ when app-owned components must participate in selection or alignment.
31
+ Load the [Composition catalog v2](./ai/component-catalog-v2.json) to
32
+ mechanically evaluate parents, contexts, zones/cardinality, children, state,
33
+ wiring, responsive/layout/accessibility rules, and public boundaries. V1
34
+ remains compatible; v2 joins catalogs by `package:id`. Consumer v2 catalogs
35
+ use [the v2 extension schema](./ai/component-catalog-extension-v2.schema.json).
36
+ Load [compile-time contracts](./ai/compile-time-contracts-v1.json) for stable
37
+ `KUI-T###` ids, exact declaration symbols, and the boundary between rejected
38
+ source states and relationships that still require runtime/catalog checks.
39
+ Before generating application UI, discover `.kerf-ui-profile.json` with the
40
+ shipped [application profile API](./ai/application-ui-profile.mjs). Merge
41
+ package defaults, workspace policy, then parent-to-child directory policy;
42
+ honor its package-qualified preferences, approved theme/density, semantic
43
+ tokens, layout conventions, and narrow source-located exceptions. Validation
44
+ is catalog-aware per layer, including parent values later overridden by a
45
+ child; synchronous hosts use [application-ui-profile-sync.cjs](./ai/application-ui-profile-sync.cjs).
46
+ See the
47
+ [workspace profile example](./docs/examples/application-ui-profile.json).
48
+ 4. **When authoring a component gallery**, load
49
+ [catalog-authoring.json](./ai/catalog-authoring.json), then follow its
50
+ authoritative [Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract).
51
+ 5. **Apply the rules below and in** [skill.md](./ai/skill.md).
52
+ 6. **Before calling an integration complete**, run
53
+ [`kerf-ui-doctor`](./docs/ui-doctor.md). Its portable JSON report merges
54
+ profile/catalog, TypeScript, Kerf ESLint, and static analyzer diagnostics;
55
+ repair source-located errors until exit 0. Use full mode for release gates;
56
+ generated `dist`/`coverage`, dependency, cache, evidence, and nested-worktree
57
+ directories are excluded consistently from every static stage.
58
+ [`kerf-ui-analyze`](./docs/ui-analyzer.md) remains available when only static
59
+ layout diagnostics are wanted; its review findings are a bounded human/AI
60
+ review queue rather than an objective aesthetic score.
61
+ 7. **Evaluate the running application** by explicitly enabling the doctor's
62
+ browser stage or directly invoking
63
+ [`kerf-ui-evaluate`](./docs/ui-evaluator.md). Preserve its `KUI-B###`
64
+ browser evidence and screenshots; record hierarchy/rhythm/density/aesthetic
65
+ ratings separately with a named reviewer rather than presenting them as
66
+ objective assertions.
19
67
 
20
- The Web Awesome theme renders Tooltip and Popover without pointer arrows by default. Restore them only when the anchor relationship needs the pointer, using `--wa-tooltip-arrow-size`, `--kui-wa-popover-arrow-size`, or one popover's public `--arrow-size`; `without-arrow` remains available for explicit local intent.
68
+ ## Core rules (do the right thing)
21
69
 
22
- Web Awesome catalog coverage means themed and inspectable, not preferred. Consider Popup when it replaces custom anchored positioning. Prefer Kerf Select over direct Dropdown/Dropdown Item/Select/Option composition, SegmentedControl over Button Group, TabBar or SegmentedControl over Web Awesome Tabs, LucideIcon over Web Awesome Icon, and ResizableRegion over Split Panel. ResizableRegion carries Hot Sheet 2's 1px separator plus hover/focus grip. Use Tree/Tree Item, Animated Image, and Comparison only for a specific required behavior; avoid Zoomable Frame.
70
+ - **Reach for the primitive, not for CSS.** The package is built to look right
71
+ _unstyled_. Before adding `padding`, `margin`, `width`, `height`, `border`,
72
+ `background`, a wrapper card, or a decoration, check whether the component, the
73
+ pane, or the content-item already owns it — it almost always does. Prefer a
74
+ component prop or a `--kui-*` token; write CSS only for genuinely new structure,
75
+ and then only join a component's documented `publicClasses` (never reach in by
76
+ tag/id/attribute or an unlisted class).
77
+ - **Never double-inset.** A `.kui-pane` has no padding; its `.kui-content` children
78
+ own the geometry (8px inline margin + 1px border + 8px padding). Do not add a
79
+ container padding on top of a content-item's own margin — pick one owner. Use
80
+ `.kui-content` for 24px major vertical rhythm.
81
+ - **Use `List` for vertical layout.** It supplies a stretch-aligned column plus
82
+ optional standard/custom `gap`, `flex`, vertical scrolling, and canonical
83
+ `dividerSides` (`t`/`r`/`b`/`l` order). It adds no list semantics; children own
84
+ those, and only one bounded region should own scrolling.
85
+ - **Keep Web Awesome on the shared inset tiers.** `webawesome.css` uses
86
+ `--kui-wa-control-inset` (8px controls/items) and
87
+ `--kui-wa-surface-margin` / `--kui-wa-surface-inset` (8px around/inside
88
+ Accordion, Card, Details, Callout, and Include), while
89
+ `--kui-wa-container-inset` keeps Tab Panel at 16px. Override the tier at the
90
+ narrowest useful scope instead of restyling individual shadow parts.
91
+ Checkbox and Radio Group option regions also receive the shared 8px inline
92
+ outer inset because those groups have no bordered field shell. The Color
93
+ Picker trigger receives the same inset for the same unbordered geometry.
94
+ Slider's complete interactive region uses the shared 8px logical inline outer
95
+ inset without shifting its already-aligned label.
96
+ Known Date's Month/Day/Year captions and bordered text-like field hints align
97
+ with field values at the shared 9px border-plus-padding inset. OTP Input's
98
+ label uses the same uppercase xs/650 treatment and its label and hint share
99
+ that 9px alignment.
100
+ - **Trust the defaults.** Render a control at its natural size and color (a
101
+ `LucideIcon` is 24px); if it looks wrong, fix the surrounding layout, not the
102
+ control. Never force a component's width/height to size it — that leaves a halo
103
+ or a stretched oval.
104
+ - **Toolbars hold only `ToolbarText` and `ToolbarControlGroup`.** Never put a bare
105
+ button, input, link, or loose markup in a `leading`/`center`/`trailing` zone.
106
+ Wrap every control — `SegmentedControl`, `Select`, a collapsible
107
+ `TokenSearchField`, Web Awesome controls — inside a `ToolbarControlGroup`. For an
108
+ ordinary icon/action control inside the group use a **plain `<button>`** (the
109
+ group styles it fully) — that is the default; reach for `wa-button` only when you
110
+ need a Web Awesome feature, chiefly the `slot="trigger"` button of a `wa-dropdown`
111
+ popup menu. A toolbar popup menu is a `single` `ToolbarControlGroup` around a
112
+ `wa-dropdown` (its `slot="trigger"` `wa-button` is the toolbar button, kept under
113
+ `data-morph-skip-children`).
114
+ - **`PanelHeader` is _the_ panel/dialog/page heading.** A plain toolbar with an
115
+ optional bordered icon group, an extra-large `ToolbarText` title, the trailing
116
+ controls you pass, and an optional subtitle below — do not hand-build a heading
117
+ row or restyle a toolbar into one.
118
+ - **Space by the five-step scale, by relationship not by eye.** `0`
119
+ `--kui-space-none`, `4px` `--kui-space-2xs`, `8px` `--kui-space-xs` (inside a
120
+ group), `16px` `--kui-space-m`, `24px` `--kui-space-l` (between major differing
121
+ regions). 12px/32px are off-scale exceptions.
122
+ - **Panes share one child-owned geometry.** Sidebars, main areas, inspectors, and
123
+ dialogs all use an unpadded `.kui-pane` (optional `.kui-pane__toolbar`, one
124
+ scrolling `.kui-pane__content`, optional `.kui-pane__footer`). A visible pane owns
125
+ its collapse control; a hidden pane's restore moves to the adjacent main
126
+ toolbar's matching edge — no icon-only rail. Keep one scroll owner per region.
127
+ - **State and behavior live in the app.** Components take semantic `data-action`
128
+ strings and controlled values; wire them once with `delegate()`/`delegateActions()`
129
+ or the disposer-returning `wire…` helpers, and own domain copy, transport, and
130
+ policy in a thin adapter. Every element must earn its place — cut chrome, labels,
131
+ and readouts that do not help a person decide or act.
132
+ - **App state is domain/persisted; helpers own only ephemeral mechanics.** Keep
133
+ navigation stacks, tab selection and order, pane sizes, and `collapsed`/`expanded`
134
+ disclosure flags in the app — they are data or persisted layout, and the app reads
135
+ them to render. The `wire…` helpers own the _ephemeral_ parts: `wireNavStack` the
136
+ push/pop animation, `wireTabBars` the overflow autoscroll, drag preview, and
137
+ replacement focus after controlled automatic tab activation,
138
+ `wireResizableRegions` the live drag preview; they report committed changes via
139
+ callbacks. Managed TokenSearchField clear also preserves open state and replacement
140
+ editor focus for continued typing. The one richer case is `wireTokenSearchFields`, which manages the
141
+ collapsible field's expand/collapse/focus by default (on, per-behavior opt-out) and
142
+ exposes the `expanded` signal on its handle — bind it in render or hand in your own
143
+ via `collapsible.signals`. Do not hand-roll open/collapse/focus that helper
144
+ provides; but do keep a plain disclosure toggle (a one-line boolean the app already
145
+ renders from) in the app. For real-app composition it also offers a focusout
146
+ keep-open exception (`data-token-search-keep-open` regions or `collapsible.keepOpenOn`,
147
+ so a sibling suggestions/date popover does not collapse an empty field), opt-in
148
+ atomic-chip keyboard (`keyboard`: Backspace/Delete remove the adjacent chip via
149
+ `onRemoveToken`, ArrowRight moves the caret past a trailing chip), and an
150
+ `onEdit({id, editor, event})` input callback (the `InputEvent` lets you gate on `inputType`/`data`) — so the app can drop its own keydown/input
151
+ boilerplate while still owning parsing and controlled token state.
152
+ - **Placeholder loading state, don't rebuild it.** For a value or component that is
153
+ still loading, set `placeholder` on the component (`Select`, `ListHeader`,
154
+ `ListItem`, `ValueTableRow`, `PanelHeader`, `SegmentedControl`, `StateBanner`,
155
+ `AppTab`, `ToolbarText`, `ListActionRow`): it renders its real chrome with value
156
+ slots as subtle **unanimated** skeleton blocks and interactivity disabled, so a
157
+ parent composes a faithful loading view (e.g. an inspector) without hand-rebuilding
158
+ markup. Use the standalone `Skeleton` for a custom slot. Prefer it over `wa-skeleton`
159
+ (the pure-Kerf primitives avoid Web Awesome), and never animate it — use
160
+ `LoadingSpinner` for known busy activity instead.
161
+ - **Use a StateBanner badge only for compact supporting status.** Pass the
162
+ optional string `badge` for a terse count or status beside the title. It
163
+ inherits the banner tone and is announced with the banner, so keep its text
164
+ meaningful and never rely on color alone.
165
+
166
+ ## Public exports
167
+
168
+ `LucideIcon`, `DisclosureArrow`, `Toolbar`, `ToolbarControlGroup`, `FloatingToolbar`, `ToolbarText`,
169
+ `PanelHeader`, `ListItem`, `ListActionRow`, `ListHeader`, `ListInsetControl`,
170
+ `ListInsetText`, `SegmentedControl`,
171
+ `Select`, `TokenSearchField` (+ `readTokenSearchField`, `placeTokenSearchCaret`,
172
+ `wireTokenSearchFields`), `AppTab`, `TabBar` (+ `wireTabBars`, `reorderTabs`),
173
+ `ResizableRegion` (+ `wireResizableRegions`), `StateBanner`, `EmptyState`,
174
+ `LoadingSpinner`, `Skeleton`, `ValueTable`, `ValueTableRow`. Whole-screen layouts (opt-in,
175
+ tree-shakeable, declarative with `wire…` helpers, each with a companion CSS import):
176
+ `NavStack`, `SplitView`, `Workbench`, `TabScaffold`, driven by `deviceClass()` from
177
+ `@kerfjs/ui/device-class`. For a standalone collapsible rail/drawer outside a full
178
+ shell, `@kerfjs/ui/collapsible-panel` (`CollapsiblePanel`, `CollapsiblePanelToggle`)
179
+
180
+ - `@kerfjs/ui/wire-sidebar` (`wireSidebar`: toggle, focus, compact overlay, persistence).
181
+ `@kerfjs/ui/catalog` is another opt-in shell — a
182
+ `Catalog` component + `wireCatalog` helper for building a component-gallery catalog
183
+ (collapsible category sidebar + preview stage + resources footer, with an opt-in
184
+ transparent-bound and margin geometry overlay plus focus-preserving active-row
185
+ reveal for long desktop sidebars) from your own
186
+ entries; controlled/stateless like the layouts. For any Catalog demo, follow
187
+ the [authoritative authoring contract](./docs/catalog.md#catalog-demo-authoring-contract)
188
+ rather than inferring structure from the shell or private CSS.
189
+ `@kerfjs/ui/webawesome` is a
190
+ type-only boundary for `wa-*` JSX; `@kerfjs/ui/select/register` and the CSS are the
191
+ declared side effects.
192
+
193
+ ## Reference
194
+
195
+ - [skill.md](./ai/skill.md): the full rule set + a common-mistakes table (the shipped AI skill).
196
+ - [design-philosophy.md](./docs/design-philosophy.md): why kerf UI is shaped this way — the decision principles behind the rules above.
197
+ - [layout.md](./docs/layout.md): the pane/content-item geometry, public roles/tokens, and the spacing scale.
198
+ - [component-contract.md](./docs/component-contract.md): what a component owns vs. what the app owns.
199
+ - [accessibility.md](./docs/accessibility.md): keyboard and ARIA contracts per component.
200
+ - [recipes.md](./docs/recipes.md): production compositions (app shell, list-detail dialog, composer form, …) as copyable references.
201
+ - [app-layouts.md](./docs/app-layouts.md): choosing `NavStack`/`SplitView`/`Workbench`/`TabScaffold` by data + interaction + device, and dialog presentation.
202
+ - [webawesome-theme.md](./docs/webawesome-theme.md): the optional Web Awesome theme; catalog coverage means themed-and-supported, not preferred (prefer the Kerf primitive when one exists). The UX sidebar visibly tags superseded and exceptional Web Awesome choices as `Discouraged`; Popup remains an available conditional positioning primitive.
203
+ - [component-catalog.json](./ai/component-catalog.json) + [component-catalog-extension.schema.json](./ai/component-catalog-extension.schema.json) + [catalog-authoring.json](./ai/catalog-authoring.json) + [public-api-signatures-v1.md](./ai/public-api-signatures-v1.md) + [webawesome-jsx-signatures-v1.md](./ai/webawesome-jsx-signatures-v1.md): machine-readable selection facts, a reusable app-component extension contract, Catalog authoring discovery, and exact signatures.
204
+ - [compile-time-contracts-v1.json](./ai/compile-time-contracts-v1.json) + [type-contracts.md](./docs/type-contracts.md): stable compile diagnostics, packed-declaration proof, migrations, and explicit non-goals.
205
+ - [README.md](./README.md): package overview and the component subpath table.