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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (498) hide show
  1. package/README.md +342 -108
  2. package/ai/application-ui-diagnostic-ids-v1.json +100 -0
  3. package/ai/application-ui-profile-sync.cjs +529 -0
  4. package/ai/application-ui-profile.d.mts +1 -0
  5. package/ai/application-ui-profile.d.ts +102 -0
  6. package/ai/application-ui-profile.defaults.json +41 -0
  7. package/ai/application-ui-profile.mjs +626 -0
  8. package/ai/application-ui-profile.schema.json +130 -0
  9. package/ai/catalog-authoring.json +25 -0
  10. package/ai/catalog-authoring.schema.json +61 -0
  11. package/ai/compile-time-contracts-v1.json +132 -0
  12. package/ai/compile-time-contracts-v1.schema.json +51 -0
  13. package/ai/component-catalog-extension-v2.d.ts +7 -0
  14. package/ai/component-catalog-extension-v2.schema.json +7 -0
  15. package/ai/component-catalog-extension.schema.json +79 -0
  16. package/ai/component-catalog-v2-overrides.json +496 -0
  17. package/ai/component-catalog-v2.d.ts +90 -0
  18. package/ai/component-catalog-v2.json +5678 -0
  19. package/ai/component-catalog-v2.schema.json +298 -0
  20. package/ai/component-catalog.json +2694 -417
  21. package/ai/component-catalog.schema.json +39 -0
  22. package/ai/public-api-signatures-v1.md +1591 -126
  23. package/ai/skill.md +140 -54
  24. package/ai/webawesome-jsx-signatures-v1.md +2 -1
  25. package/analyzer/cli.mjs +49 -0
  26. package/analyzer/index.d.mts +46 -0
  27. package/analyzer/index.mjs +1086 -0
  28. package/analyzer/report.schema.json +66 -0
  29. package/dist/app-tab.d.ts +15 -4
  30. package/dist/app-tab.js +3 -1
  31. package/dist/browser/app-tab.js +1 -0
  32. package/dist/browser/floating-toolbar.js +3 -0
  33. package/dist/browser/list-action-row.js +5 -0
  34. package/dist/browser/list-header.js +7 -0
  35. package/dist/browser/list-inset-control.js +3 -0
  36. package/dist/browser/list-inset-text.js +3 -0
  37. package/dist/browser/list-item.js +5 -0
  38. package/dist/browser/list.js +3 -0
  39. package/dist/browser/pane.js +3 -0
  40. package/dist/browser/row.js +3 -0
  41. package/dist/browser/segmented-control.js +1 -0
  42. package/dist/browser/select.js +1 -0
  43. package/dist/browser/skeleton.js +3 -0
  44. package/dist/browser/spacer.js +3 -0
  45. package/dist/browser/state-banner.js +1 -0
  46. package/dist/browser/sunken-panel.js +3 -0
  47. package/dist/browser/surface-scaffold.js +3 -0
  48. package/dist/browser/text.js +3 -0
  49. package/dist/browser/toolbar-text.js +1 -0
  50. package/dist/browser/value-table.js +1 -0
  51. package/dist/catalog-resources.d.ts +35 -0
  52. package/dist/catalog-resources.js +22 -0
  53. package/dist/catalog-resources.js.map +1 -0
  54. package/dist/catalog.d.ts +151 -0
  55. package/dist/catalog.js +396 -0
  56. package/dist/catalog.js.map +1 -0
  57. package/dist/chunk-2TYUFZUC.js +22 -0
  58. package/dist/chunk-2TYUFZUC.js.map +1 -0
  59. package/dist/chunk-6NDBE2OK.js +32 -0
  60. package/dist/chunk-6NDBE2OK.js.map +1 -0
  61. package/dist/chunk-6WTETUZ6.js +21 -0
  62. package/dist/chunk-6WTETUZ6.js.map +1 -0
  63. package/dist/chunk-AQFWBG23.js +83 -0
  64. package/dist/chunk-AQFWBG23.js.map +1 -0
  65. package/dist/chunk-B6JYRX3P.js +51 -0
  66. package/dist/chunk-B6JYRX3P.js.map +1 -0
  67. package/dist/chunk-C34NZOLJ.js +53 -0
  68. package/dist/chunk-C34NZOLJ.js.map +1 -0
  69. package/dist/chunk-CAB6NQ2T.js +102 -0
  70. package/dist/chunk-CAB6NQ2T.js.map +1 -0
  71. package/dist/chunk-CK6P5AUK.js +136 -0
  72. package/dist/chunk-CK6P5AUK.js.map +1 -0
  73. package/dist/chunk-DAO2VFTT.js +129 -0
  74. package/dist/chunk-DAO2VFTT.js.map +1 -0
  75. package/dist/chunk-DEYOGDE7.js +141 -0
  76. package/dist/chunk-DEYOGDE7.js.map +1 -0
  77. package/dist/chunk-DYBPI5O2.js +25 -0
  78. package/dist/chunk-DYBPI5O2.js.map +1 -0
  79. package/dist/{chunk-TRNBHPNW.js → chunk-E34TE2ZI.js} +12 -8
  80. package/dist/chunk-E34TE2ZI.js.map +1 -0
  81. package/dist/chunk-EYALJQQD.js +25 -0
  82. package/dist/chunk-EYALJQQD.js.map +1 -0
  83. package/dist/chunk-I45QO2IZ.js +88 -0
  84. package/dist/chunk-I45QO2IZ.js.map +1 -0
  85. package/dist/chunk-I4V3UDSA.js +79 -0
  86. package/dist/chunk-I4V3UDSA.js.map +1 -0
  87. package/dist/chunk-OGTJNHRG.js +42 -0
  88. package/dist/chunk-OGTJNHRG.js.map +1 -0
  89. package/dist/chunk-OL4TC3U2.js +156 -0
  90. package/dist/chunk-OL4TC3U2.js.map +1 -0
  91. package/dist/chunk-OMSRSL3B.js +120 -0
  92. package/dist/chunk-OMSRSL3B.js.map +1 -0
  93. package/dist/chunk-R3EBGEAW.js +46 -0
  94. package/dist/chunk-R3EBGEAW.js.map +1 -0
  95. package/dist/chunk-SOK5EUF7.js +25 -0
  96. package/dist/chunk-SOK5EUF7.js.map +1 -0
  97. package/dist/{chunk-7BR3DO2A.js → chunk-SRSJO5QE.js} +13 -4
  98. package/dist/chunk-SRSJO5QE.js.map +1 -0
  99. package/dist/chunk-T7DOWS6T.js +61 -0
  100. package/dist/chunk-T7DOWS6T.js.map +1 -0
  101. package/dist/chunk-TIGSG6BX.js +218 -0
  102. package/dist/chunk-TIGSG6BX.js.map +1 -0
  103. package/dist/chunk-UDHHKZWO.js +41 -0
  104. package/dist/chunk-UDHHKZWO.js.map +1 -0
  105. package/dist/{chunk-MQIZAD4A.js → chunk-UKKSMZYT.js} +76 -22
  106. package/dist/chunk-UKKSMZYT.js.map +1 -0
  107. package/dist/chunk-V6GQKOX2.js +39 -0
  108. package/dist/chunk-V6GQKOX2.js.map +1 -0
  109. package/dist/chunk-V6HCTCVD.js +46 -0
  110. package/dist/chunk-V6HCTCVD.js.map +1 -0
  111. package/dist/chunk-VDUJZF5G.js +515 -0
  112. package/dist/chunk-VDUJZF5G.js.map +1 -0
  113. package/dist/chunk-VXFGMDA7.js +31 -0
  114. package/dist/chunk-VXFGMDA7.js.map +1 -0
  115. package/dist/chunk-WN52USHV.js +115 -0
  116. package/dist/chunk-WN52USHV.js.map +1 -0
  117. package/dist/chunk-WSXUPSID.js +43 -0
  118. package/dist/chunk-WSXUPSID.js.map +1 -0
  119. package/dist/chunk-X5GRDQ7V.js +50 -0
  120. package/dist/chunk-X5GRDQ7V.js.map +1 -0
  121. package/dist/{chunk-56RJXPHG.js → chunk-Y6LYKFXY.js} +1 -1
  122. package/dist/{chunk-56RJXPHG.js.map → chunk-Y6LYKFXY.js.map} +1 -1
  123. package/dist/chunk-ZASJJMGV.js +17 -0
  124. package/dist/chunk-ZASJJMGV.js.map +1 -0
  125. package/dist/chunk-ZPWZIVI6.js +47 -0
  126. package/dist/chunk-ZPWZIVI6.js.map +1 -0
  127. package/dist/collapsible-panel.d.ts +77 -0
  128. package/dist/collapsible-panel.js +84 -0
  129. package/dist/collapsible-panel.js.map +1 -0
  130. package/dist/css-values.d.ts +75 -0
  131. package/dist/css-values.js +3 -0
  132. package/dist/css-values.js.map +1 -0
  133. package/dist/device-class.d.ts +62 -0
  134. package/dist/device-class.js +103 -0
  135. package/dist/device-class.js.map +1 -0
  136. package/dist/disclosure-arrow.js +1 -1
  137. package/dist/divider-sides-BzB6rphT.d.ts +6 -0
  138. package/dist/empty-state.d.ts +3 -2
  139. package/dist/empty-state.js +1 -1
  140. package/dist/flex-alignment-CF8NLj7i.d.ts +4 -0
  141. package/dist/floating-toolbar.d.ts +29 -0
  142. package/dist/floating-toolbar.js +3 -0
  143. package/dist/floating-toolbar.js.map +1 -0
  144. package/dist/index.d.ts +28 -14
  145. package/dist/index.js +34 -23
  146. package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +19 -8
  147. package/dist/list-action-row.js +7 -0
  148. package/dist/list-action-row.js.map +1 -0
  149. package/dist/list-header.d.ts +80 -0
  150. package/dist/list-header.js +9 -0
  151. package/dist/list-header.js.map +1 -0
  152. package/dist/list-inset-control.d.ts +20 -0
  153. package/dist/list-inset-control.js +3 -0
  154. package/dist/list-inset-control.js.map +1 -0
  155. package/dist/list-inset-text.d.ts +29 -0
  156. package/dist/list-inset-text.js +3 -0
  157. package/dist/list-inset-text.js.map +1 -0
  158. package/dist/list-item.d.ts +45 -0
  159. package/dist/list-item.js +7 -0
  160. package/dist/list-item.js.map +1 -0
  161. package/dist/list.d.ts +30 -0
  162. package/dist/list.js +5 -0
  163. package/dist/list.js.map +1 -0
  164. package/dist/loading-spinner.js +1 -1
  165. package/dist/nav-stack.d.ts +41 -0
  166. package/dist/nav-stack.js +6 -0
  167. package/dist/nav-stack.js.map +1 -0
  168. package/dist/pane.d.ts +50 -0
  169. package/dist/pane.js +4 -0
  170. package/dist/pane.js.map +1 -0
  171. package/dist/resizable-region.d.ts +21 -3
  172. package/dist/resizable-region.js +1 -1
  173. package/dist/row.d.ts +28 -0
  174. package/dist/row.js +5 -0
  175. package/dist/row.js.map +1 -0
  176. package/dist/segmented-control.d.ts +11 -8
  177. package/dist/segmented-control.js +3 -1
  178. package/dist/select-register.d.ts +5 -1
  179. package/dist/select-register.js +129 -1
  180. package/dist/select-register.js.map +1 -1
  181. package/dist/select.d.ts +34 -8
  182. package/dist/select.js +3 -1
  183. package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
  184. package/dist/skeleton.d.ts +25 -0
  185. package/dist/skeleton.js +4 -0
  186. package/dist/skeleton.js.map +1 -0
  187. package/dist/spacer.d.ts +16 -0
  188. package/dist/spacer.js +4 -0
  189. package/dist/spacer.js.map +1 -0
  190. package/dist/split-view.d.ts +43 -0
  191. package/dist/split-view.js +82 -0
  192. package/dist/split-view.js.map +1 -0
  193. package/dist/state-banner.d.ts +11 -5
  194. package/dist/state-banner.js +3 -1
  195. package/dist/styles/app-tab.css +26 -0
  196. package/dist/styles/catalog.css +582 -0
  197. package/dist/styles/collapsible-panel.css +212 -0
  198. package/dist/styles/floating-toolbar.css +38 -0
  199. package/dist/styles/foundation.css +80 -0
  200. package/dist/styles/layout.css +2 -20
  201. package/dist/styles/list-action-row.css +224 -0
  202. package/dist/styles/list-header.css +224 -0
  203. package/dist/styles/list-inset-control.css +23 -0
  204. package/dist/styles/list-inset-text.css +30 -0
  205. package/dist/styles/list-item.css +171 -0
  206. package/dist/styles/list.css +118 -0
  207. package/dist/styles/nav-stack.css +141 -0
  208. package/dist/styles/pane.css +62 -0
  209. package/dist/styles/resizable-region.css +158 -0
  210. package/dist/styles/row.css +92 -0
  211. package/dist/styles/segmented-control.css +10 -7
  212. package/dist/styles/select.css +115 -2
  213. package/dist/styles/skeleton.css +31 -0
  214. package/dist/styles/spacer.css +11 -0
  215. package/dist/styles/split-view.css +35 -0
  216. package/dist/styles/state-banner.css +49 -10
  217. package/dist/styles/styles.css +10 -5
  218. package/dist/styles/sunken-panel.css +22 -0
  219. package/dist/styles/surface-scaffold.css +51 -0
  220. package/dist/styles/tab-bar.css +24 -0
  221. package/dist/styles/tab-scaffold.css +85 -0
  222. package/dist/styles/text.css +6 -0
  223. package/dist/styles/token-search-field.css +14 -2
  224. package/dist/styles/toolbar-control-group.css +235 -8
  225. package/dist/styles/toolbar-text.css +65 -2
  226. package/dist/styles/toolbar.css +47 -2
  227. package/dist/styles/webawesome.css +171 -0
  228. package/dist/styles/workbench.css +187 -0
  229. package/dist/sunken-panel.d.ts +20 -0
  230. package/dist/sunken-panel.js +3 -0
  231. package/dist/sunken-panel.js.map +1 -0
  232. package/dist/surface-scaffold.d.ts +26 -0
  233. package/dist/surface-scaffold.js +3 -0
  234. package/dist/surface-scaffold.js.map +1 -0
  235. package/dist/tab-bar.d.ts +24 -6
  236. package/dist/tab-bar.js +1 -1
  237. package/dist/tab-scaffold.d.ts +31 -0
  238. package/dist/tab-scaffold.js +51 -0
  239. package/dist/tab-scaffold.js.map +1 -0
  240. package/dist/text.d.ts +20 -0
  241. package/dist/text.js +3 -0
  242. package/dist/text.js.map +1 -0
  243. package/dist/token-search-field.d.ts +30 -13
  244. package/dist/token-search-field.js +1 -1
  245. package/dist/toolbar-control-group.d.ts +33 -7
  246. package/dist/toolbar-control-group.js +1 -1
  247. package/dist/toolbar-text.d.ts +31 -4
  248. package/dist/toolbar-text.js +3 -1
  249. package/dist/toolbar.d.ts +10 -7
  250. package/dist/toolbar.js +1 -1
  251. package/dist/value-table.d.ts +7 -3
  252. package/dist/value-table.js +3 -1
  253. package/dist/webawesome.d.ts +1 -0
  254. package/dist/wire-catalog.d.ts +57 -0
  255. package/dist/wire-catalog.js +302 -0
  256. package/dist/wire-catalog.js.map +1 -0
  257. package/dist/wire-nav-stack.d.ts +18 -0
  258. package/dist/wire-nav-stack.js +228 -0
  259. package/dist/wire-nav-stack.js.map +1 -0
  260. package/dist/wire-resizable-regions.d.ts +1 -1
  261. package/dist/wire-resizable-regions.js +1 -1
  262. package/dist/wire-sidebar.d.ts +48 -0
  263. package/dist/wire-sidebar.js +147 -0
  264. package/dist/wire-sidebar.js.map +1 -0
  265. package/dist/wire-tab-bars.d.ts +19 -2
  266. package/dist/wire-tab-bars.js +1 -1
  267. package/dist/wire-tab-scaffold.d.ts +11 -0
  268. package/dist/wire-tab-scaffold.js +21 -0
  269. package/dist/wire-tab-scaffold.js.map +1 -0
  270. package/dist/wire-token-search-fields.d.ts +104 -4
  271. package/dist/wire-token-search-fields.js +1 -1
  272. package/dist/workbench.d.ts +44 -0
  273. package/dist/workbench.js +106 -0
  274. package/dist/workbench.js.map +1 -0
  275. package/docs/accessibility.md +155 -20
  276. package/docs/app-layouts.md +61 -0
  277. package/docs/catalog.md +364 -0
  278. package/docs/collapsible-panel.md +142 -0
  279. package/docs/component-contract.md +258 -28
  280. package/docs/component-integration.md +63 -0
  281. package/docs/component-selection.md +219 -57
  282. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  283. package/docs/design/templates/empty-state/filtered.svg +1 -0
  284. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  285. package/docs/design/templates/empty-state/with-action.svg +1 -0
  286. package/docs/design/templates/empty-state-dark.svg +1 -0
  287. package/docs/design/templates/empty-state.svg +1 -0
  288. package/docs/design/templates/list/compact-dark.svg +1 -0
  289. package/docs/design/templates/list/compact.svg +1 -0
  290. package/docs/design/templates/list/stack-dark.svg +1 -0
  291. package/docs/design/templates/list/stack.svg +1 -0
  292. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  293. package/docs/design/templates/list-action-row/default.svg +1 -0
  294. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  295. package/docs/design/templates/list-action-row/selected.svg +1 -0
  296. package/docs/design/templates/list-action-row-dark.svg +1 -0
  297. package/docs/design/templates/list-action-row.svg +1 -0
  298. package/docs/design/templates/list-dark.svg +1 -0
  299. package/docs/design/templates/list-header/action-dark.svg +1 -0
  300. package/docs/design/templates/list-header/action.svg +1 -0
  301. package/docs/design/templates/list-header/count-dark.svg +1 -0
  302. package/docs/design/templates/list-header/count.svg +1 -0
  303. package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
  304. package/docs/design/templates/list-header/inline-action.svg +1 -0
  305. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  306. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  307. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  308. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  309. package/docs/design/templates/list-header-dark.svg +1 -0
  310. package/docs/design/templates/list-header.svg +1 -0
  311. package/docs/design/templates/list-item/default-dark.svg +1 -0
  312. package/docs/design/templates/list-item/default.svg +1 -0
  313. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  314. package/docs/design/templates/list-item/multiline.svg +1 -0
  315. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  316. package/docs/design/templates/list-item/selected.svg +1 -0
  317. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  318. package/docs/design/templates/list-item/trailing.svg +1 -0
  319. package/docs/design/templates/list-item-dark.svg +1 -0
  320. package/docs/design/templates/list-item.svg +1 -0
  321. package/docs/design/templates/list.svg +1 -0
  322. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  323. package/docs/design/templates/segmented-control/equal.svg +1 -0
  324. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  325. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  326. package/docs/design/templates/segmented-control-dark.svg +1 -0
  327. package/docs/design/templates/segmented-control.svg +1 -0
  328. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  329. package/docs/design/templates/skeleton/avatar.svg +1 -0
  330. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  331. package/docs/design/templates/skeleton/block.svg +1 -0
  332. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  333. package/docs/design/templates/skeleton/lines.svg +1 -0
  334. package/docs/design/templates/skeleton-dark.svg +1 -0
  335. package/docs/design/templates/skeleton.svg +1 -0
  336. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  337. package/docs/design/templates/state-banner/danger.svg +1 -0
  338. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  339. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  340. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  341. package/docs/design/templates/state-banner/info.svg +1 -0
  342. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  343. package/docs/design/templates/state-banner/success.svg +1 -0
  344. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  345. package/docs/design/templates/state-banner/warning.svg +1 -0
  346. package/docs/design/templates/state-banner-dark.svg +1 -0
  347. package/docs/design/templates/state-banner.svg +1 -0
  348. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  349. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  350. package/docs/design/templates/tab-bar-dark.svg +1 -0
  351. package/docs/design/templates/tab-bar.svg +1 -0
  352. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  353. package/docs/design/templates/token-search-field/empty.svg +1 -0
  354. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  355. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  356. package/docs/design/templates/token-search-field-dark.svg +1 -0
  357. package/docs/design/templates/token-search-field.svg +1 -0
  358. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  359. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  360. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  361. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  362. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  363. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  364. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  365. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  366. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  367. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  368. package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
  369. package/docs/design/templates/toolbar-control-group.svg +1 -0
  370. package/docs/design/templates/toolbar-dark.svg +1 -0
  371. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  372. package/docs/design/templates/toolbar-text/default.svg +1 -0
  373. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  374. package/docs/design/templates/toolbar-text/large.svg +1 -0
  375. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  376. package/docs/design/templates/toolbar-text/small.svg +1 -0
  377. package/docs/design/templates/toolbar-text-dark.svg +1 -0
  378. package/docs/design/templates/toolbar-text.svg +1 -0
  379. package/docs/design/templates/toolbar.svg +1 -0
  380. package/docs/design/templates/value-table/details-dark.svg +1 -0
  381. package/docs/design/templates/value-table/details.svg +1 -0
  382. package/docs/design/templates/value-table-dark.svg +1 -0
  383. package/docs/design/templates/value-table.svg +1 -0
  384. package/docs/design/templates.md +128 -0
  385. package/docs/design-philosophy.md +33 -11
  386. package/docs/device-class.md +54 -0
  387. package/docs/examples/application-ui-profile.json +60 -0
  388. package/docs/examples/command-palette-adapter.tsx +68 -17
  389. package/docs/examples/component-catalog-extension-v2.json +80 -0
  390. package/docs/examples/component-catalog-extension.json +45 -0
  391. package/docs/layout.md +169 -38
  392. package/docs/nav-stack.md +77 -0
  393. package/docs/recipes.md +64 -16
  394. package/docs/split-view.md +55 -0
  395. package/docs/sunken-panel.md +53 -0
  396. package/docs/surface-scaffold.md +25 -0
  397. package/docs/tab-scaffold.md +52 -0
  398. package/docs/type-contracts.md +127 -0
  399. package/docs/ui-analyzer.md +118 -0
  400. package/docs/ui-doctor.md +91 -0
  401. package/docs/ui-evaluator.md +122 -0
  402. package/docs/ux-demo.md +29 -10
  403. package/docs/webawesome-theme.md +82 -8
  404. package/docs/workbench.md +123 -0
  405. package/doctor/cli.mjs +115 -0
  406. package/doctor/config.schema.json +68 -0
  407. package/doctor/eslint-diagnostics.d.mts +24 -0
  408. package/doctor/eslint-diagnostics.mjs +24 -0
  409. package/doctor/index.d.mts +116 -0
  410. package/doctor/index.mjs +1272 -0
  411. package/doctor/report.schema.json +118 -0
  412. package/evaluator/cli.mjs +89 -0
  413. package/evaluator/index.d.mts +90 -0
  414. package/evaluator/index.mjs +1138 -0
  415. package/evaluator/report.schema.json +152 -0
  416. package/llms.txt +260 -32
  417. package/package.json +205 -38
  418. package/traversal-exclusions.mjs +27 -0
  419. package/ux-demo/recipes/app-shell.tsx +223 -13
  420. package/ux-demo/recipes/collapsible-sidebar.tsx +230 -0
  421. package/ux-demo/recipes/compact-toolbar.tsx +116 -12
  422. package/ux-demo/recipes/composer-form.tsx +120 -19
  423. package/ux-demo/recipes/list-detail-dialog.tsx +205 -0
  424. package/ux-demo/recipes/list-workspace-states.tsx +176 -9
  425. package/ux-demo/recipes/loaders.ts +13 -4
  426. package/ux-demo/recipes/loading-inspector.tsx +191 -0
  427. package/ux-demo/recipes/mount-recipe.ts +31 -5
  428. package/ux-demo/recipes/navigation-sidebar.tsx +123 -11
  429. package/ux-demo/recipes/navigation-stack.tsx +121 -0
  430. package/ux-demo/recipes/recipes.css +125 -16
  431. package/ux-demo/recipes/types.ts +9 -1
  432. package/ux-demo/recipes/workspace-header.tsx +72 -3
  433. package/dist/browser/dialog-header.js +0 -5
  434. package/dist/browser/menu-action-row.js +0 -3
  435. package/dist/browser/menu-header.js +0 -5
  436. package/dist/browser/menu-item.js +0 -3
  437. package/dist/browser/page-header.js +0 -3
  438. package/dist/chunk-2PES33HS.js +0 -13
  439. package/dist/chunk-2PES33HS.js.map +0 -1
  440. package/dist/chunk-55DATV3A.js +0 -10
  441. package/dist/chunk-55DATV3A.js.map +0 -1
  442. package/dist/chunk-7BR3DO2A.js.map +0 -1
  443. package/dist/chunk-7LDCTU7D.js +0 -134
  444. package/dist/chunk-7LDCTU7D.js.map +0 -1
  445. package/dist/chunk-AQNKJRFH.js +0 -79
  446. package/dist/chunk-AQNKJRFH.js.map +0 -1
  447. package/dist/chunk-CTQKI2XL.js +0 -28
  448. package/dist/chunk-CTQKI2XL.js.map +0 -1
  449. package/dist/chunk-DAFFDO33.js +0 -14
  450. package/dist/chunk-DAFFDO33.js.map +0 -1
  451. package/dist/chunk-EGHL5S4P.js +0 -33
  452. package/dist/chunk-EGHL5S4P.js.map +0 -1
  453. package/dist/chunk-GY5WH7TO.js +0 -10
  454. package/dist/chunk-GY5WH7TO.js.map +0 -1
  455. package/dist/chunk-H5AGGVU5.js +0 -75
  456. package/dist/chunk-H5AGGVU5.js.map +0 -1
  457. package/dist/chunk-K3G72I6D.js +0 -24
  458. package/dist/chunk-K3G72I6D.js.map +0 -1
  459. package/dist/chunk-M5JRI6MN.js +0 -27
  460. package/dist/chunk-M5JRI6MN.js.map +0 -1
  461. package/dist/chunk-MBR3TYNL.js +0 -14
  462. package/dist/chunk-MBR3TYNL.js.map +0 -1
  463. package/dist/chunk-MFKMHK5W.js +0 -10
  464. package/dist/chunk-MFKMHK5W.js.map +0 -1
  465. package/dist/chunk-MQIZAD4A.js.map +0 -1
  466. package/dist/chunk-NPPD2A6O.js +0 -40
  467. package/dist/chunk-NPPD2A6O.js.map +0 -1
  468. package/dist/chunk-R6JHHBKQ.js +0 -19
  469. package/dist/chunk-R6JHHBKQ.js.map +0 -1
  470. package/dist/chunk-S3TPM2LP.js +0 -23
  471. package/dist/chunk-S3TPM2LP.js.map +0 -1
  472. package/dist/chunk-TRNBHPNW.js.map +0 -1
  473. package/dist/chunk-VHW5YNIB.js +0 -17
  474. package/dist/chunk-VHW5YNIB.js.map +0 -1
  475. package/dist/chunk-WVPYVDXY.js +0 -15
  476. package/dist/chunk-WVPYVDXY.js.map +0 -1
  477. package/dist/chunk-XZXRLY5Q.js +0 -33
  478. package/dist/chunk-XZXRLY5Q.js.map +0 -1
  479. package/dist/dialog-header.d.ts +0 -15
  480. package/dist/dialog-header.js +0 -5
  481. package/dist/dialog-header.js.map +0 -1
  482. package/dist/menu-action-row.js +0 -4
  483. package/dist/menu-action-row.js.map +0 -1
  484. package/dist/menu-header.d.ts +0 -41
  485. package/dist/menu-header.js +0 -6
  486. package/dist/menu-header.js.map +0 -1
  487. package/dist/menu-item.d.ts +0 -31
  488. package/dist/menu-item.js +0 -4
  489. package/dist/menu-item.js.map +0 -1
  490. package/dist/page-header.d.ts +0 -9
  491. package/dist/page-header.js +0 -3
  492. package/dist/page-header.js.map +0 -1
  493. package/dist/styles/dialog-header.css +0 -87
  494. package/dist/styles/menu-action-row.css +0 -160
  495. package/dist/styles/menu-header.css +0 -143
  496. package/dist/styles/menu-item.css +0 -123
  497. package/dist/styles/page-header.css +0 -33
  498. package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
