@kerfjs/ui 5.0.0-beta.3 → 5.0.0-beta.31

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 (470) hide show
  1. package/README.md +320 -107
  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 +131 -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 +486 -0
  17. package/ai/component-catalog-v2.d.ts +90 -0
  18. package/ai/component-catalog-v2.json +5455 -0
  19. package/ai/component-catalog-v2.schema.json +298 -0
  20. package/ai/component-catalog.json +2437 -419
  21. package/ai/component-catalog.schema.json +39 -0
  22. package/ai/public-api-signatures-v1.md +1442 -124
  23. package/ai/skill.md +131 -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/{menu-header.js → list-header.js} +3 -2
  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/segmented-control.js +1 -0
  41. package/dist/browser/select.js +1 -0
  42. package/dist/browser/skeleton.js +3 -0
  43. package/dist/browser/state-banner.js +1 -0
  44. package/dist/browser/sunken-panel.js +3 -0
  45. package/dist/browser/surface-scaffold.js +3 -0
  46. package/dist/browser/toolbar-text.js +1 -0
  47. package/dist/browser/value-table.js +1 -0
  48. package/dist/catalog-resources.d.ts +35 -0
  49. package/dist/catalog-resources.js +22 -0
  50. package/dist/catalog-resources.js.map +1 -0
  51. package/dist/catalog.d.ts +151 -0
  52. package/dist/catalog.js +379 -0
  53. package/dist/catalog.js.map +1 -0
  54. package/dist/chunk-6NDBE2OK.js +32 -0
  55. package/dist/chunk-6NDBE2OK.js.map +1 -0
  56. package/dist/chunk-6WTETUZ6.js +21 -0
  57. package/dist/chunk-6WTETUZ6.js.map +1 -0
  58. package/dist/chunk-AQFWBG23.js +83 -0
  59. package/dist/chunk-AQFWBG23.js.map +1 -0
  60. package/dist/chunk-B6JYRX3P.js +51 -0
  61. package/dist/chunk-B6JYRX3P.js.map +1 -0
  62. package/dist/chunk-CAB6NQ2T.js +102 -0
  63. package/dist/chunk-CAB6NQ2T.js.map +1 -0
  64. package/dist/chunk-CK6P5AUK.js +136 -0
  65. package/dist/chunk-CK6P5AUK.js.map +1 -0
  66. package/dist/chunk-DAO2VFTT.js +129 -0
  67. package/dist/chunk-DAO2VFTT.js.map +1 -0
  68. package/dist/chunk-DYBPI5O2.js +25 -0
  69. package/dist/chunk-DYBPI5O2.js.map +1 -0
  70. package/dist/{chunk-TRNBHPNW.js → chunk-E34TE2ZI.js} +12 -8
  71. package/dist/chunk-E34TE2ZI.js.map +1 -0
  72. package/dist/chunk-I45QO2IZ.js +88 -0
  73. package/dist/chunk-I45QO2IZ.js.map +1 -0
  74. package/dist/chunk-I4V3UDSA.js +79 -0
  75. package/dist/chunk-I4V3UDSA.js.map +1 -0
  76. package/dist/chunk-KFUUFNTS.js +15 -0
  77. package/dist/chunk-KFUUFNTS.js.map +1 -0
  78. package/dist/chunk-MFR2IIFG.js +20 -0
  79. package/dist/chunk-MFR2IIFG.js.map +1 -0
  80. package/dist/chunk-OC275HHS.js +128 -0
  81. package/dist/chunk-OC275HHS.js.map +1 -0
  82. package/dist/chunk-OL4TC3U2.js +156 -0
  83. package/dist/chunk-OL4TC3U2.js.map +1 -0
  84. package/dist/chunk-OMSRSL3B.js +120 -0
  85. package/dist/chunk-OMSRSL3B.js.map +1 -0
  86. package/dist/chunk-RL6COPKF.js +44 -0
  87. package/dist/chunk-RL6COPKF.js.map +1 -0
  88. package/dist/chunk-SOK5EUF7.js +25 -0
  89. package/dist/chunk-SOK5EUF7.js.map +1 -0
  90. package/dist/{chunk-7BR3DO2A.js → chunk-SRSJO5QE.js} +13 -4
  91. package/dist/chunk-SRSJO5QE.js.map +1 -0
  92. package/dist/chunk-T7DOWS6T.js +61 -0
  93. package/dist/chunk-T7DOWS6T.js.map +1 -0
  94. package/dist/chunk-TIGSG6BX.js +218 -0
  95. package/dist/chunk-TIGSG6BX.js.map +1 -0
  96. package/dist/chunk-UDHHKZWO.js +41 -0
  97. package/dist/chunk-UDHHKZWO.js.map +1 -0
  98. package/dist/{chunk-MQIZAD4A.js → chunk-UKKSMZYT.js} +76 -22
  99. package/dist/chunk-UKKSMZYT.js.map +1 -0
  100. package/dist/chunk-V6GQKOX2.js +39 -0
  101. package/dist/chunk-V6GQKOX2.js.map +1 -0
  102. package/dist/chunk-V6HCTCVD.js +46 -0
  103. package/dist/chunk-V6HCTCVD.js.map +1 -0
  104. package/dist/chunk-VDUJZF5G.js +515 -0
  105. package/dist/chunk-VDUJZF5G.js.map +1 -0
  106. package/dist/chunk-VXFGMDA7.js +31 -0
  107. package/dist/chunk-VXFGMDA7.js.map +1 -0
  108. package/dist/chunk-WN52USHV.js +115 -0
  109. package/dist/chunk-WN52USHV.js.map +1 -0
  110. package/dist/chunk-WSXUPSID.js +43 -0
  111. package/dist/chunk-WSXUPSID.js.map +1 -0
  112. package/dist/{chunk-56RJXPHG.js → chunk-Y6LYKFXY.js} +1 -1
  113. package/dist/{chunk-56RJXPHG.js.map → chunk-Y6LYKFXY.js.map} +1 -1
  114. package/dist/chunk-ZPWZIVI6.js +47 -0
  115. package/dist/chunk-ZPWZIVI6.js.map +1 -0
  116. package/dist/collapsible-panel.d.ts +77 -0
  117. package/dist/collapsible-panel.js +84 -0
  118. package/dist/collapsible-panel.js.map +1 -0
  119. package/dist/css-values.d.ts +75 -0
  120. package/dist/css-values.js +3 -0
  121. package/dist/css-values.js.map +1 -0
  122. package/dist/device-class.d.ts +62 -0
  123. package/dist/device-class.js +103 -0
  124. package/dist/device-class.js.map +1 -0
  125. package/dist/disclosure-arrow.js +1 -1
  126. package/dist/divider-sides-267FA7sY.d.ts +4 -0
  127. package/dist/empty-state.d.ts +3 -2
  128. package/dist/empty-state.js +1 -1
  129. package/dist/floating-toolbar.d.ts +29 -0
  130. package/dist/floating-toolbar.js +3 -0
  131. package/dist/floating-toolbar.js.map +1 -0
  132. package/dist/index.d.ts +23 -14
  133. package/dist/index.js +30 -23
  134. package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +19 -8
  135. package/dist/list-action-row.js +7 -0
  136. package/dist/list-action-row.js.map +1 -0
  137. package/dist/list-header.d.ts +77 -0
  138. package/dist/list-header.js +8 -0
  139. package/dist/list-header.js.map +1 -0
  140. package/dist/list-inset-control.d.ts +17 -0
  141. package/dist/list-inset-control.js +3 -0
  142. package/dist/list-inset-control.js.map +1 -0
  143. package/dist/list-inset-text.d.ts +26 -0
  144. package/dist/list-inset-text.js +3 -0
  145. package/dist/list-inset-text.js.map +1 -0
  146. package/dist/list-item.d.ts +45 -0
  147. package/dist/list-item.js +7 -0
  148. package/dist/list-item.js.map +1 -0
  149. package/dist/list.d.ts +21 -0
  150. package/dist/list.js +4 -0
  151. package/dist/list.js.map +1 -0
  152. package/dist/loading-spinner.js +1 -1
  153. package/dist/nav-stack.d.ts +41 -0
  154. package/dist/nav-stack.js +6 -0
  155. package/dist/nav-stack.js.map +1 -0
  156. package/dist/pane.d.ts +50 -0
  157. package/dist/pane.js +4 -0
  158. package/dist/pane.js.map +1 -0
  159. package/dist/resizable-region.d.ts +21 -3
  160. package/dist/resizable-region.js +1 -1
  161. package/dist/segmented-control.d.ts +11 -8
  162. package/dist/segmented-control.js +3 -1
  163. package/dist/select-register.d.ts +5 -1
  164. package/dist/select-register.js +3 -0
  165. package/dist/select-register.js.map +1 -1
  166. package/dist/select.d.ts +34 -8
  167. package/dist/select.js +3 -1
  168. package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
  169. package/dist/skeleton.d.ts +25 -0
  170. package/dist/skeleton.js +4 -0
  171. package/dist/skeleton.js.map +1 -0
  172. package/dist/split-view.d.ts +43 -0
  173. package/dist/split-view.js +82 -0
  174. package/dist/split-view.js.map +1 -0
  175. package/dist/state-banner.d.ts +11 -5
  176. package/dist/state-banner.js +3 -1
  177. package/dist/styles/app-tab.css +26 -0
  178. package/dist/styles/catalog.css +582 -0
  179. package/dist/styles/collapsible-panel.css +212 -0
  180. package/dist/styles/floating-toolbar.css +38 -0
  181. package/dist/styles/foundation.css +80 -0
  182. package/dist/styles/layout.css +2 -20
  183. package/dist/styles/list-action-row.css +224 -0
  184. package/dist/styles/list-header.css +198 -0
  185. package/dist/styles/list-inset-control.css +7 -0
  186. package/dist/styles/list-inset-text.css +14 -0
  187. package/dist/styles/list-item.css +171 -0
  188. package/dist/styles/list.css +43 -0
  189. package/dist/styles/nav-stack.css +141 -0
  190. package/dist/styles/pane.css +62 -0
  191. package/dist/styles/resizable-region.css +158 -0
  192. package/dist/styles/segmented-control.css +10 -7
  193. package/dist/styles/select.css +115 -2
  194. package/dist/styles/skeleton.css +31 -0
  195. package/dist/styles/split-view.css +35 -0
  196. package/dist/styles/state-banner.css +49 -10
  197. package/dist/styles/styles.css +7 -5
  198. package/dist/styles/sunken-panel.css +22 -0
  199. package/dist/styles/surface-scaffold.css +51 -0
  200. package/dist/styles/tab-bar.css +24 -0
  201. package/dist/styles/tab-scaffold.css +85 -0
  202. package/dist/styles/token-search-field.css +14 -2
  203. package/dist/styles/toolbar-control-group.css +224 -6
  204. package/dist/styles/toolbar-text.css +65 -2
  205. package/dist/styles/toolbar.css +47 -2
  206. package/dist/styles/webawesome.css +165 -0
  207. package/dist/styles/workbench.css +187 -0
  208. package/dist/sunken-panel.d.ts +20 -0
  209. package/dist/sunken-panel.js +3 -0
  210. package/dist/sunken-panel.js.map +1 -0
  211. package/dist/surface-scaffold.d.ts +26 -0
  212. package/dist/surface-scaffold.js +3 -0
  213. package/dist/surface-scaffold.js.map +1 -0
  214. package/dist/tab-bar.d.ts +24 -6
  215. package/dist/tab-bar.js +1 -1
  216. package/dist/tab-scaffold.d.ts +31 -0
  217. package/dist/tab-scaffold.js +51 -0
  218. package/dist/tab-scaffold.js.map +1 -0
  219. package/dist/token-search-field.d.ts +30 -13
  220. package/dist/token-search-field.js +1 -1
  221. package/dist/toolbar-control-group.d.ts +33 -7
  222. package/dist/toolbar-control-group.js +1 -1
  223. package/dist/toolbar-text.d.ts +31 -4
  224. package/dist/toolbar-text.js +3 -1
  225. package/dist/toolbar.d.ts +10 -7
  226. package/dist/toolbar.js +1 -1
  227. package/dist/value-table.d.ts +7 -3
  228. package/dist/value-table.js +3 -1
  229. package/dist/webawesome.d.ts +1 -0
  230. package/dist/wire-catalog.d.ts +57 -0
  231. package/dist/wire-catalog.js +302 -0
  232. package/dist/wire-catalog.js.map +1 -0
  233. package/dist/wire-nav-stack.d.ts +18 -0
  234. package/dist/wire-nav-stack.js +228 -0
  235. package/dist/wire-nav-stack.js.map +1 -0
  236. package/dist/wire-resizable-regions.d.ts +1 -1
  237. package/dist/wire-resizable-regions.js +1 -1
  238. package/dist/wire-sidebar.d.ts +48 -0
  239. package/dist/wire-sidebar.js +147 -0
  240. package/dist/wire-sidebar.js.map +1 -0
  241. package/dist/wire-tab-bars.d.ts +19 -2
  242. package/dist/wire-tab-bars.js +1 -1
  243. package/dist/wire-tab-scaffold.d.ts +11 -0
  244. package/dist/wire-tab-scaffold.js +21 -0
  245. package/dist/wire-tab-scaffold.js.map +1 -0
  246. package/dist/wire-token-search-fields.d.ts +104 -4
  247. package/dist/wire-token-search-fields.js +1 -1
  248. package/dist/workbench.d.ts +44 -0
  249. package/dist/workbench.js +106 -0
  250. package/dist/workbench.js.map +1 -0
  251. package/docs/accessibility.md +137 -20
  252. package/docs/app-layouts.md +61 -0
  253. package/docs/catalog.md +364 -0
  254. package/docs/collapsible-panel.md +142 -0
  255. package/docs/component-contract.md +253 -26
  256. package/docs/component-selection.md +213 -57
  257. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  258. package/docs/design/templates/empty-state/filtered.svg +1 -0
  259. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  260. package/docs/design/templates/empty-state/with-action.svg +1 -0
  261. package/docs/design/templates/empty-state-dark.svg +1 -0
  262. package/docs/design/templates/empty-state.svg +1 -0
  263. package/docs/design/templates/list/compact-dark.svg +1 -0
  264. package/docs/design/templates/list/compact.svg +1 -0
  265. package/docs/design/templates/list/stack-dark.svg +1 -0
  266. package/docs/design/templates/list/stack.svg +1 -0
  267. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  268. package/docs/design/templates/list-action-row/default.svg +1 -0
  269. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  270. package/docs/design/templates/list-action-row/selected.svg +1 -0
  271. package/docs/design/templates/list-action-row-dark.svg +1 -0
  272. package/docs/design/templates/list-action-row.svg +1 -0
  273. package/docs/design/templates/list-dark.svg +1 -0
  274. package/docs/design/templates/list-header/action-dark.svg +1 -0
  275. package/docs/design/templates/list-header/action.svg +1 -0
  276. package/docs/design/templates/list-header/count-dark.svg +1 -0
  277. package/docs/design/templates/list-header/count.svg +1 -0
  278. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  279. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  280. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  281. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  282. package/docs/design/templates/list-header-dark.svg +1 -0
  283. package/docs/design/templates/list-header.svg +1 -0
  284. package/docs/design/templates/list-item/default-dark.svg +1 -0
  285. package/docs/design/templates/list-item/default.svg +1 -0
  286. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  287. package/docs/design/templates/list-item/multiline.svg +1 -0
  288. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  289. package/docs/design/templates/list-item/selected.svg +1 -0
  290. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  291. package/docs/design/templates/list-item/trailing.svg +1 -0
  292. package/docs/design/templates/list-item-dark.svg +1 -0
  293. package/docs/design/templates/list-item.svg +1 -0
  294. package/docs/design/templates/list.svg +1 -0
  295. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  296. package/docs/design/templates/segmented-control/equal.svg +1 -0
  297. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  298. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  299. package/docs/design/templates/segmented-control-dark.svg +1 -0
  300. package/docs/design/templates/segmented-control.svg +1 -0
  301. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  302. package/docs/design/templates/skeleton/avatar.svg +1 -0
  303. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  304. package/docs/design/templates/skeleton/block.svg +1 -0
  305. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  306. package/docs/design/templates/skeleton/lines.svg +1 -0
  307. package/docs/design/templates/skeleton-dark.svg +1 -0
  308. package/docs/design/templates/skeleton.svg +1 -0
  309. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  310. package/docs/design/templates/state-banner/danger.svg +1 -0
  311. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  312. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  313. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  314. package/docs/design/templates/state-banner/info.svg +1 -0
  315. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  316. package/docs/design/templates/state-banner/success.svg +1 -0
  317. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  318. package/docs/design/templates/state-banner/warning.svg +1 -0
  319. package/docs/design/templates/state-banner-dark.svg +1 -0
  320. package/docs/design/templates/state-banner.svg +1 -0
  321. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  322. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  323. package/docs/design/templates/tab-bar-dark.svg +1 -0
  324. package/docs/design/templates/tab-bar.svg +1 -0
  325. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  326. package/docs/design/templates/token-search-field/empty.svg +1 -0
  327. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  328. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  329. package/docs/design/templates/token-search-field-dark.svg +1 -0
  330. package/docs/design/templates/token-search-field.svg +1 -0
  331. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  332. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  333. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  334. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  335. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  336. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  337. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  338. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  339. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  340. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  341. package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
  342. package/docs/design/templates/toolbar-control-group.svg +1 -0
  343. package/docs/design/templates/toolbar-dark.svg +1 -0
  344. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  345. package/docs/design/templates/toolbar-text/default.svg +1 -0
  346. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  347. package/docs/design/templates/toolbar-text/large.svg +1 -0
  348. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  349. package/docs/design/templates/toolbar-text/small.svg +1 -0
  350. package/docs/design/templates/toolbar-text-dark.svg +1 -0
  351. package/docs/design/templates/toolbar-text.svg +1 -0
  352. package/docs/design/templates/toolbar.svg +1 -0
  353. package/docs/design/templates/value-table/details-dark.svg +1 -0
  354. package/docs/design/templates/value-table/details.svg +1 -0
  355. package/docs/design/templates/value-table-dark.svg +1 -0
  356. package/docs/design/templates/value-table.svg +1 -0
  357. package/docs/design/templates.md +128 -0
  358. package/docs/design-philosophy.md +33 -11
  359. package/docs/device-class.md +54 -0
  360. package/docs/examples/application-ui-profile.json +60 -0
  361. package/docs/examples/command-palette-adapter.tsx +67 -17
  362. package/docs/examples/component-catalog-extension-v2.json +80 -0
  363. package/docs/examples/component-catalog-extension.json +45 -0
  364. package/docs/layout.md +98 -37
  365. package/docs/nav-stack.md +77 -0
  366. package/docs/recipes.md +75 -19
  367. package/docs/split-view.md +55 -0
  368. package/docs/sunken-panel.md +53 -0
  369. package/docs/surface-scaffold.md +25 -0
  370. package/docs/tab-scaffold.md +52 -0
  371. package/docs/type-contracts.md +127 -0
  372. package/docs/ui-analyzer.md +118 -0
  373. package/docs/ui-doctor.md +91 -0
  374. package/docs/ui-evaluator.md +122 -0
  375. package/docs/ux-demo.md +24 -13
  376. package/docs/webawesome-theme.md +82 -8
  377. package/docs/workbench.md +123 -0
  378. package/doctor/cli.mjs +115 -0
  379. package/doctor/config.schema.json +68 -0
  380. package/doctor/eslint-diagnostics.d.mts +24 -0
  381. package/doctor/eslint-diagnostics.mjs +24 -0
  382. package/doctor/index.d.mts +116 -0
  383. package/doctor/index.mjs +1272 -0
  384. package/doctor/report.schema.json +118 -0
  385. package/evaluator/cli.mjs +89 -0
  386. package/evaluator/index.d.mts +90 -0
  387. package/evaluator/index.mjs +1138 -0
  388. package/evaluator/report.schema.json +152 -0
  389. package/llms.txt +253 -43
  390. package/package.json +180 -37
  391. package/traversal-exclusions.mjs +27 -0
  392. package/ux-demo/recipes/app-shell.tsx +222 -13
  393. package/ux-demo/recipes/collapsible-sidebar.tsx +229 -0
  394. package/ux-demo/recipes/compact-toolbar.tsx +115 -12
  395. package/ux-demo/recipes/composer-form.tsx +119 -18
  396. package/ux-demo/recipes/list-detail-dialog.tsx +197 -0
  397. package/ux-demo/recipes/list-workspace-states.tsx +175 -9
  398. package/ux-demo/recipes/loaders.ts +13 -4
  399. package/ux-demo/recipes/loading-inspector.tsx +186 -0
  400. package/ux-demo/recipes/mount-recipe.ts +31 -5
  401. package/ux-demo/recipes/navigation-sidebar.tsx +122 -11
  402. package/ux-demo/recipes/navigation-stack.tsx +118 -0
  403. package/ux-demo/recipes/recipes.css +143 -18
  404. package/ux-demo/recipes/types.ts +9 -1
  405. package/ux-demo/recipes/workspace-header.tsx +68 -3
  406. package/dist/browser/dialog-header.js +0 -5
  407. package/dist/browser/menu-action-row.js +0 -3
  408. package/dist/browser/menu-item.js +0 -3
  409. package/dist/browser/page-header.js +0 -3
  410. package/dist/chunk-2PES33HS.js +0 -13
  411. package/dist/chunk-2PES33HS.js.map +0 -1
  412. package/dist/chunk-55DATV3A.js +0 -10
  413. package/dist/chunk-55DATV3A.js.map +0 -1
  414. package/dist/chunk-7BR3DO2A.js.map +0 -1
  415. package/dist/chunk-7LDCTU7D.js +0 -134
  416. package/dist/chunk-7LDCTU7D.js.map +0 -1
  417. package/dist/chunk-AQNKJRFH.js +0 -79
  418. package/dist/chunk-AQNKJRFH.js.map +0 -1
  419. package/dist/chunk-CTQKI2XL.js +0 -28
  420. package/dist/chunk-CTQKI2XL.js.map +0 -1
  421. package/dist/chunk-DAFFDO33.js +0 -14
  422. package/dist/chunk-DAFFDO33.js.map +0 -1
  423. package/dist/chunk-EGHL5S4P.js +0 -33
  424. package/dist/chunk-EGHL5S4P.js.map +0 -1
  425. package/dist/chunk-GY5WH7TO.js +0 -10
  426. package/dist/chunk-GY5WH7TO.js.map +0 -1
  427. package/dist/chunk-H5AGGVU5.js +0 -75
  428. package/dist/chunk-H5AGGVU5.js.map +0 -1
  429. package/dist/chunk-K3G72I6D.js +0 -24
  430. package/dist/chunk-K3G72I6D.js.map +0 -1
  431. package/dist/chunk-M5JRI6MN.js +0 -27
  432. package/dist/chunk-M5JRI6MN.js.map +0 -1
  433. package/dist/chunk-MBR3TYNL.js +0 -14
  434. package/dist/chunk-MBR3TYNL.js.map +0 -1
  435. package/dist/chunk-MFKMHK5W.js +0 -10
  436. package/dist/chunk-MFKMHK5W.js.map +0 -1
  437. package/dist/chunk-MQIZAD4A.js.map +0 -1
  438. package/dist/chunk-NPPD2A6O.js +0 -40
  439. package/dist/chunk-NPPD2A6O.js.map +0 -1
  440. package/dist/chunk-R6JHHBKQ.js +0 -19
  441. package/dist/chunk-R6JHHBKQ.js.map +0 -1
  442. package/dist/chunk-S3TPM2LP.js +0 -23
  443. package/dist/chunk-S3TPM2LP.js.map +0 -1
  444. package/dist/chunk-TRNBHPNW.js.map +0 -1
  445. package/dist/chunk-VHW5YNIB.js +0 -17
  446. package/dist/chunk-VHW5YNIB.js.map +0 -1
  447. package/dist/chunk-WVPYVDXY.js +0 -15
  448. package/dist/chunk-WVPYVDXY.js.map +0 -1
  449. package/dist/chunk-XZXRLY5Q.js +0 -33
  450. package/dist/chunk-XZXRLY5Q.js.map +0 -1
  451. package/dist/dialog-header.d.ts +0 -15
  452. package/dist/dialog-header.js +0 -5
  453. package/dist/dialog-header.js.map +0 -1
  454. package/dist/menu-action-row.js +0 -4
  455. package/dist/menu-action-row.js.map +0 -1
  456. package/dist/menu-header.d.ts +0 -41
  457. package/dist/menu-header.js +0 -6
  458. package/dist/menu-header.js.map +0 -1
  459. package/dist/menu-item.d.ts +0 -31
  460. package/dist/menu-item.js +0 -4
  461. package/dist/menu-item.js.map +0 -1
  462. package/dist/page-header.d.ts +0 -9
  463. package/dist/page-header.js +0 -3
  464. package/dist/page-header.js.map +0 -1
  465. package/dist/styles/dialog-header.css +0 -87
  466. package/dist/styles/menu-action-row.css +0 -154
  467. package/dist/styles/menu-header.css +0 -143
  468. package/dist/styles/menu-item.css +0 -118
  469. package/dist/styles/page-header.css +0 -26
  470. package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kerfjs/ui",
