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

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
@@ -1,9 +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
7
  import { Toolbar } from '@kerfjs/ui/toolbar';
8
8
  import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
9
9
  import { signal } from 'kerfjs';
@@ -14,13 +14,124 @@ import type { RecipeFactory } from './types.js';
14
14
  export const createRecipe: RecipeFactory = (announce) => {
15
15
  const selected = signal('inbox');
16
16
  const expanded = signal(true);
17
- const render = () => <aside class="kui-recipe recipe-sidebar kui-recipe__surface kui-pane" data-recipe="recipe-navigation-sidebar">
18
- <div class="recipe-sidebar__body kui-pane__content kui-content">
19
- <section><MenuHeader label="Workspace" count={3} countLabel="3 workspaces" action="recipe-action" actionLabel="Add workspace item" actionIcon={<LucideIcon icon={Plus} name="plus" />} /><MenuItem action="recipe-action" itemId="inbox" label="Inbox" icon={<LucideIcon icon={Inbox} name="inbox" />} trailing={<span>12</span>} selected={selected.value === 'inbox'} /><MenuItem action="recipe-action" itemId="shared" label="Shared with me" icon={<LucideIcon icon={Users} name="users" />} selected={selected.value === 'shared'} /><MenuItem action="recipe-action" itemId="drafts" label="Drafts without an icon" selected={selected.value === 'drafts'} /></section>
20
- <section><MenuHeader label="Projects" toggle action="recipe-action" expanded={expanded.value} />{expanded.value && <><MenuItem action="recipe-action" itemId="design" label="Design system rollout across desktop and tablet" icon={<LucideIcon icon={Folder} name="folder" />} selected={selected.value === 'design'} multiline /><MenuItem action="recipe-action" itemId="archive" label="Archived" disabled title="Available to administrators" /><div class="kui-content-item"><strong>Quarterly goal</strong><p class="kui-recipe__muted">Ship accessible navigation patterns to every workspace.</p></div></>}</section>
21
- <p class="kui-recipe__ownership kui-content-item">The recipe owns pane, content-item, and toolbar geometry. The app owns routes, permissions, labels, and disclosure state.</p>
22
- </div>
23
- <footer class="recipe-sidebar__footer kui-pane__footer"><Toolbar label="Sidebar actions" divider={false} leading={<ToolbarControlGroup appearance="borderless" single><button type="button" aria-label="Add project" data-action="recipe-action" data-recipe-command="add"><LucideIcon icon={Plus} name="plus" /></button></ToolbarControlGroup>} trailing={<ToolbarControlGroup appearance="borderless" single><button type="button" aria-label="Workspace settings" data-action="recipe-action" data-recipe-command="settings"><LucideIcon icon={Settings} name="settings" /></button></ToolbarControlGroup>} /></footer>
24
- </aside>;
25
- return { render, action(command, element) { if (element.matches('.kui-menu-header__toggle')) { expanded.value = !expanded.value; announce(expanded.value ? 'Projects expanded' : 'Projects collapsed'); return; } const id = element.dataset.itemId; if (id) selected.value = id; announce(id ? `Selected ${id}` : `${command} requested`); } };
17
+ const render = () => (
18
+ <aside
19
+ class="kui-recipe recipe-sidebar kui-recipe__surface kui-pane"
20
+ data-recipe="recipe-navigation-sidebar"
21
+ >
22
+ <div class="recipe-sidebar__body kui-pane__content kui-content">
23
+ <section>
24
+ <ListHeader
25
+ label="Workspace"
26
+ count={3}
27
+ countLabel="3 workspaces"
28
+ action="recipe-action"
29
+ actionLabel="Add workspace item"
30
+ actionIcon={<LucideIcon icon={Plus} name="plus" />}
31
+ />
32
+ <ListItem
33
+ action="recipe-action"
34
+ itemId="inbox"
35
+ label="Inbox"
36
+ icon={<LucideIcon icon={Inbox} name="inbox" />}
37
+ trailing={<span>12</span>}
38
+ selected={selected.value === 'inbox'}
39
+ />
40
+ <ListItem
41
+ action="recipe-action"
42
+ itemId="shared"
43
+ label="Shared with me"
44
+ icon={<LucideIcon icon={Users} name="users" />}
45
+ selected={selected.value === 'shared'}
46
+ />
47
+ <ListItem
48
+ action="recipe-action"
49
+ itemId="drafts"
50
+ label="Drafts without an icon"
51
+ selected={selected.value === 'drafts'}
52
+ />
53
+ </section>
54
+ <section>
55
+ <ListHeader
56
+ label="Projects"
57
+ toggle
58
+ action="recipe-action"
59
+ expanded={expanded.value}
60
+ />
61
+ {expanded.value && (
62
+ <>
63
+ <ListItem
64
+ action="recipe-action"
65
+ itemId="design"
66
+ label="Design system rollout across desktop and tablet"
67
+ icon={<LucideIcon icon={Folder} name="folder" />}
68
+ selected={selected.value === 'design'}
69
+ multiline
70
+ />
71
+ <ListItem
72
+ action="recipe-action"
73
+ itemId="archive"
74
+ label="Archived"
75
+ disabled
76
+ title="Available to administrators"
77
+ />
78
+ <div class="kui-content-item">
79
+ <strong>Quarterly goal</strong>
80
+ <p class="kui-recipe__muted">
81
+ Ship accessible navigation patterns to every workspace.
82
+ </p>
83
+ </div>
84
+ </>
85
+ )}
86
+ </section>
87
+ <p class="kui-recipe__ownership kui-content-item">
88
+ The recipe owns pane, content-item, and toolbar geometry. The app owns
89
+ routes, permissions, labels, and disclosure state.
90
+ </p>
91
+ </div>
92
+ <footer class="recipe-sidebar__footer kui-pane__footer">
93
+ <Toolbar
94
+ label="Sidebar actions"
95
+ dividerSides=""
96
+ leading={
97
+ <ToolbarControlGroup appearance="borderless" single>
98
+ <button
99
+ type="button"
100
+ aria-label="Add project"
101
+ data-action="recipe-action"
102
+ data-recipe-command="add"
103
+ >
104
+ <LucideIcon icon={Plus} name="plus" />
105
+ </button>
106
+ </ToolbarControlGroup>
107
+ }
108
+ trailing={
109
+ <ToolbarControlGroup appearance="borderless" single>
110
+ <button
111
+ type="button"
112
+ aria-label="Workspace settings"
113
+ data-action="recipe-action"
114
+ data-recipe-command="settings"
115
+ >
116
+ <LucideIcon icon={Settings} name="settings" />
117
+ </button>
118
+ </ToolbarControlGroup>
119
+ }
120
+ />
121
+ </footer>
122
+ </aside>
123
+ );
124
+ return {
125
+ render,
126
+ action(command, element) {
127
+ if (element.matches('.kui-list-header__toggle')) {
128
+ expanded.value = !expanded.value;
129
+ announce(expanded.value ? 'Projects expanded' : 'Projects collapsed');
130
+ return;
131
+ }
132
+ const id = element.dataset.itemId;
133
+ if (id) selected.value = id;
134
+ announce(id ? `Selected ${id}` : `${command} requested`);
135
+ },
136
+ };
26
137
  };
