@kerfjs/ui 5.0.0-beta.55 → 5.0.0-beta.57

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 (418) hide show
  1. package/README.md +74 -41
  2. package/ai/application-ui-diagnostic-ids-v1.json +9 -1
  3. package/ai/application-ui-profile-sync.cjs +1 -1
  4. package/ai/application-ui-profile.defaults.json +63 -8
  5. package/ai/application-ui-profile.mjs +1 -1
  6. package/ai/compile-time-contracts-v1.json +2 -2
  7. package/ai/component-catalog.json +407 -80
  8. package/ai/component-catalog.schema.json +2 -0
  9. package/ai/component-class-owners.cjs +83 -0
  10. package/ai/component-composition-extension.d.ts +7 -0
  11. package/ai/component-composition-extension.schema.json +7 -0
  12. package/ai/{component-catalog-v2-overrides.json → component-composition-rules.json} +2 -1
  13. package/ai/{component-catalog-v2.d.ts → component-composition.d.ts} +9 -5
  14. package/ai/{component-catalog-v2.json → component-composition.json} +302 -61
  15. package/ai/{component-catalog-v2.schema.json → component-composition.schema.json} +21 -5
  16. package/ai/components/README.md +170 -0
  17. package/ai/components/application-tabs.md +65 -0
  18. package/ai/components/badge.md +72 -0
  19. package/ai/components/collapsible-panel.md +102 -0
  20. package/ai/components/content-item.md +90 -0
  21. package/ai/components/disclosure-arrow.md +77 -0
  22. package/ai/components/document-baseline.md +75 -0
  23. package/ai/components/empty-state.md +80 -0
  24. package/ai/components/feedback.md +71 -0
  25. package/ai/components/floating-toolbar.md +80 -0
  26. package/ai/components/foundation.md +65 -0
  27. package/ai/components/grid.md +93 -0
  28. package/ai/components/headers.md +63 -0
  29. package/ai/components/layout.md +75 -0
  30. package/ai/components/list-action-row.md +91 -0
  31. package/ai/components/list-header.md +89 -0
  32. package/ai/components/list-inset-control.md +74 -0
  33. package/ai/components/list-inset-text.md +72 -0
  34. package/ai/components/list-item.md +88 -0
  35. package/ai/components/list.md +103 -0
  36. package/ai/components/loading-spinner.md +72 -0
  37. package/ai/components/lucide-icon.md +66 -0
  38. package/ai/components/nav-stack.md +103 -0
  39. package/ai/components/pane.md +100 -0
  40. package/ai/components/popup-menu.md +82 -0
  41. package/ai/components/recipe-app-shell.md +57 -0
  42. package/ai/components/recipe-collapsible-sidebar.md +57 -0
  43. package/ai/components/recipe-compact-toolbar.md +57 -0
  44. package/ai/components/recipe-composer-form.md +57 -0
  45. package/ai/components/recipe-list-detail-dialog.md +57 -0
  46. package/ai/components/recipe-list-workspace-states.md +57 -0
  47. package/ai/components/recipe-loading-inspector.md +57 -0
  48. package/ai/components/recipe-navigation-sidebar.md +57 -0
  49. package/ai/components/recipe-navigation-stack.md +57 -0
  50. package/ai/components/recipe-workspace-header.md +57 -0
  51. package/ai/components/resize.md +101 -0
  52. package/ai/components/row.md +96 -0
  53. package/ai/components/segmented-control.md +82 -0
  54. package/ai/components/select.md +107 -0
  55. package/ai/components/skeleton.md +84 -0
  56. package/ai/components/spacer.md +86 -0
  57. package/ai/components/split-view.md +102 -0
  58. package/ai/components/state-banner.md +92 -0
  59. package/ai/components/sunken-panel.md +79 -0
  60. package/ai/components/surface-scaffold.md +78 -0
  61. package/ai/components/tab-bar.md +112 -0
  62. package/ai/components/tab-scaffold.md +94 -0
  63. package/ai/components/tabs.md +90 -0
  64. package/ai/components/text.md +82 -0
  65. package/ai/components/token-search-field.md +101 -0
  66. package/ai/components/toolbar-control-group.md +100 -0
  67. package/ai/components/toolbar-text.md +76 -0
  68. package/ai/components/toolbar.md +95 -0
  69. package/ai/components/value-table.md +72 -0
  70. package/ai/components/wa-accordion-item.md +55 -0
  71. package/ai/components/wa-accordion.md +65 -0
  72. package/ai/components/wa-animated-image.md +55 -0
  73. package/ai/components/wa-animation.md +55 -0
  74. package/ai/components/wa-avatar.md +55 -0
  75. package/ai/components/wa-badge.md +55 -0
  76. package/ai/components/wa-breadcrumb-item.md +53 -0
  77. package/ai/components/wa-breadcrumb.md +55 -0
  78. package/ai/components/wa-button-group.md +59 -0
  79. package/ai/components/wa-button.md +55 -0
  80. package/ai/components/wa-callout.md +58 -0
  81. package/ai/components/wa-card.md +59 -0
  82. package/ai/components/wa-carousel-item.md +53 -0
  83. package/ai/components/wa-carousel.md +55 -0
  84. package/ai/components/wa-checkbox-group.md +55 -0
  85. package/ai/components/wa-checkbox.md +55 -0
  86. package/ai/components/wa-color-picker.md +55 -0
  87. package/ai/components/wa-comparison.md +55 -0
  88. package/ai/components/wa-copy-button.md +55 -0
  89. package/ai/components/wa-details.md +61 -0
  90. package/ai/components/wa-dialog.md +59 -0
  91. package/ai/components/wa-divider.md +53 -0
  92. package/ai/components/wa-drawer.md +55 -0
  93. package/ai/components/wa-dropdown-item.md +60 -0
  94. package/ai/components/wa-dropdown.md +60 -0
  95. package/ai/components/wa-format-bytes.md +53 -0
  96. package/ai/components/wa-format-date.md +53 -0
  97. package/ai/components/wa-format-number.md +53 -0
  98. package/ai/components/wa-icon.md +58 -0
  99. package/ai/components/wa-include.md +53 -0
  100. package/ai/components/wa-input.md +59 -0
  101. package/ai/components/wa-intersection-observer.md +53 -0
  102. package/ai/components/wa-known-date.md +53 -0
  103. package/ai/components/wa-markdown.md +53 -0
  104. package/ai/components/wa-mutation-observer.md +53 -0
  105. package/ai/components/wa-number-input.md +55 -0
  106. package/ai/components/wa-option.md +59 -0
  107. package/ai/components/wa-otp-input.md +53 -0
  108. package/ai/components/wa-page.md +53 -0
  109. package/ai/components/wa-pagination.md +55 -0
  110. package/ai/components/wa-popover.md +55 -0
  111. package/ai/components/wa-popup.md +53 -0
  112. package/ai/components/wa-progress-bar.md +53 -0
  113. package/ai/components/wa-progress-ring.md +53 -0
  114. package/ai/components/wa-qr-code.md +53 -0
  115. package/ai/components/wa-radio-group.md +59 -0
  116. package/ai/components/wa-radio.md +55 -0
  117. package/ai/components/wa-random-content.md +53 -0
  118. package/ai/components/wa-rating.md +55 -0
  119. package/ai/components/wa-relative-time.md +53 -0
  120. package/ai/components/wa-resize-observer.md +53 -0
  121. package/ai/components/wa-scroller.md +53 -0
  122. package/ai/components/wa-select.md +63 -0
  123. package/ai/components/wa-skeleton.md +53 -0
  124. package/ai/components/wa-slider.md +55 -0
  125. package/ai/components/wa-spinner.md +58 -0
  126. package/ai/components/wa-split-panel.md +58 -0
  127. package/ai/components/wa-switch.md +53 -0
  128. package/ai/components/wa-tab-group.md +69 -0
  129. package/ai/components/wa-tab-panel.md +60 -0
  130. package/ai/components/wa-tab.md +59 -0
  131. package/ai/components/wa-tag.md +59 -0
  132. package/ai/components/wa-textarea.md +53 -0
  133. package/ai/components/wa-time-input.md +55 -0
  134. package/ai/components/wa-toast-item.md +60 -0
  135. package/ai/components/wa-toast.md +60 -0
  136. package/ai/components/wa-tooltip.md +55 -0
  137. package/ai/components/wa-tree-item.md +55 -0
  138. package/ai/components/wa-tree.md +55 -0
  139. package/ai/components/wa-zoomable-frame.md +55 -0
  140. package/ai/components/workbench.md +114 -0
  141. package/ai/public-api-signatures-v1.md +572 -101
  142. package/ai/skill.md +107 -52
  143. package/ai/webawesome-jsx-signatures-v1.md +8 -2
  144. package/analyzer/component-ownership.d.mts +56 -0
  145. package/analyzer/component-ownership.mjs +184 -0
  146. package/analyzer/index.d.mts +3 -0
  147. package/analyzer/index.mjs +274 -20
  148. package/analyzer/selectors.d.mts +21 -0
  149. package/analyzer/selectors.mjs +212 -0
  150. package/dist/app-tab.js +1 -1
  151. package/dist/badge.d.ts +35 -7
  152. package/dist/badge.js +1 -1
  153. package/dist/browser/catalog.js +25 -0
  154. package/dist/browser/collapsible-panel.js +7 -0
  155. package/dist/browser/content-item.js +3 -0
  156. package/dist/browser/nav-stack.js +8 -0
  157. package/dist/browser/select.js +1 -0
  158. package/dist/browser/split-view.js +10 -0
  159. package/dist/browser/tab-scaffold.js +4 -0
  160. package/dist/browser/workbench.js +10 -0
  161. package/dist/catalog-resources.d.ts +12 -1
  162. package/dist/catalog.d.ts +14 -3
  163. package/dist/catalog.js +53 -43
  164. package/dist/catalog.js.map +1 -1
  165. package/dist/{chunk-WZ2GLEY4.js → chunk-2G2ZJQYK.js} +2 -14
  166. package/dist/chunk-2G2ZJQYK.js.map +1 -0
  167. package/dist/{chunk-R754MHXX.js → chunk-553ASUK6.js} +8 -8
  168. package/dist/chunk-553ASUK6.js.map +1 -0
  169. package/dist/{chunk-D7GWXIAS.js → chunk-5I7QGQVT.js} +1 -1
  170. package/dist/chunk-5I7QGQVT.js.map +1 -0
  171. package/dist/{chunk-RNRUVPJ3.js → chunk-63ZWBGE3.js} +3 -2
  172. package/dist/chunk-63ZWBGE3.js.map +1 -0
  173. package/dist/{chunk-44IG7PFV.js → chunk-6CINWX2E.js} +3 -3
  174. package/dist/{chunk-44IG7PFV.js.map → chunk-6CINWX2E.js.map} +1 -1
  175. package/dist/{chunk-MTM43SJO.js → chunk-6YFHCLHG.js} +2 -2
  176. package/dist/chunk-6YFHCLHG.js.map +1 -0
  177. package/dist/{chunk-C2FAYFDE.js → chunk-AGXQQFKZ.js} +2 -2
  178. package/dist/{chunk-C2FAYFDE.js.map → chunk-AGXQQFKZ.js.map} +1 -1
  179. package/dist/{chunk-ATHXW6RP.js → chunk-AHEG27M7.js} +2 -2
  180. package/dist/{chunk-ATHXW6RP.js.map → chunk-AHEG27M7.js.map} +1 -1
  181. package/dist/chunk-BFPBS5Y4.js +250 -0
  182. package/dist/chunk-BFPBS5Y4.js.map +1 -0
  183. package/dist/{chunk-5OLVUEND.js → chunk-DG6G5EPF.js} +4 -6
  184. package/dist/chunk-DG6G5EPF.js.map +1 -0
  185. package/dist/{chunk-LZXQVUGN.js → chunk-EVYKTVBQ.js} +5 -14
  186. package/dist/chunk-EVYKTVBQ.js.map +1 -0
  187. package/dist/{chunk-7GUQYHKA.js → chunk-EZVNC4J6.js} +7 -1
  188. package/dist/chunk-EZVNC4J6.js.map +1 -0
  189. package/dist/{chunk-RNZAKSME.js → chunk-F4QMLOXJ.js} +5 -4
  190. package/dist/chunk-F4QMLOXJ.js.map +1 -0
  191. package/dist/{chunk-EAX2GSS4.js → chunk-G2RKFVRB.js} +54 -20
  192. package/dist/chunk-G2RKFVRB.js.map +1 -0
  193. package/dist/chunk-JCV4GXWB.js +249 -0
  194. package/dist/chunk-JCV4GXWB.js.map +1 -0
  195. package/dist/chunk-K47P7QZC.js +17 -0
  196. package/dist/chunk-K47P7QZC.js.map +1 -0
  197. package/dist/{chunk-HMQ2ZDGG.js → chunk-KROD7KZK.js} +3 -2
  198. package/dist/chunk-KROD7KZK.js.map +1 -0
  199. package/dist/{chunk-5NDQABWK.js → chunk-M7QV3IHH.js} +3 -1
  200. package/dist/chunk-M7QV3IHH.js.map +1 -0
  201. package/dist/chunk-MA73TA6D.js +42 -0
  202. package/dist/chunk-MA73TA6D.js.map +1 -0
  203. package/dist/{chunk-ZMBU522F.js → chunk-MEY33VWB.js} +2 -2
  204. package/dist/{chunk-ZMBU522F.js.map → chunk-MEY33VWB.js.map} +1 -1
  205. package/dist/chunk-MP2GDBQZ.js +50 -0
  206. package/dist/chunk-MP2GDBQZ.js.map +1 -0
  207. package/dist/{chunk-3NBL3OUQ.js → chunk-NAPE7WUS.js} +2 -2
  208. package/dist/chunk-NAPE7WUS.js.map +1 -0
  209. package/dist/{chunk-BSKEH3UC.js → chunk-NBYTIVHS.js} +2 -2
  210. package/dist/{chunk-BSKEH3UC.js.map → chunk-NBYTIVHS.js.map} +1 -1
  211. package/dist/{chunk-T22EM4ET.js → chunk-OUK6QRDR.js} +71 -31
  212. package/dist/chunk-OUK6QRDR.js.map +1 -0
  213. package/dist/chunk-PWXNJS2B.js +115 -0
  214. package/dist/chunk-PWXNJS2B.js.map +1 -0
  215. package/dist/{chunk-GUIHMIT2.js → chunk-QOWG4ZCL.js} +5 -4
  216. package/dist/chunk-QOWG4ZCL.js.map +1 -0
  217. package/dist/{chunk-5I22LMCV.js → chunk-VZOFZPSO.js} +2 -2
  218. package/dist/chunk-VZOFZPSO.js.map +1 -0
  219. package/dist/{chunk-4BIMLITI.js → chunk-WLG6SSNT.js} +5 -3
  220. package/dist/chunk-WLG6SSNT.js.map +1 -0
  221. package/dist/{chunk-NE5JAOQS.js → chunk-WOUF7YXM.js} +3 -3
  222. package/dist/{chunk-NE5JAOQS.js.map → chunk-WOUF7YXM.js.map} +1 -1
  223. package/dist/{chunk-N7FHFNT6.js → chunk-XCO6YCYM.js} +34 -5
  224. package/dist/chunk-XCO6YCYM.js.map +1 -0
  225. package/dist/{chunk-TZ5IHWB2.js → chunk-XDKAYSVD.js} +5 -3
  226. package/dist/chunk-XDKAYSVD.js.map +1 -0
  227. package/dist/collapsible-panel.d.ts +14 -3
  228. package/dist/collapsible-panel.js +13 -16
  229. package/dist/collapsible-panel.js.map +1 -1
  230. package/dist/content-item.d.ts +46 -0
  231. package/dist/content-item.js +4 -0
  232. package/dist/content-item.js.map +1 -0
  233. package/dist/css-values.d.ts +5 -11
  234. package/dist/css-values.js +1 -1
  235. package/dist/disclosure-arrow.d.ts +4 -1
  236. package/dist/disclosure-arrow.js +1 -1
  237. package/dist/floating-toolbar.d.ts +17 -6
  238. package/dist/floating-toolbar.js +1 -1
  239. package/dist/grid.js +1 -1
  240. package/dist/help-tags-register.d.ts +13 -0
  241. package/dist/help-tags-register.js +9 -0
  242. package/dist/help-tags-register.js.map +1 -0
  243. package/dist/index.d.ts +7 -5
  244. package/dist/index.js +29 -26
  245. package/dist/list-action-row.js +2 -1
  246. package/dist/list-header.d.ts +14 -1
  247. package/dist/list-header.js +1 -1
  248. package/dist/list-inset-control.d.ts +1 -1
  249. package/dist/list-inset-control.js +1 -1
  250. package/dist/list-inset-text.d.ts +3 -10
  251. package/dist/list-inset-text.js +1 -1
  252. package/dist/list-item.js +2 -1
  253. package/dist/list.d.ts +10 -3
  254. package/dist/list.js +1 -1
  255. package/dist/nav-stack.d.ts +50 -5
  256. package/dist/nav-stack.js +4 -1
  257. package/dist/pane.d.ts +37 -2
  258. package/dist/pane.js +1 -1
  259. package/dist/{panel-toolbar-BFQxFITu.d.ts → panel-toolbar-BN4x0rth.d.ts} +13 -1
  260. package/dist/popup-menu-register.js +3 -2
  261. package/dist/popup-menu-register.js.map +1 -1
  262. package/dist/popup-menu.js +1 -1
  263. package/dist/row.d.ts +1 -1
  264. package/dist/row.js +1 -1
  265. package/dist/select-register.js +70 -3
  266. package/dist/select-register.js.map +1 -1
  267. package/dist/select.d.ts +46 -8
  268. package/dist/select.js +2 -1
  269. package/dist/{divider-sides-BzB6rphT.d.ts → sides-BPSWde0A.d.ts} +1 -3
  270. package/dist/skeleton.js +1 -1
  271. package/dist/spacer.js +1 -1
  272. package/dist/split-view.d.ts +31 -3
  273. package/dist/split-view.js +34 -5
  274. package/dist/split-view.js.map +1 -1
  275. package/dist/state-banner.js +1 -1
  276. package/dist/styles/app-tab.css +31 -0
  277. package/dist/styles/badge.css +32 -11
  278. package/dist/styles/catalog/components/catalog-example.css +1 -1
  279. package/dist/styles/catalog/components/catalog-stage.css +1 -1
  280. package/dist/styles/collapsible-panel.css +199 -42
  281. package/dist/styles/content-item.css +30 -0
  282. package/dist/styles/floating-toolbar.css +26 -2
  283. package/dist/styles/foundation.css +28 -19
  284. package/dist/styles/layout.css +1 -21
  285. package/dist/styles/list-action-row.css +13 -1
  286. package/dist/styles/list-header.css +0 -12
  287. package/dist/styles/list-inset-text.css +1 -2
  288. package/dist/styles/list-item.css +14 -1
  289. package/dist/styles/list.css +5 -5
  290. package/dist/styles/nav-stack.css +63 -71
  291. package/dist/styles/pane.css +83 -1
  292. package/dist/styles/popup-menu.css +229 -0
  293. package/dist/styles/resizable-region.css +70 -15
  294. package/dist/styles/select.css +60 -19
  295. package/dist/styles/skeleton.css +30 -3
  296. package/dist/styles/split-view.css +31 -32
  297. package/dist/styles/state-banner.css +0 -19
  298. package/dist/styles/surface-scaffold.css +8 -3
  299. package/dist/styles/tab-bar.css +79 -28
  300. package/dist/styles/tab-scaffold.css +60 -14
  301. package/dist/styles/text.css +17 -1
  302. package/dist/styles/token-search-field.css +4 -4
  303. package/dist/styles/toolbar-control-group.css +143 -69
  304. package/dist/styles/toolbar-text.css +21 -0
  305. package/dist/styles/toolbar.css +22 -37
  306. package/dist/styles/value-table.css +19 -2
  307. package/dist/styles/webawesome.css +3 -1
  308. package/dist/styles/workbench.css +145 -42
  309. package/dist/tab-scaffold.d.ts +46 -2
  310. package/dist/tab-scaffold.js +52 -16
  311. package/dist/tab-scaffold.js.map +1 -1
  312. package/dist/token-search-field.d.ts +4 -2
  313. package/dist/token-search-field.js +1 -1
  314. package/dist/toolbar-text.d.ts +7 -1
  315. package/dist/toolbar-text.js +1 -1
  316. package/dist/toolbar.d.ts +20 -5
  317. package/dist/toolbar.js +1 -1
  318. package/dist/{types-D6vzj-VT.d.ts → types-BuHELdXR.d.ts} +39 -6
  319. package/dist/value-table.js +1 -1
  320. package/dist/webawesome.d.ts +7 -1
  321. package/dist/wire-catalog.d.ts +15 -2
  322. package/dist/wire-catalog.js +12 -2
  323. package/dist/wire-catalog.js.map +1 -1
  324. package/dist/wire-scroll-dividers.d.ts +69 -0
  325. package/dist/wire-scroll-dividers.js +3 -0
  326. package/dist/wire-scroll-dividers.js.map +1 -0
  327. package/dist/wire-token-search-fields.js +1 -1
  328. package/dist/workbench.d.ts +60 -22
  329. package/dist/workbench.js +1 -1
  330. package/docs/accessibility.md +116 -7
  331. package/docs/app-layouts.md +18 -8
  332. package/docs/catalog.md +26 -7
  333. package/docs/collapsible-panel.md +32 -9
  334. package/docs/component-contract.md +182 -30
  335. package/docs/component-selection.md +59 -46
  336. package/docs/design/templates/empty-state/with-action-dark.svg +1 -1
  337. package/docs/design/templates/empty-state/with-action.svg +1 -1
  338. package/docs/design/templates/empty-state-dark.svg +1 -1
  339. package/docs/design/templates/empty-state.svg +1 -1
  340. package/docs/design/templates/list/compact-dark.svg +1 -1
  341. package/docs/design/templates/list/compact.svg +1 -1
  342. package/docs/design/templates/list/stack-dark.svg +1 -1
  343. package/docs/design/templates/list/stack.svg +1 -1
  344. package/docs/design/templates/list-action-row/default-dark.svg +1 -1
  345. package/docs/design/templates/list-action-row/default.svg +1 -1
  346. package/docs/design/templates/list-action-row/selected-dark.svg +1 -1
  347. package/docs/design/templates/list-action-row/selected.svg +1 -1
  348. package/docs/design/templates/list-action-row-dark.svg +1 -1
  349. package/docs/design/templates/list-action-row.svg +1 -1
  350. package/docs/design/templates/list-dark.svg +1 -1
  351. package/docs/design/templates/list-item/default-dark.svg +1 -1
  352. package/docs/design/templates/list-item/default.svg +1 -1
  353. package/docs/design/templates/list-item/selected-dark.svg +1 -1
  354. package/docs/design/templates/list-item/selected.svg +1 -1
  355. package/docs/design/templates/list-item/trailing-dark.svg +1 -1
  356. package/docs/design/templates/list-item/trailing.svg +1 -1
  357. package/docs/design/templates/list-item-dark.svg +1 -1
  358. package/docs/design/templates/list-item.svg +1 -1
  359. package/docs/design/templates/list.svg +1 -1
  360. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -1
  361. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -1
  362. package/docs/design/templates/tab-bar-dark.svg +1 -1
  363. package/docs/design/templates/tab-bar.svg +1 -1
  364. package/docs/design/templates/value-table/details-dark.svg +1 -1
  365. package/docs/design/templates/value-table/details.svg +1 -1
  366. package/docs/design/templates/value-table-dark.svg +1 -1
  367. package/docs/design/templates/value-table.svg +1 -1
  368. package/docs/design-philosophy.md +31 -4
  369. package/docs/examples/application-ui-profile.json +4 -4
  370. package/docs/examples/command-palette-adapter.tsx +3 -2
  371. package/docs/examples/{component-catalog-extension-v2.json → component-composition-extension.json} +3 -3
  372. package/docs/layout.md +148 -29
  373. package/docs/nav-stack.md +77 -3
  374. package/docs/recipes.md +4 -3
  375. package/docs/split-view.md +54 -5
  376. package/docs/tab-scaffold.md +73 -2
  377. package/docs/type-contracts.md +21 -20
  378. package/docs/ui-analyzer.md +99 -5
  379. package/docs/ui-doctor.md +10 -0
  380. package/docs/ux-demo.md +2 -2
  381. package/docs/webawesome-theme.md +1 -2
  382. package/docs/workbench.md +57 -11
  383. package/doctor/index.mjs +6 -1
  384. package/llms.txt +117 -24
  385. package/package.json +29 -6
  386. package/ux-demo/recipes/collapsible-sidebar.tsx +3 -3
  387. package/ux-demo/recipes/composer-form.tsx +0 -1
  388. package/ux-demo/recipes/list-detail-dialog.tsx +0 -2
  389. package/ux-demo/recipes/list-workspace-states.tsx +0 -1
  390. package/ux-demo/recipes/loading-inspector.tsx +0 -1
  391. package/ux-demo/recipes/navigation-sidebar.tsx +3 -2
  392. package/ux-demo/recipes/navigation-stack.tsx +3 -2
  393. package/ux-demo/recipes/workspace-header.tsx +0 -1
  394. package/ai/component-catalog-extension-v2.d.ts +0 -7
  395. package/ai/component-catalog-extension-v2.schema.json +0 -7
  396. package/dist/chunk-3NBL3OUQ.js.map +0 -1
  397. package/dist/chunk-4BIMLITI.js.map +0 -1
  398. package/dist/chunk-5I22LMCV.js.map +0 -1
  399. package/dist/chunk-5NDQABWK.js.map +0 -1
  400. package/dist/chunk-5OLVUEND.js.map +0 -1
  401. package/dist/chunk-7GUQYHKA.js.map +0 -1
  402. package/dist/chunk-D7GWXIAS.js.map +0 -1
  403. package/dist/chunk-DQA5FMOX.js +0 -85
  404. package/dist/chunk-DQA5FMOX.js.map +0 -1
  405. package/dist/chunk-EAX2GSS4.js.map +0 -1
  406. package/dist/chunk-GUIHMIT2.js.map +0 -1
  407. package/dist/chunk-HMQ2ZDGG.js.map +0 -1
  408. package/dist/chunk-LZXQVUGN.js.map +0 -1
  409. package/dist/chunk-MTM43SJO.js.map +0 -1
  410. package/dist/chunk-N7FHFNT6.js.map +0 -1
  411. package/dist/chunk-R754MHXX.js.map +0 -1
  412. package/dist/chunk-RNRUVPJ3.js.map +0 -1
  413. package/dist/chunk-RNZAKSME.js.map +0 -1
  414. package/dist/chunk-T22EM4ET.js.map +0 -1
  415. package/dist/chunk-TZ5IHWB2.js.map +0 -1
  416. package/dist/chunk-WZ2GLEY4.js.map +0 -1
  417. package/dist/chunk-XD7DWYXG.js +0 -34
  418. package/dist/chunk-XD7DWYXG.js.map +0 -1