@@ -1,3 +1,4 @@
1
+ import { wireNavStack } from '@kerfjs/ui/wire-nav-stack';
1
2
  import { wireResizableRegions } from '@kerfjs/ui/wire-resizable-regions';
2
3
  import { delegate, mount } from 'kerfjs';
3
4
  import { delegateActions } from 'kerfjs/actions';
@@ -8,7 +9,10 @@ import type { RecipeController } from './types.js';
8
9
  * Copyable application boundary for a recipe. The caller owns one stable root
9
10
  * and retains the returned disposer for that root's lifetime.
10
11
  */
11
- export function mountRecipe(root: HTMLElement, controller: RecipeController): () => void {
12
+ export function mountRecipe(
13
+ root: HTMLElement,
14
+ controller: RecipeController,
15
+ ): () => void {
12
16
  const stopMount = mount(root, controller.render);
13
17
  const stopActions = delegateActions(root, 'click', {
14
18
  'recipe-action': (_event, element) => {
@@ -16,18 +20,40 @@ export function mountRecipe(root: HTMLElement, controller: RecipeController): ()
16
20
  controller.action(target.dataset.recipeCommand ?? '', target);
17
21
  },
18
22
  });
19
- const dispatchChange = (_event: Event, element: Element) => controller.change?.(element as HTMLElement);
20
- const stopChanges = delegate(root, 'change', 'wa-select, wa-input, wa-textarea', dispatchChange);
21
- const stopInputs = delegate(root, 'input', 'wa-input, wa-textarea', dispatchChange);
22
- const stopDialogs = delegate(root, 'wa-after-hide', 'wa-dialog', (_event, element) => controller.afterHide?.(element as HTMLElement));
23
+ const dispatchChange = (_event: Event, element: Element) =>
24
+ controller.change?.(element as HTMLElement);
25
+ const stopChanges = delegate(
26
+ root,
27
+ 'change',
28
+ 'wa-select, wa-input, wa-textarea',
29
+ dispatchChange,
30
+ );
31
+ const stopInputs = delegate(
32
+ root,
33
+ 'input',
34
+ 'wa-input, wa-textarea',
35
+ dispatchChange,
36
+ );
37
+ const stopDialogs = delegate(
38
+ root,
39
+ 'wa-after-hide',
40
+ 'wa-dialog',
41
+ (_event, element) => controller.afterHide?.(element as HTMLElement),
42
+ );
23
43
  const stopResize = wireResizableRegions(root, {
24
44
  onCommit: ({ id, size }) => controller.resize?.(id, size),
25
45
  });
46
+ const stopNav = wireNavStack(root, {
47
+ onBack: () => controller.action('nav-back', root),
48
+ });
49
+ const stopWire = controller.wire?.(root);
26
50
 
27
51
  let disposed = false;
28
52
  return () => {
29
53
  if (disposed) return;
30
54
  disposed = true;
55
+ stopWire?.();
56
+ stopNav();
31
57
  stopResize();
32
58
  stopDialogs();
33
59
  stopInputs();
@@ -1,9 +1,10 @@
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 { Text } from '@kerfjs/ui/text';
7
8
  import { Toolbar } from '@kerfjs/ui/toolbar';
8
9
  import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
9
10
  import { signal } from 'kerfjs';
@@ -14,13 +15,124 @@ import type { RecipeFactory } from './types.js';
14
15
  export const createRecipe: RecipeFactory = (announce) => {
15
16
  const selected = signal('inbox');
16
17
  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`); } };
18
+ const render = () => (
19
+ <aside
20
+ class="kui-recipe recipe-sidebar kui-recipe__surface kui-pane"
21
+ data-recipe="recipe-navigation-sidebar"
22
+ >
23
+ <div class="recipe-sidebar__body kui-pane__content kui-content">
24
+ <section>
25
+ <ListHeader
26
+ label="Workspace"
27
+ count={3}
28
+ countLabel="3 workspaces"
29
+ action="recipe-action"
30
+ actionLabel="Add workspace item"
31
+ actionIcon={<LucideIcon icon={Plus} name="plus" />}
32
+ />
33
+ <ListItem
34
+ action="recipe-action"
35
+ itemId="inbox"
36
+ label="Inbox"
37
+ icon={<LucideIcon icon={Inbox} name="inbox" />}
38
+ trailing={<span>12</span>}
39
+ selected={selected.value === 'inbox'}
40
+ />
41
+ <ListItem
42
+ action="recipe-action"
43
+ itemId="shared"
44
+ label="Shared with me"
45
+ icon={<LucideIcon icon={Users} name="users" />}
46
+ selected={selected.value === 'shared'}
47
+ />
48
+ <ListItem
49
+ action="recipe-action"
50
+ itemId="drafts"
51
+ label="Drafts without an icon"
52
+ selected={selected.value === 'drafts'}
53
+ />
54
+ </section>
55
+ <section>
56
+ <ListHeader
57
+ label="Projects"
58
+ toggle
59
+ action="recipe-action"
60
+ expanded={expanded.value}
61
+ />
62
+ {expanded.value && (
63
+ <>
64
+ <ListItem
65
+ action="recipe-action"
66
+ itemId="design"
67
+ label="Design system rollout across desktop and tablet"
68
+ icon={<LucideIcon icon={Folder} name="folder" />}
69
+ selected={selected.value === 'design'}
70
+ multiline
71
+ />
72
+ <ListItem
73
+ action="recipe-action"
74
+ itemId="archive"
75
+ label="Archived"
76
+ disabled
77
+ title="Available to administrators"
78
+ />
79
+ <div class="kui-content-item">
80
+ <strong>Quarterly goal</strong>
81
+ <Text variant="p" class="kui-recipe__muted">
82
+ Ship accessible navigation patterns to every workspace.
83
+ </Text>
84
+ </div>
85
+ </>
86
+ )}
87
+ </section>
88
+ <Text variant="p" class="kui-recipe__ownership kui-content-item">
89
+ The recipe owns pane, content-item, and toolbar geometry. The app owns
90
+ routes, permissions, labels, and disclosure state.
91
+ </Text>
92
+ </div>
93
+ <footer class="recipe-sidebar__footer kui-pane__footer">
94
+ <Toolbar
95
+ label="Sidebar actions"
96
+ dividerSides=""
97
+ leading={
98
+ <ToolbarControlGroup appearance="borderless" single>
99
+ <button
100
+ type="button"
101
+ aria-label="Add project"
102
+ data-action="recipe-action"
103
+ data-recipe-command="add"
104
+ >
105
+ <LucideIcon icon={Plus} name="plus" />
106
+ </button>
107
+ </ToolbarControlGroup>
108
+ }
109
+ trailing={
110
+ <ToolbarControlGroup appearance="borderless" single>
111
+ <button
112
+ type="button"
113
+ aria-label="Workspace settings"
114
+ data-action="recipe-action"
115
+ data-recipe-command="settings"
116
+ >
117
+ <LucideIcon icon={Settings} name="settings" />
118
+ </button>
119
+ </ToolbarControlGroup>
120
+ }
121
+ />
122
+ </footer>
123
+ </aside>
124
+ );
125
+ return {
126
+ render,
127
+ action(command, element) {
128
+ if (element.matches('.kui-list-header__toggle')) {
129
+ expanded.value = !expanded.value;
130
+ announce(expanded.value ? 'Projects expanded' : 'Projects collapsed');
131
+ return;
132
+ }
133
+ const id = element.dataset.itemId;
134
+ if (id) selected.value = id;
135
+ announce(id ? `Selected ${id}` : `${command} requested`);
136
+ },
137
+ };
26
138
  };
@@ -0,0 +1,121 @@
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 { Text } from '@kerfjs/ui/text';
11
+ import { signal } from 'kerfjs';
12
+ import { ChevronRight, FileText, Folder } from 'lucide';
13
+
14
+ import type { RecipeFactory } from './types.js';
15
+
16
+ interface LibraryItem {
17
+ id: string;
18
+ label: string;
19
+ detail: string;
20
+ }
21
+
22
+ const ITEMS: LibraryItem[] = [
23
+ {
24
+ id: 'tokens',
25
+ label: 'Design tokens',
26
+ detail:
27
+ 'Semantic color, spacing, and radius scales shared across every surface.',
28
+ },
29
+ {
30
+ id: 'controls',
31
+ label: 'Toolbar controls',
32
+ detail:
33
+ 'Control groups and segmented controls with their hover and pressed contracts.',
34
+ },
35
+ {
36
+ id: 'layouts',
37
+ label: 'App layouts',
38
+ detail:
39
+ 'Navigation stacks, split views, workbench, and bottom-tab scaffolds.',
40
+ },
41
+ ];
42
+
43
+ export const createRecipe: RecipeFactory = (announce) => {
44
+ const listView = (): NavStackView => ({
45
+ key: 'library',
46
+ title: 'Library',
47
+ content: (
48
+ <div class="recipe-navstack__view kui-pane__content kui-content">
49
+ <section>
50
+ <ListHeader label="Components" />
51
+ {ITEMS.map((item) => (
52
+ <ListItem
53
+ action="recipe-action"
54
+ itemId={item.id}
55
+ label={item.label}
56
+ icon={<LucideIcon icon={Folder} name="folder" />}
57
+ trailing={<LucideIcon icon={ChevronRight} name="chevron-right" />}
58
+ />
59
+ ))}
60
+ </section>
61
+ <Text variant="p" class="kui-recipe__ownership kui-content-item">
62
+ The recipe owns the stack as a signal of views and pushes/pops it;
63
+ `NavStack` renders the stack and `wireNavStack` slides the content and
64
+ settles the chrome. The app owns selection, data, and routing.
65
+ </Text>
66
+ </div>
67
+ ),
68
+ });
69
+
70
+ const detailView = (item: LibraryItem): NavStackView => ({
71
+ key: item.id,
72
+ title: item.label,
73
+ content: (
74
+ <div class="recipe-navstack__view kui-pane__content kui-content">
75
+ <div class="kui-content-item">
76
+ <LucideIcon icon={FileText} name="file-text" />
77
+ <strong>{item.label}</strong>
78
+ <Text variant="p" class="kui-recipe__muted">
79
+ {item.detail}
80
+ </Text>
81
+ </div>
82
+ </div>
83
+ ),
84
+ });
85
+
86
+ const views = signal<NavStackView[]>([listView()]);
87
+
88
+ const render = () => (
89
+ <section
90
+ class="kui-recipe recipe-navstack kui-recipe__surface"
91
+ data-recipe="recipe-navigation-stack"
92
+ >
93
+ <div class="recipe-navstack__stage">
94
+ <NavStack
95
+ id="recipe-nav"
96
+ label="Component library"
97
+ views={views.value}
98
+ />
99
+ </div>
100
+ </section>
101
+ );
102
+
103
+ return {
104
+ render,
105
+ action(command, element) {
106
+ if (command === 'nav-back') {
107
+ if (views.value.length > 1) {
108
+ views.value = views.value.slice(0, -1);
109
+ announce('Navigated back');
110
+ }
111
+ return;
112
+ }
113
+ const id = element.dataset.itemId;
114
+ const item = ITEMS.find((candidate) => candidate.id === id);
115
+ if (item) {
116
+ views.value = [...views.value, detailView(item)];
117
+ announce(`Opened ${item.label}`);
118
+ }
119
+ },
120
+ };
121
+ };
@@ -113,35 +113,39 @@
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
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
  }
133
- .recipe-master-detail__title {
132
+ .recipe-list-detail__title {
134
133
  margin-inline: var(--kui-layout-inline-margin, remify(8px));
135
134
  }
136
- .recipe-master-detail__actions {
135
+ .recipe-list-detail__actions {
137
136
  margin-inline: var(--kui-layout-inline-margin, remify(8px));
138
137
  }
139
138
  .recipe-dialog {
140
139
  --spacing: 0;
141
140
  --width: min(62rem, calc(100vw - 2rem));
142
141
  }
143
- .recipe-dialog .kui-dialog-header {
144
- margin-inline: 0;
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;
145
149
  }
146
150
 
147
151
  .recipe-form {
@@ -206,8 +210,11 @@
206
210
  gap: var(--kui-layout-content-gap);
207
211
  }
208
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. */
209
215
  display: grid;
210
216
  grid-template-columns: repeat(4, minmax(0, 1fr));
217
+ margin-inline: 0;
211
218
  gap: var(--kui-layout-control-gap);
212
219
  }
213
220
  .recipe-compact-toolbar__guide > div {
@@ -256,10 +263,10 @@
256
263
  .recipe-compact-toolbar__guide {
257
264
  grid-template-columns: 1fr 1fr;
258
265
  }
259
- .recipe-master-detail {
266
+ .recipe-list-detail {
260
267
  grid-template-columns: 1fr;
261
268
  }
262
- .recipe-master-detail__master {
269
+ .recipe-list-detail__list {
263
270
  border-inline-end: 0;
264
271
  border-block-end: 1px solid var(--kui-color-border);
265
272
  }
@@ -321,10 +328,6 @@
321
328
  .recipe-compact-toolbar__guide {
322
329
  grid-template-columns: 1fr;
323
330
  }
324
- .recipe-header .kui-page-header {
325
- align-items: flex-start;
326
- flex-direction: column;
327
- }
328
331
  }
329
332
 
330
333
  @media (forced-colors: active) {
@@ -342,3 +345,109 @@
342
345
  transition-duration: 1ms !important;
343
346
  }
344
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,81 @@
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 { Text } from '@kerfjs/ui/text';
6
+ import { Toolbar } from '@kerfjs/ui/toolbar';
7
+ import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
8
+ import { ToolbarText } from '@kerfjs/ui/toolbar-text';
6
9
 
7
10
  import type { RecipeFactory } from './types.js';
8
11
 
9
12
  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`); },
13
+ render: () => (
14
+ <section
15
+ class="kui-recipe recipe-header kui-recipe__surface kui-content"
16
+ data-recipe="recipe-workspace-header"
17
+ >
18
+ <Text
19
+ variant="p"
20
+ class="recipe-header__context kui-inline-metadata kui-content-item"
21
+ >
22
+ <span>Northstar workspace</span>
23
+ <span>·</span>
24
+ <span>Product planning</span>
25
+ </Text>
26
+ <Toolbar
27
+ label="Workspace heading"
28
+ dividerSides=""
29
+ leading={
30
+ <ToolbarText
31
+ text="Accessibility readiness and responsive navigation rollout"
32
+ size="xlarge"
33
+ id="recipe-workspace-title"
34
+ headingLevel={1}
35
+ />
36
+ }
37
+ trailing={
38
+ <ToolbarControlGroup appearance="borderless">
39
+ <button
40
+ class="kui-recipe__button"
41
+ type="button"
42
+ data-action="recipe-action"
43
+ data-recipe-command="share"
44
+ >
45
+ Share
46
+ </button>
47
+ <button
48
+ class="kui-recipe__button"
49
+ type="button"
50
+ data-action="recipe-action"
51
+ data-recipe-command="more"
52
+ >
53
+ More actions
54
+ </button>
55
+ <button
56
+ class="kui-recipe__button"
57
+ data-primary="true"
58
+ type="button"
59
+ data-action="recipe-action"
60
+ data-recipe-command="publish"
61
+ >
62
+ Publish update
63
+ </button>
64
+ </ToolbarControlGroup>
65
+ }
66
+ />
67
+ <StateBanner
68
+ title="Ready for review"
69
+ detail="All required checks passed 18 minutes ago."
70
+ tone="success"
71
+ />
72
+ <Text variant="p" class="kui-recipe__ownership kui-content-item">
73
+ The recipe owns page hierarchy and action relocation. The app owns
74
+ authorization, command behavior, breadcrumbs, and product copy.
75
+ </Text>
76
+ </section>
77
+ ),
78
+ action(command) {
79
+ announce(`${command} requested`);
80
+ },
12
81
  });
@@ -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,5 +0,0 @@
1
- import '../styles/foundation.css';
2
- import '../styles/lucide-icon.css';
3
- import '../styles/disclosure-arrow.css';
4
- import '../styles/menu-header.css';
5
- export * from '../menu-header.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"]}