@kerfjs/ui 5.0.0-beta.8 → 5.0.0-beta.80

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 (807) hide show
  1. package/README.md +546 -139
  2. package/ai/application-ui-diagnostic-ids-v1.json +113 -0
  3. package/ai/application-ui-profile-sync.cjs +548 -0
  4. package/ai/application-ui-profile.d.mts +1 -0
  5. package/ai/application-ui-profile.d.ts +106 -0
  6. package/ai/application-ui-profile.defaults.json +96 -0
  7. package/ai/application-ui-profile.mjs +653 -0
  8. package/ai/application-ui-profile.schema.json +140 -0
  9. package/ai/catalog-authoring.json +36 -0
  10. package/ai/catalog-authoring.schema.json +109 -0
  11. package/ai/compile-time-contracts-v1.json +149 -0
  12. package/ai/compile-time-contracts-v1.schema.json +52 -0
  13. package/ai/component-catalog-extension.schema.json +104 -0
  14. package/ai/component-catalog.json +4280 -457
  15. package/ai/component-catalog.schema.json +94 -1
  16. package/ai/component-class-owners.cjs +83 -0
  17. package/ai/component-composition-extension.d.ts +7 -0
  18. package/ai/component-composition-extension.schema.json +7 -0
  19. package/ai/component-composition-rules.json +516 -0
  20. package/ai/component-composition.d.ts +129 -0
  21. package/ai/component-composition.json +7397 -0
  22. package/ai/component-composition.schema.json +408 -0
  23. package/ai/components/README.md +171 -0
  24. package/ai/components/application-tabs.md +65 -0
  25. package/ai/components/badge.md +72 -0
  26. package/ai/components/chip.md +72 -0
  27. package/ai/components/collapsible-panel.md +102 -0
  28. package/ai/components/content-item.md +96 -0
  29. package/ai/components/disclosure-arrow.md +77 -0
  30. package/ai/components/document-baseline.md +75 -0
  31. package/ai/components/empty-state.md +80 -0
  32. package/ai/components/feedback.md +71 -0
  33. package/ai/components/floating-toolbar.md +82 -0
  34. package/ai/components/foundation.md +65 -0
  35. package/ai/components/grid.md +100 -0
  36. package/ai/components/headers.md +63 -0
  37. package/ai/components/layout.md +75 -0
  38. package/ai/components/list-action-row.md +91 -0
  39. package/ai/components/list-header.md +91 -0
  40. package/ai/components/list-inset-control.md +74 -0
  41. package/ai/components/list-inset-text.md +72 -0
  42. package/ai/components/list-item.md +94 -0
  43. package/ai/components/list.md +106 -0
  44. package/ai/components/loading-spinner.md +73 -0
  45. package/ai/components/lucide-icon.md +97 -0
  46. package/ai/components/nav-stack.md +105 -0
  47. package/ai/components/pane.md +104 -0
  48. package/ai/components/popup-menu.md +171 -0
  49. package/ai/components/recipe-app-shell.md +57 -0
  50. package/ai/components/recipe-collapsible-sidebar.md +57 -0
  51. package/ai/components/recipe-compact-toolbar.md +57 -0
  52. package/ai/components/recipe-composer-form.md +57 -0
  53. package/ai/components/recipe-list-detail-dialog.md +57 -0
  54. package/ai/components/recipe-list-workspace-states.md +57 -0
  55. package/ai/components/recipe-loading-inspector.md +57 -0
  56. package/ai/components/recipe-navigation-sidebar.md +57 -0
  57. package/ai/components/recipe-navigation-stack.md +57 -0
  58. package/ai/components/recipe-workspace-header.md +57 -0
  59. package/ai/components/resize.md +106 -0
  60. package/ai/components/row.md +96 -0
  61. package/ai/components/segmented-control.md +82 -0
  62. package/ai/components/select.md +115 -0
  63. package/ai/components/skeleton.md +84 -0
  64. package/ai/components/spacer.md +86 -0
  65. package/ai/components/split-view.md +103 -0
  66. package/ai/components/state-banner.md +94 -0
  67. package/ai/components/sunken-panel.md +79 -0
  68. package/ai/components/surface-scaffold.md +87 -0
  69. package/ai/components/tab-bar.md +113 -0
  70. package/ai/components/tab-navigator.md +95 -0
  71. package/ai/components/tabs.md +95 -0
  72. package/ai/components/text.md +87 -0
  73. package/ai/components/token-search-field.md +107 -0
  74. package/ai/components/toolbar-control-group.md +121 -0
  75. package/ai/components/toolbar-text.md +98 -0
  76. package/ai/components/toolbar.md +101 -0
  77. package/ai/components/value-table.md +73 -0
  78. package/ai/components/wa-accordion-item.md +55 -0
  79. package/ai/components/wa-accordion.md +65 -0
  80. package/ai/components/wa-animated-image.md +55 -0
  81. package/ai/components/wa-animation.md +55 -0
  82. package/ai/components/wa-avatar.md +55 -0
  83. package/ai/components/wa-badge.md +55 -0
  84. package/ai/components/wa-breadcrumb-item.md +53 -0
  85. package/ai/components/wa-breadcrumb.md +55 -0
  86. package/ai/components/wa-button-group.md +59 -0
  87. package/ai/components/wa-button.md +55 -0
  88. package/ai/components/wa-callout.md +58 -0
  89. package/ai/components/wa-card.md +59 -0
  90. package/ai/components/wa-carousel-item.md +53 -0
  91. package/ai/components/wa-carousel.md +55 -0
  92. package/ai/components/wa-checkbox-group.md +55 -0
  93. package/ai/components/wa-checkbox.md +55 -0
  94. package/ai/components/wa-color-picker.md +55 -0
  95. package/ai/components/wa-comparison.md +55 -0
  96. package/ai/components/wa-copy-button.md +55 -0
  97. package/ai/components/wa-details.md +61 -0
  98. package/ai/components/wa-dialog.md +59 -0
  99. package/ai/components/wa-divider.md +53 -0
  100. package/ai/components/wa-drawer.md +55 -0
  101. package/ai/components/wa-dropdown-item.md +60 -0
  102. package/ai/components/wa-dropdown.md +60 -0
  103. package/ai/components/wa-format-bytes.md +53 -0
  104. package/ai/components/wa-format-date.md +53 -0
  105. package/ai/components/wa-format-number.md +53 -0
  106. package/ai/components/wa-icon.md +58 -0
  107. package/ai/components/wa-include.md +53 -0
  108. package/ai/components/wa-input.md +59 -0
  109. package/ai/components/wa-intersection-observer.md +53 -0
  110. package/ai/components/wa-known-date.md +53 -0
  111. package/ai/components/wa-markdown.md +53 -0
  112. package/ai/components/wa-mutation-observer.md +53 -0
  113. package/ai/components/wa-number-input.md +55 -0
  114. package/ai/components/wa-option.md +59 -0
  115. package/ai/components/wa-otp-input.md +53 -0
  116. package/ai/components/wa-page.md +53 -0
  117. package/ai/components/wa-pagination.md +55 -0
  118. package/ai/components/wa-popover.md +55 -0
  119. package/ai/components/wa-popup.md +53 -0
  120. package/ai/components/wa-progress-bar.md +53 -0
  121. package/ai/components/wa-progress-ring.md +53 -0
  122. package/ai/components/wa-qr-code.md +53 -0
  123. package/ai/components/wa-radio-group.md +59 -0
  124. package/ai/components/wa-radio.md +55 -0
  125. package/ai/components/wa-random-content.md +53 -0
  126. package/ai/components/wa-rating.md +55 -0
  127. package/ai/components/wa-relative-time.md +53 -0
  128. package/ai/components/wa-resize-observer.md +53 -0
  129. package/ai/components/wa-scroller.md +53 -0
  130. package/ai/components/wa-select.md +63 -0
  131. package/ai/components/wa-skeleton.md +53 -0
  132. package/ai/components/wa-slider.md +55 -0
  133. package/ai/components/wa-spinner.md +58 -0
  134. package/ai/components/wa-split-panel.md +58 -0
  135. package/ai/components/wa-switch.md +53 -0
  136. package/ai/components/wa-tab-group.md +69 -0
  137. package/ai/components/wa-tab-panel.md +60 -0
  138. package/ai/components/wa-tab.md +59 -0
  139. package/ai/components/wa-tag.md +59 -0
  140. package/ai/components/wa-textarea.md +53 -0
  141. package/ai/components/wa-time-input.md +55 -0
  142. package/ai/components/wa-toast-item.md +60 -0
  143. package/ai/components/wa-toast.md +60 -0
  144. package/ai/components/wa-tooltip.md +55 -0
  145. package/ai/components/wa-tree-item.md +55 -0
  146. package/ai/components/wa-tree.md +55 -0
  147. package/ai/components/wa-zoomable-frame.md +55 -0
  148. package/ai/components/workbench.md +119 -0
  149. package/ai/public-api-signatures-v1.md +2821 -250
  150. package/ai/skill.md +354 -66
  151. package/ai/webawesome-jsx-signatures-v1.md +9 -2
  152. package/analyzer/cli.mjs +49 -0
  153. package/analyzer/component-ownership.d.mts +72 -0
  154. package/analyzer/component-ownership.mjs +429 -0
  155. package/analyzer/index.d.mts +53 -0
  156. package/analyzer/index.mjs +2346 -0
  157. package/analyzer/loud-pairs.d.mts +49 -0
  158. package/analyzer/loud-pairs.mjs +357 -0
  159. package/analyzer/report.schema.json +66 -0
  160. package/analyzer/selectors.d.mts +21 -0
  161. package/analyzer/selectors.mjs +212 -0
  162. package/catalog-projection-cli.mjs +96 -0
  163. package/catalog-projection.d.mts +55 -0
  164. package/catalog-projection.mjs +62 -0
  165. package/dist/app-tab.d.ts +39 -4
  166. package/dist/app-tab.js +2 -1
  167. package/dist/badge.d.ts +54 -0
  168. package/dist/badge.js +3 -0
  169. package/dist/badge.js.map +1 -0
  170. package/dist/browser/badge.js +3 -0
  171. package/dist/browser/catalog.js +26 -0
  172. package/dist/browser/chip.js +3 -0
  173. package/dist/browser/collapsible-panel.js +9 -0
  174. package/dist/browser/content-item.js +3 -0
  175. package/dist/browser/floating-toolbar.js +3 -0
  176. package/dist/browser/grid.js +3 -0
  177. package/dist/browser/list-action-row.js +5 -0
  178. package/dist/browser/{menu-header.js → list-header.js} +5 -3
  179. package/dist/browser/list-inset-control.js +3 -0
  180. package/dist/browser/list-inset-text.js +3 -0
  181. package/dist/browser/list-item.js +5 -0
  182. package/dist/browser/list.js +3 -0
  183. package/dist/browser/nav-stack.js +11 -0
  184. package/dist/browser/pane.js +3 -0
  185. package/dist/browser/popup-menu.js +3 -0
  186. package/dist/browser/row.js +3 -0
  187. package/dist/browser/segmented-control.js +0 -1
  188. package/dist/browser/select.js +2 -1
  189. package/dist/browser/spacer.js +3 -0
  190. package/dist/browser/split-view.js +13 -0
  191. package/dist/browser/state-banner.js +1 -0
  192. package/dist/browser/sunken-panel.js +3 -0
  193. package/dist/browser/surface-scaffold.js +3 -0
  194. package/dist/browser/tab-navigator.js +4 -0
  195. package/dist/browser/text.js +3 -0
  196. package/dist/browser/toolbar-control-group.js +1 -0
  197. package/dist/browser/workbench.js +14 -0
  198. package/dist/catalog-resources.d.ts +48 -0
  199. package/dist/catalog-resources.js +22 -0
  200. package/dist/catalog-resources.js.map +1 -0
  201. package/dist/catalog.d.ts +92 -0
  202. package/dist/catalog.js +541 -0
  203. package/dist/catalog.js.map +1 -0
  204. package/dist/chip.d.ts +36 -0
  205. package/dist/chip.js +3 -0
  206. package/dist/chip.js.map +1 -0
  207. package/dist/chunk-2GOCOLQL.js +270 -0
  208. package/dist/chunk-2GOCOLQL.js.map +1 -0
  209. package/dist/chunk-3CXRQAYT.js +288 -0
  210. package/dist/chunk-3CXRQAYT.js.map +1 -0
  211. package/dist/chunk-3RE2JMZU.js +48 -0
  212. package/dist/chunk-3RE2JMZU.js.map +1 -0
  213. package/dist/chunk-3SXWV2IR.js +295 -0
  214. package/dist/chunk-3SXWV2IR.js.map +1 -0
  215. package/dist/chunk-3XPGJUUQ.js +37 -0
  216. package/dist/chunk-3XPGJUUQ.js.map +1 -0
  217. package/dist/chunk-4Y4L5YEI.js +66 -0
  218. package/dist/chunk-4Y4L5YEI.js.map +1 -0
  219. package/dist/chunk-5BZBIRQG.js +452 -0
  220. package/dist/chunk-5BZBIRQG.js.map +1 -0
  221. package/dist/chunk-5D3WDMIK.js +71 -0
  222. package/dist/chunk-5D3WDMIK.js.map +1 -0
  223. package/dist/chunk-62VMNBV2.js +779 -0
  224. package/dist/chunk-62VMNBV2.js.map +1 -0
  225. package/dist/chunk-75I3SNUJ.js +44 -0
  226. package/dist/chunk-75I3SNUJ.js.map +1 -0
  227. package/dist/chunk-7QQ3HE47.js +17 -0
  228. package/dist/chunk-7QQ3HE47.js.map +1 -0
  229. package/dist/chunk-7TE6XDFI.js +91 -0
  230. package/dist/chunk-7TE6XDFI.js.map +1 -0
  231. package/dist/chunk-A7DYEERU.js +59 -0
  232. package/dist/chunk-A7DYEERU.js.map +1 -0
  233. package/dist/chunk-AN5IWMTM.js +24 -0
  234. package/dist/chunk-AN5IWMTM.js.map +1 -0
  235. package/dist/chunk-ARZ4RSQO.js +48 -0
  236. package/dist/chunk-ARZ4RSQO.js.map +1 -0
  237. package/dist/chunk-BJLXE56E.js +135 -0
  238. package/dist/chunk-BJLXE56E.js.map +1 -0
  239. package/dist/chunk-BYHGRKC3.js +44 -0
  240. package/dist/chunk-BYHGRKC3.js.map +1 -0
  241. package/dist/chunk-CEJ5FK6G.js +288 -0
  242. package/dist/chunk-CEJ5FK6G.js.map +1 -0
  243. package/dist/chunk-CVKIADIS.js +172 -0
  244. package/dist/chunk-CVKIADIS.js.map +1 -0
  245. package/dist/chunk-DQDTZE4W.js +70 -0
  246. package/dist/chunk-DQDTZE4W.js.map +1 -0
  247. package/dist/chunk-EFDCALR3.js +66 -0
  248. package/dist/chunk-EFDCALR3.js.map +1 -0
  249. package/dist/chunk-FL6J644M.js +116 -0
  250. package/dist/chunk-FL6J644M.js.map +1 -0
  251. package/dist/chunk-GS2QD3N7.js +14 -0
  252. package/dist/chunk-GS2QD3N7.js.map +1 -0
  253. package/dist/chunk-H45DAZBL.js +491 -0
  254. package/dist/chunk-H45DAZBL.js.map +1 -0
  255. package/dist/chunk-H7ZJEI3H.js +52 -0
  256. package/dist/chunk-H7ZJEI3H.js.map +1 -0
  257. package/dist/chunk-HFLGWMG3.js +138 -0
  258. package/dist/chunk-HFLGWMG3.js.map +1 -0
  259. package/dist/chunk-HFQDSSED.js +188 -0
  260. package/dist/chunk-HFQDSSED.js.map +1 -0
  261. package/dist/{chunk-56RJXPHG.js → chunk-I4SDIMFA.js} +7 -4
  262. package/dist/chunk-I4SDIMFA.js.map +1 -0
  263. package/dist/chunk-IM3GKYOG.js +202 -0
  264. package/dist/chunk-IM3GKYOG.js.map +1 -0
  265. package/dist/chunk-J3AWE5I4.js +50 -0
  266. package/dist/chunk-J3AWE5I4.js.map +1 -0
  267. package/dist/chunk-JOR5LGYE.js +55 -0
  268. package/dist/chunk-JOR5LGYE.js.map +1 -0
  269. package/dist/chunk-JZM3G6RT.js +149 -0
  270. package/dist/chunk-JZM3G6RT.js.map +1 -0
  271. package/dist/{chunk-7BR3DO2A.js → chunk-LAZLBC2Q.js} +14 -5
  272. package/dist/chunk-LAZLBC2Q.js.map +1 -0
  273. package/dist/chunk-LQKY5S4F.js +506 -0
  274. package/dist/chunk-LQKY5S4F.js.map +1 -0
  275. package/dist/chunk-LRAIS3YB.js +158 -0
  276. package/dist/chunk-LRAIS3YB.js.map +1 -0
  277. package/dist/chunk-MXNIVEVL.js +48 -0
  278. package/dist/chunk-MXNIVEVL.js.map +1 -0
  279. package/dist/chunk-NJZMR7HM.js +135 -0
  280. package/dist/chunk-NJZMR7HM.js.map +1 -0
  281. package/dist/chunk-NMWDHZVM.js +35 -0
  282. package/dist/chunk-NMWDHZVM.js.map +1 -0
  283. package/dist/{chunk-YGN7OMLT.js → chunk-NS2TBYM4.js} +8 -5
  284. package/dist/chunk-NS2TBYM4.js.map +1 -0
  285. package/dist/chunk-NVKRZ5DI.js +222 -0
  286. package/dist/chunk-NVKRZ5DI.js.map +1 -0
  287. package/dist/chunk-NVRJ7C3W.js +83 -0
  288. package/dist/chunk-NVRJ7C3W.js.map +1 -0
  289. package/dist/chunk-O27D24CA.js +250 -0
  290. package/dist/chunk-O27D24CA.js.map +1 -0
  291. package/dist/chunk-PQQQXJGV.js +58 -0
  292. package/dist/chunk-PQQQXJGV.js.map +1 -0
  293. package/dist/chunk-RRCD3A6G.js +139 -0
  294. package/dist/chunk-RRCD3A6G.js.map +1 -0
  295. package/dist/chunk-S3ECMF23.js +33 -0
  296. package/dist/chunk-S3ECMF23.js.map +1 -0
  297. package/dist/chunk-S4ZGTDSG.js +18 -0
  298. package/dist/chunk-S4ZGTDSG.js.map +1 -0
  299. package/dist/chunk-VHXHLZ6R.js +69 -0
  300. package/dist/chunk-VHXHLZ6R.js.map +1 -0
  301. package/dist/chunk-VIGVNDXZ.js +165 -0
  302. package/dist/chunk-VIGVNDXZ.js.map +1 -0
  303. package/dist/chunk-VR7MWD2X.js +91 -0
  304. package/dist/chunk-VR7MWD2X.js.map +1 -0
  305. package/dist/chunk-Y6KT7ZTR.js +109 -0
  306. package/dist/chunk-Y6KT7ZTR.js.map +1 -0
  307. package/dist/chunk-YLJ6X3AC.js +34 -0
  308. package/dist/chunk-YLJ6X3AC.js.map +1 -0
  309. package/dist/collapsible-panel.d.ts +137 -0
  310. package/dist/collapsible-panel.js +135 -0
  311. package/dist/collapsible-panel.js.map +1 -0
  312. package/dist/content-item.d.ts +99 -0
  313. package/dist/content-item.js +4 -0
  314. package/dist/content-item.js.map +1 -0
  315. package/dist/css-values.d.ts +112 -0
  316. package/dist/css-values.js +3 -0
  317. package/dist/css-values.js.map +1 -0
  318. package/dist/device-class.js +34 -6
  319. package/dist/device-class.js.map +1 -1
  320. package/dist/disclosure-arrow.d.ts +6 -1
  321. package/dist/disclosure-arrow.js +2 -1
  322. package/dist/empty-state.d.ts +5 -2
  323. package/dist/empty-state.js +2 -1
  324. package/dist/flex-alignment-4ms8ZbV8.d.ts +5 -0
  325. package/dist/floating-toolbar.d.ts +51 -0
  326. package/dist/floating-toolbar.js +3 -0
  327. package/dist/floating-toolbar.js.map +1 -0
  328. package/dist/grid.d.ts +57 -0
  329. package/dist/grid.js +5 -0
  330. package/dist/grid.js.map +1 -0
  331. package/dist/help-tags-register.d.ts +13 -0
  332. package/dist/help-tags-register.js +9 -0
  333. package/dist/help-tags-register.js.map +1 -0
  334. package/dist/index.d.ts +40 -18
  335. package/dist/index.js +44 -23
  336. package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +21 -9
  337. package/dist/list-action-row.js +8 -0
  338. package/dist/list-action-row.js.map +1 -0
  339. package/dist/list-header.d.ts +98 -0
  340. package/dist/list-header.js +10 -0
  341. package/dist/list-header.js.map +1 -0
  342. package/dist/list-inset-control.d.ts +22 -0
  343. package/dist/list-inset-control.js +3 -0
  344. package/dist/list-inset-control.js.map +1 -0
  345. package/dist/list-inset-text.d.ts +30 -0
  346. package/dist/list-inset-text.js +4 -0
  347. package/dist/list-inset-text.js.map +1 -0
  348. package/dist/list-item.d.ts +62 -0
  349. package/dist/list-item.js +8 -0
  350. package/dist/list-item.js.map +1 -0
  351. package/dist/list.d.ts +63 -0
  352. package/dist/list.js +6 -0
  353. package/dist/list.js.map +1 -0
  354. package/dist/loading-spinner.d.ts +12 -2
  355. package/dist/loading-spinner.js +2 -1
  356. package/dist/lucide-icon.d.ts +14 -2
  357. package/dist/lucide-icon.js +2 -1
  358. package/dist/nav-stack-B1Qc2e5q.d.ts +101 -0
  359. package/dist/nav-stack.d.ts +13 -38
  360. package/dist/nav-stack.js +10 -1
  361. package/dist/pane.d.ts +116 -0
  362. package/dist/pane.js +4 -0
  363. package/dist/pane.js.map +1 -0
  364. package/dist/panel-toolbar-CL9tYOkh.d.ts +72 -0
  365. package/dist/popup-menu-register.d.ts +9 -0
  366. package/dist/popup-menu-register.js +244 -0
  367. package/dist/popup-menu-register.js.map +1 -0
  368. package/dist/popup-menu.d.ts +100 -0
  369. package/dist/popup-menu.js +3 -0
  370. package/dist/popup-menu.js.map +1 -0
  371. package/dist/resizable-region.d.ts +32 -3
  372. package/dist/resizable-region.js +1 -1
  373. package/dist/row.d.ts +48 -0
  374. package/dist/row.js +6 -0
  375. package/dist/row.js.map +1 -0
  376. package/dist/segmented-control.d.ts +12 -9
  377. package/dist/segmented-control.js +1 -2
  378. package/dist/select-register.d.ts +5 -1
  379. package/dist/select-register.js +247 -3
  380. package/dist/select-register.js.map +1 -1
  381. package/dist/select.d.ts +103 -8
  382. package/dist/select.js +3 -1
  383. package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
  384. package/dist/semantic-tone-CdW013KF.d.ts +4 -0
  385. package/dist/sides-BPSWde0A.d.ts +4 -0
  386. package/dist/skeleton.d.ts +14 -7
  387. package/dist/skeleton.js +2 -1
  388. package/dist/spacer.d.ts +18 -0
  389. package/dist/spacer.js +4 -0
  390. package/dist/spacer.js.map +1 -0
  391. package/dist/split-view.d.ts +44 -7
  392. package/dist/split-view.js +124 -10
  393. package/dist/split-view.js.map +1 -1
  394. package/dist/state-banner.d.ts +21 -7
  395. package/dist/state-banner.js +3 -1
  396. package/dist/styles/app-tab.css +224 -0
  397. package/dist/styles/badge.css +118 -0
  398. package/dist/styles/catalog/components/catalog-example-stack.css +9 -0
  399. package/dist/styles/catalog/components/catalog-example.css +168 -0
  400. package/dist/styles/catalog/components/catalog-stage.css +55 -0
  401. package/dist/styles/catalog/components/catalog.css +50 -0
  402. package/dist/styles/catalog.css +5 -0
  403. package/dist/styles/chip.css +138 -0
  404. package/dist/styles/collapsible-panel.css +580 -0
  405. package/dist/styles/components/actions/floating-toolbar/floating-toolbar.css +119 -0
  406. package/dist/styles/components/actions/popup-menu/popup-menu.css +285 -0
  407. package/dist/styles/components/actions/toolbar/toolbar.css +417 -0
  408. package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +891 -0
  409. package/dist/styles/components/actions/toolbar-text/toolbar-text.css +171 -0
  410. package/dist/styles/components/collections/list/list.css +133 -0
  411. package/dist/styles/components/collections/list-action-row/list-action-row.css +258 -0
  412. package/dist/styles/components/collections/list-header/list-header.css +229 -0
  413. package/dist/styles/components/collections/list-inset-control/list-inset-control.css +30 -0
  414. package/dist/styles/components/collections/list-inset-text/list-inset-text.css +29 -0
  415. package/dist/styles/components/collections/list-item/list-item.css +255 -0
  416. package/dist/styles/components/data-display/value-table/value-table.css +105 -0
  417. package/dist/styles/components/feedback/badge/badge.css +118 -0
  418. package/dist/styles/components/feedback/chip/chip.css +138 -0
  419. package/dist/styles/components/feedback/empty-state/empty-state.css +47 -0
  420. package/dist/styles/components/feedback/loading-spinner/loading-spinner.css +25 -0
  421. package/dist/styles/components/feedback/skeleton/skeleton.css +92 -0
  422. package/dist/styles/components/feedback/state-banner/state-banner.css +248 -0
  423. package/dist/styles/components/forms/segmented-control/segmented-control.css +196 -0
  424. package/dist/styles/components/forms/select/select.css +454 -0
  425. package/dist/styles/components/forms/token-search-field/token-search-field.css +392 -0
  426. package/dist/styles/components/layout/collapsible-panel/collapsible-panel.css +580 -0
  427. package/dist/styles/components/layout/grid/grid.css +85 -0
  428. package/dist/styles/components/layout/pane/pane.css +294 -0
  429. package/dist/styles/components/layout/resizable-region/resizable-region.css +545 -0
  430. package/dist/styles/components/layout/row/row.css +111 -0
  431. package/dist/styles/components/layout/spacer/spacer.css +11 -0
  432. package/dist/styles/components/layout/split-view/split-view.css +146 -0
  433. package/dist/styles/components/layout/workbench/workbench.css +1075 -0
  434. package/dist/styles/components/media/lucide-icon/lucide-icon.css +15 -0
  435. package/dist/styles/components/navigation/app-tab/app-tab.css +376 -0
  436. package/dist/styles/components/navigation/disclosure-arrow/disclosure-arrow.css +23 -0
  437. package/dist/styles/components/navigation/nav-stack/nav-stack.css +242 -0
  438. package/dist/styles/components/navigation/tab-bar/tab-bar.css +183 -0
  439. package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +237 -0
  440. package/dist/styles/components/surfaces/content-item/content-item.css +120 -0
  441. package/dist/styles/components/surfaces/sunken-panel/sunken-panel.css +34 -0
  442. package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +111 -0
  443. package/dist/styles/components/typography/text/text.css +158 -0
  444. package/dist/styles/content-item.css +120 -0
  445. package/dist/styles/document.css +33 -0
  446. package/dist/styles/floating-toolbar.css +119 -0
  447. package/dist/styles/foundation.css +187 -45
  448. package/dist/styles/grid.css +85 -0
  449. package/dist/styles/layout.css +3 -41
  450. package/dist/styles/list-action-row.css +258 -0
  451. package/dist/styles/list-header.css +229 -0
  452. package/dist/styles/list-inset-control.css +30 -0
  453. package/dist/styles/list-inset-text.css +29 -0
  454. package/dist/styles/list-item.css +255 -0
  455. package/dist/styles/list.css +133 -0
  456. package/dist/styles/loading-spinner.css +4 -0
  457. package/dist/styles/lucide-icon.css +9 -0
  458. package/dist/styles/nav-stack.css +180 -50
  459. package/dist/styles/pane.css +294 -0
  460. package/dist/styles/popup-menu.css +285 -0
  461. package/dist/styles/resizable-region.css +438 -4
  462. package/dist/styles/row.css +111 -0
  463. package/dist/styles/segmented-control.css +36 -9
  464. package/dist/styles/select.css +337 -21
  465. package/dist/styles/skeleton.css +64 -3
  466. package/dist/styles/spacer.css +11 -0
  467. package/dist/styles/split-view.css +114 -3
  468. package/dist/styles/state-banner.css +94 -19
  469. package/dist/styles/styles.css +13 -4
  470. package/dist/styles/sunken-panel.css +34 -0
  471. package/dist/styles/surface-scaffold.css +111 -0
  472. package/dist/styles/tab-bar.css +147 -9
  473. package/dist/styles/tab-navigator.css +237 -0
  474. package/dist/styles/text.css +158 -0
  475. package/dist/styles/token-search-field.css +167 -56
  476. package/dist/styles/toolbar-control-group.css +710 -30
  477. package/dist/styles/toolbar-text.css +139 -8
  478. package/dist/styles/toolbar.css +367 -11
  479. package/dist/styles/value-table.css +34 -4
  480. package/dist/styles/webawesome.css +388 -16
  481. package/dist/styles/workbench.css +988 -7
  482. package/dist/sunken-panel.d.ts +31 -0
  483. package/dist/sunken-panel.js +3 -0
  484. package/dist/sunken-panel.js.map +1 -0
  485. package/dist/surface-scaffold-register.d.ts +4 -0
  486. package/dist/surface-scaffold-register.js +59 -0
  487. package/dist/surface-scaffold-register.js.map +1 -0
  488. package/dist/surface-scaffold.d.ts +38 -0
  489. package/dist/surface-scaffold.js +3 -0
  490. package/dist/surface-scaffold.js.map +1 -0
  491. package/dist/tab-bar.d.ts +39 -6
  492. package/dist/tab-bar.js +1 -1
  493. package/dist/tab-navigator.d.ts +86 -0
  494. package/dist/tab-navigator.js +95 -0
  495. package/dist/tab-navigator.js.map +1 -0
  496. package/dist/text.d.ts +63 -0
  497. package/dist/text.js +3 -0
  498. package/dist/text.js.map +1 -0
  499. package/dist/token-search-field.d.ts +3 -43
  500. package/dist/token-search-field.js +2 -1
  501. package/dist/token-search-model-DTcTXWMS.d.ts +154 -0
  502. package/dist/token-search-model.d.ts +3 -0
  503. package/dist/token-search-model.js +3 -0
  504. package/dist/token-search-model.js.map +1 -0
  505. package/dist/toolbar-control-group.d.ts +89 -7
  506. package/dist/toolbar-control-group.js +3 -1
  507. package/dist/toolbar-text.d.ts +45 -9
  508. package/dist/toolbar-text.js +2 -1
  509. package/dist/toolbar.d.ts +59 -7
  510. package/dist/toolbar.js +1 -1
  511. package/dist/types-C9BubXfz.d.ts +117 -0
  512. package/dist/value-table.d.ts +11 -3
  513. package/dist/value-table.js +2 -1
  514. package/dist/webawesome.d.ts +8 -1
  515. package/dist/wire-catalog.d.ts +82 -0
  516. package/dist/wire-catalog.js +407 -0
  517. package/dist/wire-catalog.js.map +1 -0
  518. package/dist/wire-content-items.d.ts +11 -0
  519. package/dist/wire-content-items.js +114 -0
  520. package/dist/wire-content-items.js.map +1 -0
  521. package/dist/wire-nav-stack.d.ts +4 -1
  522. package/dist/wire-nav-stack.js +191 -15
  523. package/dist/wire-nav-stack.js.map +1 -1
  524. package/dist/wire-resizable-regions.d.ts +2 -1
  525. package/dist/wire-resizable-regions.js +2 -1
  526. package/dist/wire-scroll-dividers.d.ts +72 -0
  527. package/dist/wire-scroll-dividers.js +3 -0
  528. package/dist/wire-scroll-dividers.js.map +1 -0
  529. package/dist/wire-sidebar.d.ts +63 -0
  530. package/dist/wire-sidebar.js +231 -0
  531. package/dist/wire-sidebar.js.map +1 -0
  532. package/dist/wire-tab-bars.d.ts +19 -2
  533. package/dist/wire-tab-bars.js +1 -1
  534. package/dist/wire-tab-navigator.d.ts +11 -0
  535. package/dist/wire-tab-navigator.js +21 -0
  536. package/dist/wire-tab-navigator.js.map +1 -0
  537. package/dist/wire-token-search-fields.d.ts +65 -3
  538. package/dist/wire-token-search-fields.js +2 -1
  539. package/dist/wire-toolbar-visibility.d.ts +13 -0
  540. package/dist/wire-toolbar-visibility.js +3 -0
  541. package/dist/wire-toolbar-visibility.js.map +1 -0
  542. package/dist/wire-workbench.d.ts +116 -0
  543. package/dist/wire-workbench.js +6 -0
  544. package/dist/wire-workbench.js.map +1 -0
  545. package/dist/workbench.d.ts +246 -9
  546. package/dist/workbench.js +17 -15
  547. package/dist/workbench.js.map +1 -1
  548. package/docs/accessibility.md +497 -26
  549. package/docs/app-layouts.md +141 -10
  550. package/docs/apple-hig.md +1 -0
  551. package/docs/catalog.md +493 -0
  552. package/docs/collapsible-panel.md +382 -0
  553. package/docs/component-contract.md +736 -61
  554. package/docs/component-integration.md +75 -0
  555. package/docs/component-selection.md +617 -97
  556. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  557. package/docs/design/templates/empty-state/filtered.svg +1 -0
  558. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  559. package/docs/design/templates/empty-state/with-action.svg +1 -0
  560. package/docs/design/templates/empty-state-dark.svg +1 -0
  561. package/docs/design/templates/empty-state.svg +1 -0
  562. package/docs/design/templates/list/compact-dark.svg +1 -0
  563. package/docs/design/templates/list/compact.svg +1 -0
  564. package/docs/design/templates/list/stack-dark.svg +1 -0
  565. package/docs/design/templates/list/stack.svg +1 -0
  566. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  567. package/docs/design/templates/list-action-row/default.svg +1 -0
  568. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  569. package/docs/design/templates/list-action-row/selected.svg +1 -0
  570. package/docs/design/templates/list-action-row-dark.svg +1 -0
  571. package/docs/design/templates/list-action-row.svg +1 -0
  572. package/docs/design/templates/list-dark.svg +1 -0
  573. package/docs/design/templates/list-header/action-dark.svg +1 -0
  574. package/docs/design/templates/list-header/action.svg +1 -0
  575. package/docs/design/templates/list-header/count-dark.svg +1 -0
  576. package/docs/design/templates/list-header/count.svg +1 -0
  577. package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
  578. package/docs/design/templates/list-header/inline-action.svg +1 -0
  579. package/docs/design/templates/list-header/size-l-dark.svg +1 -0
  580. package/docs/design/templates/list-header/size-l.svg +1 -0
  581. package/docs/design/templates/list-header/size-m-dark.svg +1 -0
  582. package/docs/design/templates/list-header/size-m.svg +1 -0
  583. package/docs/design/templates/list-header/size-xl-dark.svg +1 -0
  584. package/docs/design/templates/list-header/size-xl.svg +1 -0
  585. package/docs/design/templates/list-header/size-xs-dark.svg +1 -0
  586. package/docs/design/templates/list-header/size-xs.svg +1 -0
  587. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  588. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  589. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  590. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  591. package/docs/design/templates/list-header-dark.svg +1 -0
  592. package/docs/design/templates/list-header.svg +1 -0
  593. package/docs/design/templates/list-item/default-dark.svg +1 -0
  594. package/docs/design/templates/list-item/default.svg +1 -0
  595. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  596. package/docs/design/templates/list-item/multiline.svg +1 -0
  597. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  598. package/docs/design/templates/list-item/selected.svg +1 -0
  599. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  600. package/docs/design/templates/list-item/trailing.svg +1 -0
  601. package/docs/design/templates/list-item-dark.svg +1 -0
  602. package/docs/design/templates/list-item.svg +1 -0
  603. package/docs/design/templates/list.svg +1 -0
  604. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  605. package/docs/design/templates/segmented-control/equal.svg +1 -0
  606. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  607. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  608. package/docs/design/templates/segmented-control-dark.svg +1 -0
  609. package/docs/design/templates/segmented-control.svg +1 -0
  610. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  611. package/docs/design/templates/skeleton/avatar.svg +1 -0
  612. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  613. package/docs/design/templates/skeleton/block.svg +1 -0
  614. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  615. package/docs/design/templates/skeleton/lines.svg +1 -0
  616. package/docs/design/templates/skeleton-dark.svg +1 -0
  617. package/docs/design/templates/skeleton.svg +1 -0
  618. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  619. package/docs/design/templates/state-banner/danger.svg +1 -0
  620. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  621. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  622. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  623. package/docs/design/templates/state-banner/info.svg +1 -0
  624. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  625. package/docs/design/templates/state-banner/success.svg +1 -0
  626. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  627. package/docs/design/templates/state-banner/warning.svg +1 -0
  628. package/docs/design/templates/state-banner-dark.svg +1 -0
  629. package/docs/design/templates/state-banner.svg +1 -0
  630. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  631. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  632. package/docs/design/templates/tab-bar-dark.svg +1 -0
  633. package/docs/design/templates/tab-bar.svg +1 -0
  634. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  635. package/docs/design/templates/token-search-field/empty.svg +1 -0
  636. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  637. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  638. package/docs/design/templates/token-search-field-dark.svg +1 -0
  639. package/docs/design/templates/token-search-field.svg +1 -0
  640. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  641. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  642. package/docs/design/templates/toolbar/width-visibility-320-dark.svg +1 -0
  643. package/docs/design/templates/toolbar/width-visibility-320.svg +1 -0
  644. package/docs/design/templates/toolbar/width-visibility-600-dark.svg +1 -0
  645. package/docs/design/templates/toolbar/width-visibility-600.svg +1 -0
  646. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  647. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  648. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  649. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  650. package/docs/design/templates/toolbar-control-group/icon-tile-brand-dark.svg +1 -0
  651. package/docs/design/templates/toolbar-control-group/icon-tile-brand.svg +1 -0
  652. package/docs/design/templates/toolbar-control-group/icon-tile-danger-dark.svg +1 -0
  653. package/docs/design/templates/toolbar-control-group/icon-tile-danger.svg +1 -0
  654. package/docs/design/templates/toolbar-control-group/icon-tile-neutral-dark.svg +1 -0
  655. package/docs/design/templates/toolbar-control-group/icon-tile-neutral.svg +1 -0
  656. package/docs/design/templates/toolbar-control-group/icon-tile-success-dark.svg +1 -0
  657. package/docs/design/templates/toolbar-control-group/icon-tile-success.svg +1 -0
  658. package/docs/design/templates/toolbar-control-group/icon-tile-warning-dark.svg +1 -0
  659. package/docs/design/templates/toolbar-control-group/icon-tile-warning.svg +1 -0
  660. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  661. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  662. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  663. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  664. package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
  665. package/docs/design/templates/toolbar-control-group.svg +1 -0
  666. package/docs/design/templates/toolbar-dark.svg +1 -0
  667. package/docs/design/templates/toolbar-text/dark-tone-dark.svg +1 -0
  668. package/docs/design/templates/toolbar-text/dark-tone.svg +1 -0
  669. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  670. package/docs/design/templates/toolbar-text/default.svg +1 -0
  671. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  672. package/docs/design/templates/toolbar-text/large.svg +1 -0
  673. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  674. package/docs/design/templates/toolbar-text/small.svg +1 -0
  675. package/docs/design/templates/toolbar-text-dark.svg +1 -0
  676. package/docs/design/templates/toolbar-text.svg +1 -0
  677. package/docs/design/templates/toolbar.svg +1 -0
  678. package/docs/design/templates/value-table/details-dark.svg +1 -0
  679. package/docs/design/templates/value-table/details.svg +1 -0
  680. package/docs/design/templates/value-table-dark.svg +1 -0
  681. package/docs/design/templates/value-table.svg +1 -0
  682. package/docs/design/templates.md +140 -0
  683. package/docs/design-philosophy.md +48 -20
  684. package/docs/device-class.md +10 -9
  685. package/docs/document-baseline.md +42 -0
  686. package/docs/examples/application-ui-profile.json +60 -0
  687. package/docs/examples/command-palette-adapter.tsx +69 -17
  688. package/docs/examples/component-catalog-extension.json +52 -0
  689. package/docs/examples/component-composition-extension.json +80 -0
  690. package/docs/layout.md +601 -59
  691. package/docs/nav-stack.md +154 -14
  692. package/docs/recipes.md +142 -55
  693. package/docs/split-view.md +77 -6
  694. package/docs/sunken-panel.md +93 -0
  695. package/docs/surface-scaffold.md +74 -0
  696. package/docs/tab-navigator.md +210 -0
  697. package/docs/type-contracts.md +135 -0
  698. package/docs/ui-analyzer.md +404 -0
  699. package/docs/ui-doctor.md +202 -0
  700. package/docs/ui-evaluator.md +139 -0
  701. package/docs/ux-demo.md +46 -16
  702. package/docs/webawesome-theme.md +188 -16
  703. package/docs/workbench.md +621 -12
  704. package/doctor/cli.mjs +120 -0
  705. package/doctor/component-style-checks.mjs +457 -0
  706. package/doctor/config.schema.json +94 -0
  707. package/doctor/eslint-diagnostics.d.mts +24 -0
  708. package/doctor/eslint-diagnostics.mjs +24 -0
  709. package/doctor/index.d.mts +122 -0
  710. package/doctor/index.mjs +1403 -0
  711. package/doctor/report.schema.json +118 -0
  712. package/evaluator/cli.mjs +89 -0
  713. package/evaluator/index.d.mts +90 -0
  714. package/evaluator/index.mjs +1203 -0
  715. package/evaluator/report.schema.json +152 -0
  716. package/llms.txt +510 -49
  717. package/package.json +266 -44
  718. package/scripts/component-catalog-extension-validation.mjs +28 -0
  719. package/traversal-exclusions.mjs +27 -0
  720. package/ux-demo/recipes/app-shell.tsx +205 -17
  721. package/ux-demo/recipes/collapsible-sidebar.tsx +260 -0
  722. package/ux-demo/recipes/compact-toolbar.tsx +135 -14
  723. package/ux-demo/recipes/composer-form.tsx +133 -21
  724. package/ux-demo/recipes/list-detail-dialog.tsx +286 -0
  725. package/ux-demo/recipes/list-workspace-states.tsx +183 -11
  726. package/ux-demo/recipes/loaders.ts +15 -5
  727. package/ux-demo/recipes/loading-inspector.tsx +204 -0
  728. package/ux-demo/recipes/mount-recipe.ts +28 -10
  729. package/ux-demo/recipes/navigation-sidebar.tsx +139 -13
  730. package/ux-demo/recipes/navigation-stack.tsx +81 -26
  731. package/ux-demo/recipes/types.ts +23 -2
  732. package/ux-demo/recipes/workspace-header.tsx +86 -5
  733. package/dist/browser/menu-action-row.js +0 -4
  734. package/dist/browser/menu-item.js +0 -4
  735. package/dist/browser/panel-header.js +0 -7
  736. package/dist/chunk-2RJBFNB6.js +0 -172
  737. package/dist/chunk-2RJBFNB6.js.map +0 -1
  738. package/dist/chunk-2Z5TWHKQ.js +0 -34
  739. package/dist/chunk-2Z5TWHKQ.js.map +0 -1
  740. package/dist/chunk-3YD6ZNRA.js +0 -34
  741. package/dist/chunk-3YD6ZNRA.js.map +0 -1
  742. package/dist/chunk-55DATV3A.js +0 -10
  743. package/dist/chunk-55DATV3A.js.map +0 -1
  744. package/dist/chunk-56RJXPHG.js.map +0 -1
  745. package/dist/chunk-7BR3DO2A.js.map +0 -1
  746. package/dist/chunk-7LDCTU7D.js +0 -134
  747. package/dist/chunk-7LDCTU7D.js.map +0 -1
  748. package/dist/chunk-AQNKJRFH.js +0 -79
  749. package/dist/chunk-AQNKJRFH.js.map +0 -1
  750. package/dist/chunk-B24C4A6T.js +0 -22
  751. package/dist/chunk-B24C4A6T.js.map +0 -1
  752. package/dist/chunk-BLK3UEEI.js +0 -23
  753. package/dist/chunk-BLK3UEEI.js.map +0 -1
  754. package/dist/chunk-BNQ2YDV4.js +0 -20
  755. package/dist/chunk-BNQ2YDV4.js.map +0 -1
  756. package/dist/chunk-DAFFDO33.js +0 -14
  757. package/dist/chunk-DAFFDO33.js.map +0 -1
  758. package/dist/chunk-H6URQGJI.js +0 -42
  759. package/dist/chunk-H6URQGJI.js.map +0 -1
  760. package/dist/chunk-I7INRJO4.js +0 -17
  761. package/dist/chunk-I7INRJO4.js.map +0 -1
  762. package/dist/chunk-LC3YSAZC.js +0 -39
  763. package/dist/chunk-LC3YSAZC.js.map +0 -1
  764. package/dist/chunk-M5JRI6MN.js +0 -27
  765. package/dist/chunk-M5JRI6MN.js.map +0 -1
  766. package/dist/chunk-MBR3TYNL.js +0 -14
  767. package/dist/chunk-MBR3TYNL.js.map +0 -1
  768. package/dist/chunk-MFKMHK5W.js +0 -10
  769. package/dist/chunk-MFKMHK5W.js.map +0 -1
  770. package/dist/chunk-MQIZAD4A.js +0 -227
  771. package/dist/chunk-MQIZAD4A.js.map +0 -1
  772. package/dist/chunk-PONXLV5U.js +0 -19
  773. package/dist/chunk-PONXLV5U.js.map +0 -1
  774. package/dist/chunk-RUNWEPR4.js +0 -10
  775. package/dist/chunk-RUNWEPR4.js.map +0 -1
  776. package/dist/chunk-W2FK7ZNY.js +0 -26
  777. package/dist/chunk-W2FK7ZNY.js.map +0 -1
  778. package/dist/chunk-WVPYVDXY.js +0 -15
  779. package/dist/chunk-WVPYVDXY.js.map +0 -1
  780. package/dist/chunk-YGN7OMLT.js.map +0 -1
  781. package/dist/chunk-YKUUZPED.js +0 -24
  782. package/dist/chunk-YKUUZPED.js.map +0 -1
  783. package/dist/menu-action-row.js +0 -5
  784. package/dist/menu-action-row.js.map +0 -1
  785. package/dist/menu-header.d.ts +0 -43
  786. package/dist/menu-header.js +0 -7
  787. package/dist/menu-header.js.map +0 -1
  788. package/dist/menu-item.d.ts +0 -33
  789. package/dist/menu-item.js +0 -5
  790. package/dist/menu-item.js.map +0 -1
  791. package/dist/panel-header.d.ts +0 -36
  792. package/dist/panel-header.js +0 -7
  793. package/dist/panel-header.js.map +0 -1
  794. package/dist/styles/menu-action-row.css +0 -160
  795. package/dist/styles/menu-header.css +0 -160
  796. package/dist/styles/menu-item.css +0 -123
  797. package/dist/styles/panel-header.css +0 -64
  798. package/dist/styles/tab-scaffold.css +0 -84
  799. package/dist/tab-scaffold.d.ts +0 -30
  800. package/dist/tab-scaffold.js +0 -16
  801. package/dist/tab-scaffold.js.map +0 -1
  802. package/dist/wire-tab-scaffold.d.ts +0 -11
  803. package/dist/wire-tab-scaffold.js +0 -16
  804. package/dist/wire-tab-scaffold.js.map +0 -1
  805. package/docs/tab-scaffold.md +0 -41
  806. package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
  807. package/ux-demo/recipes/recipes.css +0 -355