@@ -0,0 +1,118 @@
1
+ import '@kerfjs/ui/layout.css';
2
+ import '@kerfjs/ui/nav-stack.css';
3
+ import '@kerfjs/ui/toolbar-text.css';
4
+ import './recipes.css';
5
+
6
+ import { ListHeader } from '@kerfjs/ui/list-header';
7
+ import { ListItem } from '@kerfjs/ui/list-item';
8
+ import { LucideIcon } from '@kerfjs/ui/lucide-icon';
9
+ import { NavStack, type NavStackView } from '@kerfjs/ui/nav-stack';
10
+ import { signal } from 'kerfjs';
11
+ import { ChevronRight, FileText, Folder } from 'lucide';
12
+
13
+ import type { RecipeFactory } from './types.js';
14
+
15
+ interface LibraryItem {
16
+ id: string;
17
+ label: string;
18
+ detail: string;
19
+ }
20
+
21
+ const ITEMS: LibraryItem[] = [
22
+ {
23
+ id: 'tokens',
24
+ label: 'Design tokens',
25
+ detail:
26
+ 'Semantic color, spacing, and radius scales shared across every surface.',
27
+ },
28
+ {
29
+ id: 'controls',
30
+ label: 'Toolbar controls',
31
+ detail:
32
+ 'Control groups and segmented controls with their hover and pressed contracts.',
33
+ },
34
+ {
35
+ id: 'layouts',
36
+ label: 'App layouts',
37
+ detail:
38
+ 'Navigation stacks, split views, workbench, and bottom-tab scaffolds.',
39
+ },
40
+ ];
41
+
42
+ export const createRecipe: RecipeFactory = (announce) => {
43
+ const listView = (): NavStackView => ({
44
+ key: 'library',
45
+ title: 'Library',
46
+ content: (
47
+ <div class="recipe-navstack__view kui-pane__content kui-content">
48
+ <section>
49
+ <ListHeader label="Components" />
50
+ {ITEMS.map((item) => (
51
+ <ListItem
52
+ action="recipe-action"
53
+ itemId={item.id}
54
+ label={item.label}
55
+ icon={<LucideIcon icon={Folder} name="folder" />}
56
+ trailing={<LucideIcon icon={ChevronRight} name="chevron-right" />}
57
+ />
58
+ ))}
59
+ </section>
60
+ <p class="kui-recipe__ownership kui-content-item">
61
+ The recipe owns the stack as a signal of views and pushes/pops it;
62
+ `NavStack` renders the stack and `wireNavStack` slides the content and
63
+ settles the chrome. The app owns selection, data, and routing.
64
+ </p>
65
+ </div>
66
+ ),
67
+ });
68
+
69
+ const detailView = (item: LibraryItem): NavStackView => ({
70
+ key: item.id,
71
+ title: item.label,
72
+ content: (
73
+ <div class="recipe-navstack__view kui-pane__content kui-content">
74
+ <div class="kui-content-item">
75
+ <LucideIcon icon={FileText} name="file-text" />
76
+ <strong>{item.label}</strong>
77
+ <p class="kui-recipe__muted">{item.detail}</p>
78
+ </div>
79
+ </div>
80
+ ),
81
+ });
82
+
83
+ const views = signal<NavStackView[]>([listView()]);
84
+
85
+ const render = () => (
86
+ <section
87
+ class="kui-recipe recipe-navstack kui-recipe__surface"
88
+ data-recipe="recipe-navigation-stack"
89
+ >
90
+ <div class="recipe-navstack__stage">
91
+ <NavStack
92
+ id="recipe-nav"
93
+ label="Component library"
94
+ views={views.value}
95
+ />
96
+ </div>
97
+ </section>
98
+ );
99
+
100
+ return {
101
+ render,
102
+ action(command, element) {
103
+ if (command === 'nav-back') {
104
+ if (views.value.length > 1) {
105
+ views.value = views.value.slice(0, -1);
106
+ announce('Navigated back');
107
+ }
108
+ return;
109
+ }
110
+ const id = element.dataset.itemId;
111
+ const item = ITEMS.find((candidate) => candidate.id === id);
112
+ if (item) {
113
+ views.value = [...views.value, detailView(item)];
114
+ announce(`Opened ${item.label}`);
115
+ }
116
+ },
117
+ };
118
+ };
@@ -113,27 +113,40 @@
113
113
  .recipe-header__context {
114
114
  margin: 0;
115
115
  }