@@ -1,10 +1,10 @@
1
1
  import { WORKBENCH_MAIN_MIN_SIZE, WORKBENCH_MAIN_MIN_HEIGHT, workbenchRegionId, WORKBENCH_RESIZE_DEFAULTS } from './chunk-PSHUSWQH.js';
2
2
  import { clampRegionSize, ResizeGrip } from './chunk-VHADGP3B.js';
3
- import { List } from './chunk-3NBL3OUQ.js';
4
- import { FloatingToolbar } from './chunk-5NDQABWK.js';
5
- import { composedPanelToolbar, relocatedPanelGroups } from './chunk-N7FHFNT6.js';
6
- import { Toolbar } from './chunk-MTM43SJO.js';
7
- import { Pane } from './chunk-7GUQYHKA.js';
3
+ import { List } from './chunk-NAPE7WUS.js';
4
+ import { FloatingToolbar } from './chunk-M7QV3IHH.js';
5
+ import { composedPanelBody, relocatedPanelGroups } from './chunk-XCO6YCYM.js';
6
+ import { Toolbar } from './chunk-6YFHCLHG.js';
7
+ import { Pane } from './chunk-EZVNC4J6.js';
8
8
  import { jsxs, jsx, Fragment } from 'kerfjs/jsx-runtime';