@@ -0,0 +1,114 @@
1
+ // src/components/surfaces/content-item/wiring/wire-content-items.ts
2
+ var ITEM_SELECTOR = '[data-component="content-item"][data-interactive="true"]';
3
+ var NESTED_CONTROL_SELECTOR = 'button, a[href], input, select, textarea, [contenteditable="true"], [role="button"]';
4
+ var MULTI_GRID_SELECTOR = '[role="grid"][aria-multiselectable="true"]';
5
+ function nextTile(item, rows, key) {
6
+ const current = item.getBoundingClientRect();
7
+ const centerX = current.left + current.width / 2;
8
+ const candidates = rows.filter((row) => row !== item).map((row) => {
9
+ const rect = row.getBoundingClientRect();
10
+ return { row, x: rect.left + rect.width / 2, y: rect.top };
11
+ });
12
+ const sameLine = (y) => Math.abs(y - current.top) < 1;
13
+ const directed = candidates.filter(
14
+ ({ x, y }) => key === "ArrowLeft" ? sameLine(y) && x < centerX : key === "ArrowRight" ? sameLine(y) && x > centerX : key === "ArrowUp" ? y < current.top - 1 : y > current.top + 1
15
+ );
16
+ directed.sort((a, b) => {
17
+ if (key === "ArrowLeft") return b.x - a.x;
18
+ if (key === "ArrowRight") return a.x - b.x;
19
+ const vertical = Math.abs(a.y - current.top) - Math.abs(b.y - current.top);
20
+ return vertical || Math.abs(a.x - centerX) - Math.abs(b.x - centerX);
21
+ });
22
+ return directed[0]?.row;
23
+ }
24
+ function actionItem(root, event) {
25
+ const target = event.target;
26
+ if (!(target instanceof Element)) return null;
27
+ const item = target.closest(ITEM_SELECTOR);
28
+ if (!item || !root.contains(item) || item.dataset.disabled === "true")
29
+ return null;
30
+ for (const node of event.composedPath()) {
31
+ if (node === item) break;
32
+ if (node instanceof Element && node.matches(NESTED_CONTROL_SELECTOR))
33
+ return null;
34
+ }
35
+ return item;
36
+ }
37
+ function isContentItemActivation(event, item) {
38
+ return actionItem(item, event) === item;
39
+ }
40
+ function wireContentItems(root) {
41
+ let pendingSpace = null;
42
+ const clearSpace = () => {
43
+ pendingSpace?.removeAttribute("data-kui-pressed");
44
+ pendingSpace = null;
45
+ };
46
+ const keydown = (event) => {
47
+ if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey)
48
+ return;
49
+ const item = actionItem(root, event);
50
+ if (!item) return;
51
+ if (item.dataset.selectionMode === "multiple" && [
52
+ "ArrowDown",
53
+ "ArrowUp",
54
+ "ArrowLeft",
55
+ "ArrowRight",
56
+ "Home",
57
+ "End"
58
+ ].includes(event.key)) {
59
+ const grid = item.closest(MULTI_GRID_SELECTOR);
60
+ if (!grid) return;
61
+ const rows = Array.from(
62
+ grid.querySelectorAll(
63
+ `${ITEM_SELECTOR}[data-selection-mode="multiple"]:not([data-disabled="true"])`
64
+ )
65
+ ).filter((row) => row.closest(MULTI_GRID_SELECTOR) === grid);
66
+ const index = rows.indexOf(item);
67
+ if (index < 0) return;
68
+ const isTileGrid = grid.getAttribute("data-component") === "grid";
69
+ const next = event.key === "Home" ? rows[0] : event.key === "End" ? rows[rows.length - 1] : isTileGrid ? nextTile(item, rows, event.key) : event.key === "ArrowDown" || event.key === "ArrowUp" ? rows[index + (event.key === "ArrowDown" ? 1 : -1)] : void 0;
70
+ if (next) {
71
+ event.preventDefault();
72
+ next.focus();
73
+ }
74
+ return;
75
+ }
76
+ if (event.key === "Enter") {
77
+ event.preventDefault();
78
+ item.click();
79
+ return;
80
+ }
81
+ if (event.key === " " || event.key === "Spacebar") {
82
+ event.preventDefault();
83
+ if (event.repeat) return;
84
+ clearSpace();
85
+ pendingSpace = item;
86
+ item.setAttribute("data-kui-pressed", "true");
87
+ }
88
+ };
89
+ const keyup = (event) => {
90
+ if (event.key !== " " && event.key !== "Spacebar") return;
91
+ const item = pendingSpace;
92
+ if (!item) return;
93
+ event.preventDefault();
94
+ clearSpace();
95
+ if (item === actionItem(root, event) && item.ownerDocument.activeElement === item)
96
+ item.click();
97
+ };
98
+ const focusout = (event) => {
99
+ if (event.target === pendingSpace) clearSpace();
100
+ };
101
+ root.addEventListener("keydown", keydown);
102
+ root.addEventListener("keyup", keyup);
103
+ root.addEventListener("focusout", focusout);
104
+ return () => {
105
+ clearSpace();
106
+ root.removeEventListener("keydown", keydown);
107
+ root.removeEventListener("keyup", keyup);
108
+ root.removeEventListener("focusout", focusout);
109
+ };
110
+ }
111
+
112
+ export { isContentItemActivation, wireContentItems };
113
+
114
+ //# sourceMappingURL=wire-content-items.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/surfaces/content-item/wiring/wire-content-items.ts"],"names":[],"mappings":"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","file":"wire-content-items.js","sourcesContent":["const ITEM_SELECTOR =\n '[data-component=\"content-item\"][data-interactive=\"true\"]';\nconst NESTED_CONTROL_SELECTOR =\n 'button, a[href], input, select, textarea, [contenteditable=\"true\"], [role=\"button\"]';\nconst MULTI_GRID_SELECTOR = '[role=\"grid\"][aria-multiselectable=\"true\"]';\n\nfunction nextTile(\n item: HTMLElement,\n rows: HTMLElement[],\n key: string,\n): HTMLElement | undefined {\n const current = item.getBoundingClientRect();\n const centerX = current.left + current.width / 2;\n const candidates = rows\n .filter((row) => row !== item)\n .map((row) => {\n const rect = row.getBoundingClientRect();\n return { row, x: rect.left + rect.width / 2, y: rect.top };\n });\n const sameLine = (y: number) => Math.abs(y - current.top) < 1;\n const directed = candidates.filter(({ x, y }) =>\n key === 'ArrowLeft'\n ? sameLine(y) && x < centerX\n : key === 'ArrowRight'\n ? sameLine(y) && x > centerX\n : key === 'ArrowUp'\n ? y < current.top - 1\n : y > current.top + 1,\n );\n directed.sort((a, b) => {\n if (key === 'ArrowLeft') return b.x - a.x;\n if (key === 'ArrowRight') return a.x - b.x;\n const vertical = Math.abs(a.y - current.top) - Math.abs(b.y - current.top);\n return vertical || Math.abs(a.x - centerX) - Math.abs(b.x - centerX);\n });\n return directed[0]?.row;\n}\n\nfunction actionItem(root: HTMLElement, event: Event) {\n const target = event.target;\n if (!(target instanceof Element)) return null;\n const item = target.closest<HTMLElement>(ITEM_SELECTOR);\n if (!item || !root.contains(item) || item.dataset.disabled === 'true')\n return null;\n // Composed events expose native controls inside a custom element's shadow\n // root even though event.target is retargeted to its host here.\n for (const node of event.composedPath()) {\n if (node === item) break;\n if (node instanceof Element && node.matches(NESTED_CONTROL_SELECTOR))\n return null;\n }\n return item;\n}\n\n/** True when a card action originated on the card rather than a nested control. */\nexport function isContentItemActivation(\n event: Event,\n item: HTMLElement,\n): boolean {\n return actionItem(item, event) === item;\n}\n\n/**\n * Give interactive ContentItems native-like Enter/Space activation with one\n * delegated listener pair. Space activates on release and is cancelled if\n * focus moves; the item's own `data-action` still goes through the app's\n * ordinary delegated click handler. Returns a disposer.\n */\nexport function wireContentItems(root: HTMLElement): () => void {\n let pendingSpace: HTMLElement | null = null;\n\n const clearSpace = () => {\n pendingSpace?.removeAttribute('data-kui-pressed');\n pendingSpace = null;\n };\n\n const keydown = (event: KeyboardEvent) => {\n if (\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey\n )\n return;\n const item = actionItem(root, event);\n if (!item) return;\n if (\n item.dataset.selectionMode === 'multiple' &&\n [\n 'ArrowDown',\n 'ArrowUp',\n 'ArrowLeft',\n 'ArrowRight',\n 'Home',\n 'End',\n ].includes(event.key)\n ) {\n const grid = item.closest(MULTI_GRID_SELECTOR);\n if (!grid) return;\n const rows = Array.from(\n grid.querySelectorAll<HTMLElement>(\n `${ITEM_SELECTOR}[data-selection-mode=\"multiple\"]:not([data-disabled=\"true\"])`,\n ),\n ).filter((row) => row.closest(MULTI_GRID_SELECTOR) === grid);\n const index = rows.indexOf(item);\n if (index < 0) return;\n const isTileGrid = grid.getAttribute('data-component') === 'grid';\n const next =\n event.key === 'Home'\n ? rows[0]\n : event.key === 'End'\n ? rows[rows.length - 1]\n : isTileGrid\n ? nextTile(item, rows, event.key)\n : event.key === 'ArrowDown' || event.key === 'ArrowUp'\n ? rows[index + (event.key === 'ArrowDown' ? 1 : -1)]\n : undefined;\n if (next) {\n event.preventDefault();\n next.focus();\n }\n return;\n }\n if (event.key === 'Enter') {\n event.preventDefault();\n item.click();\n return;\n }\n if (event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n if (event.repeat) return;\n clearSpace();\n pendingSpace = item;\n item.setAttribute('data-kui-pressed', 'true');\n }\n };\n\n const keyup = (event: KeyboardEvent) => {\n if (event.key !== ' ' && event.key !== 'Spacebar') return;\n const item = pendingSpace;\n if (!item) return;\n event.preventDefault();\n clearSpace();\n if (\n item === actionItem(root, event) &&\n item.ownerDocument.activeElement === item\n )\n item.click();\n };\n\n const focusout = (event: FocusEvent) => {\n if (event.target === pendingSpace) clearSpace();\n };\n\n root.addEventListener('keydown', keydown);\n root.addEventListener('keyup', keyup);\n root.addEventListener('focusout', focusout);\n return () => {\n clearSpace();\n root.removeEventListener('keydown', keydown);\n root.removeEventListener('keyup', keyup);\n root.removeEventListener('focusout', focusout);\n };\n}\n"]}
@@ -8,7 +8,10 @@ interface WireNavStackOptions {
8
8
  * Animate a `NavStack`'s push/pop transitions and wire its back control. The app
9
9
  * owns the stack (a signal of `NavStackView[]`) and re-renders `NavStack` when it
10
10
  * changes; this helper slides the content and settles the chrome across each
11
- * change, and calls `onBack` when the back control is used. Returns a disposer.
11
+ * change, moves focus into every new top view, restores that view's last focused
12
+ * descendant on pop, and calls `onBack` when the back control is used. Mark a
13
+ * preferred initial target with `data-nav-focus`; otherwise the first focusable
14
+ * descendant (or the view itself) receives focus. Returns a disposer.
12
15
  */
13
16
  declare function wireNavStack(root: Element, options?: WireNavStackOptions): () => void;
14
17
 
@@ -1,17 +1,39 @@
1
1
  import { delegate } from 'kerfjs';
2
2
 
3
- // src/wire-nav-stack.ts
3
+ // src/components/navigation/nav-stack/wiring/wire-nav-stack.ts
4
4
  var DEFAULT_DURATION = 200;
5
+ var FOCUSABLE_SELECTOR = [
6
+ "a[href]",
7
+ "button:not([disabled])",
8
+ "input:not([disabled])",
9
+ "select:not([disabled])",
10
+ "textarea:not([disabled])",
11
+ '[tabindex]:not([tabindex="-1"])'
12
+ ].join(",");
5
13
  function viewsOf(viewport) {
6
- return Array.from(viewport.querySelectorAll(":scope > .kui-nav-stack__view"));
14
+ return Array.from(
15
+ viewport.querySelectorAll(":scope > .kui-nav-stack__view")
16
+ );
7
17
  }
8
18
  function topView(viewport) {
9
- const live = viewsOf(viewport).filter((view) => view.dataset.navExiting !== "true");
19
+ const live = viewsOf(viewport).filter(
20
+ (view) => view.dataset.navExiting !== "true"
21
+ );
10
22
  return live[live.length - 1];
11
23
  }
12
24
  function reducedMotion(view) {
13
25
  return typeof view.matchMedia === "function" && view.matchMedia("(prefers-reduced-motion: reduce)").matches;
14
26
  }
27
+ function chromeOf(section) {
28
+ return Array.from(
29
+ section.querySelectorAll(
30
+ ":scope > [data-nav-stack-chrome]:not([data-nav-chrome-copy]), :scope > [data-nav-stack-bottom]:not([data-nav-chrome-copy])"
31
+ )
32
+ );
33
+ }
34
+ function availableFocusTarget(element) {
35
+ return element instanceof HTMLElement && element.isConnected && !element.matches('[disabled], [aria-disabled="true"]') && !element.closest('[inert], [hidden], [aria-hidden="true"]');
36
+ }
15
37
  function wireNavStack(root, options = {}) {
16
38
  const section = root.matches('[data-component="nav-stack"]') ? root : root.querySelector('[data-component="nav-stack"]');
17
39
  const viewport = section?.querySelector("[data-nav-stack-viewport]");
@@ -19,9 +41,52 @@ function wireNavStack(root, options = {}) {
19
41
  };
20
42
  const view = section.ownerDocument.defaultView ?? window;
21
43
  const duration = options.duration ?? DEFAULT_DURATION;
22
- const disposeBack = delegate(section, "click", "[data-nav-back]", () => options.onBack?.());
44
+ const previousDuration = section.style.getPropertyValue(
45
+ "--kui-nav-stack-transition-duration"
46
+ );
47
+ section.style.setProperty(
48
+ "--kui-nav-stack-transition-duration",
49
+ `${Math.max(0, duration)}ms`
50
+ );
51
+ const disposeBack = delegate(
52
+ section,
53
+ "click",
54
+ "[data-nav-back]",
55
+ () => options.onBack?.()
56
+ );
23
57
  let activeKey = topView(viewport)?.dataset.navKey;
24
58
  const timers = /* @__PURE__ */ new Set();
59
+ const frames = /* @__PURE__ */ new Set();
60
+ const frame = (fn) => {
61
+ const id = view.requestAnimationFrame(() => {
62
+ frames.delete(id);
63
+ fn();
64
+ });
65
+ frames.add(id);
66
+ };
67
+ const finishTransition = () => {
68
+ for (const id of frames) view.cancelAnimationFrame(id);
69
+ frames.clear();
70
+ for (const id of timers) view.clearTimeout(id);
71
+ timers.clear();
72
+ section.querySelectorAll(":scope > [data-nav-chrome-copy]").forEach((element) => element.remove());
73
+ chromeOf(section).forEach(
74
+ (element) => element.classList.remove("kui-nav-stack__chrome--entering")
75
+ );
76
+ viewsOf(viewport).forEach((element) => {
77
+ if (element.dataset.navExiting === "true") element.remove();
78
+ else {
79
+ element.classList.remove("kui-nav-stack__view--entering");
80
+ delete element.dataset.navRevealed;
81
+ }
82
+ });
83
+ delete section.dataset.navChromeTransition;
84
+ };
85
+ const rememberedFocus = /* @__PURE__ */ new Map();
86
+ const generatedFallbacks = /* @__PURE__ */ new Map();
87
+ let chromeSnapshots = chromeOf(section).map(
88
+ (element) => element.cloneNode(true)
89
+ );
25
90
  const settle = (fn) => {
26
91
  if (duration <= 0 || reducedMotion(view)) {
27
92
  fn();
@@ -39,47 +104,158 @@ function wireNavStack(root, options = {}) {
39
104
  el.classList.add("kui-nav-stack__view--entering");
40
105
  if (animated) {
41
106
  void el.offsetWidth;
42
- view.requestAnimationFrame(() => el.classList.remove("kui-nav-stack__view--entering"));
107
+ frame(() => el.classList.remove("kui-nav-stack__view--entering"));
43
108
  } else {
44
109
  el.classList.remove("kui-nav-stack__view--entering");
45
110
  }
46
111
  } else if (animated) {
47
- view.requestAnimationFrame(() => el.classList.add("kui-nav-stack__view--exiting"));
112
+ frame(() => el.classList.add("kui-nav-stack__view--exiting"));
48
113
  } else {
49
114
  el.classList.add("kui-nav-stack__view--exiting");
50
115
  }
51
116
  };
117
+ const rememberFocusedView = (target) => {
118
+ if (!(target instanceof HTMLElement)) return;
119
+ const owner = target.closest(".kui-nav-stack__view");
120
+ const key = owner?.dataset.navKey;
121
+ if (key && owner !== target && viewport.contains(owner))
122
+ rememberedFocus.set(key, target);
123
+ };
124
+ const focusInto = (targetView) => {
125
+ const key = targetView.dataset.navKey;
126
+ const remembered = key ? rememberedFocus.get(key) : void 0;
127
+ const preferred = Array.from(
128
+ targetView.querySelectorAll("[data-nav-focus]")
129
+ ).find(availableFocusTarget);
130
+ const first = Array.from(
131
+ targetView.querySelectorAll(FOCUSABLE_SELECTOR)
132
+ ).find(availableFocusTarget);
133
+ const target = (availableFocusTarget(remembered) && targetView.contains(remembered) ? remembered : void 0) ?? preferred ?? first;
134
+ if (target) {
135
+ target.focus({ preventScroll: true });
136
+ return;
137
+ }
138
+ if (!generatedFallbacks.has(targetView)) {
139
+ generatedFallbacks.set(
140
+ targetView,
141
+ targetView.hasAttribute("tabindex") ? targetView.getAttribute("tabindex") : null
142
+ );
143
+ targetView.tabIndex = -1;
144
+ }
145
+ targetView.focus({ preventScroll: true });
146
+ };
147
+ const onFocusIn = (event) => rememberFocusedView(event.target);
148
+ section.addEventListener("focusin", onFocusIn);
149
+ rememberFocusedView(section.ownerDocument.activeElement);
150
+ const crossFadeChrome = () => {
151
+ const current = chromeOf(section);
152
+ const animated = duration > 0 && !reducedMotion(view);
153
+ if (!animated) {
154
+ chromeSnapshots = current.map(
155
+ (element) => element.cloneNode(true)
156
+ );
157
+ return;
158
+ }
159
+ section.dataset.navChromeTransition = "true";
160
+ const copies = chromeSnapshots.map((snapshot) => {
161
+ const copy = snapshot.cloneNode(true);
162
+ copy.classList.add("kui-nav-stack__chrome-copy");
163
+ copy.dataset.navChromeCopy = "";
164
+ copy.setAttribute("aria-hidden", "true");
165
+ copy.setAttribute("inert", "");
166
+ if (copy.hasAttribute("data-nav-stack-bottom"))
167
+ copy.classList.add("kui-nav-stack__chrome-copy--bottom");
168
+ section.append(copy);
169
+ return copy;
170
+ });
171
+ current.forEach(
172
+ (element) => element.classList.add("kui-nav-stack__chrome--entering")
173
+ );
174
+ void section.offsetWidth;
175
+ frame(() => {
176
+ current.forEach(
177
+ (element) => element.classList.remove("kui-nav-stack__chrome--entering")
178
+ );
179
+ copies.forEach(
180
+ (copy) => copy.classList.add("kui-nav-stack__chrome-copy--exiting")
181
+ );
182
+ });
183
+ settle(() => {
184
+ copies.forEach((copy) => copy.remove());
185
+ delete section.dataset.navChromeTransition;
186
+ });
187
+ chromeSnapshots = current.map((element) => {
188
+ const snapshot = element.cloneNode(true);
189
+ snapshot.classList.remove("kui-nav-stack__chrome--entering");
190
+ return snapshot;
191
+ });
192
+ };
52
193
  const observer = new MutationObserver((records) => {
53
194
  const removed = [];
54
- let added = false;
55
195
  for (const record of records) {
196
+ if (record.target !== viewport) continue;
56
197
  record.removedNodes.forEach((node) => {
57
- if (node instanceof HTMLElement && node.classList.contains("kui-nav-stack__view") && node.dataset.navExiting !== "true") removed.push(node);
58
- });
59
- record.addedNodes.forEach((node) => {
60
- if (node instanceof HTMLElement && node.classList.contains("kui-nav-stack__view")) added = true;
198
+ if (node instanceof HTMLElement && node.classList.contains("kui-nav-stack__view") && node.dataset.navExiting !== "true")
199
+ removed.push(node);
61
200
  });
62
201
  }
63
202
  const top = topView(viewport);
64
203
  const currentKey = top?.dataset.navKey;
65
204
  const poppedTop = removed.find((node) => node.dataset.navKey === activeKey);
66
205
  if (poppedTop && currentKey !== activeKey) {
206
+ finishTransition();
207
+ poppedTop.classList.remove(
208
+ "kui-nav-stack__view--entering",
209
+ "kui-nav-stack__view--exiting"
210
+ );
67
211
  poppedTop.dataset.navExiting = "true";
68
212
  poppedTop.setAttribute("aria-hidden", "true");
69
213
  viewport.append(poppedTop);
214
+ void poppedTop.offsetWidth;
70
215
  play(poppedTop, "exiting");
216
+ crossFadeChrome();
217
+ if (top) focusInto(top);
71
218
  settle(() => poppedTop.remove());
72
- } else if (added && currentKey !== activeKey && top) {
219
+ } else if (currentKey !== activeKey && top) {
220
+ finishTransition();
221
+ const previous = viewsOf(viewport).find(
222
+ (element) => element.dataset.navKey === activeKey
223
+ );
224
+ if (previous) {
225
+ previous.dataset.navRevealed = "true";
226
+ settle(() => delete previous.dataset.navRevealed);
227
+ }
228
+ rememberFocusedView(section.ownerDocument.activeElement);
73
229
  play(top, "entering");
230
+ crossFadeChrome();
231
+ focusInto(top);
74
232
  }
75
233
  activeKey = currentKey;
76
234
  });
77
- observer.observe(viewport, { childList: true });
235
+ observer.observe(viewport, {
236
+ childList: true,
237
+ subtree: true,
238
+ attributes: true,
239
+ attributeFilter: ["data-nav-key", "data-nav-active"]
240
+ });
78
241
  return () => {
79
242
  disposeBack();
243
+ section.removeEventListener("focusin", onFocusIn);
80
244
  observer.disconnect();
81
- for (const timer of timers) view.clearTimeout(timer);
82
- timers.clear();
245
+ finishTransition();
246
+ for (const [element, previousTabIndex] of generatedFallbacks) {
247
+ if (!element.isConnected || element.tabIndex !== -1) continue;
248
+ if (previousTabIndex === null) element.removeAttribute("tabindex");
249
+ else element.setAttribute("tabindex", previousTabIndex);
250
+ }
251
+ generatedFallbacks.clear();
252
+ rememberedFocus.clear();
253
+ if (previousDuration)
254
+ section.style.setProperty(
255
+ "--kui-nav-stack-transition-duration",
256
+ previousDuration
257
+ );
258
+ else section.style.removeProperty("--kui-nav-stack-transition-duration");
83
259
  };
84
260
  }
85
261
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/wire-nav-stack.ts"],"names":[],"mappings":"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","file":"wire-nav-stack.js","sourcesContent":["import { delegate } from 'kerfjs';\n\nexport interface WireNavStackOptions {\n /** Invoked when the back control is activated. The app pops its own stack. */\n onBack?: () => void;\n /** Transition duration in ms (default 200). Set 0 to disable animation. */\n duration?: number;\n}\n\nconst DEFAULT_DURATION = 200;\n\nfunction viewsOf(viewport: Element): HTMLElement[] {\n return Array.from(viewport.querySelectorAll<HTMLElement>(':scope > .kui-nav-stack__view'));\n}\n\nfunction topView(viewport: Element): HTMLElement | undefined {\n const live = viewsOf(viewport).filter((view) => view.dataset.navExiting !== 'true');\n return live[live.length - 1];\n}\n\nfunction reducedMotion(view: Window): boolean {\n return typeof view.matchMedia === 'function' && view.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/**\n * Animate a `NavStack`'s push/pop transitions and wire its back control. The app\n * owns the stack (a signal of `NavStackView[]`) and re-renders `NavStack` when it\n * changes; this helper slides the content and settles the chrome across each\n * change, and calls `onBack` when the back control is used. Returns a disposer.\n */\nexport function wireNavStack(root: Element, options: WireNavStackOptions = {}): () => void {\n const section = root.matches('[data-component=\"nav-stack\"]') ? root : root.querySelector('[data-component=\"nav-stack\"]');\n const viewport = section?.querySelector('[data-nav-stack-viewport]');\n if (!(section instanceof HTMLElement) || !viewport) return () => {};\n\n const view = section.ownerDocument.defaultView ?? window;\n const duration = options.duration ?? DEFAULT_DURATION;\n const disposeBack = delegate(section, 'click', '[data-nav-back]', () => options.onBack?.());\n\n let activeKey = topView(viewport)?.dataset.navKey;\n const timers = new Set<number>();\n\n const settle = (fn: () => void): void => {\n if (duration <= 0 || reducedMotion(view)) {\n fn();\n return;\n }\n const timer = view.setTimeout(() => {\n timers.delete(timer);\n fn();\n }, duration);\n timers.add(timer);\n };\n\n const play = (el: HTMLElement, kind: 'entering' | 'exiting'): void => {\n const animated = duration > 0 && !reducedMotion(view);\n if (kind === 'entering') {\n // Push: start the incoming view off the trailing edge, then release it so\n // it slides to rest (translateX(100%) → 0).\n el.classList.add('kui-nav-stack__view--entering');\n if (animated) {\n // Force a reflow so the starting transform applies before we clear it.\n void el.offsetWidth;\n view.requestAnimationFrame(() => el.classList.remove('kui-nav-stack__view--entering'));\n } else {\n el.classList.remove('kui-nav-stack__view--entering');\n }\n } else if (animated) {\n // Pop: the outgoing view is at rest; add the off-edge class on the next\n // frame so it slides OUT (translateX(0) → 100%), not in.\n view.requestAnimationFrame(() => el.classList.add('kui-nav-stack__view--exiting'));\n } else {\n el.classList.add('kui-nav-stack__view--exiting');\n }\n };\n\n const observer = new MutationObserver((records) => {\n const removed: HTMLElement[] = [];\n let added = false;\n for (const record of records) {\n record.removedNodes.forEach((node) => {\n if (node instanceof HTMLElement && node.classList.contains('kui-nav-stack__view') && node.dataset.navExiting !== 'true') removed.push(node);\n });\n record.addedNodes.forEach((node) => {\n if (node instanceof HTMLElement && node.classList.contains('kui-nav-stack__view')) added = true;\n });\n }\n\n const top = topView(viewport);\n const currentKey = top?.dataset.navKey;\n const poppedTop = removed.find((node) => node.dataset.navKey === activeKey);\n\n if (poppedTop && currentKey !== activeKey) {\n // Pop: bring the removed node back briefly to slide it out over the revealed view.\n poppedTop.dataset.navExiting = 'true';\n poppedTop.setAttribute('aria-hidden', 'true');\n viewport.append(poppedTop);\n play(poppedTop, 'exiting');\n settle(() => poppedTop.remove());\n } else if (added && currentKey !== activeKey && top) {\n // Push: slide the new top in.\n play(top, 'entering');\n }\n\n activeKey = currentKey;\n });\n observer.observe(viewport, { childList: true });\n\n return () => {\n disposeBack();\n observer.disconnect();\n for (const timer of timers) view.clearTimeout(timer);\n timers.clear();\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/components/navigation/nav-stack/wiring/wire-nav-stack.ts"],"names":[],"mappings":"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","file":"wire-nav-stack.js","sourcesContent":["import { delegate } from 'kerfjs';\n\nexport interface WireNavStackOptions {\n /** Invoked when the back control is activated. The app pops its own stack. */\n onBack?: () => void;\n /** Transition duration in ms (default 200). Set 0 to disable animation. */\n duration?: number;\n}\n\nconst DEFAULT_DURATION = 200;\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\nfunction viewsOf(viewport: Element): HTMLElement[] {\n return Array.from(\n viewport.querySelectorAll<HTMLElement>(':scope > .kui-nav-stack__view'),\n );\n}\n\nfunction topView(viewport: Element): HTMLElement | undefined {\n const live = viewsOf(viewport).filter(\n (view) => view.dataset.navExiting !== 'true',\n );\n return live[live.length - 1];\n}\n\nfunction reducedMotion(view: Window): boolean {\n return (\n typeof view.matchMedia === 'function' &&\n view.matchMedia('(prefers-reduced-motion: reduce)').matches\n );\n}\n\nfunction chromeOf(section: HTMLElement): HTMLElement[] {\n return Array.from(\n section.querySelectorAll<HTMLElement>(\n ':scope > [data-nav-stack-chrome]:not([data-nav-chrome-copy]), :scope > [data-nav-stack-bottom]:not([data-nav-chrome-copy])',\n ),\n );\n}\n\nfunction availableFocusTarget(\n element: Element | null | undefined,\n): element is HTMLElement {\n return (\n element instanceof HTMLElement &&\n element.isConnected &&\n !element.matches('[disabled], [aria-disabled=\"true\"]') &&\n !element.closest('[inert], [hidden], [aria-hidden=\"true\"]')\n );\n}\n\n/**\n * Animate a `NavStack`'s push/pop transitions and wire its back control. The app\n * owns the stack (a signal of `NavStackView[]`) and re-renders `NavStack` when it\n * changes; this helper slides the content and settles the chrome across each\n * change, moves focus into every new top view, restores that view's last focused\n * descendant on pop, and calls `onBack` when the back control is used. Mark a\n * preferred initial target with `data-nav-focus`; otherwise the first focusable\n * descendant (or the view itself) receives focus. Returns a disposer.\n */\nexport function wireNavStack(\n root: Element,\n options: WireNavStackOptions = {},\n): () => void {\n const section = root.matches('[data-component=\"nav-stack\"]')\n ? root\n : root.querySelector('[data-component=\"nav-stack\"]');\n const viewport = section?.querySelector('[data-nav-stack-viewport]');\n if (!(section instanceof HTMLElement) || !viewport) return () => {};\n\n const view = section.ownerDocument.defaultView ?? window;\n const duration = options.duration ?? DEFAULT_DURATION;\n const previousDuration = section.style.getPropertyValue(\n '--kui-nav-stack-transition-duration',\n );\n section.style.setProperty(\n '--kui-nav-stack-transition-duration',\n `${Math.max(0, duration)}ms`,\n );\n const disposeBack = delegate(section, 'click', '[data-nav-back]', () =>\n options.onBack?.(),\n );\n\n let activeKey = topView(viewport)?.dataset.navKey;\n const timers = new Set<number>();\n const frames = new Set<number>();\n const frame = (fn: () => void): void => {\n const id = view.requestAnimationFrame(() => {\n frames.delete(id);\n fn();\n });\n frames.add(id);\n };\n const finishTransition = (): void => {\n for (const id of frames) view.cancelAnimationFrame(id);\n frames.clear();\n for (const id of timers) view.clearTimeout(id);\n timers.clear();\n section\n .querySelectorAll<HTMLElement>(':scope > [data-nav-chrome-copy]')\n .forEach((element) => element.remove());\n chromeOf(section).forEach((element) =>\n element.classList.remove('kui-nav-stack__chrome--entering'),\n );\n viewsOf(viewport).forEach((element) => {\n if (element.dataset.navExiting === 'true') element.remove();\n else {\n element.classList.remove('kui-nav-stack__view--entering');\n delete element.dataset.navRevealed;\n }\n });\n delete section.dataset.navChromeTransition;\n };\n const rememberedFocus = new Map<string, HTMLElement>();\n const generatedFallbacks = new Map<HTMLElement, string | null>();\n let chromeSnapshots = chromeOf(section).map((element) =>\n element.cloneNode(true),\n ) as HTMLElement[];\n\n const settle = (fn: () => void): void => {\n if (duration <= 0 || reducedMotion(view)) {\n fn();\n return;\n }\n const timer = view.setTimeout(() => {\n timers.delete(timer);\n fn();\n }, duration);\n timers.add(timer);\n };\n\n const play = (el: HTMLElement, kind: 'entering' | 'exiting'): void => {\n const animated = duration > 0 && !reducedMotion(view);\n if (kind === 'entering') {\n // Push: start the incoming view off the trailing edge, then release it so\n // it slides to rest (translateX(100%) → 0).\n el.classList.add('kui-nav-stack__view--entering');\n if (animated) {\n // Force a reflow so the starting transform applies before we clear it.\n void el.offsetWidth;\n frame(() => el.classList.remove('kui-nav-stack__view--entering'));\n } else {\n el.classList.remove('kui-nav-stack__view--entering');\n }\n } else if (animated) {\n // Pop: the outgoing view is at rest; add the off-edge class on the next\n // frame so it slides OUT (translateX(0) → 100%), not in.\n frame(() => el.classList.add('kui-nav-stack__view--exiting'));\n } else {\n el.classList.add('kui-nav-stack__view--exiting');\n }\n };\n\n const rememberFocusedView = (target: Element | null): void => {\n if (!(target instanceof HTMLElement)) return;\n const owner = target.closest<HTMLElement>('.kui-nav-stack__view');\n const key = owner?.dataset.navKey;\n if (key && owner !== target && viewport.contains(owner))\n rememberedFocus.set(key, target);\n };\n\n const focusInto = (targetView: HTMLElement): void => {\n const key = targetView.dataset.navKey;\n const remembered = key ? rememberedFocus.get(key) : undefined;\n const preferred = Array.from(\n targetView.querySelectorAll<HTMLElement>('[data-nav-focus]'),\n ).find(availableFocusTarget);\n const first = Array.from(\n targetView.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n ).find(availableFocusTarget);\n const target =\n (availableFocusTarget(remembered) && targetView.contains(remembered)\n ? remembered\n : undefined) ??\n preferred ??\n first;\n if (target) {\n target.focus({ preventScroll: true });\n return;\n }\n\n if (!generatedFallbacks.has(targetView)) {\n generatedFallbacks.set(\n targetView,\n targetView.hasAttribute('tabindex')\n ? targetView.getAttribute('tabindex')\n : null,\n );\n targetView.tabIndex = -1;\n }\n targetView.focus({ preventScroll: true });\n };\n\n const onFocusIn = (event: Event): void =>\n rememberFocusedView(event.target as Element | null);\n section.addEventListener('focusin', onFocusIn);\n rememberFocusedView(section.ownerDocument.activeElement);\n\n const crossFadeChrome = (): void => {\n const current = chromeOf(section);\n const animated = duration > 0 && !reducedMotion(view);\n if (!animated) {\n chromeSnapshots = current.map((element) =>\n element.cloneNode(true),\n ) as HTMLElement[];\n return;\n }\n\n section.dataset.navChromeTransition = 'true';\n const copies = chromeSnapshots.map((snapshot) => {\n const copy = snapshot.cloneNode(true) as HTMLElement;\n copy.classList.add('kui-nav-stack__chrome-copy');\n copy.dataset.navChromeCopy = '';\n copy.setAttribute('aria-hidden', 'true');\n copy.setAttribute('inert', '');\n if (copy.hasAttribute('data-nav-stack-bottom'))\n copy.classList.add('kui-nav-stack__chrome-copy--bottom');\n section.append(copy);\n return copy;\n });\n\n current.forEach((element) =>\n element.classList.add('kui-nav-stack__chrome--entering'),\n );\n void section.offsetWidth;\n frame(() => {\n current.forEach((element) =>\n element.classList.remove('kui-nav-stack__chrome--entering'),\n );\n copies.forEach((copy) =>\n copy.classList.add('kui-nav-stack__chrome-copy--exiting'),\n );\n });\n settle(() => {\n copies.forEach((copy) => copy.remove());\n delete section.dataset.navChromeTransition;\n });\n chromeSnapshots = current.map((element) => {\n const snapshot = element.cloneNode(true) as HTMLElement;\n snapshot.classList.remove('kui-nav-stack__chrome--entering');\n return snapshot;\n });\n };\n\n const observer = new MutationObserver((records) => {\n const removed: HTMLElement[] = [];\n for (const record of records) {\n if (record.target !== viewport) continue;\n record.removedNodes.forEach((node) => {\n if (\n node instanceof HTMLElement &&\n node.classList.contains('kui-nav-stack__view') &&\n node.dataset.navExiting !== 'true'\n )\n removed.push(node);\n });\n }\n\n const top = topView(viewport);\n const currentKey = top?.dataset.navKey;\n const poppedTop = removed.find((node) => node.dataset.navKey === activeKey);\n\n if (poppedTop && currentKey !== activeKey) {\n finishTransition();\n // Pop: bring the removed node back briefly to slide it out over the revealed view.\n poppedTop.classList.remove(\n 'kui-nav-stack__view--entering',\n 'kui-nav-stack__view--exiting',\n );\n poppedTop.dataset.navExiting = 'true';\n poppedTop.setAttribute('aria-hidden', 'true');\n viewport.append(poppedTop);\n void poppedTop.offsetWidth;\n play(poppedTop, 'exiting');\n crossFadeChrome();\n if (top) focusInto(top);\n settle(() => poppedTop.remove());\n } else if (currentKey !== activeKey && top) {\n finishTransition();\n const previous = viewsOf(viewport).find(\n (element) => element.dataset.navKey === activeKey,\n );\n if (previous) {\n previous.dataset.navRevealed = 'true';\n settle(() => delete previous.dataset.navRevealed);\n }\n // Push: slide the new top in.\n rememberFocusedView(section.ownerDocument.activeElement);\n play(top, 'entering');\n crossFadeChrome();\n focusInto(top);\n }\n\n activeKey = currentKey;\n });\n observer.observe(viewport, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['data-nav-key', 'data-nav-active'],\n });\n\n return () => {\n disposeBack();\n section.removeEventListener('focusin', onFocusIn);\n observer.disconnect();\n finishTransition();\n for (const [element, previousTabIndex] of generatedFallbacks) {\n if (!element.isConnected || element.tabIndex !== -1) continue;\n if (previousTabIndex === null) element.removeAttribute('tabindex');\n else element.setAttribute('tabindex', previousTabIndex);\n }\n generatedFallbacks.clear();\n rememberedFocus.clear();\n if (previousDuration)\n section.style.setProperty(\n '--kui-nav-stack-transition-duration',\n previousDuration,\n );\n else section.style.removeProperty('--kui-nav-stack-transition-duration');\n };\n}\n"]}
@@ -9,7 +9,8 @@ interface WireResizableRegionsOptions {
9
9
  onPreview?: (change: ResizeCommit) => void;
10
10
  onCommit: (change: ResizeCommit) => void;
11
11
  }
12
+
12
13
  /** Wire pointer and separator-keyboard behavior for every ResizableRegion below root. */
13
- declare function wireResizableRegions(root: HTMLElement, { step, largeStep, onPreview, onCommit }: WireResizableRegionsOptions): () => void;
14
+ declare function wireResizableRegions(root: HTMLElement, options: WireResizableRegionsOptions): () => void;
14
15
 
15
16
  export { type ResizeCommit, type WireResizableRegionsOptions, wireResizableRegions };
@@ -1,4 +1,5 @@
1
- export { wireResizableRegions } from './chunk-AQNKJRFH.js';
1
+ export { wireResizableRegions } from './chunk-GS2QD3N7.js';
2
+
2
3
 
3
4
 
4
5
  //# sourceMappingURL=wire-resizable-regions.js.map
@@ -0,0 +1,72 @@
1
+ /**
2
+ * An app-owned scroll arrangement outside a `Pane`: the `id` of the element
3
+ * that scrolls and the `id`s of the pinned chrome on each physical side of it.
4
+ * Each named chrome element shows its divider on the side facing the scroller
5
+ * while content is scrolled away beyond that side. Ids are resolved below the
6
+ * wired root on every refresh, so a re-render that replaces an element keeps
7
+ * the pairing.
8
+ */
9
+ interface ScrollDividerTarget {
10
+ /** The `id` of the scrolling element. */
11
+ scroller: string;
12
+ /** Chrome above the scroller: shows its bottom divider once scrolled down. */
13
+ top?: string;
14
+ /**
15
+ * Chrome right of the scroller: shows its left divider while content is
16
+ * hidden beyond the scroller's right edge (never when nothing overflows).
17
+ */
18
+ right?: string;
19
+ /**
20
+ * Chrome below the scroller: shows its top divider while content is hidden
21
+ * beyond the scroller's bottom edge (never when nothing overflows).
22
+ */
23
+ bottom?: string;
24
+ /** Chrome left of the scroller: shows its right divider once scrolled right. */
25
+ left?: string;
26
+ }
27
+ interface WireScrollDividersOptions {
28
+ /**
29
+ * App-owned scroll arrangements to pair beyond the ones found by structure
30
+ * (every `Pane`'s header and footer around its content, every `NavStack`'s
31
+ * and `TabNavigator`'s chrome around its active region, and every `TabBar`
32
+ * strip).
33
+ */
34
+ targets?: readonly ScrollDividerTarget[];
35
+ }
36
+ type Root = HTMLElement | Document;
37
+ /**
38
+ * Wire scroll dividers below `root`: a divider between pinned chrome and the
39
+ * content that scrolls beside it shows only while content is scrolled away
40
+ * from that edge. Near edges (top, left) hide at the scroll start; far edges
41
+ * (bottom, right) hide at the scroll end and whenever nothing overflows.
42
+ *
43
+ * The wiring only reports scroll state; each component draws its own divider
44
+ * from it. It writes `data-scroll-overflow` (the edges with hidden content, in
45
+ * canonical `t`/`r`/`b`/`l` order) on each scroller, and `data-scroll-divider`
46
+ * (the sides to draw) on each paired chrome element:
47
+ *
48
+ * - every `Pane` with a header or footer: its header shows a bottom divider and
49
+ * its footer a top divider (drawn by the Pane, per its `chromeDividers`);
50
+ * - every `NavStack`'s top chrome and bottom toolbar around its active view,
51
+ * and every `TabNavigator`'s bar under its active scene: the chrome shows a
52
+ * bottom (top chrome) or top (bottom toolbar, bar) divider. The scroller is
53
+ * whichever element actually scrolls there: the view or scene itself, or,
54
+ * through a sole child with no chrome of its own on that edge, a `Pane`'s
55
+ * content or a nested `NavStack` / `TabNavigator` region (a Pane's own header
56
+ * or footer draws that boundary instead);
57
+ * - every `TabBar` strip: the bar draws a divider on each side of the strip
58
+ * whose tabs are scrolled out of view;
59
+ * - each app-owned `targets` pairing: a `Toolbar` or `List` named as chrome
60
+ * draws the divider on its facing side.
61
+ *
62
+ * Structure is re-read after every DOM change below root (a re-render that
63
+ * drops the attributes gets them back before paint), scroll is tracked with
64
+ * one capturing listener per registered root, and size changes of each
65
+ * scroller and its children with a `ResizeObserver`. Overlapping registrations
66
+ * share one attribute writer; each disposer removes its registration, and the
67
+ * final disposer removes the wiring-owned attributes. See
68
+ * `docs/23-app-layouts.md` §3.7.
69
+ */
70
+ declare function wireScrollDividers(root: Root, { targets }?: WireScrollDividersOptions): () => void;
71
+
72
+ export { type ScrollDividerTarget, type WireScrollDividersOptions, wireScrollDividers };
@@ -0,0 +1,3 @@
1
+ export { wireScrollDividers } from './chunk-3CXRQAYT.js';
2
+
3
+ //# sourceMappingURL=wire-scroll-dividers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"wire-scroll-dividers.js"}
@@ -0,0 +1,63 @@
1
+ import { Signal, ReadonlySignal } from 'kerfjs';
2
+ import { DeviceClass } from './device-class.js';
3
+
4
+ /** Minimal `localStorage`-shaped store, so the persistence hook is testable. */
5
+ interface SidebarStorage {
6
+ getItem(key: string): string | null;
7
+ setItem(key: string, value: string): void;
8
+ }
9
+ interface WireSidebarPanel {
10
+ /** The panel id — matches `CollapsiblePanel`'s `id` and a toggle's `panelId`. */
11
+ id: string;
12
+ /** The app-owned collapsed signal. `wireSidebar` reads it (focus, overlay) and
13
+ * writes it (toggle, Escape, backdrop, persistence). */
14
+ collapsed: Signal<boolean>;
15
+ /** `data-action` value the panel's toggle button(s) carry. */
16
+ toggleAction: string;
17
+ /** When set, the panel's inline collapsed state is loaded from and saved to
18
+ * `storage` under this key (a persistence hook), so the panel remembers the
19
+ * user's inline choice. A compact overlay's open/closed state is transient
20
+ * and is never persisted. */
21
+ storageKey?: string;
22
+ /** The panel's inline (non-compact) collapsed state when `storage` holds no
23
+ * choice for it; wire-up seeds the signal with it. Defaults to the signal's
24
+ * own value. Set it when the app seeds the signal from the device class
25
+ * (`signal(device.value.compact)`) so a compact first render already starts
26
+ * collapsed while a later crossing to a wide class still restores this
27
+ * inline default. */
28
+ inlineCollapsed?: boolean;
29
+ }
30
+ interface WireSidebarOptions {
31
+ panels: readonly WireSidebarPanel[];
32
+ /**
33
+ * When provided, the sidebar adopts a compact **overlay** presentation while
34
+ * `deviceClass.compact` is true: an open panel floats over the content with a
35
+ * dismissable backdrop, Escape and backdrop-click collapse it, and focus is
36
+ * trapped within the open panel (the ARIA dialog pattern). Without it the panel
37
+ * is always inline.
38
+ *
39
+ * An overlay is transient and user-initiated: whenever the compact overlay
40
+ * presentation begins (wire-up on a compact device, or a crossing from a wide
41
+ * class), every panel starts collapsed so nothing blocks the page until the
42
+ * user opens it. The inline state is remembered and restored when the device
43
+ * crosses back to a wide class (and on disposal).
44
+ */
45
+ deviceClass?: ReadonlySignal<DeviceClass>;
46
+ /** Compact devices either overlay the panels (default) or hide them in favor
47
+ * of an application-owned responsive replacement. */
48
+ compactPresentation?: 'overlay' | 'hidden';
49
+ /** Collapse the other panels when one opens in compact overlay mode. */
50
+ exclusiveCompact?: boolean;
51
+ /** Persistence store (default `globalThis.localStorage`, if present). */
52
+ storage?: SidebarStorage;
53
+ }
54
+ /**
55
+ * The reusable sidebar-semantics layer for {@link CollapsiblePanel}s: toggle
56
+ * delegation with focus restore, focus-into on open, an optional compact overlay
57
+ * (backdrop + Escape + focus trap) driven by {@link deviceClass}, and an optional
58
+ * persistence hook. The app owns each `collapsed` signal and the layout; this wire
59
+ * owns the interaction. Returns a disposer. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.
60
+ */
61
+ declare function wireSidebar(root: HTMLElement, { panels, deviceClass, compactPresentation, exclusiveCompact, storage, }: WireSidebarOptions): () => void;
62
+
63
+ export { type SidebarStorage, type WireSidebarOptions, type WireSidebarPanel, wireSidebar };