116
- .recipe-header .kui-page-header__action {
117
- max-width: 100%;
118
- }
119
116
 
120
- .recipe-master-detail {
117
+ .recipe-list-detail {
121
118
  display: grid;
122
- width: min(58rem, 100%);
119
+ width: 100%;
123
120
  min-height: 25rem;
124
121
  grid-template-columns: minmax(13rem, 0.8fr) minmax(18rem, 1.4fr);
125
122
  }
126
- .recipe-master-detail__master {
123
+ .recipe-list-detail__list {
127
124
  border-inline-end: 1px solid var(--kui-color-border);
128
125
  }
129
- .recipe-master-detail__detail {
126
+ .recipe-list-detail__detail {
130
127
  min-width: 0;
128
+ }
129
+ .recipe-list-detail__body {
131
130
  padding-block: var(--kui-layout-item-gap);
132
131
  }
132
+ .recipe-list-detail__title {
133
+ margin-inline: var(--kui-layout-inline-margin, remify(8px));
134
+ }
135
+ .recipe-list-detail__actions {
136
+ margin-inline: var(--kui-layout-inline-margin, remify(8px));
137
+ }
133
138
  .recipe-dialog {
134
139
  --spacing: 0;
135
140
  --width: min(62rem, calc(100vw - 2rem));
136
141
  }
142
+ .kui-recipe__heading-summary {
143
+ min-width: 0;
144
+ margin: 0 var(--kui-layout-inline-margin, remify(8px));
145
+ overflow: hidden;
146
+ color: var(--kui-color-text-quiet);
147
+ text-overflow: ellipsis;
148
+ white-space: nowrap;
149
+ }
137
150
 
138
151
  .recipe-form {
139
152
  width: min(38rem, 100%);
@@ -141,17 +154,24 @@
141
154
  padding-block: var(--kui-layout-item-gap);
142
155
  }
143
156
  .recipe-form__section {
144
- --kui-content-item-border: transparent;
145
- --kui-content-item-background: transparent;
146
157
  display: grid;
158
+ min-width: 0;
159
+ margin-inline: var(--kui-layout-inline-margin, remify(8px));
147
160
  gap: var(--kui-layout-item-gap);
148
161
  }
149
- .recipe-form__introduction > :where(h2, p) {
150
- margin: 0;
151
- }
152
162
  .recipe-form__fields {
153
163
  align-content: start;
154
164
  }
165
+ .recipe-form__fields wa-input::part(form-control-label),
166
+ .recipe-form__fields wa-input::part(hint),
167
+ .recipe-form__fields wa-textarea::part(form-control-label),
168
+ .recipe-form__fields wa-textarea::part(hint),
169
+ .recipe-form__fields .kui-select::part(form-control-label) {
170
+ padding-inline: remify(8px);
171
+ }
172
+ .recipe-form__fields wa-textarea::part(textarea) {
173
+ padding-inline: remify(8px);
174
+ }
155
175
  .recipe-form__footer {
156
176
  align-content: start;
157
177
  }
@@ -190,8 +210,11 @@
190
210
  gap: var(--kui-layout-content-gap);
191
211
  }
192
212
  .recipe-compact-toolbar__guide {
213
+ /* Span the toolbar's full width instead of the 8px content-item inset — under a
214
+ full-bleed toolbar/divider the inset read as the boxes floating too far in. */
193
215
  display: grid;
194
216
  grid-template-columns: repeat(4, minmax(0, 1fr));
217
+ margin-inline: 0;
195
218
  gap: var(--kui-layout-control-gap);
196
219
  }
197
220
  .recipe-compact-toolbar__guide > div {
@@ -240,10 +263,10 @@
240
263
  .recipe-compact-toolbar__guide {
241
264
  grid-template-columns: 1fr 1fr;
242
265
  }
243
- .recipe-master-detail {
266
+ .recipe-list-detail {
244
267
  grid-template-columns: 1fr;
245
268
  }
246
- .recipe-master-detail__master {
269
+ .recipe-list-detail__list {
247
270
  border-inline-end: 0;
248
271
  border-block-end: 1px solid var(--kui-color-border);
249
272
  }
@@ -305,10 +328,6 @@
305
328
  .recipe-compact-toolbar__guide {
306
329
  grid-template-columns: 1fr;
307
330
  }
308
- .recipe-header .kui-page-header {
309
- align-items: flex-start;
310
- flex-direction: column;
311
- }
312
331
  }
313
332
 
314
333
  @media (forced-colors: active) {
@@ -326,3 +345,109 @@
326
345
  transition-duration: 1ms !important;
327
346
  }
328
347
  }
348
+
349
+ .recipe-navstack {
350
+ display: flex;
351
+ width: min(28rem, 100%);
352
+ margin-inline: auto;
353
+ flex-direction: column;
354
+ }
355
+ .recipe-navstack__stage {
356
+ height: 24rem;
357
+ }
358
+ .recipe-navstack__view {
359
+ /* The view is a .kui-content stack whose rows own their 8px margins; add only a
360
+ little block breathing room, not an inline pad that would double-inset them. */
361
+ padding-block: var(--kui-space-2xs);
362
+ }
363
+
364
+ .recipe-inspector {
365
+ width: min(remify(560px), 100%);
366
+ }
367
+
368
+ /* The bare Select + SegmentedControl carry no content-item geometry, so inset
369
+ them to the shared inline margin to line up with the ValueTable / list / banner
370
+ content-items, and group the two related controls closer than the 24px
371
+ between-region content gap. */
372
+ .recipe-inspector__controls {
373
+ display: flex;
374
+ min-width: 0;
375
+ flex-direction: column;
376
+ margin-inline: var(--kui-layout-inline-margin, remify(8px));
377
+ gap: var(--kui-space-s);
378
+ }
379
+
380
+ /* Collapsible-sidebar recipe: a mini app frame with a left rail (CollapsiblePanel)
381
+ full-height at the leading edge, the main pane, and a bottom drawer under it.
382
+ `contain: paint` bounds the wire's compact overlay (a viewport-`fixed` panel +
383
+ backdrop) to this frame so the embedded demo does not cover the whole catalog. */
384
+ .recipe-collapsible-sidebar {
385
+ display: grid;
386
+ height: min(34rem, 70vh);
387
+ contain: paint;
388
+ grid-template-areas:
389
+ "rail main"
390
+ "rail drawer";
391
+ grid-template-columns: auto minmax(0, 1fr);
392
+ grid-template-rows: minmax(0, 1fr) auto;
393
+ }
394
+ .recipe-collapsible-sidebar__rail {
395
+ grid-area: rail;
396
+ display: flex;
397
+ min-height: 0;
398
+ flex-direction: column;
399
+ }
400
+ .recipe-collapsible-sidebar__rail-head {
401
+ display: flex;
402
+ align-items: center;
403
+ justify-content: space-between;
404
+ padding: var(--kui-space-2xs) var(--kui-layout-inline-margin, remify(8px));
405
+ border-block-end: 1px solid var(--kui-color-border);
406
+ }
407
+ .recipe-collapsible-sidebar__nav {
408
+ min-height: 0;
409
+ }
410
+ .recipe-collapsible-sidebar__main {
411
+ display: grid;
412
+ grid-area: main;
413
+ min-width: 0;
414
+ min-height: 0;
415
+ grid-template-rows: auto minmax(0, 1fr);
416
+ background: var(--kui-color-surface-lowered);
417
+ }
418
+ .recipe-collapsible-sidebar__body {
419
+ min-height: 0;
420
+ }
421
+ .recipe-collapsible-sidebar__card strong {
422
+ display: block;
423
+ }
424
+ .recipe-collapsible-sidebar__drawer {
425
+ grid-area: drawer;
426
+ display: flex;
427
+ min-height: 0;
428
+ flex-direction: column;
429
+ }
430
+ .recipe-collapsible-sidebar__drawer-body {
431
+ min-height: 0;
432
+ }
433
+ .recipe-collapsible-sidebar__log {
434
+ display: flex;
435
+ min-width: 0;
436
+ flex-direction: column;
437
+ margin: 0;
438
+ margin-inline: var(--kui-layout-inline-margin, remify(8px));
439
+ padding: 0;
440
+ list-style: none;
441
+ gap: var(--kui-space-xs);
442
+ }
443
+ .recipe-collapsible-sidebar__log li {
444
+ display: flex;
445
+ align-items: center;
446
+ color: var(--kui-color-text-quiet);
447
+ font-size: var(--kui-font-s);
448
+ gap: var(--kui-space-xs);
449
+ }
450
+ .recipe-collapsible-sidebar__log svg {
451
+ width: remify(16px);
452
+ height: remify(16px);
453
+ }
@@ -6,6 +6,14 @@ export interface RecipeController {
6
6
  change?(element: HTMLElement): void;
7
7
  afterHide?(element: HTMLElement): void;
8
8
  resize?(id: string, size: number): void;
9
+ /**
10
+ * Install any imperative wiring the recipe owns on its mounted root (e.g.
11
+ * `wireSidebar` for a collapsible rail/drawer), returning a disposer. The
12
+ * application boundary calls it once per mount and disposes it on teardown.
13
+ */
14
+ wire?(root: HTMLElement): () => void;
9
15
  }
10
16
 
11
- export type RecipeFactory = (announce: (message: string) => void) => RecipeController;
17
+ export type RecipeFactory = (
18
+ announce: (message: string) => void,
19
+ ) => RecipeController;
@@ -1,12 +1,77 @@
1
1
  import '@kerfjs/ui/layout.css';
2
2
  import './recipes.css';
3
3
 
4
- import { PageHeader } from '@kerfjs/ui/page-header';
5
4
  import { StateBanner } from '@kerfjs/ui/state-banner';
5
+ import { Toolbar } from '@kerfjs/ui/toolbar';
6
+ import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
7
+ import { ToolbarText } from '@kerfjs/ui/toolbar-text';
6
8
 
7
9
  import type { RecipeFactory } from './types.js';
8
10
 
9
11
  export const createRecipe: RecipeFactory = (announce) => ({
10
- render: () => <section class="kui-recipe recipe-header kui-recipe__surface kui-content" data-recipe="recipe-workspace-header"><p class="recipe-header__context kui-inline-metadata kui-content-item"><span>Northstar workspace</span><span>·</span><span>Product planning</span></p><PageHeader title="Accessibility readiness and responsive navigation rollout" action={<div class="kui-control-cluster"><button class="kui-recipe__button" type="button" data-action="recipe-action" data-recipe-command="share">Share</button><button class="kui-recipe__button" type="button" data-action="recipe-action" data-recipe-command="more">More actions</button><button class="kui-recipe__button" data-primary="true" type="button" data-action="recipe-action" data-recipe-command="publish">Publish update</button></div>} /><StateBanner title="Ready for review" detail="All required checks passed 18 minutes ago." tone="success" /><p class="kui-recipe__ownership kui-content-item">The recipe owns page hierarchy and action relocation. The app owns authorization, command behavior, breadcrumbs, and product copy.</p></section>,
11
- action(command) { announce(`${command} requested`); },
12
+ render: () => (
13
+ <section
14
+ class="kui-recipe recipe-header kui-recipe__surface kui-content"
15
+ data-recipe="recipe-workspace-header"
16
+ >
17
+ <p class="recipe-header__context kui-inline-metadata kui-content-item">
18
+ <span>Northstar workspace</span>
19
+ <span>·</span>
20
+ <span>Product planning</span>
21
+ </p>
22
+ <Toolbar
23
+ label="Workspace heading"
24
+ dividerSides=""
25
+ leading={
26
+ <ToolbarText
27
+ text="Accessibility readiness and responsive navigation rollout"
28
+ size="xlarge"
29
+ id="recipe-workspace-title"
30
+ headingLevel={1}
31
+ />
32
+ }
33
+ trailing={
34
+ <ToolbarControlGroup appearance="borderless">
35
+ <button
36
+ class="kui-recipe__button"
37
+ type="button"
38
+ data-action="recipe-action"
39
+ data-recipe-command="share"
40
+ >
41
+ Share
42
+ </button>
43
+ <button
44
+ class="kui-recipe__button"
45
+ type="button"
46
+ data-action="recipe-action"
47
+ data-recipe-command="more"
48
+ >
49
+ More actions
50
+ </button>
51
+ <button
52
+ class="kui-recipe__button"
53
+ data-primary="true"
54
+ type="button"
55
+ data-action="recipe-action"
56
+ data-recipe-command="publish"
57
+ >
58
+ Publish update
59
+ </button>
60
+ </ToolbarControlGroup>
61
+ }
62
+ />
63
+ <StateBanner
64
+ title="Ready for review"
65
+ detail="All required checks passed 18 minutes ago."
66
+ tone="success"
67
+ />
68
+ <p class="kui-recipe__ownership kui-content-item">
69
+ The recipe owns page hierarchy and action relocation. The app owns
70
+ authorization, command behavior, breadcrumbs, and product copy.
71
+ </p>
72
+ </section>
73
+ ),
74
+ action(command) {
75
+ announce(`${command} requested`);
76
+ },
12
77
  });
@@ -1,5 +0,0 @@
1
- import '../styles/foundation.css';
2
- import '../styles/toolbar.css';
3
- import '../styles/toolbar-control-group.css';
4
- import '../styles/dialog-header.css';
5
- export * from '../dialog-header.js';
@@ -1,3 +0,0 @@
1
- import '../styles/foundation.css';
2
- import '../styles/menu-action-row.css';
3
- export * from '../menu-action-row.js';
@@ -1,3 +0,0 @@
1
- import '../styles/foundation.css';
2
- import '../styles/menu-item.css';
3
- export * from '../menu-item.js';
@@ -1,3 +0,0 @@
1
- import '../styles/foundation.css';
2
- import '../styles/page-header.css';
3
- export * from '../page-header.js';
@@ -1,13 +0,0 @@
1
- import { jsxs, jsx } from 'kerfjs/jsx-runtime';
2
-
3
- // src/page-header.tsx
4
- function PageHeader({ title, action }) {
5
- return /* @__PURE__ */ jsxs("header", { class: "kui-page-header", "data-component": "page-header", children: [
6
- /* @__PURE__ */ jsx("h1", { children: title }),
7
- action && /* @__PURE__ */ jsx("div", { class: "kui-page-header__action", children: action })
8
- ] });
9
- }
10
-
11
- export { PageHeader };
12
-
13
- //# sourceMappingURL=chunk-2PES33HS.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/page-header.tsx"],"names":[],"mappings":";;;AAOO,SAAS,UAAA,CAAW,EAAE,KAAA,EAAO,MAAA,EAAO,EAAoB;AAC7D,EAAA,uBAAO,IAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,iBAAA,EAAkB,kBAAe,aAAA,EAAc,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,QAAI,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,IAAM,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,2BAA2B,QAAA,EAAA,MAAA,EAAO;AAAA,GAAA,EAAO,CAAA;AACrJ","file":"chunk-2PES33HS.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nexport interface PageHeaderProps {\n title: string | SafeHtml;\n action?: SafeHtml;\n}\n\nexport function PageHeader({ title, action }: PageHeaderProps) {\n return <header class=\"kui-page-header\" data-component=\"page-header\"><h1>{title}</h1>{action && <div class=\"kui-page-header__action\">{action}</div>}</header>;\n}\n"]}
@@ -1,10 +0,0 @@
1
- import { jsx } from 'kerfjs/jsx-runtime';
2
-
3
- // src/loading-spinner.tsx
4
- function LoadingSpinner({ className = "", label }) {
5
- return /* @__PURE__ */ jsx("svg", { class: `kui-loading-spinner ${className}`.trim(), "data-component": "loading-spinner", viewBox: "0 0 24 24", role: label ? "img" : void 0, "aria-label": label, "aria-hidden": label ? void 0 : "true", children: /* @__PURE__ */ jsx("path", { d: "M12,4a8,8,0,0,1,7.89,6.7A1.53,1.53,0,0,0,21.38,12h0a1.5,1.5,0,0,0,1.48-1.75,11,11,0,0,0-21.72,0A1.5,1.5,0,0,0,2.62,12h0a1.53,1.53,0,0,0,1.49-1.3A8,8,0,0,1,12,4Z" }) });
6
- }
7
-
8
- export { LoadingSpinner };
9
-
10
- //# sourceMappingURL=chunk-55DATV3A.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/loading-spinner.tsx"],"names":[],"mappings":";;;AAMO,SAAS,cAAA,CAAe,EAAE,SAAA,GAAY,EAAA,EAAI,OAAM,EAAwB;AAC7E,EAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,CAAA,oBAAA,EAAuB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK,EAAG,gBAAA,EAAe,iBAAA,EAAkB,OAAA,EAAQ,WAAA,EAAY,IAAA,EAAM,QAAQ,KAAA,GAAQ,MAAA,EAAW,YAAA,EAAY,KAAA,EAAO,aAAA,EAAa,KAAA,GAAQ,MAAA,GAAY,MAAA,EAAQ,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,kKAAA,EAAmK,CAAA,EAAO,CAAA;AACpY","file":"chunk-55DATV3A.js","sourcesContent":["export interface LoadingSpinnerProps {\n className?: string;\n label?: string;\n}\n\n/** Stable viewBox-centered progress ring based on svg-spinners' MIT-licensed 180-ring. */\nexport function LoadingSpinner({ className = '', label }: LoadingSpinnerProps) {\n return <svg class={`kui-loading-spinner ${className}`.trim()} data-component=\"loading-spinner\" viewBox=\"0 0 24 24\" role={label ? 'img' : undefined} aria-label={label} aria-hidden={label ? undefined : 'true'}><path d=\"M12,4a8,8,0,0,1,7.89,6.7A1.53,1.53,0,0,0,21.38,12h0a1.5,1.5,0,0,0,1.48-1.75,11,11,0,0,0-21.72,0A1.5,1.5,0,0,0,2.62,12h0a1.53,1.53,0,0,0,1.49-1.3A8,8,0,0,1,12,4Z\"></path></svg>;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/extension-attributes.ts"],"names":[],"mappings":";AAEA,IAAM,mBAAA,GAAsB,sBAAA;AAC5B,IAAM,yCAAyB,IAAI,GAAA,CAAI,CAAC,QAAA,EAAU,MAAA,EAAQ,MAAM,CAAC,CAAA;AACjE,IAAM,oBAAA,mBAAuB,IAAI,GAAA,CAAI,CAAC,QAAA,EAAU,QAAQ,SAAA,EAAW,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAC,CAAA;AAEnF,SAAS,oBAAA,CACd,YACA,cAAA,EACwB;AACxB,EAAA,MAAM,WAAmC,EAAC;AAE1C,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,UAA0B,CAAA,EAAG;AACtE,IAAA,MAAM,cAAA,GAAiB,KAAK,WAAA,EAAY;AACxC,IAAA,IACE,OAAO,KAAA,KAAU,QAAA,IACd,mBAAA,CAAoB,IAAA,CAAK,cAAc,CAAA,IACvC,CAAC,cAAA,CAAe,GAAA,CAAI,cAAc,CAAA,EACrC;AACA,MAAA,QAAA,CAAS,cAAc,CAAA,GAAI,KAAA;AAAA,IAC7B;AAAA,EACF;AAEA,EAAA,OAAO,QAAA;AACT;AAEO,SAAS,uBAAA,CACd,YACA,kBAAA,EACwB;AACxB,EAAA,MAAM,MAAA,GAAS,UAAA;AACf,EAAA,MAAM,QAAA,GAAW,oBAAA,CAAqB,UAAA,EAAY,kBAAkB,CAAA;AAEpE,EAAA,IAAI,OAAO,MAAA,CAAO,aAAA,KAAkB,QAAA,EAAU,QAAA,CAAS,gBAAgB,MAAA,CAAO,aAAA;AAC9E,EAAA,IAAI,sBAAA,CAAuB,GAAA,CAAI,MAAA,CAAO,mBAA6B,CAAA,EAAG;AACpE,IAAA,QAAA,CAAS,sBAAsB,MAAA,CAAO,mBAAA;AAAA,EACxC;AACA,EAAA,IAAI,OAAO,OAAO,eAAe,CAAA,KAAM,UAAU,QAAA,CAAS,eAAe,CAAA,GAAI,MAAA,CAAO,eAAe,CAAA;AACnG,EAAA,IAAI,oBAAA,CAAqB,GAAA,CAAI,MAAA,CAAO,eAAe,CAAW,CAAA,EAAG;AAC/D,IAAA,QAAA,CAAS,eAAe,CAAA,GAAI,MAAA,CAAO,eAAe,CAAA;AAAA,EACpD;AAEA,EAAA,OAAO,QAAA;AACT","file":"chunk-7BR3DO2A.js","sourcesContent":["type AttributeBag = Readonly<Record<string, unknown>>;\n\nconst DATA_ATTRIBUTE_NAME = /^data-[a-z0-9_.:-]+$/;\nconst POPOVER_TARGET_ACTIONS = new Set(['toggle', 'show', 'hide']);\nconst ARIA_HASPOPUP_VALUES = new Set(['dialog', 'menu', 'listbox', 'tree', 'grid', 'true']);\n\nexport function filterDataAttributes(\n attributes: object,\n protectedNames: ReadonlySet<string>,\n): Record<string, string> {\n const filtered: Record<string, string> = {};\n\n for (const [name, value] of Object.entries(attributes as AttributeBag)) {\n const normalizedName = name.toLowerCase();\n if (\n typeof value === 'string'\n && DATA_ATTRIBUTE_NAME.test(normalizedName)\n && !protectedNames.has(normalizedName)\n ) {\n filtered[normalizedName] = value;\n }\n }\n\n return filtered;\n}\n\nexport function filterControlAttributes(\n attributes: object,\n protectedDataNames: ReadonlySet<string>,\n): Record<string, string> {\n const source = attributes as AttributeBag;\n const filtered = filterDataAttributes(attributes, protectedDataNames);\n\n if (typeof source.popoverTarget === 'string') filtered.popoverTarget = source.popoverTarget;\n if (POPOVER_TARGET_ACTIONS.has(source.popoverTargetAction as string)) {\n filtered.popoverTargetAction = source.popoverTargetAction as string;\n }\n if (typeof source['aria-controls'] === 'string') filtered['aria-controls'] = source['aria-controls'];\n if (ARIA_HASPOPUP_VALUES.has(source['aria-haspopup'] as string)) {\n filtered['aria-haspopup'] = source['aria-haspopup'] as string;\n }\n\n return filtered;\n}\n"]}