3
- "version": "5.0.0-beta.3",
3
+ "version": "5.0.0-beta.31",
4
4
  "description": "Accessible, composable UI primitives for kerf applications.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,6 +27,11 @@
27
27
  "publishConfig": {
28
28
  "access": "public"
29
29
  },
30
+ "bin": {
31
+ "kerf-ui-analyze": "./analyzer/cli.mjs",
32
+ "kerf-ui-doctor": "./doctor/cli.mjs",
33
+ "kerf-ui-evaluate": "./evaluator/cli.mjs"
34
+ },
30
35
  "main": "./dist/index.js",
31
36
  "types": "./dist/index.d.ts",
32
37
  "sideEffects": [
@@ -39,6 +44,10 @@
39
44
  "types": "./dist/index.d.ts",
40
45
  "import": "./dist/index.js"
41
46
  },
47
+ "./css-values": {
48
+ "types": "./dist/css-values.d.ts",
49
+ "import": "./dist/css-values.js"
50
+ },
42
51
  "./lucide-icon": {
43
52
  "types": "./dist/lucide-icon.d.ts",
44
53
  "browser": "./dist/browser/lucide-icon.js",
@@ -59,25 +68,50 @@
59
68
  "browser": "./dist/browser/toolbar-control-group.js",
60
69
  "import": "./dist/toolbar-control-group.js"
61
70
  },