9
9
 
10
10
  var SIDES = {
@@ -30,17 +30,27 @@ function relocatedGroups(workbenchId, key, panel) {
30
30
  function panelBody(workbenchId, key, panel) {
31
31
  const toolbar = panel.toolbar;
32
32
  if (!toolbar) return panel.content;
33
+ return composedPanelBody({
34
+ toolbar,
35
+ side: SIDES[key],
36
+ collapsed: Boolean(panel.collapsed),
37
+ attributes: toggleAttributes(workbenchId, key),
38
+ pane: panel.pane,
39
+ footer: panel.footer,
40
+ content: panel.content
41
+ });
42
+ }
43
+ function chromeList(content, config) {
33
44
  return /* @__PURE__ */ jsx(
34
- Pane,
45
+ List,
35
46
  {
36
- header: composedPanelToolbar(
37
- toolbar,
38
- SIDES[key],
39
- Boolean(panel.collapsed),
40
- toggleAttributes(workbenchId, key)
41
- ),
42
- footer: panel.footer,
43
- children: panel.content
47
+ dividerSides: config?.dividerSides,
48
+ gap: config?.gap,
49
+ hAlign: config?.hAlign,
50
+ vAlign: config?.vAlign,
51
+ textInsets: config?.textInsets,
52
+ controlInsets: config?.controlInsets,
53
+ children: content
44
54
  }
45
55
  );
46
56
  }
@@ -53,6 +63,9 @@ function mainBody({
53
63
  mainBottomToolbar,
54
64
  mainHeaderPlacement = "fixed",
55
65
  mainFooterPlacement = "fixed",
66
+ mainPane,
67
+ mainHeaderList,
68
+ mainFooterList,
56
69
  leftRail,
57
70
  rightRail,
58
71
  bottomDrawer
@@ -67,9 +80,11 @@ function mainBody({
67
80
  Toolbar,
68
81
  {
69
82
  label: mainToolbar.label,
70
- dividerSides: mainHeader ? "" : "b",
83
+ dividerSides: mainToolbar.dividerSides,
84
+ centerAlign: mainToolbar.centerAlign,
71
85
  responsive: mainToolbar.responsive,
72
86
  responsiveAt: mainToolbar.responsiveAt,
87
+ safeAreaEdges: mainToolbar.safeAreaEdges,
73
88
  leading: /* @__PURE__ */ jsxs(Fragment, { children: [
74
89
  left,
75
90
  mainToolbar.title,
@@ -82,16 +97,21 @@ function mainBody({
82
97
  ] })
83
98
  }
84
99
  ) : null,
85
- mainHeader ? /* @__PURE__ */ jsx(List, { dividerSides: "b", children: mainHeader }) : null
100
+ mainHeader ? chromeList(mainHeader, mainHeaderList) : null
86
101
  ] });
87
102
  const footer = !mainFooter && !mainBottomToolbar ? void 0 : /* @__PURE__ */ jsxs(Fragment, { children: [
88
- mainFooter ? /* @__PURE__ */ jsx(List, { dividerSides: mainBottomToolbar ? "" : "t", children: mainFooter }) : null,
103
+ mainFooter ? chromeList(mainFooter, mainFooterList) : null,
89
104
  mainBottomToolbar ? /* @__PURE__ */ jsx(
90
105
  Toolbar,
91
106
  {
92
107
  label: mainBottomToolbar.label,
93
- dividerSides: mainFooter ? "" : "t",
108
+ dividerSides: mainBottomToolbar.dividerSides,
109
+ centerAlign: mainBottomToolbar.centerAlign,
110
+ responsive: mainBottomToolbar.responsive,
111
+ responsiveAt: mainBottomToolbar.responsiveAt,
112
+ safeAreaEdges: mainBottomToolbar.safeAreaEdges,
94
113
  leading: mainBottomToolbar.leading,
114
+ center: mainBottomToolbar.center,
95
115
  trailing: /* @__PURE__ */ jsxs(Fragment, { children: [
96
116
  mainBottomToolbar.trailing,
97
117
  drawer
@@ -106,6 +126,12 @@ function mainBody({
106
126
  {
107
127
  header: scrollHeader ? void 0 : header,
108
128
  footer: scrollFooter ? void 0 : footer,
129
+ chromePlacement: mainHeaderPlacement === "auto" || mainFooterPlacement === "auto" ? "auto" : "fixed",
130
+ contentElement: mainPane?.contentElement,
131
+ contentLabel: mainPane?.contentLabel,
132
+ separators: mainPane?.separators,
133
+ safeAreaEdges: mainPane?.safeAreaEdges,
134
+ chromeDividers: mainPane?.chromeDividers,
109
135
  children: scrollHeader || scrollFooter ? (
110
136
  // Chrome that scrolls joins the content in one gapless column that
111
137
  // fills the scroller, so it scrolls away with the content.
@@ -126,7 +152,7 @@ function floatingRestore(workbenchId, key, panel, hasTargetToolbar) {
126
152
  FloatingToolbar,
127
153
  {
128
154
  label: panel.toolbar.label,
129
- position: key === "leftRail" ? "bottom-start" : "bottom-end",
155
+ position: panel.restorePosition ?? (key === "leftRail" ? "bottom-start" : "bottom-end"),
130
156
  children: groups
131
157
  }
132
158
  );
@@ -226,6 +252,7 @@ function Rail({
226
252
  "div",
227
253
  {
228
254
  class: "kui-workbench__panel-content",
255
+ "data-workbench-panel-content": true,
229
256
  inert: Boolean(panel.collapsed),
230
257
  children: panelBody(id, key, panel)
231
258
  }
@@ -266,6 +293,7 @@ function Drawer({ id, panel }) {
266
293
  "div",
267
294
  {
268
295
  class: "kui-workbench__panel-content",
296
+ "data-workbench-panel-content": true,
269
297
  inert: Boolean(panel.collapsed),
270
298
  children: panelBody(id, "bottomDrawer", panel)
271
299
  }
@@ -309,6 +337,9 @@ function Workbench({
309
337
  mainBottomToolbar,
310
338
  mainHeaderPlacement,
311
339
  mainFooterPlacement,
340
+ mainPane,
341
+ mainHeaderList,
342
+ mainFooterList,
312
343
  mainMinSize = WORKBENCH_MAIN_MIN_SIZE,
313
344
  mainMinHeight = WORKBENCH_MAIN_MIN_HEIGHT,
314
345
  className = "",
@@ -350,6 +381,9 @@ function Workbench({
350
381
  mainBottomToolbar,
351
382
  mainHeaderPlacement,
352
383
  mainFooterPlacement,
384
+ mainPane,
385
+ mainHeaderList,
386
+ mainFooterList,
353
387
  leftRail,
354
388
  rightRail,
355
389
  bottomDrawer
@@ -381,4 +415,4 @@ function Workbench({
381
415
 
382
416
  export { Workbench };
383
417
 
384
- //# sourceMappingURL=chunk-EAX2GSS4.js.map
418
+ //# sourceMappingURL=chunk-G2RKFVRB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/workbench-toolbars.tsx","../src/workbench.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-G2RKFVRB.js","sourcesContent":["import {\n FloatingToolbar,\n type FloatingToolbarPosition,\n} from './floating-toolbar.js';\nimport { List, type ListConfig } from './list.js';\nimport { Pane, type PaneConfig } from './pane.js';\nimport {\n composedPanelBody,\n type PanelSide,\n type PanelToggle,\n type PanelToggleAttributes,\n type PanelToolbar,\n relocatedPanelGroups,\n} from './panel-toolbar.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport { Toolbar, type ToolbarConfig } from './toolbar.js';\nimport {\n type WorkbenchPanelKey,\n workbenchRegionId,\n} from './workbench-resize.js';\n\n/** The standard toggle a Workbench renders for a panel (see {@link PanelToggle}). */\nexport type WorkbenchPanelToggle = PanelToggle;\n\n/**\n * A Workbench panel's top toolbar, composed by the Workbench so its groups can\n * follow the panel's open state (see {@link PanelToolbar} for the roles).\n * A collapsed rail's `constant` groups and toggle go to the leading edge of\n * `mainToolbar` (left rail) or its trailing edge (right rail); a collapsed\n * drawer's go to the trailing edge of `mainBottomToolbar`, else to a\n * `FloatingToolbar` in the work area's bottom-end corner.\n */\nexport type WorkbenchPanelToolbar = PanelToolbar;\n\n/**\n * The work area's top toolbar; collapsed rails add their groups to it. Its\n * configuration forwards to its `Toolbar`. It draws no divider of its own by\n * default: the work area's `Pane` draws one under its header chrome, wherever\n * that chrome ends, while `main` is scrolled (`mainPane.chromeDividers`).\n */\nexport interface WorkbenchMainToolbar extends ToolbarConfig {\n label: string;\n /** The work area's title, usually an extra-large `ToolbarText`. */\n title?: KerfUiContent;\n /** Groups after the title. */\n leading?: KerfUiContent;\n center?: KerfUiContent;\n /** Groups at the trailing edge, before a collapsed right rail's groups. */\n trailing?: KerfUiContent;\n}\n\n/**\n * The work area's bottom toolbar; a collapsed drawer adds its groups to it.\n * Its configuration forwards to its `Toolbar`. It draws no divider of its own\n * by default: the work area's `Pane` draws one over its footer chrome while\n * more of `main` lies below (`mainPane.chromeDividers`).\n */\nexport interface WorkbenchMainBottomToolbar extends ToolbarConfig {\n label: string;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n}\n\nconst SIDES: Record<WorkbenchPanelKey, PanelSide> = {\n leftRail: 'left',\n rightRail: 'right',\n bottomDrawer: 'bottom',\n};\n\n/** A panel as far as its toolbar is concerned. */\nexport interface WorkbenchToolbarPanel {\n toolbar?: WorkbenchPanelToolbar;\n footer?: KerfUiContent;\n /** Configuration for the `Pane` a `toolbar` panel's content renders in. */\n pane?: PaneConfig;\n content: KerfUiContent;\n collapsed?: boolean;\n /** The corner a collapsed panel's restore controls float in. */\n restorePosition?: FloatingToolbarPosition;\n}\n\n/** A Workbench toggle's wiring hooks: its side, morph key, and panel. */\nconst toggleAttributes = (\n workbenchId: string,\n key: WorkbenchPanelKey,\n): PanelToggleAttributes => ({\n 'data-workbench-toggle': SIDES[key],\n // Keyed, so the morph removes a toggle that leaves a toolbar instead of\n // reusing its (possibly focused) button for a different control.\n 'data-key': `${workbenchRegionId(workbenchId, key)}-toggle`,\n 'aria-controls': workbenchRegionId(workbenchId, key),\n});\n\n/**\n * The groups a collapsed panel hands to the work area: its `constant` groups,\n * then its toggle. Empty while the panel is open or has no toolbar.\n */\nexport function relocatedGroups(\n workbenchId: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchToolbarPanel | undefined,\n): KerfUiContent[] {\n return relocatedPanelGroups(\n panel?.toolbar,\n SIDES[key],\n Boolean(panel?.collapsed),\n toggleAttributes(workbenchId, key),\n );\n}\n\n/**\n * A panel's content, wrapped in a `Pane` under its composed toolbar when it\n * has one (with its optional `footer` below). Without a toolbar the content\n * renders as given.\n */\nexport function panelBody(\n workbenchId: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchToolbarPanel,\n) {\n const toolbar = panel.toolbar;\n if (!toolbar) return panel.content;\n return composedPanelBody({\n toolbar,\n side: SIDES[key],\n collapsed: Boolean(panel.collapsed),\n attributes: toggleAttributes(workbenchId, key),\n pane: panel.pane,\n footer: panel.footer,\n content: panel.content,\n });\n}\n\n/**\n * The work area's `mainHeader` / `mainFooter` chrome in a `List` carrying the\n * app's configuration; an omitted or `undefined` field keeps the `List`\n * default (no divider: the work area's `Pane` draws its chrome dividers).\n */\nfunction chromeList(content: KerfUiContent, config: ListConfig | undefined) {\n return (\n <List\n dividerSides={config?.dividerSides}\n gap={config?.gap}\n hAlign={config?.hAlign}\n vAlign={config?.vAlign}\n textInsets={config?.textInsets}\n controlInsets={config?.controlInsets}\n >\n {content}\n </List>\n );\n}\n\n/**\n * Whether the work area's header or footer chrome stays pinned (`fixed`),\n * scrolls away with the content (`scroll`), or stays pinned while the work\n * area is tall enough and scrolls with the content when it is short (`auto`,\n * the Pane's `chromePlacement=\"auto\"`; it applies to the pinned header and\n * footer together).\n */\nexport type WorkbenchChromePlacement = 'fixed' | 'scroll' | 'auto';\n\n/**\n * The work area: the app's `main` in a `Pane` (configured by `mainPane`)\n * under `mainToolbar` and any `mainHeader` list, and above any `mainFooter`\n * list and `mainBottomToolbar` (the header and footer lists configured by\n * `mainHeaderList` / `mainFooterList`), with each collapsed panel's groups\n * added to the toolbar on its side. Without any of that chrome, `main`\n * renders as given and `mainPane` is ignored.\n */\nexport function mainBody({\n workbenchId,\n main,\n mainToolbar,\n mainHeader,\n mainFooter,\n mainBottomToolbar,\n mainHeaderPlacement = 'fixed',\n mainFooterPlacement = 'fixed',\n mainPane,\n mainHeaderList,\n mainFooterList,\n leftRail,\n rightRail,\n bottomDrawer,\n}: {\n workbenchId: string;\n main: KerfUiContent;\n mainToolbar?: WorkbenchMainToolbar;\n mainHeader?: KerfUiContent;\n mainFooter?: KerfUiContent;\n mainBottomToolbar?: WorkbenchMainBottomToolbar;\n mainHeaderPlacement?: WorkbenchChromePlacement;\n mainFooterPlacement?: WorkbenchChromePlacement;\n mainPane?: PaneConfig;\n mainHeaderList?: ListConfig;\n mainFooterList?: ListConfig;\n leftRail?: WorkbenchToolbarPanel;\n rightRail?: WorkbenchToolbarPanel;\n bottomDrawer?: WorkbenchToolbarPanel;\n}) {\n if (!mainToolbar && !mainBottomToolbar && !mainHeader && !mainFooter)\n return main;\n const left = relocatedGroups(workbenchId, 'leftRail', leftRail);\n const right = relocatedGroups(workbenchId, 'rightRail', rightRail);\n const drawer = mainBottomToolbar\n ? relocatedGroups(workbenchId, 'bottomDrawer', bottomDrawer)\n : [];\n // The Pane draws one divider under the header chrome and one over the\n // footer chrome, wherever that chrome ends, from the scroll state.\n const header =\n !mainToolbar && !mainHeader ? undefined : (\n <>\n {mainToolbar ? (\n <Toolbar\n label={mainToolbar.label}\n dividerSides={mainToolbar.dividerSides}\n centerAlign={mainToolbar.centerAlign}\n responsive={mainToolbar.responsive}\n responsiveAt={mainToolbar.responsiveAt}\n safeAreaEdges={mainToolbar.safeAreaEdges}\n leading={\n <>\n {left}\n {mainToolbar.title}\n {mainToolbar.leading}\n </>\n }\n center={mainToolbar.center}\n trailing={\n <>\n {mainToolbar.trailing}\n {right}\n </>\n }\n />\n ) : null}\n {mainHeader ? chromeList(mainHeader, mainHeaderList) : null}\n </>\n );\n const footer =\n !mainFooter && !mainBottomToolbar ? undefined : (\n <>\n {mainFooter ? chromeList(mainFooter, mainFooterList) : null}\n {mainBottomToolbar ? (\n <Toolbar\n label={mainBottomToolbar.label}\n dividerSides={mainBottomToolbar.dividerSides}\n centerAlign={mainBottomToolbar.centerAlign}\n responsive={mainBottomToolbar.responsive}\n responsiveAt={mainBottomToolbar.responsiveAt}\n safeAreaEdges={mainBottomToolbar.safeAreaEdges}\n leading={mainBottomToolbar.leading}\n center={mainBottomToolbar.center}\n trailing={\n <>\n {mainBottomToolbar.trailing}\n {drawer}\n </>\n }\n />\n ) : null}\n </>\n );\n const scrollHeader = mainHeaderPlacement === 'scroll';\n const scrollFooter = mainFooterPlacement === 'scroll';\n return (\n <Pane\n header={scrollHeader ? undefined : header}\n footer={scrollFooter ? undefined : footer}\n chromePlacement={\n mainHeaderPlacement === 'auto' || mainFooterPlacement === 'auto'\n ? 'auto'\n : 'fixed'\n }\n contentElement={mainPane?.contentElement}\n contentLabel={mainPane?.contentLabel}\n separators={mainPane?.separators}\n safeAreaEdges={mainPane?.safeAreaEdges}\n chromeDividers={mainPane?.chromeDividers}\n >\n {scrollHeader || scrollFooter ? (\n // Chrome that scrolls joins the content in one gapless column that\n // fills the scroller, so it scrolls away with the content.\n <List flex>\n {scrollHeader ? header : null}\n {main}\n {scrollFooter ? footer : null}\n </List>\n ) : (\n main\n )}\n </Pane>\n );\n}\n\n/**\n * A collapsed panel's groups when the work area has no toolbar on its side\n * to take them: a `FloatingToolbar` for the panel's restore corner, so the\n * panel can always be reopened.\n */\nexport function floatingRestore(\n workbenchId: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchToolbarPanel | undefined,\n hasTargetToolbar: boolean,\n) {\n if (hasTargetToolbar) return undefined;\n const groups = relocatedGroups(workbenchId, key, panel);\n if (groups.length === 0) return undefined;\n return (\n <FloatingToolbar\n label={panel!.toolbar!.label}\n position={\n panel!.restorePosition ??\n (key === 'leftRail' ? 'bottom-start' : 'bottom-end')\n }\n >\n {groups}\n </FloatingToolbar>\n );\n}\n","import type { SafeHtml } from 'kerfjs';\n\nimport type { ListConfig } from './list.js';\nimport type { PaneConfig } from './pane.js';\nimport {\n clampRegionSize,\n type ResizableRegionAxis,\n type ResizableRegionCollapseMotion,\n type ResizableRegionContentOverflow,\n type ResizableRegionEdge,\n type ResizableRegionPresentation,\n type ResizableRegionRestorePosition,\n type ResizableRegionSeparator,\n} from './resizable-region.js';\nimport { ResizeGrip } from './resize-grip.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport {\n WORKBENCH_MAIN_MIN_HEIGHT,\n WORKBENCH_MAIN_MIN_SIZE,\n WORKBENCH_RESIZE_DEFAULTS,\n type WorkbenchPanelKey,\n workbenchRegionId,\n} from './workbench-resize.js';\nimport {\n floatingRestore,\n mainBody,\n panelBody,\n type WorkbenchChromePlacement,\n type WorkbenchMainBottomToolbar,\n type WorkbenchMainToolbar,\n type WorkbenchPanelToolbar,\n} from './workbench-toolbars.js';\n\nexport type {\n WorkbenchChromePlacement,\n WorkbenchMainBottomToolbar,\n WorkbenchMainToolbar,\n WorkbenchPanelToggle,\n WorkbenchPanelToolbar,\n} from './workbench-toolbars.js';\n\n/**\n * The Workbench container breakpoint below which a panel presents as an\n * overlay: `narrow` (704px or less) or `compact` (448px or less) — the same\n * breakpoints as `ResizableRegion`'s `responsiveFillAt` — or `never` to keep\n * it inline at every width.\n */\nexport type WorkbenchResponsiveOverlayAt = 'compact' | 'narrow' | 'never';\n\n/**\n * How wide a rail's overlay is in a compact (448px or less) Workbench: `inset`\n * fills the Workbench less a dismiss margin on the side away from the rail's\n * edge, so a press beside it closes it; `full` fills the Workbench.\n */\nexport type WorkbenchCompactOverlay = 'inset' | 'full';\n\n/** Drag-resize limits for a resizable Workbench panel, in px. */\nexport interface WorkbenchPanelResizable {\n /** Smallest size (default 180 for a rail, 120 for the drawer). */\n min?: number;\n /** Largest size (default 480). */\n max?: number;\n}\n\n/** A collapsible Workbench panel — a side rail or the bottom drawer. */\nexport interface WorkbenchPanel {\n content: KerfUiContent;\n /**\n * The panel's top toolbar, composed by the Workbench: its `constant` groups\n * and standard `toggle` move to the work area's toolbar while the panel is\n * collapsed. With it, `content` renders in a `Pane` below the toolbar.\n */\n toolbar?: WorkbenchPanelToolbar;\n /** Optional bottom toolbar under a `toolbar` panel's content. */\n footer?: KerfUiContent;\n /**\n * Configuration for a `toolbar` panel's `Pane` (`contentElement`,\n * `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`) — for example\n * `{ contentElement: 'nav', contentLabel: 'Sections' }` for a navigation\n * rail. Omitted or `undefined` fields keep the `Pane` defaults. Ignored\n * without a `toolbar`, where `content` renders as given.\n */\n pane?: PaneConfig;\n /** Whether the panel is currently collapsed (the app owns this). */\n collapsed?: boolean;\n /**\n * Rail width, or drawer height, in px. Overrides the CSS default. For a\n * resizable panel it is the current size (default 280 for a rail, 220 for\n * the drawer), clamped to the limits; the app owns it and `wireWorkbench`\n * reports each resize.\n */\n size?: number;\n /**\n * Opt in to drag and keyboard resizing on the panel's inner separator:\n * `true` for the default limits, or `{ min, max }`. Off by default. Pair it\n * with `wireWorkbench` from `@kerfjs/ui/wire-workbench`.\n */\n resizable?: boolean | WorkbenchPanelResizable;\n /** Accessible name for the panel region. */\n label?: string;\n separator?: ResizableRegionSeparator;\n collapseMotion?: ResizableRegionCollapseMotion;\n contentOverflow?: ResizableRegionContentOverflow;\n presentation?: ResizableRegionPresentation;\n /**\n * Present the panel as an overlay, without a separator, below a Workbench\n * container breakpoint, and inline above it — the CSS decides, so the app\n * needs no device-class check. A rail overlays from its side at full\n * height, over the work area and an open drawer; the bottom drawer\n * overlays the bottom of the work-area column. Rails default to `narrow`\n * (pass `never` to keep one inline); the drawer defaults to inline.\n */\n responsiveOverlayAt?: WorkbenchResponsiveOverlayAt;\n /**\n * A rail's overlay width in a compact Workbench (default `inset`: the\n * Workbench less `--kui-workbench-overlay-dismiss-margin`, 44px). Ignored\n * by the drawer.\n */\n compactOverlay?: WorkbenchCompactOverlay;\n /**\n * Control shown while collapsed, in a safe-area-aware corner of the\n * Workbench (not the viewport); the bottom drawer's sits in the work-area\n * column. Prefer `toolbar.toggle`, which the Workbench relocates into the\n * work area's toolbar (or this corner when that toolbar is absent).\n */\n restoreControl?: SafeHtml;\n restorePosition?: ResizableRegionRestorePosition;\n}\n\nexport interface WorkbenchProps {\n /**\n * The Workbench's `id`. Each panel's `id` derives from it —\n * `<id>-left-rail`, `<id>-right-rail`, `<id>-bottom-drawer` — so a toggle\n * can name the panel it shows and hides with `aria-controls`.\n */\n id: string;\n label: string;\n /** The central work area. */\n main: KerfUiContent;\n /**\n * The work area's top toolbar. A collapsed left rail's `constant` groups\n * and toggle lead it; a collapsed right rail's trail it. With it, `main`\n * renders in a `Pane` below the toolbar.\n */\n mainToolbar?: WorkbenchMainToolbar;\n /**\n * Fixed content under `mainToolbar` — supporting copy such as a\n * description — divided from the scrolling `main` below it.\n */\n mainHeader?: KerfUiContent;\n /**\n * Fixed content over `mainBottomToolbar` — a status line or a resource\n * toolbar — divided from the scrolling `main` above it.\n */\n mainFooter?: KerfUiContent;\n /**\n * The work area's bottom toolbar. A collapsed drawer's `constant` groups and\n * toggle trail it; without it they float in the work area's corner.\n */\n mainBottomToolbar?: WorkbenchMainBottomToolbar;\n /**\n * Whether `mainToolbar` and `mainHeader` stay pinned (`fixed`, default),\n * scroll away with `main` (`scroll`) — useful where large text would leave\n * pinned chrome little room — or stay pinned while the work area is tall\n * enough and scroll with `main` when it is short (`auto`).\n */\n mainHeaderPlacement?: WorkbenchChromePlacement;\n /** The same for `mainFooter` and `mainBottomToolbar` (default `fixed`). */\n mainFooterPlacement?: WorkbenchChromePlacement;\n /**\n * Configuration for the work area's `Pane` (`contentElement`,\n * `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`), which it has whenever it\n * has a toolbar, `mainHeader`, or `mainFooter`; without that chrome, `main`\n * renders as given and this is ignored. Omitted or `undefined` fields keep\n * the `Pane` defaults.\n */\n mainPane?: PaneConfig;\n /**\n * Configuration for the `List` that holds `mainHeader` (`gap`, `hAlign`,\n * `vAlign`, `dividerSides`, `textInsets`, `controlInsets`). Omitted or\n * `undefined` fields keep the defaults (no divider: the work area's\n * `Pane` draws the line under its header chrome).\n */\n mainHeaderList?: ListConfig;\n /**\n * The same for the `List` that holds `mainFooter` (no divider by default:\n * the work area's `Pane` draws the line over its footer chrome).\n */\n mainFooterList?: ListConfig;\n leftRail?: WorkbenchPanel;\n rightRail?: WorkbenchPanel;\n bottomDrawer?: WorkbenchPanel;\n /**\n * Minimum width, in px, the work area keeps beside the inline rails, fixed\n * or `resizable` (default 320; `0` turns it off). Resizing a rail stops\n * where the work area would drop below it, and inline rails shrink\n * proportionally when the Workbench gets narrower. Workbenches without a\n * rail ignore it.\n */\n mainMinSize?: number;\n /**\n * Minimum height, in px, the work area keeps above an inline bottom drawer,\n * fixed or `resizable` (default 120; `0` turns it off) — the drawer's\n * counterpart of `mainMinSize`. Resizing the drawer stops where the work\n * area would drop below it, and the drawer shrinks when the Workbench gets\n * shorter. Workbenches without a drawer ignore it.\n */\n mainMinHeight?: number;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\ninterface ResolvedResize {\n regionId: string;\n axis: ResizableRegionAxis;\n edge: ResizableRegionEdge;\n size: number;\n min: number;\n max: number;\n}\n\n/**\n * Each panel's separator is its inner edge. Growing the left rail moves that\n * edge toward the inline end; growing the right rail or the drawer moves it\n * toward the start — the same edge vocabulary `ResizableRegion` uses.\n */\nconst EDGES: Record<WorkbenchPanelKey, ResizableRegionEdge> = {\n leftRail: 'end',\n rightRail: 'start',\n bottomDrawer: 'start',\n};\n\nconst DEFAULT_LABELS: Record<WorkbenchPanelKey, string> = {\n leftRail: 'left rail',\n rightRail: 'right rail',\n bottomDrawer: 'bottom drawer',\n};\n\nfunction resolveResize(\n id: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchPanel,\n): ResolvedResize | undefined {\n if (!panel.resizable) return undefined;\n const defaults = WORKBENCH_RESIZE_DEFAULTS[key];\n const limits = panel.resizable === true ? {} : panel.resizable;\n const min = limits.min ?? defaults.min;\n const max = Math.max(min, limits.max ?? defaults.max);\n return {\n regionId: workbenchRegionId(id, key),\n axis: key === 'bottomDrawer' ? 'vertical' : 'horizontal',\n edge: EDGES[key],\n size: clampRegionSize(panel.size ?? defaults.size, min, max),\n min,\n max,\n };\n}\n\n/** The attributes a resizable panel adds for the resize wiring to read. */\nconst resizeAttributes = (resize: ResolvedResize | undefined) =>\n resize\n ? {\n 'data-resizable': 'true',\n 'data-region-id': resize.regionId,\n 'data-axis': resize.axis,\n 'data-edge': resize.edge,\n }\n : {};\n\n/**\n * A resizable panel's size lives in the resize wiring's track property, so a\n * drag or key press resizes the panel before the app re-renders; the CSS maps\n * it onto the rail width or drawer height.\n */\nfunction panelStyle(\n panel: WorkbenchPanel,\n resize: ResolvedResize | undefined,\n sizeProperty: string,\n) {\n if (resize) return `--kui-resizable-region-size:${resize.size}px`;\n return panel.size ? `${sizeProperty}: ${panel.size}px` : undefined;\n}\n\n/**\n * The separator a resizable panel owns: the same focusable `role=\"separator\"`\n * contract a `ResizableRegion` handle carries, so one resize wiring drives\n * both. It leaves the tab order while the panel is collapsed or not inline.\n */\nfunction PanelHandle({\n panel,\n resize,\n label,\n}: {\n panel: WorkbenchPanel;\n resize: ResolvedResize;\n label: string;\n}) {\n const inert =\n Boolean(panel.collapsed) || (panel.presentation ?? 'inline') !== 'inline';\n return (\n <div\n class=\"kui-workbench__handle\"\n role=\"separator\"\n tabindex={inert ? '-1' : '0'}\n aria-label={`Resize ${label}`}\n aria-orientation={\n resize.axis === 'horizontal' ? 'vertical' : 'horizontal'\n }\n aria-valuemin={resize.min}\n aria-valuemax={resize.max}\n aria-valuenow={resize.size}\n aria-hidden={inert ? 'true' : undefined}\n data-kui-resize-handle\n data-region-id={resize.regionId}\n >\n <span class=\"kui-workbench__handle-icon\" aria-hidden=\"true\">\n <ResizeGrip axis={resize.axis} />\n </span>\n </div>\n );\n}\n\n/**\n * A collapsed panel leaves the accessibility tree as a whole, like a collapsed\n * `CollapsiblePanel`: its content and separator are already inert or hidden,\n * so the labeled landmark would otherwise stay behind, empty, for a screen\n * reader to land on. Its restore control renders outside it and stays\n * reachable.\n */\nfunction hiddenFromAccessibility(panel: WorkbenchPanel) {\n return panel.collapsed || panel.presentation === 'hidden'\n ? ('true' as const)\n : undefined;\n}\n\n/** A breakpoint's attribute value; `never` (or none) renders no attribute. */\nconst responsiveAt = (at: WorkbenchResponsiveOverlayAt | undefined) =>\n at === 'never' ? undefined : at;\n\nfunction Rail({\n id,\n side,\n panel,\n}: {\n id: string;\n side: 'left' | 'right';\n panel: WorkbenchPanel;\n}) {\n const key: WorkbenchPanelKey = side === 'left' ? 'leftRail' : 'rightRail';\n const resize = resolveResize(id, key, panel);\n return (\n <aside\n id={workbenchRegionId(id, key)}\n class={`kui-workbench__rail kui-workbench__rail--${side}`}\n data-workbench-rail={side}\n data-collapsed={String(panel.collapsed ?? false)}\n data-separator={panel.separator ?? 'auto'}\n data-collapse-motion={panel.collapseMotion ?? 'slide'}\n data-content-overflow={panel.contentOverflow ?? 'clip'}\n data-presentation={panel.presentation ?? 'inline'}\n data-responsive-overlay-at={responsiveAt(\n panel.responsiveOverlayAt ?? 'narrow',\n )}\n data-compact-overlay={panel.compactOverlay ?? 'inset'}\n {...resizeAttributes(resize)}\n aria-label={panel.label || undefined}\n aria-hidden={hiddenFromAccessibility(panel)}\n inert={Boolean(panel.collapsed)}\n style={panelStyle(panel, resize, '--kui-workbench-rail-width')}\n >\n <div\n class=\"kui-workbench__panel-content\"\n data-workbench-panel-content\n inert={Boolean(panel.collapsed)}\n >\n {panelBody(id, key, panel)}\n </div>\n {resize && (\n <PanelHandle\n panel={panel}\n resize={resize}\n label={panel.label || DEFAULT_LABELS[key]}\n />\n )}\n </aside>\n );\n}\n\nfunction Drawer({ id, panel }: { id: string; panel: WorkbenchPanel }) {\n const resize = resolveResize(id, 'bottomDrawer', panel);\n return (\n <section\n id={workbenchRegionId(id, 'bottomDrawer')}\n class=\"kui-workbench__drawer\"\n data-workbench-drawer\n data-collapsed={String(panel.collapsed ?? false)}\n data-separator={panel.separator ?? 'auto'}\n data-collapse-motion={panel.collapseMotion ?? 'slide'}\n data-content-overflow={panel.contentOverflow ?? 'clip'}\n data-presentation={panel.presentation ?? 'inline'}\n data-responsive-overlay-at={responsiveAt(panel.responsiveOverlayAt)}\n {...resizeAttributes(resize)}\n aria-label={panel.label || undefined}\n aria-hidden={hiddenFromAccessibility(panel)}\n inert={Boolean(panel.collapsed)}\n style={panelStyle(panel, resize, '--kui-workbench-drawer-height')}\n >\n <div\n class=\"kui-workbench__panel-content\"\n data-workbench-panel-content\n inert={Boolean(panel.collapsed)}\n >\n {panelBody(id, 'bottomDrawer', panel)}\n </div>\n {resize && (\n <PanelHandle\n panel={panel}\n resize={resize}\n label={panel.label || DEFAULT_LABELS.bottomDrawer}\n />\n )}\n </section>\n );\n}\n\n/** A collapsed panel's restore control, outside the clipped panel. */\nfunction restore(\n panel: WorkbenchPanel | undefined,\n side: 'left' | 'right' | 'bottom',\n position: ResizableRegionRestorePosition,\n generated: SafeHtml | undefined,\n) {\n const control = panel?.restoreControl ?? generated;\n if (!panel?.collapsed || !control || panel.presentation === 'hidden')\n return '';\n return (\n <div\n class=\"kui-workbench__restore\"\n data-panel={side}\n data-position={panel.restorePosition ?? position}\n >\n {control}\n </div>\n );\n}\n\n/**\n * The Xcode-like multi-panel workspace: a collapsible left rail, right rail, and\n * bottom drawer around a central work area (any absent). Collapsing snaps the\n * panel's track to zero in one reflow while its fixed-size content slides out via\n * a composited transform — the instant-width / sliding-content technique, so the\n * work area relayouts once, not per frame. Bottom-drawer content stays anchored\n * to the shell's stable bottom edge throughout that transition. The app owns\n * each `collapsed` flag; the collapse is pure CSS. A collapsed panel renders\n * `inert` and `aria-hidden`, so neither Tab nor assistive technology reaches\n * controls that have slid out of view or an empty landmark (its restore control\n * lives outside it and stays reachable). A panel may opt in to drag and keyboard resizing with\n * `resizable`, which `wireWorkbench` drives. See `docs/23-app-layouts.md` §3.3.\n */\nexport function Workbench({\n id,\n label,\n main,\n leftRail,\n rightRail,\n bottomDrawer,\n mainToolbar,\n mainHeader,\n mainFooter,\n mainBottomToolbar,\n mainHeaderPlacement,\n mainFooterPlacement,\n mainPane,\n mainHeaderList,\n mainFooterList,\n mainMinSize = WORKBENCH_MAIN_MIN_SIZE,\n mainMinHeight = WORKBENCH_MAIN_MIN_HEIGHT,\n className = '',\n slot,\n}: WorkbenchProps) {\n // Each work-area minimum applies only on an axis a panel shares with it:\n // the width beside a rail, the height above the drawer.\n const px = (value: number) => Math.max(0, Math.round(value));\n const mainMin = leftRail || rightRail ? px(mainMinSize) : undefined;\n const mainMinBlock = bottomDrawer ? px(mainMinHeight) : undefined;\n const style = [\n mainMin === undefined ? '' : `--_kui-workbench-main-min-width:${mainMin}px`,\n mainMinBlock === undefined\n ? ''\n : `--_kui-workbench-main-min-height:${mainMinBlock}px`,\n ]\n .filter(Boolean)\n .join(';');\n return (\n <section\n class={`kui-workbench ${className}`.trim()}\n id={id}\n data-component=\"workbench\"\n data-main-min-size={mainMin === undefined ? undefined : String(mainMin)}\n data-main-min-height={\n mainMinBlock === undefined ? undefined : String(mainMinBlock)\n }\n style={style || undefined}\n aria-label={label}\n slot={slot}\n >\n {leftRail && <Rail id={id} side=\"left\" panel={leftRail} />}\n {restore(\n leftRail,\n 'left',\n 'bottom-start',\n floatingRestore(id, 'leftRail', leftRail, Boolean(mainToolbar)),\n )}\n <div class=\"kui-workbench__center\">\n <div class=\"kui-workbench__main\" data-workbench-main>\n {mainBody({\n workbenchId: id,\n main,\n mainToolbar,\n mainHeader,\n mainFooter,\n mainBottomToolbar,\n mainHeaderPlacement,\n mainFooterPlacement,\n mainPane,\n mainHeaderList,\n mainFooterList,\n leftRail,\n rightRail,\n bottomDrawer,\n })}\n </div>\n {bottomDrawer && <Drawer id={id} panel={bottomDrawer} />}\n {restore(\n bottomDrawer,\n 'bottom',\n 'bottom-end',\n floatingRestore(\n id,\n 'bottomDrawer',\n bottomDrawer,\n Boolean(mainBottomToolbar),\n ),\n )}\n </div>\n {rightRail && <Rail id={id} side=\"right\" panel={rightRail} />}\n {restore(\n rightRail,\n 'right',\n 'bottom-end',\n floatingRestore(id, 'rightRail', rightRail, Boolean(mainToolbar)),\n )}\n </section>\n );\n}\n"]}
@@ -0,0 +1,249 @@
1
+ // src/wire-scroll-dividers.ts
2
+ var EDGES = ["t", "r", "b", "l"];
3
+ var FACING = { t: "b", r: "l", b: "t", l: "r" };
4
+ var TARGET_EDGES = {
5
+ t: "top",
6
+ r: "right",
7
+ b: "bottom",
8
+ l: "left"
9
+ };
10
+ var SCROLL_OVERFLOW = "data-scroll-overflow";
11
+ var SCROLL_DIVIDER = "data-scroll-divider";
12
+ var THRESHOLD = 1;
13
+ var quoted = (value) => `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
14
+ function within(root, selector) {
15
+ const found = [...root.querySelectorAll(selector)];
16
+ if (root.nodeType === 1 && root.matches(selector))
17
+ found.unshift(root);
18
+ return found;
19
+ }
20
+ var directChild = (parent, selector) => [...parent.children].find(
21
+ (child) => child.matches(selector)
22
+ );
23
+ var PANE_CHROME = {
24
+ t: ".kui-pane__header, .kui-pane__toolbar",
25
+ b: ".kui-pane__footer"
26
+ };
27
+ var NAV_STACK_CHROME = {
28
+ t: ".kui-nav-stack__chrome:not([data-nav-chrome-copy])",
29
+ b: ".kui-nav-stack__bottom:not([data-nav-chrome-copy])"
30
+ };
31
+ function activeView(stack) {
32
+ const viewport = directChild(stack, ".kui-nav-stack__viewport");
33
+ if (!viewport) return void 0;
34
+ return [...viewport.children].filter(
35
+ (child) => child.matches(
36
+ '.kui-nav-stack__view[data-nav-active="true"]:not([data-nav-exiting="true"])'
37
+ )
38
+ ).at(-1);
39
+ }
40
+ function activeScene(scaffold) {
41
+ const scenes = directChild(scaffold, ".kui-tab-scaffold__scenes");
42
+ return scenes ? directChild(scenes, '.kui-tab-scaffold__scene[data-active="true"]') : void 0;
43
+ }
44
+ function regionScrollers(region, edge) {
45
+ const found = [];
46
+ let current = region;
47
+ while (current) {
48
+ found.push(current);
49
+ if (current.children.length !== 1) break;
50
+ const child = current.children[0];
51
+ if (child.matches(".kui-pane")) {
52
+ current = directChild(child, PANE_CHROME[edge]) ? void 0 : directChild(child, ".kui-pane__content");
53
+ if (current) found.push(current);
54
+ break;
55
+ }
56
+ if (child.matches(".kui-nav-stack"))
57
+ current = directChild(child, NAV_STACK_CHROME[edge]) ? void 0 : activeView(child);
58
+ else if (child.matches(".kui-tab-scaffold") && edge === "t")
59
+ current = activeScene(child);
60
+ else current = void 0;
61
+ }
62
+ return found;
63
+ }
64
+ var sides = (edges) => EDGES.filter((edge) => edges.has(edge)).join("");
65
+ function measure(scroller) {
66
+ const edges = /* @__PURE__ */ new Set();
67
+ const maxY = scroller.scrollHeight - scroller.clientHeight;
68
+ if (maxY > THRESHOLD) {
69
+ if (scroller.scrollTop > THRESHOLD) edges.add("t");
70
+ if (maxY - scroller.scrollTop > THRESHOLD) edges.add("b");
71
+ }
72
+ const maxX = scroller.scrollWidth - scroller.clientWidth;
73
+ if (maxX > THRESHOLD) {
74
+ const view = scroller.ownerDocument.defaultView;
75
+ const rtl = view?.getComputedStyle(scroller).direction === "rtl";
76
+ const left = rtl ? maxX + scroller.scrollLeft : scroller.scrollLeft;
77
+ if (left > THRESHOLD) edges.add("l");
78
+ if (maxX - left > THRESHOLD) edges.add("r");
79
+ }
80
+ return sides(edges);
81
+ }
82
+ function write(element, name, value) {
83
+ if (element.getAttribute(name) === (value || null)) return;
84
+ if (name === SCROLL_OVERFLOW) {
85
+ if (value) element.setAttribute(SCROLL_OVERFLOW, value);
86
+ else element.removeAttribute(SCROLL_OVERFLOW);
87
+ } else if (value) element.setAttribute(SCROLL_DIVIDER, value);
88
+ else element.removeAttribute(SCROLL_DIVIDER);
89
+ }
90
+ function wireScrollDividers(root, { targets = [] } = {}) {
91
+ const ownerDocument = root.nodeType === 9 ? root : root.ownerDocument;
92
+ const view = ownerDocument.defaultView;
93
+ let disposed = false;
94
+ let pairings = [];
95
+ const overflow = /* @__PURE__ */ new Map();
96
+ const written = /* @__PURE__ */ new Map();
97
+ const byId = (id) => {
98
+ if (!id) return void 0;
99
+ const [match] = within(root, `[id=${quoted(id)}]`);
100
+ return match;
101
+ };
102
+ const collect = () => {
103
+ const found = [];
104
+ for (const pane of within(root, ".kui-pane")) {
105
+ const scroller = directChild(pane, ".kui-pane__content");
106
+ const header = directChild(pane, PANE_CHROME.t);
107
+ const footer = directChild(pane, PANE_CHROME.b);
108
+ if (scroller && (header || footer))
109
+ found.push({ scroller, chrome: { t: header, b: footer } });
110
+ }
111
+ const pairRegion = (region, edge, chrome) => {
112
+ if (!region || !chrome) return;
113
+ for (const scroller of regionScrollers(region, edge))
114
+ found.push({ scroller, chrome: { [edge]: chrome } });
115
+ };
116
+ for (const stack of within(root, ".kui-nav-stack")) {
117
+ const view2 = activeView(stack);
118
+ for (const edge of ["t", "b"])
119
+ pairRegion(view2, edge, directChild(stack, NAV_STACK_CHROME[edge]));
120
+ }
121
+ for (const scaffold of within(root, ".kui-tab-scaffold"))
122
+ pairRegion(
123
+ activeScene(scaffold),
124
+ "b",
125
+ directChild(scaffold, ".kui-tab-scaffold__bar")
126
+ );
127
+ for (const strip of within(root, "[data-kui-tab-list]"))
128
+ found.push({ scroller: strip, chrome: {} });
129
+ for (const target of targets) {
130
+ const scroller = byId(target.scroller);
131
+ if (!scroller) continue;
132
+ const chrome = {};
133
+ for (const edge of EDGES) chrome[edge] = byId(target[TARGET_EDGES[edge]]);
134
+ found.push({ scroller, chrome });
135
+ }
136
+ return found;
137
+ };
138
+ const apply = () => {
139
+ const current = /* @__PURE__ */ new Map();
140
+ const dividers = /* @__PURE__ */ new Map();
141
+ for (const { scroller, chrome } of pairings) {
142
+ const edges = overflow.get(scroller);
143
+ (current.get(scroller) ?? current.set(scroller, /* @__PURE__ */ new Map()).get(scroller)).set(SCROLL_OVERFLOW, edges);
144
+ for (const edge of EDGES) {
145
+ const element = chrome[edge];
146
+ if (!element) continue;
147
+ const shown = dividers.get(element) ?? /* @__PURE__ */ new Set();
148
+ dividers.set(element, shown);
149
+ if (edges.includes(edge)) shown.add(FACING[edge]);
150
+ }
151
+ }
152
+ for (const [element, shown] of dividers)
153
+ (current.get(element) ?? current.set(element, /* @__PURE__ */ new Map()).get(element)).set(SCROLL_DIVIDER, sides(shown));
154
+ for (const [element, values] of written)
155
+ for (const name of values.keys())
156
+ if (!current.get(element)?.has(name)) write(element, name, "");
157
+ written.clear();
158
+ for (const [element, values] of current) {
159
+ written.set(element, values);
160
+ for (const [name, value] of values) write(element, name, value);
161
+ }
162
+ };
163
+ const observed = /* @__PURE__ */ new Set();
164
+ const resizeObserver = view?.ResizeObserver ? new view.ResizeObserver((entries) => {
165
+ if (disposed) return;
166
+ const scrollers = new Set(pairings.map(({ scroller }) => scroller));
167
+ for (const { target } of entries) {
168
+ const scroller = scrollers.has(target) ? target : target.parentElement;
169
+ if (scroller && scrollers.has(scroller))
170
+ overflow.set(scroller, measure(scroller));
171
+ }
172
+ apply();
173
+ }) : void 0;
174
+ const observeSizes = () => {
175
+ if (!resizeObserver) return;
176
+ const wanted = /* @__PURE__ */ new Set();
177
+ for (const { scroller } of pairings) {
178
+ wanted.add(scroller);
179
+ for (const child of scroller.children) wanted.add(child);
180
+ }
181
+ for (const element of observed)
182
+ if (!wanted.has(element)) {
183
+ resizeObserver.unobserve(element);
184
+ observed.delete(element);
185
+ }
186
+ for (const element of wanted)
187
+ if (!observed.has(element)) {
188
+ resizeObserver.observe(element);
189
+ observed.add(element);
190
+ }
191
+ };
192
+ const refresh = () => {
193
+ pairings = collect();
194
+ overflow.clear();
195
+ for (const { scroller } of pairings)
196
+ overflow.set(scroller, measure(scroller));
197
+ observeSizes();
198
+ apply();
199
+ };
200
+ const onScroll = (event) => {
201
+ const scroller = event.target;
202
+ if (!overflow.has(scroller)) return;
203
+ const edges = measure(scroller);
204
+ if (edges === overflow.get(scroller)) return;
205
+ overflow.set(scroller, edges);
206
+ apply();
207
+ };
208
+ const mutationObserver = view?.MutationObserver ? new view.MutationObserver((records) => {
209
+ if (records.every(
210
+ ({ type, attributeName }) => type === "attributes" && (attributeName === SCROLL_OVERFLOW || attributeName === SCROLL_DIVIDER)
211
+ ))
212
+ apply();
213
+ else refresh();
214
+ }) : void 0;
215
+ refresh();
216
+ root.addEventListener("scroll", onScroll, { capture: true, passive: true });
217
+ mutationObserver?.observe(root, {
218
+ subtree: true,
219
+ childList: true,
220
+ attributes: true,
221
+ // The shown NavStack view and TabScaffold scene change by attribute.
222
+ attributeFilter: [
223
+ SCROLL_OVERFLOW,
224
+ SCROLL_DIVIDER,
225
+ "id",
226
+ "class",
227
+ "data-nav-active",
228
+ "data-nav-exiting",
229
+ "data-active"
230
+ ]
231
+ });
232
+ return () => {
233
+ if (disposed) return;
234
+ disposed = true;
235
+ mutationObserver?.disconnect();
236
+ resizeObserver?.disconnect();
237
+ root.removeEventListener("scroll", onScroll, { capture: true });
238
+ for (const [element, values] of written)
239
+ for (const name of values.keys()) write(element, name, "");
240
+ written.clear();
241
+ overflow.clear();
242
+ observed.clear();
243
+ pairings = [];
244
+ };
245
+ }
246
+
247
+ export { wireScrollDividers };
248
+
249
+ //# sourceMappingURL=chunk-JCV4GXWB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/wire-scroll-dividers.ts"],"names":["view"],"mappings":"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","file":"chunk-JCV4GXWB.js","sourcesContent":["/**\n * An app-owned scroll arrangement outside a `Pane`: the `id` of the element\n * that scrolls and the `id`s of the pinned chrome on each physical side of it.\n * Each named chrome element shows its divider on the side facing the scroller\n * while content is scrolled away beyond that side. Ids are resolved below the\n * wired root on every refresh, so a re-render that replaces an element keeps\n * the pairing.\n */\nexport interface ScrollDividerTarget {\n /** The `id` of the scrolling element. */\n scroller: string;\n /** Chrome above the scroller: shows its bottom divider once scrolled down. */\n top?: string;\n /**\n * Chrome right of the scroller: shows its left divider while content is\n * hidden beyond the scroller's right edge (never when nothing overflows).\n */\n right?: string;\n /**\n * Chrome below the scroller: shows its top divider while content is hidden\n * beyond the scroller's bottom edge (never when nothing overflows).\n */\n bottom?: string;\n /** Chrome left of the scroller: shows its right divider once scrolled right. */\n left?: string;\n}\n\nexport interface WireScrollDividersOptions {\n /**\n * App-owned scroll arrangements to pair beyond the ones found by structure\n * (every `Pane`'s header and footer around its content, every `NavStack`'s\n * and `TabScaffold`'s chrome around its active region, and every `TabBar`\n * strip).\n */\n targets?: readonly ScrollDividerTarget[];\n}\n\ntype Edge = 't' | 'r' | 'b' | 'l';\n\nconst EDGES: readonly Edge[] = ['t', 'r', 'b', 'l'];\n\n/** The side of a chrome element that faces a scroller it sits on `edge` of. */\nconst FACING: Record<Edge, Edge> = { t: 'b', r: 'l', b: 't', l: 'r' };\n\nconst TARGET_EDGES: Record<Edge, 'top' | 'right' | 'bottom' | 'left'> = {\n t: 'top',\n r: 'right',\n b: 'bottom',\n l: 'left',\n};\n\n/** On a scroller: the edges beyond which content is currently hidden. */\nconst SCROLL_OVERFLOW = 'data-scroll-overflow';\n/** On a chrome element: its sides that currently show a scroll divider. */\nconst SCROLL_DIVIDER = 'data-scroll-divider';\n\n/**\n * Scroll distance, in px, that must be exceeded to count as \"away from an\n * edge\": `scrollWidth`/`scrollHeight` are rounded to whole pixels while the\n * scroll position is fractional, so a scroller at its end can report up to a\n * pixel still to go.\n */\nconst THRESHOLD = 1;\n\ninterface Pairing {\n scroller: HTMLElement;\n chrome: Partial<Record<Edge, HTMLElement>>;\n}\n\n/** A double-quoted CSS attribute-selector value. */\nconst quoted = (value: string) =>\n `\"${value.replaceAll('\\\\', '\\\\\\\\').replaceAll('\"', '\\\\\"')}\"`;\n\n/** Elements matching `selector` at and below root. */\nfunction within<T extends Element>(\n root: HTMLElement | Document,\n selector: string,\n): T[] {\n const found = [...root.querySelectorAll<T>(selector)];\n if (root.nodeType === 1 && (root as HTMLElement).matches(selector))\n found.unshift(root as unknown as T);\n return found;\n}\n\nconst directChild = (parent: Element, selector: string) =>\n [...parent.children].find((child): child is HTMLElement =>\n child.matches(selector),\n );\n\nconst PANE_CHROME = {\n t: '.kui-pane__header, .kui-pane__toolbar',\n b: '.kui-pane__footer',\n} as const;\n\n/** A NavStack's live (not cross-fading copy) chrome on `edge`. */\nconst NAV_STACK_CHROME = {\n t: '.kui-nav-stack__chrome:not([data-nav-chrome-copy])',\n b: '.kui-nav-stack__bottom:not([data-nav-chrome-copy])',\n} as const;\n\n/** A NavStack's active view: the top entry, never one sliding out. */\nfunction activeView(stack: Element): HTMLElement | undefined {\n const viewport = directChild(stack, '.kui-nav-stack__viewport');\n if (!viewport) return undefined;\n return [...viewport.children]\n .filter((child): child is HTMLElement =>\n child.matches(\n '.kui-nav-stack__view[data-nav-active=\"true\"]:not([data-nav-exiting=\"true\"])',\n ),\n )\n .at(-1);\n}\n\n/** A TabScaffold's shown scene. */\nfunction activeScene(scaffold: Element): HTMLElement | undefined {\n const scenes = directChild(scaffold, '.kui-tab-scaffold__scenes');\n return scenes\n ? directChild(scenes, '.kui-tab-scaffold__scene[data-active=\"true\"]')\n : undefined;\n}\n\n/**\n * The elements that may scroll against a layout region's `edge` (the top or\n * bottom of a NavStack view or a TabScaffold scene): the region itself, then,\n * through a sole child that puts no chrome of its own on that edge, a Pane's\n * content slot or a nested NavStack's or TabScaffold's active region. Every\n * candidate is paired with the layout's chrome; one that does not overflow\n * reports nothing, so the chrome keys on whichever element actually scrolls.\n * A sole child with chrome on that edge (a Pane header, a nested NavStack's\n * top chrome, a TabScaffold's bar) stops the walk: that chrome draws its own\n * divider against its own content.\n */\nfunction regionScrollers(region: HTMLElement, edge: 't' | 'b'): HTMLElement[] {\n const found: HTMLElement[] = [];\n let current: HTMLElement | undefined = region;\n while (current) {\n found.push(current);\n if (current.children.length !== 1) break;\n const child: Element = current.children[0]!;\n if (child.matches('.kui-pane')) {\n current = directChild(child, PANE_CHROME[edge])\n ? undefined\n : directChild(child, '.kui-pane__content');\n if (current) found.push(current);\n break;\n }\n if (child.matches('.kui-nav-stack'))\n current = directChild(child, NAV_STACK_CHROME[edge])\n ? undefined\n : activeView(child);\n else if (child.matches('.kui-tab-scaffold') && edge === 't')\n current = activeScene(child);\n else current = undefined;\n }\n return found;\n}\n\n/** Canonical top/right/bottom/left string of the given edges. */\nconst sides = (edges: ReadonlySet<Edge>) =>\n EDGES.filter((edge) => edges.has(edge)).join('');\n\n/**\n * Which edges of `scroller` currently have content hidden beyond them. Nothing\n * overflows when the content fits, so the far edges report no divider then.\n * Horizontal edges are physical, so a right-to-left scroller (whose\n * `scrollLeft` runs from the negative maximum to 0) reports the same sides.\n */\nfunction measure(scroller: HTMLElement): string {\n const edges = new Set<Edge>();\n const maxY = scroller.scrollHeight - scroller.clientHeight;\n if (maxY > THRESHOLD) {\n if (scroller.scrollTop > THRESHOLD) edges.add('t');\n if (maxY - scroller.scrollTop > THRESHOLD) edges.add('b');\n }\n const maxX = scroller.scrollWidth - scroller.clientWidth;\n if (maxX > THRESHOLD) {\n const view = scroller.ownerDocument.defaultView;\n const rtl = view?.getComputedStyle(scroller).direction === 'rtl';\n const left = rtl ? maxX + scroller.scrollLeft : scroller.scrollLeft;\n if (left > THRESHOLD) edges.add('l');\n if (maxX - left > THRESHOLD) edges.add('r');\n }\n return sides(edges);\n}\n\ntype StateAttribute = typeof SCROLL_OVERFLOW | typeof SCROLL_DIVIDER;\n\n/** Set (or, for an empty value, remove) one of this wiring's attributes. */\nfunction write(element: Element, name: StateAttribute, value: string) {\n if (element.getAttribute(name) === (value || null)) return;\n if (name === SCROLL_OVERFLOW) {\n if (value) element.setAttribute(SCROLL_OVERFLOW, value);\n else element.removeAttribute(SCROLL_OVERFLOW);\n } else if (value) element.setAttribute(SCROLL_DIVIDER, value);\n else element.removeAttribute(SCROLL_DIVIDER);\n}\n\n/**\n * Wire scroll dividers below `root`: a divider between pinned chrome and the\n * content that scrolls beside it shows only while content is scrolled away\n * from that edge. Near edges (top, left) hide at the scroll start; far edges\n * (bottom, right) hide at the scroll end and whenever nothing overflows.\n *\n * The wiring only reports scroll state; each component draws its own divider\n * from it. It writes `data-scroll-overflow` (the edges with hidden content, in\n * canonical `t`/`r`/`b`/`l` order) on each scroller, and `data-scroll-divider`\n * (the sides to draw) on each paired chrome element:\n *\n * - every `Pane` with a header or footer: its header shows a bottom divider and\n * its footer a top divider (drawn by the Pane, per its `chromeDividers`);\n * - every `NavStack`'s top chrome and bottom toolbar around its active view,\n * and every `TabScaffold`'s bar under its active scene: the chrome shows a\n * bottom (top chrome) or top (bottom toolbar, bar) divider. The scroller is\n * whichever element actually scrolls there: the view or scene itself, or,\n * through a sole child with no chrome of its own on that edge, a `Pane`'s\n * content or a nested `NavStack` / `TabScaffold` region (a Pane's own header\n * or footer draws that boundary instead);\n * - every `TabBar` strip: the bar draws a divider on each side of the strip\n * whose tabs are scrolled out of view;\n * - each app-owned `targets` pairing: a `Toolbar` or `List` named as chrome\n * draws the divider on its facing side.\n *\n * Structure is re-read after every DOM change below root (a re-render that\n * drops the attributes gets them back before paint), scroll is tracked with\n * one capturing listener, and size changes of each scroller and its children\n * with a `ResizeObserver`. Returns a disposer that removes every attribute it\n * wrote. See `docs/23-app-layouts.md` §3.7.\n */\nexport function wireScrollDividers(\n root: HTMLElement | Document,\n { targets = [] }: WireScrollDividersOptions = {},\n): () => void {\n const ownerDocument = (\n root.nodeType === 9 ? (root as Document) : root.ownerDocument\n )!;\n const view = ownerDocument.defaultView;\n let disposed = false;\n let pairings: Pairing[] = [];\n const overflow = new Map<HTMLElement, string>();\n /** Every element this wiring has written, with what it wrote. */\n const written = new Map<Element, Map<StateAttribute, string>>();\n\n const byId = (id: string | undefined) => {\n if (!id) return undefined;\n const [match] = within<HTMLElement>(root, `[id=${quoted(id)}]`);\n return match;\n };\n\n const collect = (): Pairing[] => {\n const found: Pairing[] = [];\n for (const pane of within<HTMLElement>(root, '.kui-pane')) {\n const scroller = directChild(pane, '.kui-pane__content');\n const header = directChild(pane, PANE_CHROME.t);\n const footer = directChild(pane, PANE_CHROME.b);\n if (scroller && (header || footer))\n found.push({ scroller, chrome: { t: header, b: footer } });\n }\n const pairRegion = (\n region: HTMLElement | undefined,\n edge: 't' | 'b',\n chrome: HTMLElement | undefined,\n ) => {\n if (!region || !chrome) return;\n for (const scroller of regionScrollers(region, edge))\n found.push({ scroller, chrome: { [edge]: chrome } });\n };\n for (const stack of within<HTMLElement>(root, '.kui-nav-stack')) {\n const view = activeView(stack);\n for (const edge of ['t', 'b'] as const)\n pairRegion(view, edge, directChild(stack, NAV_STACK_CHROME[edge]));\n }\n for (const scaffold of within<HTMLElement>(root, '.kui-tab-scaffold'))\n pairRegion(\n activeScene(scaffold),\n 'b',\n directChild(scaffold, '.kui-tab-scaffold__bar'),\n );\n for (const strip of within<HTMLElement>(root, '[data-kui-tab-list]'))\n found.push({ scroller: strip, chrome: {} });\n for (const target of targets) {\n const scroller = byId(target.scroller);\n if (!scroller) continue;\n const chrome: Pairing['chrome'] = {};\n for (const edge of EDGES) chrome[edge] = byId(target[TARGET_EDGES[edge]]);\n found.push({ scroller, chrome });\n }\n return found;\n };\n\n /** Write every paired element's attributes from the measured overflow. */\n const apply = () => {\n const current = new Map<Element, Map<StateAttribute, string>>();\n const dividers = new Map<HTMLElement, Set<Edge>>();\n for (const { scroller, chrome } of pairings) {\n const edges = overflow.get(scroller)!;\n (\n current.get(scroller) ?? current.set(scroller, new Map()).get(scroller)!\n ).set(SCROLL_OVERFLOW, edges);\n for (const edge of EDGES) {\n const element = chrome[edge];\n if (!element) continue;\n const shown = dividers.get(element) ?? new Set<Edge>();\n dividers.set(element, shown);\n if (edges.includes(edge)) shown.add(FACING[edge]);\n }\n }\n for (const [element, shown] of dividers)\n (\n current.get(element) ?? current.set(element, new Map()).get(element)!\n ).set(SCROLL_DIVIDER, sides(shown));\n // Anything written before that is no longer paired gets its attributes back.\n for (const [element, values] of written)\n for (const name of values.keys())\n if (!current.get(element)?.has(name)) write(element, name, '');\n written.clear();\n for (const [element, values] of current) {\n written.set(element, values);\n for (const [name, value] of values) write(element, name, value);\n }\n };\n\n const observed = new Set<Element>();\n const resizeObserver = view?.ResizeObserver\n ? new view.ResizeObserver((entries) => {\n if (disposed) return;\n const scrollers = new Set(pairings.map(({ scroller }) => scroller));\n for (const { target } of entries) {\n const scroller = scrollers.has(target as HTMLElement)\n ? (target as HTMLElement)\n : target.parentElement;\n if (scroller && scrollers.has(scroller))\n overflow.set(scroller, measure(scroller));\n }\n apply();\n })\n : undefined;\n\n const observeSizes = () => {\n if (!resizeObserver) return;\n const wanted = new Set<Element>();\n for (const { scroller } of pairings) {\n wanted.add(scroller);\n for (const child of scroller.children) wanted.add(child);\n }\n for (const element of observed)\n if (!wanted.has(element)) {\n resizeObserver.unobserve(element);\n observed.delete(element);\n }\n for (const element of wanted)\n if (!observed.has(element)) {\n resizeObserver.observe(element);\n observed.add(element);\n }\n };\n\n const refresh = () => {\n pairings = collect();\n overflow.clear();\n for (const { scroller } of pairings)\n overflow.set(scroller, measure(scroller));\n observeSizes();\n apply();\n };\n\n const onScroll = (event: Event) => {\n const scroller = event.target as HTMLElement;\n if (!overflow.has(scroller)) return;\n const edges = measure(scroller);\n if (edges === overflow.get(scroller)) return;\n overflow.set(scroller, edges);\n apply();\n };\n\n const mutationObserver = view?.MutationObserver\n ? new view.MutationObserver((records) => {\n // A re-render that only dropped or changed attributes this wiring\n // owns gets them back without re-measuring; structure changes\n // re-read every pairing.\n if (\n records.every(\n ({ type, attributeName }) =>\n type === 'attributes' &&\n (attributeName === SCROLL_OVERFLOW ||\n attributeName === SCROLL_DIVIDER),\n )\n )\n apply();\n else refresh();\n })\n : undefined;\n\n refresh();\n root.addEventListener('scroll', onScroll, { capture: true, passive: true });\n mutationObserver?.observe(root, {\n subtree: true,\n childList: true,\n attributes: true,\n // The shown NavStack view and TabScaffold scene change by attribute.\n attributeFilter: [\n SCROLL_OVERFLOW,\n SCROLL_DIVIDER,\n 'id',\n 'class',\n 'data-nav-active',\n 'data-nav-exiting',\n 'data-active',\n ],\n });\n\n return () => {\n if (disposed) return;\n disposed = true;\n mutationObserver?.disconnect();\n resizeObserver?.disconnect();\n root.removeEventListener('scroll', onScroll, { capture: true });\n for (const [element, values] of written)\n for (const name of values.keys()) write(element, name, '');\n written.clear();\n overflow.clear();\n observed.clear();\n pairings = [];\n };\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { jsx, Fragment, jsxs } from 'kerfjs/jsx-runtime';
2
+
3
+ // src/word-breaks.tsx
4
+ var CAMEL_BOUNDARY = /(?<=[\p{Ll}\p{N}])(?=\p{Lu})|(?<=\p{Lu})(?=\p{Lu}\p{Ll})/u;
5
+ function withWordBreaks(label) {
6
+ if (typeof label !== "string") return label;
7
+ const parts = label.split(CAMEL_BOUNDARY);
8
+ if (parts.length < 2) return label;
9
+ return /* @__PURE__ */ jsx(Fragment, { children: parts.map((part, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
10
+ index > 0 ? /* @__PURE__ */ jsx("wbr", {}) : null,
11
+ part
12
+ ] })) });
13
+ }
14
+
15
+ export { withWordBreaks };
16
+
17
+ //# sourceMappingURL=chunk-K47P7QZC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/word-breaks.tsx"],"names":[],"mappings":";;;AAIA,IAAM,cAAA,GACJ,2DAAA;AAQK,SAAS,eAAe,KAAA,EAA6C;AAC1E,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,cAAc,CAAA;AACxC,EAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,OAAO,KAAA;AAC7B,EAAA,uCAEK,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,0BAChB,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,KAAA,GAAQ,CAAA,mBAAI,GAAA,CAAC,KAAA,EAAA,EAAI,CAAA,GAAK,IAAA;AAAA,IACtB;AAAA,GAAA,EACH,CACD,CAAA,EACH,CAAA;AAEJ","file":"chunk-K47P7QZC.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\n// A lowercase letter or digit followed by an uppercase letter (\"ticketBoard\"),\n// or an acronym followed by a capitalized word (\"HTMLParser\" → \"HTML|Parser\").\nconst CAMEL_BOUNDARY =\n /(?<=[\\p{Ll}\\p{N}])(?=\\p{Lu})|(?<=\\p{Lu})(?=\\p{Lu}\\p{Ll})/u;\n\n/**\n * A label with line-break opportunities (`<wbr>`) at camelCase boundaries, so a\n * wrapping row breaks a long identifier-like name (`QuickTicketComposer`) at a\n * word boundary instead of mid-word. The text, and so the accessible name, is\n * unchanged; a `SafeHtml` label is returned as given.\n */\nexport function withWordBreaks(label: string | SafeHtml): string | SafeHtml {\n if (typeof label !== 'string') return label;\n const parts = label.split(CAMEL_BOUNDARY);\n if (parts.length < 2) return label;\n return (\n <>\n {parts.map((part, index) => (\n <>\n {index > 0 ? <wbr /> : null}\n {part}\n </>\n ))}\n </>\n );\n}\n"]}
@@ -20,6 +20,7 @@ function DisclosureArrow({
20
20
  openDirection = "down",
21
21
  closedDirection = "right",
22
22
  icon,
23
+ size,
23
24
  className = "",
24
25
  slot
25
26
  }) {
@@ -29,7 +30,7 @@ function DisclosureArrow({
29
30
  "span",
30
31
  {
31
32
  class: `kui-disclosure-arrow ${className}`.trim(),
32
- style: `--_kui-disclosure-arrow-rotation:${rotation}deg`,
33
+ style: `--_kui-disclosure-arrow-rotation:${rotation}deg${size ? `;--kui-disclosure-arrow-size:${size}` : ""}`,
33
34
  "data-component": "disclosure-arrow",
34
35
  "data-open": String(open),
35
36
  "data-direction": direction,
@@ -42,4 +43,4 @@ function DisclosureArrow({
42
43
 
43
44
  export { DisclosureArrow };
44
45
 
45
- //# sourceMappingURL=chunk-HMQ2ZDGG.js.map
46
+ //# sourceMappingURL=chunk-KROD7KZK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/disclosure-arrow.tsx"],"names":[],"mappings":";;;;AAqBA,IAAM,kBAAA,GAA0D;AAAA,EAC9D,KAAA,EAAO,CAAA;AAAA,EACP,IAAA,EAAM,EAAA;AAAA,EACN,IAAA,EAAM,GAAA;AAAA,EACN,EAAA,EAAI;AACN,CAAA;AAEA,SAAS,gBAAA,CACP,IAAA,EACA,aAAA,EACA,eAAA,EACA;AACA,EAAA,MAAM,cAAA,GAAiB,mBAAmB,eAAe,CAAA;AACzD,EAAA,IAAI,CAAC,MAAM,OAAO,cAAA;AAElB,EAAA,MAAM,YAAA,GAAe,mBAAmB,aAAa,CAAA;AACrD,EAAA,MAAM,aAAA,GAAA,CAAkB,YAAA,GAAe,cAAA,GAAiB,GAAA,IAAO,GAAA,GAAO,GAAA;AACtE,EAAA,OAAO,cAAA,GAAiB,aAAA;AAC1B;AAEO,SAAS,eAAA,CAAgB;AAAA,EAC9B,IAAA;AAAA,EACA,aAAA,GAAgB,MAAA;AAAA,EAChB,eAAA,GAAkB,OAAA;AAAA,EAClB,IAAA;AAAA,EACA,IAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAyB;AACvB,EAAA,MAAM,SAAA,GAAY,OAAO,aAAA,GAAgB,eAAA;AACzC,EAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,IAAA,EAAM,aAAA,EAAe,eAAe,CAAA;AACtE,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,qBAAA,EAAwB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAChD,KAAA,EAAO,oCAAoC,QAAQ,CAAA,GAAA,EAAM,OAAO,CAAA,6BAAA,EAAgC,IAAI,KAAK,EAAE,CAAA,CAAA;AAAA,MAC3G,gBAAA,EAAe,kBAAA;AAAA,MACf,WAAA,EAAW,OAAO,IAAI,CAAA;AAAA,MACtB,gBAAA,EAAgB,SAAA;AAAA,MAChB,aAAA,EAAY,MAAA;AAAA,MACZ,IAAA;AAAA,MAEC,kCAAQ,GAAA,CAAC,UAAA,EAAA,EAAW,IAAA,EAAM,YAAA,EAAc,MAAK,eAAA,EAAgB;AAAA;AAAA,GAChE;AAEJ","file":"chunk-KROD7KZK.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\nimport { ChevronRight } from 'lucide';\n\nimport type { CssLength } from './css-values.js';\nimport { LucideIcon } from './lucide-icon.js';\n\nexport type DisclosureDirection = 'up' | 'down' | 'left' | 'right';\n\nexport interface DisclosureArrowProps {\n open: boolean;\n openDirection?: DisclosureDirection;\n closedDirection?: DisclosureDirection;\n /** Replacement icons should use right as their unrotated orientation. */\n icon?: SafeHtml;\n /** Typed box size for the square visual. Default: `remify(18px)`. */\n size?: CssLength;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nconst directionRotations: Record<DisclosureDirection, number> = {\n right: 0,\n down: 90,\n left: 180,\n up: 270,\n};\n\nfunction rotationForState(\n open: boolean,\n openDirection: DisclosureDirection,\n closedDirection: DisclosureDirection,\n) {\n const closedRotation = directionRotations[closedDirection];\n if (!open) return closedRotation;\n\n const openRotation = directionRotations[openDirection];\n const shortestDelta = ((openRotation - closedRotation + 540) % 360) - 180;\n return closedRotation + shortestDelta;\n}\n\nexport function DisclosureArrow({\n open,\n openDirection = 'down',\n closedDirection = 'right',\n icon,\n size,\n className = '',\n slot,\n}: DisclosureArrowProps) {\n const direction = open ? openDirection : closedDirection;\n const rotation = rotationForState(open, openDirection, closedDirection);\n return (\n <span\n class={`kui-disclosure-arrow ${className}`.trim()}\n style={`--_kui-disclosure-arrow-rotation:${rotation}deg${size ? `;--kui-disclosure-arrow-size:${size}` : ''}`}\n data-component=\"disclosure-arrow\"\n data-open={String(open)}\n data-direction={direction}\n aria-hidden=\"true\"\n slot={slot}\n >\n {icon ?? <LucideIcon icon={ChevronRight} name=\"chevron-right\" />}\n </span>\n );\n}\n"]}