71
+ "./surface-scaffold": {
72
+ "types": "./dist/surface-scaffold.d.ts",
73
+ "browser": "./dist/browser/surface-scaffold.js",
74
+ "import": "./dist/surface-scaffold.js"
75
+ },
76
+ "./floating-toolbar": {
77
+ "types": "./dist/floating-toolbar.d.ts",
78
+ "browser": "./dist/browser/floating-toolbar.js",
79
+ "import": "./dist/floating-toolbar.js"
80
+ },
62
81
  "./toolbar-text": {
63
82
  "types": "./dist/toolbar-text.d.ts",
64
83
  "browser": "./dist/browser/toolbar-text.js",
65
84
  "import": "./dist/toolbar-text.js"
66
85
  },
67
- "./menu-action-row": {
68
- "types": "./dist/menu-action-row.d.ts",
69
- "browser": "./dist/browser/menu-action-row.js",
70
- "import": "./dist/menu-action-row.js"
86
+ "./list": {
87
+ "types": "./dist/list.d.ts",
88
+ "browser": "./dist/browser/list.js",
89
+ "import": "./dist/list.js"
71
90
  },
72
- "./menu-item": {
73
- "types": "./dist/menu-item.d.ts",
74
- "browser": "./dist/browser/menu-item.js",
75
- "import": "./dist/menu-item.js"
91
+ "./list-action-row": {
92
+ "types": "./dist/list-action-row.d.ts",
93
+ "browser": "./dist/browser/list-action-row.js",
94
+ "import": "./dist/list-action-row.js"
76
95
  },
77
- "./menu-header": {
78
- "types": "./dist/menu-header.d.ts",
79
- "browser": "./dist/browser/menu-header.js",
80
- "import": "./dist/menu-header.js"
96
+ "./list-item": {
97
+ "types": "./dist/list-item.d.ts",
98
+ "browser": "./dist/browser/list-item.js",
99
+ "import": "./dist/list-item.js"
100
+ },
101
+ "./list-header": {
102
+ "types": "./dist/list-header.d.ts",
103
+ "browser": "./dist/browser/list-header.js",
104
+ "import": "./dist/list-header.js"
105
+ },
106
+ "./list-inset-control": {
107
+ "types": "./dist/list-inset-control.d.ts",
108
+ "browser": "./dist/browser/list-inset-control.js",
109
+ "import": "./dist/list-inset-control.js"
110
+ },
111
+ "./list-inset-text": {
112
+ "types": "./dist/list-inset-text.d.ts",
113
+ "browser": "./dist/browser/list-inset-text.js",
114
+ "import": "./dist/list-inset-text.js"
81
115
  },
82
116
  "./resizable-region": {
83
117
  "types": "./dist/resizable-region.d.ts",
@@ -88,11 +122,43 @@
88
122
  "types": "./dist/wire-resizable-regions.d.ts",
89
123
  "import": "./dist/wire-resizable-regions.js"
90
124
  },
125
+ "./device-class": {
126
+ "types": "./dist/device-class.d.ts",
127
+ "import": "./dist/device-class.js"
128
+ },
91
129
  "./app-tab": {
92
130
  "types": "./dist/app-tab.d.ts",
93
131
  "browser": "./dist/browser/app-tab.js",
94
132
  "import": "./dist/app-tab.js"
95
133
  },
134
+ "./catalog": {
135
+ "types": "./dist/catalog.d.ts",
136
+ "import": "./dist/catalog.js"
137
+ },
138
+ "./catalog-resources": {
139
+ "types": "./dist/catalog-resources.d.ts",
140
+ "import": "./dist/catalog-resources.js"
141
+ },
142
+ "./analyzer": {
143
+ "types": "./analyzer/index.d.mts",
144
+ "import": "./analyzer/index.mjs"
145
+ },
146
+ "./analyzer/report.schema.json": "./analyzer/report.schema.json",
147
+ "./doctor": {
148
+ "types": "./doctor/index.d.mts",
149
+ "import": "./doctor/index.mjs"
150
+ },
151
+ "./doctor/config.schema.json": "./doctor/config.schema.json",
152
+ "./doctor/report.schema.json": "./doctor/report.schema.json",
153
+ "./evaluator": {
154
+ "types": "./evaluator/index.d.mts",
155
+ "import": "./evaluator/index.mjs"
156
+ },
157
+ "./evaluator/report.schema.json": "./evaluator/report.schema.json",
158
+ "./wire-catalog": {
159
+ "types": "./dist/wire-catalog.d.ts",
160
+ "import": "./dist/wire-catalog.js"
161
+ },
96
162
  "./tab-bar": {
97
163
  "types": "./dist/tab-bar.d.ts",
98
164
  "browser": "./dist/browser/tab-bar.js",
@@ -102,10 +168,42 @@
102
168
  "types": "./dist/wire-tab-bars.d.ts",
103
169
  "import": "./dist/wire-tab-bars.js"
104
170
  },
105
- "./page-header": {
106
- "types": "./dist/page-header.d.ts",
107
- "browser": "./dist/browser/page-header.js",
108
- "import": "./dist/page-header.js"
171
+ "./nav-stack": {
172
+ "types": "./dist/nav-stack.d.ts",
173
+ "import": "./dist/nav-stack.js"
174
+ },
175
+ "./wire-nav-stack": {
176
+ "types": "./dist/wire-nav-stack.d.ts",
177
+ "import": "./dist/wire-nav-stack.js"
178
+ },
179
+ "./split-view": {
180
+ "types": "./dist/split-view.d.ts",
181
+ "import": "./dist/split-view.js"
182
+ },
183
+ "./pane": {
184
+ "types": "./dist/pane.d.ts",
185
+ "browser": "./dist/browser/pane.js",
186
+ "import": "./dist/pane.js"
187
+ },
188
+ "./workbench": {
189
+ "types": "./dist/workbench.d.ts",
190
+ "import": "./dist/workbench.js"
191
+ },
192
+ "./collapsible-panel": {
193
+ "types": "./dist/collapsible-panel.d.ts",
194
+ "import": "./dist/collapsible-panel.js"
195
+ },
196
+ "./wire-sidebar": {
197
+ "types": "./dist/wire-sidebar.d.ts",
198
+ "import": "./dist/wire-sidebar.js"
199
+ },
200
+ "./tab-scaffold": {
201
+ "types": "./dist/tab-scaffold.d.ts",
202
+ "import": "./dist/tab-scaffold.js"
203
+ },
204
+ "./wire-tab-scaffold": {
205
+ "types": "./dist/wire-tab-scaffold.d.ts",
206
+ "import": "./dist/wire-tab-scaffold.js"
109
207
  },
110
208
  "./loading-spinner": {
111
209
  "types": "./dist/loading-spinner.d.ts",
@@ -117,6 +215,16 @@
117
215
  "browser": "./dist/browser/select.js",
118
216
  "import": "./dist/select.js"
119
217
  },
218
+ "./skeleton": {
219
+ "types": "./dist/skeleton.d.ts",
220
+ "browser": "./dist/browser/skeleton.js",
221
+ "import": "./dist/skeleton.js"
222
+ },
223
+ "./sunken-panel": {
224
+ "types": "./dist/sunken-panel.d.ts",
225
+ "browser": "./dist/browser/sunken-panel.js",
226
+ "import": "./dist/sunken-panel.js"
227
+ },
120
228
  "./segmented-control": {
121
229
  "types": "./dist/segmented-control.d.ts",
122
230
  "browser": "./dist/browser/segmented-control.js",
@@ -149,11 +257,6 @@
149
257
  "browser": "./dist/browser/empty-state.js",
150
258
  "import": "./dist/empty-state.js"
151
259
  },
152
- "./dialog-header": {
153
- "types": "./dist/dialog-header.d.ts",
154
- "browser": "./dist/browser/dialog-header.js",
155
- "import": "./dist/dialog-header.js"
156
- },
157
260
  "./value-table": {
158
261
  "types": "./dist/value-table.d.ts",
159
262
  "browser": "./dist/browser/value-table.js",
@@ -171,21 +274,33 @@
171
274
  "./disclosure-arrow.css": "./dist/styles/disclosure-arrow.css",
172
275
  "./toolbar.css": "./dist/styles/toolbar.css",
173
276
  "./toolbar-control-group.css": "./dist/styles/toolbar-control-group.css",
277
+ "./surface-scaffold.css": "./dist/styles/surface-scaffold.css",
278
+ "./floating-toolbar.css": "./dist/styles/floating-toolbar.css",
174
279
  "./toolbar-text.css": "./dist/styles/toolbar-text.css",
175
- "./menu-action-row.css": "./dist/styles/menu-action-row.css",
176
- "./menu-item.css": "./dist/styles/menu-item.css",
177
- "./menu-header.css": "./dist/styles/menu-header.css",
280
+ "./list.css": "./dist/styles/list.css",
281
+ "./list-action-row.css": "./dist/styles/list-action-row.css",
282
+ "./list-item.css": "./dist/styles/list-item.css",
283
+ "./list-header.css": "./dist/styles/list-header.css",
284
+ "./list-inset-control.css": "./dist/styles/list-inset-control.css",
285
+ "./list-inset-text.css": "./dist/styles/list-inset-text.css",
178
286
  "./resizable-region.css": "./dist/styles/resizable-region.css",
179
287
  "./app-tab.css": "./dist/styles/app-tab.css",
288
+ "./catalog.css": "./dist/styles/catalog.css",
180
289
  "./tab-bar.css": "./dist/styles/tab-bar.css",
181
- "./page-header.css": "./dist/styles/page-header.css",
290
+ "./nav-stack.css": "./dist/styles/nav-stack.css",
291
+ "./split-view.css": "./dist/styles/split-view.css",
292
+ "./pane.css": "./dist/styles/pane.css",
293
+ "./workbench.css": "./dist/styles/workbench.css",
294
+ "./collapsible-panel.css": "./dist/styles/collapsible-panel.css",
295
+ "./tab-scaffold.css": "./dist/styles/tab-scaffold.css",
182
296
  "./loading-spinner.css": "./dist/styles/loading-spinner.css",
183
297
  "./select.css": "./dist/styles/select.css",
298
+ "./skeleton.css": "./dist/styles/skeleton.css",
299
+ "./sunken-panel.css": "./dist/styles/sunken-panel.css",
184
300
  "./segmented-control.css": "./dist/styles/segmented-control.css",
185
301
  "./token-search-field.css": "./dist/styles/token-search-field.css",
186
302
  "./state-banner.css": "./dist/styles/state-banner.css",
187
303
  "./empty-state.css": "./dist/styles/empty-state.css",
188
- "./dialog-header.css": "./dist/styles/dialog-header.css",
189
304
  "./value-table.css": "./dist/styles/value-table.css",
190
305
  "./ai/*": "./ai/*",
191
306
  "./docs/*": "./docs/*"
@@ -193,6 +308,10 @@
193
308
  "files": [
194
309
  "dist",
195
310
  "ai",
311
+ "analyzer",
312
+ "doctor",
313
+ "evaluator",
314
+ "traversal-exclusions.mjs",
196
315
  "docs",
197
316
  "ux-demo/recipes",
198
317
  "llms.txt",
@@ -204,39 +323,62 @@
204
323
  "dev": "npm run build && vite --config ux-demo/vite.config.ts",
205
324
  "demo:build": "npm run build && vite build --config ux-demo/vite.config.ts && node scripts/check-demo-bundle.mjs",
206
325
  "demo:serve": "vite preview --config ux-demo/vite.config.ts",
326
+ "format": "prettier --write . --ignore-unknown",
207
327
  "format:css": "prettier --write \"src/**/*.css\" \"ux-demo/**/*.css\"",
208
- "check:format": "prettier --check \"src/**/*.css\" \"ux-demo/**/*.css\"",
209
- "catalog:sync": "node scripts/sync-component-catalog.mjs",
210
- "check:catalog": "node scripts/sync-component-catalog.mjs --check && node scripts/check-component-catalog.mjs",
328
+ "check:format": "prettier --check . --ignore-unknown",
329
+ "catalog:sync": "node scripts/sync-component-catalog.mjs && node scripts/sync-component-catalog-v2.mjs",
330
+ "catalog:v2:sync": "node scripts/sync-component-catalog-v2.mjs",
331
+ "check:catalog": "node scripts/sync-component-catalog.mjs --check && node scripts/sync-component-catalog-v2.mjs --check && node scripts/check-component-catalog.mjs",
332
+ "check:profile": "node scripts/check-application-ui-profile.mjs",
333
+ "check:demo-conformance": "node scripts/check-catalog-demo-conformance.mjs",
211
334
  "check:recipes": "node scripts/check-recipes.mjs",
212
- "check:ai-regressions": "node scripts/check-ai-regressions.mjs && node scripts/audit-ai-regression-results.mjs",
335
+ "check:ai-regressions": "node scripts/check-ai-regressions.mjs && node scripts/audit-ai-regression-results.mjs && node scripts/audit-ai-regression-results-v3.mjs",
213
336
  "check:ai-signatures": "node scripts/sync-ai-public-signatures.mjs --check",
214
337
  "ai:signatures:sync": "npm run build && node scripts/sync-ai-public-signatures.mjs",
215
338
  "ai:regressions:compile": "node scripts/compile-ai-regression-response.mjs",
216
339
  "ai:regressions:prepare": "node scripts/prepare-ai-regression.mjs",
217
340
  "ai:regressions:record": "node scripts/record-ai-regression-run.mjs",
341
+ "ai:regressions:record-v3": "node scripts/record-ai-regression-run-v3.mjs",
342
+ "ai:regressions:replay-v3": "node scripts/replay-ai-regression-run-v3.mjs",
218
343
  "ai:regressions:score": "node scripts/score-ai-regression.mjs",
219
344
  "check:guidance": "node scripts/check-decision-guidance.mjs",
220
- "lint": "eslint src tests ux-demo docs/examples --max-warnings 0",
345
+ "lint:eslint": "eslint src tests ux-demo docs/examples --max-warnings 0",
346
+ "lint": "npm run lint:eslint && npm run check:format",
221
347
  "typecheck": "node node_modules/typescript7/bin/tsc --noEmit",
222
- "test": "npm run test:unit && npm run test:bundle",
348
+ "test": "npm run test:unit && npm run test:bundle && npm run test:analyzer && npm run test:doctor && npm run test:evaluator",
223
349
  "test:unit": "vitest run tests/unit --coverage",
224
350
  "test:bundle": "npm run build && vitest run tests/bundle",
225
- "test:consumer-types": "npm run build && node node_modules/typescript7/bin/tsc -p tests/consumer-types/webawesome/tsconfig.json",
351
+ "test:analyzer": "vitest run tests/integration/ui-analyzer-downstream.test.ts",
352
+ "test:doctor": "vitest run tests/unit/ui-doctor.test.ts tests/integration/ui-doctor-downstream.test.ts",
353
+ "test:evaluator": "vitest run tests/unit/ui-evaluator.test.ts tests/integration/ui-evaluator-downstream.test.ts",
354
+ "test:contract-types:source": "node node_modules/typescript7/bin/tsc -p tests/consumer-types/contracts/tsconfig.source.json",
355
+ "test:contract-types:packed": "node scripts/check-packed-type-contracts.mjs",
356
+ "test:consumer-types": "npm run test:contract-types:source && npm run build && node node_modules/typescript7/bin/tsc -p tests/consumer-types/webawesome/tsconfig.json && npm run test:contract-types:packed",
226
357
  "test:e2e": "npm run demo:build && playwright test",
227
- "check": "npm run check:format && npm run check:catalog && npm run check:recipes && npm run check:guidance && npm run check:ai-regressions && npm run lint && npm run typecheck && npm test && npm run test:consumer-types && npm run check:ai-signatures && npm run demo:build && npm pack --dry-run",
228
- "prepublishOnly": "npm run check"
358
+ "check": "npm run check:catalog && npm run check:profile && npm run check:demo-conformance && npm run check:recipes && npm run check:guidance && npm run check:ai-regressions && npm run lint && npm run typecheck && npm test && npm run test:consumer-types && npm run check:ai-signatures && npm run demo:build && npm run check:design-templates && npm pack --dry-run",
359
+ "prepublishOnly": "npm run check",
360
+ "check:design-templates": "node scripts/check-design-templates.mjs",
361
+ "check:design-templates:drift": "node scripts/check-design-templates-drift.mjs",
362
+ "design-templates:build": "node scripts/build-design-templates.mjs"
229
363
  },
230
364
  "peerDependencies": {
231
365
  "@awesome.me/webawesome": "^3.12.0",
232
366
  "kerfjs": "^5.0.0-0",
233
- "lucide": "^1.43.0"
367
+ "lucide": "^1.43.0",
368
+ "playwright": "^1.63.0"
234
369
  },
235
370
  "peerDependenciesMeta": {
236
371
  "@awesome.me/webawesome": {
237
372
  "optional": true
373
+ },
374
+ "playwright": {
375
+ "optional": true
238
376
  }
239
377
  },
378
+ "dependencies": {
379
+ "postcss": "^8.5.28",
380
+ "typescript": "^6.0.3"
381
+ },
240
382
  "devDependencies": {
241
383
  "@awesome.me/webawesome": "3.12.0",
242
384
  "@eslint/js": "^10.0.1",
@@ -245,6 +387,7 @@
245
387
  "@typescript-eslint/eslint-plugin": "^8.65.0",
246
388
  "@typescript-eslint/parser": "^8.65.0",
247
389
  "@vitest/coverage-v8": "4.1.11",
390
+ "domotion-svg": "^0.30.1",
248
391
  "esbuild": "^0.25.0",
249
392
  "eslint": "^10.8.0",
250
393
  "eslint-plugin-simple-import-sort": "^12.1.1",
@@ -0,0 +1,27 @@
1
+ import { relative, sep } from 'node:path';
2
+
3
+ export const UI_TRAVERSAL_IGNORED_DIRECTORY_NAMES = Object.freeze([
4
+ '.git',
5
+ '.kerf-cache',
6
+ 'coverage',
7
+ 'dist',
8
+ 'kerf-ui-evidence',
9
+ 'node_modules',
10
+ ]);
11
+ const ignoredDirectoryNames = new Set(UI_TRAVERSAL_IGNORED_DIRECTORY_NAMES);
12
+
13
+ export const UI_TRAVERSAL_ESLINT_IGNORES = Object.freeze([
14
+ ...UI_TRAVERSAL_IGNORED_DIRECTORY_NAMES.map((name) => `**/${name}/**`),
15
+ '**/.claude/worktrees/**',
16
+ ]);
17
+
18
+ export function isUiTraversalExcluded(root, candidate) {
19
+ const segments = relative(root, candidate).split(sep);
20
+ return (
21
+ segments.some((segment) => ignoredDirectoryNames.has(segment)) ||
22
+ segments.some(
23
+ (segment, index) =>
24
+ segment === '.claude' && segments[index + 1] === 'worktrees',
25
+ )
26
+ );
27
+ }
@@ -1,10 +1,9 @@
1
1
  import '@kerfjs/ui/layout.css';
2
2
  import './recipes.css';
3
3
 
4
+ import { ListHeader } from '@kerfjs/ui/list-header';
5
+ import { ListItem } from '@kerfjs/ui/list-item';
4
6
  import { LucideIcon } from '@kerfjs/ui/lucide-icon';
5
- import { MenuHeader } from '@kerfjs/ui/menu-header';
6
- import { MenuItem } from '@kerfjs/ui/menu-item';
7
- import { PageHeader } from '@kerfjs/ui/page-header';
8
7
  import { ResizableRegion } from '@kerfjs/ui/resizable-region';
9
8
  import { Toolbar } from '@kerfjs/ui/toolbar';
10
9
  import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
@@ -19,14 +18,224 @@ export const createRecipe: RecipeFactory = (announce) => {
19
18
  const selected = signal('inbox');
20
19
  const navigationSize = signal(224);
21
20
  const inspectorSize = signal(240);
22
- const responsivePane = signal<'content' | 'navigation' | 'inspector'>('content');
23
- const render = () => <section class="kui-recipe recipe-shell kui-recipe__surface kui-layout" data-recipe="recipe-app-shell" data-responsive-pane={responsivePane.value}>
24
- <Toolbar label="Atlas workspace" leading={<ToolbarControlGroup appearance="borderless" single><ToolbarText text="Atlas" /></ToolbarControlGroup>} trailing={<div class="recipe-shell__toolbar-actions"><ToolbarControlGroup className="recipe-shell__responsive-controls" appearance="borderless" label="Workspace panes"><button type="button" aria-label="Show navigation" aria-controls="recipe-shell-navigation" aria-pressed={String(responsivePane.value === 'navigation')} data-action="recipe-action" data-recipe-command="show-navigation"><LucideIcon icon={Folder} name="folder" /></button><button type="button" aria-label="Show content" aria-controls="recipe-shell-content" aria-pressed={String(responsivePane.value === 'content')} data-action="recipe-action" data-recipe-command="show-content"><LucideIcon icon={Inbox} name="inbox" /></button><button type="button" aria-label="Show inspector" aria-controls="recipe-shell-inspector" aria-pressed={String(responsivePane.value === 'inspector')} data-action="recipe-action" data-recipe-command="show-inspector"><LucideIcon icon={Settings} name="settings" /></button></ToolbarControlGroup><ToolbarControlGroup appearance="borderless" label="Workspace controls"><button type="button" aria-label="Notifications" data-action="recipe-action" data-recipe-command="notify"><LucideIcon icon={Bell} name="bell" /></button><button type="button" aria-label="Settings" data-action="recipe-action" data-recipe-command="settings"><LucideIcon icon={Settings} name="settings" /></button></ToolbarControlGroup></div>} />
25
- <div class="recipe-shell__body">
26
- <div id="recipe-shell-navigation" class="recipe-shell__nav-region"><ResizableRegion id="recipe-navigation" label="Navigation" size={navigationSize.value} min={180} max={320}><aside class="recipe-shell__nav kui-pane"><MenuHeader label="Workspace" /><nav class="recipe-shell__nav-list kui-pane__content kui-content" aria-label="Workspace"><section><MenuItem action="recipe-action" itemId="inbox" label="Inbox" icon={<LucideIcon icon={Inbox} name="inbox" />} selected={selected.value === 'inbox'} /><MenuItem action="recipe-action" itemId="projects" label="Projects with a deliberately wrapping title" icon={<LucideIcon icon={Folder} name="folder" />} selected={selected.value === 'projects'} multiline /></section></nav></aside></ResizableRegion></div>
27
- <main id="recipe-shell-content" class="recipe-shell__main kui-pane"><PageHeader title={selected.value === 'inbox' ? 'Inbox triage' : 'Active projects'} action={<button class="kui-recipe__button" data-primary="true" type="button" data-action="recipe-action" data-recipe-command="new">New task</button>} /><div class="recipe-shell__main-body kui-pane__content kui-content"><p class="kui-recipe__ownership kui-content-item">Recipe owns pane geometry and one scroll owner per pane. The app owns routing, data, pane visibility, sizes, and persistence.</p><div class="recipe-shell__cards">{['Release accessibility audit', 'Prepare tablet navigation', 'Review stale-data states', 'Confirm package boundaries'].map((title) => <article class="recipe-shell__card kui-content-item"><strong>{title}</strong><p class="kui-recipe__muted">Assigned to the interface systems team · due this week</p></article>)}</div></div></main>
28
- <div id="recipe-shell-inspector" class="recipe-shell__inspector-region"><ResizableRegion id="recipe-inspector" label="Inspector" size={inspectorSize.value} min={200} max={360} edge="start"><aside class="recipe-shell__inspector kui-pane"><PageHeader title="Inspector" /><div class="recipe-shell__inspector-body kui-pane__content kui-content"><ValueTable label="Selected task"><ValueTableRow label="Status" value="In review" /><ValueTableRow label="Owner" value="Mara Chen" /><ValueTableRow label="Priority" value="High" /></ValueTable></div></aside></ResizableRegion></div>
29
- </div>
30
- </section>;
31
- return { render, action(command, element) { const pane = command.match(/^show-(navigation|content|inspector)$/)?.[1] as typeof responsivePane.value | undefined; if (pane) responsivePane.value = pane; const id = element.dataset.itemId; if (id) selected.value = id; announce(id ? `Opened ${id}` : pane ? `Showing ${pane}` : command === 'new' ? 'New task requested' : `${command} requested`); }, resize(id, size) { if (id === 'recipe-navigation') navigationSize.value = size; if (id === 'recipe-inspector') inspectorSize.value = size; announce(`${id} resized to ${size}px`); } };
21
+ const responsivePane = signal<'content' | 'navigation' | 'inspector'>(
22
+ 'content',
23
+ );
24
+ const render = () => (
25
+ <section
26
+ class="kui-recipe recipe-shell kui-recipe__surface kui-layout"
27
+ data-recipe="recipe-app-shell"
28
+ data-responsive-pane={responsivePane.value}
29
+ >
30
+ <Toolbar
31
+ label="Atlas workspace"
32
+ leading={<ToolbarText text="Atlas" />}
33
+ trailing={
34
+ <div class="recipe-shell__toolbar-actions">
35
+ <ToolbarControlGroup
36
+ className="recipe-shell__responsive-controls"
37
+ appearance="borderless"
38
+ label="Workspace panes"
39
+ >
40
+ <button
41
+ type="button"
42
+ aria-label="Show navigation"
43
+ aria-controls="recipe-shell-navigation"
44
+ aria-pressed={String(responsivePane.value === 'navigation')}
45
+ data-action="recipe-action"
46
+ data-recipe-command="show-navigation"
47
+ >
48
+ <LucideIcon icon={Folder} name="folder" />
49
+ </button>
50
+ <button
51
+ type="button"
52
+ aria-label="Show content"
53
+ aria-controls="recipe-shell-content"
54
+ aria-pressed={String(responsivePane.value === 'content')}
55
+ data-action="recipe-action"
56
+ data-recipe-command="show-content"
57
+ >
58
+ <LucideIcon icon={Inbox} name="inbox" />
59
+ </button>
60
+ <button
61
+ type="button"
62
+ aria-label="Show inspector"
63
+ aria-controls="recipe-shell-inspector"
64
+ aria-pressed={String(responsivePane.value === 'inspector')}
65
+ data-action="recipe-action"
66
+ data-recipe-command="show-inspector"
67
+ >
68
+ <LucideIcon icon={Settings} name="settings" />
69
+ </button>
70
+ </ToolbarControlGroup>
71
+ <ToolbarControlGroup
72
+ appearance="borderless"
73
+ label="Workspace controls"
74
+ >
75
+ <button
76
+ type="button"
77
+ aria-label="Notifications"
78
+ data-action="recipe-action"
79
+ data-recipe-command="notify"
80
+ >
81
+ <LucideIcon icon={Bell} name="bell" />
82
+ </button>
83
+ <button
84
+ type="button"
85
+ aria-label="Settings"
86
+ data-action="recipe-action"
87
+ data-recipe-command="settings"
88
+ >
89
+ <LucideIcon icon={Settings} name="settings" />
90
+ </button>
91
+ </ToolbarControlGroup>
92
+ </div>
93
+ }
94
+ />
95
+ <div class="recipe-shell__body">
96
+ <div id="recipe-shell-navigation" class="recipe-shell__nav-region">
97
+ <ResizableRegion
98
+ id="recipe-navigation"
99
+ label="Navigation"
100
+ size={navigationSize.value}
101
+ min={180}
102
+ max={320}
103
+ >
104
+ <aside class="recipe-shell__nav kui-pane">
105
+ <ListHeader label="Workspace" />
106
+ <nav
107
+ class="recipe-shell__nav-list kui-pane__content kui-content"
108
+ aria-label="Workspace"
109
+ >
110
+ <section>
111
+ <ListItem
112
+ action="recipe-action"
113
+ itemId="inbox"
114
+ label="Inbox"
115
+ icon={<LucideIcon icon={Inbox} name="inbox" />}
116
+ selected={selected.value === 'inbox'}
117
+ />
118
+ <ListItem
119
+ action="recipe-action"
120
+ itemId="projects"
121
+ label="Projects with a deliberately wrapping title"
122
+ icon={<LucideIcon icon={Folder} name="folder" />}
123
+ selected={selected.value === 'projects'}
124
+ multiline
125
+ />
126
+ </section>
127
+ </nav>
128
+ </aside>
129
+ </ResizableRegion>
130
+ </div>
131
+ <main id="recipe-shell-content" class="recipe-shell__main kui-pane">
132
+ <Toolbar
133
+ label="Current workspace view"
134
+ dividerSides=""
135
+ leading={
136
+ <ToolbarText
137
+ text={
138
+ selected.value === 'inbox'
139
+ ? 'Inbox triage'
140
+ : 'Active projects'
141
+ }
142
+ size="xlarge"
143
+ id="recipe-shell-main-title"
144
+ />
145
+ }
146
+ trailing={
147
+ <ToolbarControlGroup appearance="borderless" single>
148
+ <button
149
+ class="kui-recipe__button"
150
+ data-primary="true"
151
+ type="button"
152
+ data-action="recipe-action"
153
+ data-recipe-command="new"
154
+ >
155
+ New task
156
+ </button>
157
+ </ToolbarControlGroup>
158
+ }
159
+ />
160
+ <div class="recipe-shell__main-body kui-pane__content kui-content">
161
+ <p class="kui-recipe__ownership kui-content-item">
162
+ Recipe owns pane geometry and one scroll owner per pane. The app
163
+ owns routing, data, pane visibility, sizes, and persistence.
164
+ </p>
165
+ <div class="recipe-shell__cards">
166
+ {[
167
+ 'Release accessibility audit',
168
+ 'Prepare tablet navigation',
169
+ 'Review stale-data states',
170
+ 'Confirm package boundaries',
171
+ ].map((title) => (
172
+ <article class="recipe-shell__card kui-content-item">
173
+ <strong>{title}</strong>
174
+ <p class="kui-recipe__muted">
175
+ Assigned to the interface systems team · due this week
176
+ </p>
177
+ </article>
178
+ ))}
179
+ </div>
180
+ </div>
181
+ </main>
182
+ <div id="recipe-shell-inspector" class="recipe-shell__inspector-region">
183
+ <ResizableRegion
184
+ id="recipe-inspector"
185
+ label="Inspector"
186
+ size={inspectorSize.value}
187
+ min={200}
188
+ max={360}
189
+ edge="start"
190
+ >
191
+ <aside class="recipe-shell__inspector kui-pane">
192
+ <Toolbar
193
+ label="Inspector"
194
+ dividerSides=""
195
+ leading={
196
+ <ToolbarText
197
+ text="Inspector"
198
+ size="xlarge"
199
+ id="recipe-shell-inspector-title"
200
+ />
201
+ }
202
+ />
203
+ <div class="recipe-shell__inspector-body kui-pane__content kui-content">
204
+ <ValueTable label="Selected task">
205
+ <ValueTableRow label="Status" value="In review" />
206
+ <ValueTableRow label="Owner" value="Mara Chen" />
207
+ <ValueTableRow label="Priority" value="High" />
208
+ </ValueTable>
209
+ </div>
210
+ </aside>
211
+ </ResizableRegion>
212
+ </div>
213
+ </div>
214
+ </section>
215
+ );
216
+ return {
217
+ render,
218
+ action(command, element) {
219
+ const pane = command.match(
220
+ /^show-(navigation|content|inspector)$/,
221
+ )?.[1] as typeof responsivePane.value | undefined;
222
+ if (pane) responsivePane.value = pane;
223
+ const id = element.dataset.itemId;
224
+ if (id) selected.value = id;
225
+ announce(
226
+ id
227
+ ? `Opened ${id}`
228
+ : pane
229
+ ? `Showing ${pane}`
230
+ : command === 'new'
231
+ ? 'New task requested'
232
+ : `${command} requested`,
233
+ );
234
+ },
235
+ resize(id, size) {
236
+ if (id === 'recipe-navigation') navigationSize.value = size;
237
+ if (id === 'recipe-inspector') inspectorSize.value = size;
238
+ announce(`${id} resized to ${size}px`);
239
+ },
240
+ };
32
241
  };