@kerfjs/ui 5.0.0-beta.23 → 5.0.0-beta.25

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 (288) hide show
  1. package/README.md +45 -23
  2. package/ai/application-ui-diagnostic-ids-v1.json +3 -0
  3. package/ai/application-ui-profile.defaults.json +1 -1
  4. package/ai/compile-time-contracts-v1.json +5 -12
  5. package/ai/component-catalog-v2-overrides.json +12 -49
  6. package/ai/component-catalog-v2.d.ts +1 -0
  7. package/ai/component-catalog-v2.json +458 -123
  8. package/ai/component-catalog-v2.schema.json +2 -1
  9. package/ai/component-catalog.json +658 -195
  10. package/ai/public-api-signatures-v1.md +160 -80
  11. package/ai/skill.md +22 -22
  12. package/ai/webawesome-jsx-signatures-v1.md +2 -1
  13. package/analyzer/cli.mjs +5 -2
  14. package/analyzer/index.d.mts +1 -0
  15. package/analyzer/index.mjs +117 -10
  16. package/dist/app-tab.d.ts +10 -2
  17. package/dist/app-tab.js +1 -1
  18. package/dist/browser/list-action-row.js +1 -0
  19. package/dist/browser/list-item.js +1 -0
  20. package/dist/browser/list.js +3 -0
  21. package/dist/browser/surface-scaffold.js +3 -0
  22. package/dist/catalog.d.ts +8 -4
  23. package/dist/catalog.js +21 -11
  24. package/dist/catalog.js.map +1 -1
  25. package/dist/{chunk-ELSJX4W7.js → chunk-4EF2CMYS.js} +25 -6
  26. package/dist/chunk-4EF2CMYS.js.map +1 -0
  27. package/dist/{chunk-OHU6CI22.js → chunk-B3A3IVO5.js} +2 -2
  28. package/dist/{chunk-OHU6CI22.js.map → chunk-B3A3IVO5.js.map} +1 -1
  29. package/dist/{chunk-K57KRAOV.js → chunk-FRVS5RFM.js} +24 -6
  30. package/dist/chunk-FRVS5RFM.js.map +1 -0
  31. package/dist/{chunk-DSNIYOZ3.js → chunk-GWEAPEZI.js} +16 -3
  32. package/dist/chunk-GWEAPEZI.js.map +1 -0
  33. package/dist/chunk-HP2B2L26.js +102 -0
  34. package/dist/chunk-HP2B2L26.js.map +1 -0
  35. package/dist/{chunk-OZWU5ZPZ.js → chunk-IJBSZ4NX.js} +2 -2
  36. package/dist/{chunk-OZWU5ZPZ.js.map → chunk-IJBSZ4NX.js.map} +1 -1
  37. package/dist/chunk-J5BFYY7Q.js +35 -0
  38. package/dist/chunk-J5BFYY7Q.js.map +1 -0
  39. package/dist/{chunk-GP5DP5DL.js → chunk-JFGXQBIP.js} +85 -24
  40. package/dist/chunk-JFGXQBIP.js.map +1 -0
  41. package/dist/{chunk-QQFJMRIB.js → chunk-KWWR5VMS.js} +2 -2
  42. package/dist/{chunk-QQFJMRIB.js.map → chunk-KWWR5VMS.js.map} +1 -1
  43. package/dist/chunk-OBLTAKSX.js +43 -0
  44. package/dist/chunk-OBLTAKSX.js.map +1 -0
  45. package/dist/{chunk-PIDTEQ3U.js → chunk-OT6RPYAP.js} +17 -3
  46. package/dist/chunk-OT6RPYAP.js.map +1 -0
  47. package/dist/{chunk-W7YD6E4N.js → chunk-R7ZWUN64.js} +2 -2
  48. package/dist/{chunk-W7YD6E4N.js.map → chunk-R7ZWUN64.js.map} +1 -1
  49. package/dist/{chunk-PZQVSDLH.js → chunk-RKVQEH4J.js} +1 -1
  50. package/dist/chunk-RKVQEH4J.js.map +1 -0
  51. package/dist/{chunk-7L6EHUMV.js → chunk-SYDMYBPG.js} +3 -3
  52. package/dist/chunk-SYDMYBPG.js.map +1 -0
  53. package/dist/{chunk-W4CXQYSG.js → chunk-TB6DY7H5.js} +3 -1
  54. package/dist/chunk-TB6DY7H5.js.map +1 -0
  55. package/dist/{chunk-AASLYRGE.js → chunk-UKKSMZYT.js} +18 -7
  56. package/dist/chunk-UKKSMZYT.js.map +1 -0
  57. package/dist/{chunk-BBRXX6PF.js → chunk-VCE4MPVE.js} +26 -4
  58. package/dist/chunk-VCE4MPVE.js.map +1 -0
  59. package/dist/{chunk-VLYV65LK.js → chunk-W5L2JSBY.js} +5 -3
  60. package/dist/chunk-W5L2JSBY.js.map +1 -0
  61. package/dist/{chunk-5VTB2BKP.js → chunk-WNWD54GR.js} +16 -2
  62. package/dist/chunk-WNWD54GR.js.map +1 -0
  63. package/dist/{chunk-M7JBER5U.js → chunk-X2U3QJCJ.js} +8 -2
  64. package/dist/chunk-X2U3QJCJ.js.map +1 -0
  65. package/dist/{chunk-DPDBVKNA.js → chunk-YMKH5XTF.js} +5 -3
  66. package/dist/chunk-YMKH5XTF.js.map +1 -0
  67. package/dist/collapsible-panel.d.ts +9 -1
  68. package/dist/collapsible-panel.js +36 -15
  69. package/dist/collapsible-panel.js.map +1 -1
  70. package/dist/divider-sides-267FA7sY.d.ts +4 -0
  71. package/dist/index.d.ts +5 -3
  72. package/dist/index.js +20 -19
  73. package/dist/list-action-row.d.ts +11 -1
  74. package/dist/list-action-row.js +2 -1
  75. package/dist/list-header.d.ts +15 -2
  76. package/dist/list-header.js +1 -1
  77. package/dist/list-item.d.ts +12 -1
  78. package/dist/list-item.js +2 -1
  79. package/dist/list.d.ts +19 -0
  80. package/dist/list.js +3 -0
  81. package/dist/list.js.map +1 -0
  82. package/dist/nav-stack.js +1 -1
  83. package/dist/resizable-region.d.ts +19 -2
  84. package/dist/resizable-region.js +1 -1
  85. package/dist/segmented-control.js +1 -1
  86. package/dist/select.d.ts +12 -1
  87. package/dist/select.js +1 -1
  88. package/dist/skeleton.d.ts +1 -1
  89. package/dist/skeleton.js +1 -1
  90. package/dist/split-view.js +2 -2
  91. package/dist/state-banner.d.ts +4 -2
  92. package/dist/state-banner.js +1 -1
  93. package/dist/styles/app-tab.css +26 -0
  94. package/dist/styles/catalog.css +8 -2
  95. package/dist/styles/collapsible-panel.css +66 -4
  96. package/dist/styles/list-action-row.css +64 -0
  97. package/dist/styles/list-header.css +32 -0
  98. package/dist/styles/list-item.css +45 -6
  99. package/dist/styles/list.css +43 -0
  100. package/dist/styles/resizable-region.css +132 -0
  101. package/dist/styles/select.css +68 -0
  102. package/dist/styles/state-banner.css +32 -1
  103. package/dist/styles/styles.css +2 -1
  104. package/dist/styles/sunken-panel.css +4 -0
  105. package/dist/styles/surface-scaffold.css +51 -0
  106. package/dist/styles/tab-bar.css +24 -0
  107. package/dist/styles/toolbar-control-group.css +73 -1
  108. package/dist/styles/toolbar-text.css +1 -1
  109. package/dist/styles/toolbar.css +38 -2
  110. package/dist/styles/webawesome.css +12 -0
  111. package/dist/styles/workbench.css +89 -0
  112. package/dist/sunken-panel.d.ts +5 -2
  113. package/dist/sunken-panel.js +1 -1
  114. package/dist/surface-scaffold.d.ts +25 -0
  115. package/dist/surface-scaffold.js +3 -0
  116. package/dist/surface-scaffold.js.map +1 -0
  117. package/dist/tab-bar.d.ts +11 -2
  118. package/dist/tab-bar.js +1 -1
  119. package/dist/toolbar-control-group.d.ts +16 -2
  120. package/dist/toolbar-control-group.js +1 -1
  121. package/dist/toolbar-text.js +1 -1
  122. package/dist/toolbar.d.ts +5 -3
  123. package/dist/toolbar.js +1 -1
  124. package/dist/value-table.js +1 -1
  125. package/dist/webawesome.d.ts +1 -0
  126. package/dist/wire-catalog.d.ts +4 -2
  127. package/dist/wire-catalog.js +95 -36
  128. package/dist/wire-catalog.js.map +1 -1
  129. package/dist/wire-resizable-regions.js +1 -1
  130. package/dist/wire-sidebar.d.ts +6 -1
  131. package/dist/wire-sidebar.js +27 -8
  132. package/dist/wire-sidebar.js.map +1 -1
  133. package/dist/wire-tab-bars.js +1 -1
  134. package/dist/wire-token-search-fields.d.ts +1 -1
  135. package/dist/wire-token-search-fields.js +1 -1
  136. package/dist/workbench.d.ts +8 -0
  137. package/dist/workbench.js +42 -0
  138. package/dist/workbench.js.map +1 -1
  139. package/docs/accessibility.md +67 -15
  140. package/docs/catalog.md +17 -12
  141. package/docs/collapsible-panel.md +7 -0
  142. package/docs/component-contract.md +19 -9
  143. package/docs/component-selection.md +65 -31
  144. package/docs/design/templates/empty-state/filtered-dark.svg +1 -1
  145. package/docs/design/templates/empty-state/filtered.svg +1 -1
  146. package/docs/design/templates/empty-state/with-action-dark.svg +1 -1
  147. package/docs/design/templates/empty-state/with-action.svg +1 -1
  148. package/docs/design/templates/empty-state-dark.svg +1 -7
  149. package/docs/design/templates/empty-state.svg +1 -7
  150. package/docs/design/templates/list/compact-dark.svg +1 -0
  151. package/docs/design/templates/list/compact.svg +1 -0
  152. package/docs/design/templates/list/stack-dark.svg +1 -0
  153. package/docs/design/templates/list/stack.svg +1 -0
  154. package/docs/design/templates/list-action-row/default-dark.svg +1 -1
  155. package/docs/design/templates/list-action-row/default.svg +1 -1
  156. package/docs/design/templates/list-action-row/selected-dark.svg +1 -1
  157. package/docs/design/templates/list-action-row/selected.svg +1 -1
  158. package/docs/design/templates/list-action-row-dark.svg +1 -7
  159. package/docs/design/templates/list-action-row.svg +1 -7
  160. package/docs/design/templates/list-dark.svg +1 -0
  161. package/docs/design/templates/list-header/action-dark.svg +1 -1
  162. package/docs/design/templates/list-header/action.svg +1 -1
  163. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -1
  164. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -1
  165. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -1
  166. package/docs/design/templates/list-header/toggle-expanded.svg +1 -1
  167. package/docs/design/templates/list-header-dark.svg +1 -11
  168. package/docs/design/templates/list-header.svg +1 -11
  169. package/docs/design/templates/list-item/default-dark.svg +1 -1
  170. package/docs/design/templates/list-item/default.svg +1 -1
  171. package/docs/design/templates/list-item/multiline-dark.svg +1 -1
  172. package/docs/design/templates/list-item/multiline.svg +1 -1
  173. package/docs/design/templates/list-item/selected-dark.svg +1 -1
  174. package/docs/design/templates/list-item/selected.svg +1 -1
  175. package/docs/design/templates/list-item/trailing-dark.svg +1 -1
  176. package/docs/design/templates/list-item/trailing.svg +1 -1
  177. package/docs/design/templates/list-item-dark.svg +1 -11
  178. package/docs/design/templates/list-item.svg +1 -11
  179. package/docs/design/templates/list.svg +1 -0
  180. package/docs/design/templates/segmented-control-dark.svg +1 -7
  181. package/docs/design/templates/segmented-control.svg +1 -7
  182. package/docs/design/templates/skeleton-dark.svg +1 -9
  183. package/docs/design/templates/skeleton.svg +1 -9
  184. package/docs/design/templates/state-banner/danger-dark.svg +1 -1
  185. package/docs/design/templates/state-banner/danger.svg +1 -1
  186. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
  187. package/docs/design/templates/state-banner/info-badge.svg +1 -0
  188. package/docs/design/templates/state-banner/info-dark.svg +1 -1
  189. package/docs/design/templates/state-banner/info.svg +1 -1
  190. package/docs/design/templates/state-banner/success-dark.svg +1 -1
  191. package/docs/design/templates/state-banner/success.svg +1 -1
  192. package/docs/design/templates/state-banner/warning-dark.svg +1 -1
  193. package/docs/design/templates/state-banner/warning.svg +1 -1
  194. package/docs/design/templates/state-banner-dark.svg +1 -11
  195. package/docs/design/templates/state-banner.svg +1 -11
  196. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -1
  197. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -1
  198. package/docs/design/templates/tab-bar-dark.svg +1 -5
  199. package/docs/design/templates/tab-bar.svg +1 -5
  200. package/docs/design/templates/token-search-field/empty-dark.svg +1 -1
  201. package/docs/design/templates/token-search-field/empty.svg +1 -1
  202. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -1
  203. package/docs/design/templates/token-search-field/tokens.svg +1 -1
  204. package/docs/design/templates/token-search-field-dark.svg +1 -7
  205. package/docs/design/templates/token-search-field.svg +1 -7
  206. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
  207. package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
  208. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -1
  209. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -1
  210. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -1
  211. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -1
  212. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -1
  213. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -1
  214. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -1
  215. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -1
  216. package/docs/design/templates/toolbar-control-group-dark.svg +1 -11
  217. package/docs/design/templates/toolbar-control-group.svg +1 -11
  218. package/docs/design/templates/toolbar-dark.svg +1 -5
  219. package/docs/design/templates/toolbar-text-dark.svg +1 -9
  220. package/docs/design/templates/toolbar-text.svg +1 -9
  221. package/docs/design/templates/toolbar.svg +1 -5
  222. package/docs/design/templates/value-table/details-dark.svg +1 -1
  223. package/docs/design/templates/value-table/details.svg +1 -1
  224. package/docs/design/templates/value-table-dark.svg +1 -5
  225. package/docs/design/templates/value-table.svg +1 -5
  226. package/docs/design/templates.md +29 -20
  227. package/docs/examples/component-catalog-extension-v2.json +3 -6
  228. package/docs/examples/component-catalog-extension.json +1 -1
  229. package/docs/layout.md +7 -9
  230. package/docs/recipes.md +8 -7
  231. package/docs/sunken-panel.md +11 -1
  232. package/docs/surface-scaffold.md +17 -0
  233. package/docs/type-contracts.md +11 -10
  234. package/docs/ui-analyzer.md +19 -1
  235. package/docs/ui-doctor.md +7 -5
  236. package/docs/ux-demo.md +6 -3
  237. package/docs/webawesome-theme.md +4 -1
  238. package/docs/workbench.md +49 -2
  239. package/doctor/eslint-diagnostics.d.mts +16 -0
  240. package/doctor/eslint-diagnostics.mjs +17 -0
  241. package/doctor/index.mjs +21 -3
  242. package/llms.txt +33 -11
  243. package/package.json +14 -8
  244. package/traversal-exclusions.mjs +7 -1
  245. package/ux-demo/recipes/app-shell.tsx +36 -23
  246. package/ux-demo/recipes/collapsible-sidebar.tsx +23 -17
  247. package/ux-demo/recipes/composer-form.tsx +15 -6
  248. package/ux-demo/recipes/list-detail-dialog.tsx +31 -15
  249. package/ux-demo/recipes/list-workspace-states.tsx +16 -7
  250. package/ux-demo/recipes/loading-inspector.tsx +39 -18
  251. package/ux-demo/recipes/navigation-sidebar.tsx +1 -1
  252. package/ux-demo/recipes/recipes.css +7 -2
  253. package/ux-demo/recipes/workspace-header.tsx +17 -7
  254. package/dist/browser/panel-header.js +0 -7
  255. package/dist/chunk-5VTB2BKP.js.map +0 -1
  256. package/dist/chunk-7L6EHUMV.js.map +0 -1
  257. package/dist/chunk-AASLYRGE.js.map +0 -1
  258. package/dist/chunk-BBRXX6PF.js.map +0 -1
  259. package/dist/chunk-DPDBVKNA.js.map +0 -1
  260. package/dist/chunk-DSNIYOZ3.js.map +0 -1
  261. package/dist/chunk-ELSJX4W7.js.map +0 -1
  262. package/dist/chunk-GP5DP5DL.js.map +0 -1
  263. package/dist/chunk-K57KRAOV.js.map +0 -1
  264. package/dist/chunk-M7JBER5U.js.map +0 -1
  265. package/dist/chunk-NENBUYX5.js +0 -79
  266. package/dist/chunk-NENBUYX5.js.map +0 -1
  267. package/dist/chunk-PIDTEQ3U.js.map +0 -1
  268. package/dist/chunk-PZQVSDLH.js.map +0 -1
  269. package/dist/chunk-RYRIFZCT.js +0 -58
  270. package/dist/chunk-RYRIFZCT.js.map +0 -1
  271. package/dist/chunk-VLYV65LK.js.map +0 -1
  272. package/dist/chunk-W4CXQYSG.js.map +0 -1
  273. package/dist/panel-header.d.ts +0 -42
  274. package/dist/panel-header.js +0 -7
  275. package/dist/panel-header.js.map +0 -1
  276. package/dist/styles/panel-header.css +0 -64
  277. package/docs/design/templates/panel-header/icon-actions-dark.svg +0 -1
  278. package/docs/design/templates/panel-header/icon-actions.svg +0 -1
  279. package/docs/design/templates/panel-header/icon-summary-actions-dark.svg +0 -1
  280. package/docs/design/templates/panel-header/icon-summary-actions.svg +0 -1
  281. package/docs/design/templates/panel-header/no-icon-dark.svg +0 -1
  282. package/docs/design/templates/panel-header/no-icon.svg +0 -1
  283. package/docs/design/templates/panel-header/page-heading-dark.svg +0 -1
  284. package/docs/design/templates/panel-header/page-heading.svg +0 -1
  285. package/docs/design/templates/panel-header/title-only-dark.svg +0 -1
  286. package/docs/design/templates/panel-header/title-only.svg +0 -1
  287. package/docs/design/templates/panel-header-dark.svg +0 -13
  288. package/docs/design/templates/panel-header.svg +0 -13
@@ -6,7 +6,7 @@ function Toolbar({
6
6
  center,
7
7
  trailing,
8
8
  label,
9
- divider = true,
9
+ dividerSides = "b",
10
10
  className = ""
11
11
  }) {
12
12
  return /* @__PURE__ */ jsxs(
@@ -14,7 +14,7 @@ function Toolbar({
14
14
  {
15
15
  class: `kui-toolbar ${className}`.trim(),
16
16
  "data-component": "toolbar",
17
- "data-divider": String(divider),
17
+ "divider-sides": dividerSides || void 0,
18
18
  "data-has-center": String(Boolean(center)),
19
19
  "aria-label": label,
20
20
  children: [
@@ -28,4 +28,4 @@ function Toolbar({
28
28
 
29
29
  export { Toolbar };
30
30
 
31
- //# sourceMappingURL=chunk-7L6EHUMV.js.map
31
+ //# sourceMappingURL=chunk-SYDMYBPG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/toolbar.tsx"],"names":[],"mappings":";;;AAcO,SAAS,OAAA,CAAQ;AAAA,EACtB,OAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,YAAA,GAAe,GAAA;AAAA,EACf,SAAA,GAAY;AACd,CAAA,EAAiB;AACf,EAAA,uBACE,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,YAAA,EAAe,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACvC,gBAAA,EAAe,SAAA;AAAA,MACf,iBAAe,YAAA,IAAgB,MAAA;AAAA,MAC/B,iBAAA,EAAiB,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAC,CAAA;AAAA,MACvC,YAAA,EAAY,KAAA;AAAA,MAEZ,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,sBAAA,EAAwB,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,wBAC3C,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,qBAAA,EAAuB,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,wBACzC,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,uBAAA,EAAyB,QAAA,EAAA,QAAA,EAAS;AAAA;AAAA;AAAA,GAC/C;AAEJ","file":"chunk-SYDMYBPG.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport type { DividerSides } from './divider-sides.js';\n\nexport interface ToolbarProps {\n leading?: SafeHtml;\n center?: SafeHtml;\n trailing?: SafeHtml;\n label?: string;\n /** Physical divider edges in canonical top/right/bottom/left order. Defaults to bottom. */\n dividerSides?: DividerSides;\n className?: string;\n}\n\nexport function Toolbar({\n leading,\n center,\n trailing,\n label,\n dividerSides = 'b',\n className = '',\n}: ToolbarProps) {\n return (\n <header\n class={`kui-toolbar ${className}`.trim()}\n data-component=\"toolbar\"\n divider-sides={dividerSides || undefined}\n data-has-center={String(Boolean(center))}\n aria-label={label}\n >\n <div class=\"kui-toolbar__leading\">{leading}</div>\n <div class=\"kui-toolbar__center\">{center}</div>\n <div class=\"kui-toolbar__trailing\">{trailing}</div>\n </header>\n );\n}\n\nexport type { DividerSides } from './divider-sides.js';\n"]}
@@ -4,6 +4,7 @@ import { jsx } from 'kerfjs/jsx-runtime';
4
4
  function SunkenPanel({
5
5
  children,
6
6
  ariaLabel,
7
+ shape = "rounded",
7
8
  className = ""
8
9
  }) {
9
10
  return /* @__PURE__ */ jsx(
@@ -11,6 +12,7 @@ function SunkenPanel({
11
12
  {
12
13
  class: `kui-sunken-panel ${className}`.trim(),
13
14
  "data-component": "sunken-panel",
15
+ "data-shape": shape,
14
16
  role: ariaLabel ? "region" : void 0,
15
17
  "aria-label": ariaLabel,
16
18
  children
@@ -20,4 +22,4 @@ function SunkenPanel({
20
22
 
21
23
  export { SunkenPanel };
22
24
 
23
- //# sourceMappingURL=chunk-W4CXQYSG.js.map
25
+ //# sourceMappingURL=chunk-TB6DY7H5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sunken-panel.tsx"],"names":[],"mappings":";;;AAkBO,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA,GAAQ,SAAA;AAAA,EACR,SAAA,GAAY;AACd,CAAA,EAAqB;AACnB,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC5C,gBAAA,EAAe,cAAA;AAAA,MACf,YAAA,EAAY,KAAA;AAAA,MACZ,IAAA,EAAM,YAAY,QAAA,GAAW,MAAA;AAAA,MAC7B,YAAA,EAAY,SAAA;AAAA,MAEX;AAAA;AAAA,GACH;AAEJ","file":"chunk-TB6DY7H5.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nexport type SunkenPanelShape = 'rounded' | 'square';\n\nexport interface SunkenPanelProps {\n children?: SafeHtml | readonly SafeHtml[];\n /** Optional accessible landmark name for a distinct application region. */\n ariaLabel?: string;\n /** Corner shape: a rounded rectangle (default) or square corners. */\n shape?: SunkenPanelShape;\n className?: string;\n}\n\n/**\n * A lowered application surface with one compact inset and a vertical content\n * stack. The panel owns its background and padding; children own their own\n * borders and internal geometry.\n */\nexport function SunkenPanel({\n children,\n ariaLabel,\n shape = 'rounded',\n className = '',\n}: SunkenPanelProps) {\n return (\n <div\n class={`kui-sunken-panel ${className}`.trim()}\n data-component=\"sunken-panel\"\n data-shape={shape}\n role={ariaLabel ? 'region' : undefined}\n aria-label={ariaLabel}\n >\n {children}\n </div>\n );\n}\n"]}
@@ -121,7 +121,9 @@ function wireTabBars(root, { onReorder, activation = "automatic" }) {
121
121
  delete tab.dataset.tabDropPosition;
122
122
  });
123
123
  };
124
+ let disposed = false;
124
125
  const afterControlledRender = (sourceBarId, sourceTabId) => globalThis.queueMicrotask(() => {
126
+ if (disposed) return;
125
127
  const tab = [
126
128
  ...root.querySelectorAll('[data-component="app-tab"]')
127
129
  ].find((candidate) => {
@@ -209,12 +211,12 @@ function wireTabBars(root, { onReorder, activation = "automatic" }) {
209
211
  const current = tabs.indexOf(button);
210
212
  if (current < 0) return;
211
213
  if (keyboardEvent.altKey && keyboardEvent.shiftKey && (keyboardEvent.key === "ArrowLeft" || keyboardEvent.key === "ArrowRight")) {
212
- const target = tabs[current + (keyboardEvent.key === "ArrowLeft" ? -1 : 1)];
214
+ const target2 = tabs[current + (keyboardEvent.key === "ArrowLeft" ? -1 : 1)];
213
215
  const sourceId = tabId(tab);
214
- const targetRoot = target && tabRoot(target);
216
+ const targetRoot = target2 && tabRoot(target2);
215
217
  const targetId = targetRoot && tabId(targetRoot);
216
218
  const sourceBarId = barId(bar);
217
- if (!target || !sourceId || !targetId || !sourceBarId || tab.getAttribute("draggable") !== "true")
219
+ if (!target2 || !sourceId || !targetId || !sourceBarId || tab.getAttribute("draggable") !== "true")
218
220
  return;
219
221
  keyboardEvent.preventDefault();
220
222
  onReorder({
@@ -237,9 +239,17 @@ function wireTabBars(root, { onReorder, activation = "automatic" }) {
237
239
  keyboardEvent.preventDefault();
238
240
  const perBar = bar.dataset.tabActivation;
239
241
  const mode = perBar === "manual" || perBar === "automatic" ? perBar : activation;
240
- tabs[next]?.focus();
241
- if (mode === "automatic") tabs[next]?.click();
242
- reveal(tabs[next]);
242
+ const target = tabs[next];
243
+ target.focus();
244
+ if (mode === "automatic") {
245
+ target.click();
246
+ if (!target.isConnected)
247
+ afterControlledRender(
248
+ bar.dataset.tabBarId,
249
+ tabRoot(target).dataset.tabId
250
+ );
251
+ }
252
+ reveal(target);
243
253
  };
244
254
  const onFocusIn = (event) => {
245
255
  const tab = event.target instanceof HTMLElement && event.target.matches('[role="tab"]') ? event.target : void 0;
@@ -255,6 +265,7 @@ function wireTabBars(root, { onReorder, activation = "automatic" }) {
255
265
  '[data-kui-tab-list] [role="tab"][aria-selected="true"]'
256
266
  ).forEach(reveal);
257
267
  return () => {
268
+ disposed = true;
258
269
  clear();
259
270
  root.removeEventListener("dragstart", onDragStart);
260
271
  root.removeEventListener("dragover", onDragOver);
@@ -267,4 +278,4 @@ function wireTabBars(root, { onReorder, activation = "automatic" }) {
267
278
 
268
279
  export { reorderTabs, wireTabBars };
269
280
 
270
- //# sourceMappingURL=chunk-AASLYRGE.js.map
281
+ //# sourceMappingURL=chunk-UKKSMZYT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/wire-tab-bars.ts"],"names":["target"],"mappings":"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","file":"chunk-UKKSMZYT.js","sourcesContent":["import type { TabActivation } from './tab-bar.js';\n\nexport type TabReorderSource = 'pointer' | 'keyboard';\nexport type TabDropPosition = 'before' | 'after';\n\nexport interface TabReorder {\n barId: string;\n sourceId: string;\n targetId: string;\n position: TabDropPosition;\n source: TabReorderSource;\n}\n\nexport type { TabActivation } from './tab-bar.js';\n\nexport interface WireTabBarsOptions {\n onReorder: (change: TabReorder) => void;\n /**\n * How arrow / Home / End keys activate tabs (default `'automatic'`):\n * - `'automatic'` moves roving focus **and** selects the focused tab (clicks it).\n * - `'manual'` moves roving focus only; the user selects with Enter / Space / click\n * (the ARIA Tabs manual-activation pattern). Use this when activation is a heavy or\n * side-effecting action (e.g. a tab that loads a project) so arrowing through the\n * strip doesn't trigger it on every tab.\n *\n * A per-bar `data-tab-activation=\"manual\" | \"automatic\"` attribute (see the `TabBar`\n * `activation` prop) overrides this option for that strip.\n */\n activation?: TabActivation;\n}\n\ntype TabRoot = HTMLElement;\ntype TabBarRoot = HTMLElement;\n\nconst AUTO_SCROLL_EDGE_PX = 56;\nconst AUTO_SCROLL_MIN_PX_PER_SECOND = 180;\nconst AUTO_SCROLL_MAX_PX_PER_SECOND = 900;\n\nexport function reorderTabs<T>(\n items: readonly T[],\n getId: (item: T) => string,\n sourceId: string,\n targetId: string,\n position: TabDropPosition,\n): T[] {\n if (sourceId === targetId) return [...items];\n const source = items.find((item) => getId(item) === sourceId);\n if (!source || !items.some((item) => getId(item) === targetId))\n return [...items];\n const remaining = items.filter((item) => getId(item) !== sourceId);\n const targetIndex = remaining.findIndex((item) => getId(item) === targetId);\n remaining.splice(targetIndex + (position === 'after' ? 1 : 0), 0, source);\n return remaining;\n}\n\nfunction tabRoot(target: EventTarget | null): TabRoot | undefined {\n return target instanceof Element\n ? (target.closest<TabRoot>('[data-component=\"app-tab\"]') ?? undefined)\n : undefined;\n}\n\nfunction tabBar(tab: TabRoot): TabBarRoot | undefined {\n return tab.closest<TabBarRoot>('[data-component=\"tab-bar\"]') ?? undefined;\n}\n\nfunction tabId(tab: TabRoot): string | undefined {\n return tab.dataset.tabId || undefined;\n}\n\nfunction barId(bar: TabBarRoot): string | undefined {\n return bar.dataset.tabBarId || undefined;\n}\n\nfunction positionFor(event: DragEvent, tab: TabRoot): TabDropPosition {\n const bounds = tab.getBoundingClientRect();\n return event.clientX < bounds.left + bounds.width / 2 ? 'before' : 'after';\n}\n\nfunction tabsIn(bar: TabBarRoot): HTMLButtonElement[] {\n return [\n ...bar.querySelectorAll<HTMLButtonElement>(\n '[data-kui-tab-list] [role=\"tab\"]',\n ),\n ];\n}\n\nfunction reveal(tab: HTMLElement | null | undefined): void {\n tab?.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n}\n\n/** Wire reordering and keyboard navigation while leaving controlled state in the application. */\nexport function wireTabBars(\n root: HTMLElement | Document,\n { onReorder, activation = 'automatic' }: WireTabBarsOptions,\n): () => void {\n const ownerDocument = (\n root.nodeType === 9 ? (root as Document) : root.ownerDocument\n )!;\n const view = ownerDocument.defaultView!;\n let autoScroll:\n | {\n strip: HTMLElement;\n velocity: number;\n frame: number | undefined;\n previousTime: number | undefined;\n }\n | undefined;\n const stopAutoScroll = () => {\n if (!autoScroll) return;\n if (autoScroll.frame !== undefined)\n view.cancelAnimationFrame(autoScroll.frame);\n delete autoScroll.strip.dataset.tabAutoscroll;\n autoScroll = undefined;\n };\n const runAutoScroll = (time: number) => {\n const current = autoScroll;\n if (!current) return;\n current.frame = undefined;\n const elapsed =\n current.previousTime === undefined\n ? 1000 / 60\n : Math.min(40, Math.max(1, time - current.previousTime));\n current.previousTime = time;\n const maximum = Math.max(\n 0,\n current.strip.scrollWidth - current.strip.clientWidth,\n );\n const previous = current.strip.scrollLeft;\n current.strip.scrollLeft = Math.max(\n 0,\n Math.min(maximum, previous + (current.velocity * elapsed) / 1000),\n );\n if (current.strip.scrollLeft === previous) {\n stopAutoScroll();\n return;\n }\n current.frame = view.requestAnimationFrame(runAutoScroll);\n };\n const updateAutoScroll = (event: DragEvent, strip: HTMLElement) => {\n if (strip.scrollWidth <= strip.clientWidth) {\n stopAutoScroll();\n return;\n }\n const bounds = strip.getBoundingClientRect();\n const edge = Math.min(AUTO_SCROLL_EDGE_PX, bounds.width / 3);\n const startDistance = event.clientX - bounds.left;\n const endDistance = bounds.right - event.clientX;\n let direction = 0;\n let strength = 0;\n if (startDistance >= 0 && startDistance < edge) {\n direction = -1;\n strength = 1 - startDistance / edge;\n } else if (endDistance >= 0 && endDistance < edge) {\n direction = 1;\n strength = 1 - endDistance / edge;\n }\n if (direction === 0) {\n stopAutoScroll();\n return;\n }\n const maximum = Math.max(0, strip.scrollWidth - strip.clientWidth);\n if (\n (direction < 0 && strip.scrollLeft <= 0) ||\n (direction > 0 && strip.scrollLeft >= maximum)\n ) {\n stopAutoScroll();\n return;\n }\n const speed =\n AUTO_SCROLL_MIN_PX_PER_SECOND +\n (AUTO_SCROLL_MAX_PX_PER_SECOND - AUTO_SCROLL_MIN_PX_PER_SECOND) *\n strength *\n strength;\n if (autoScroll?.strip !== strip) stopAutoScroll();\n autoScroll ??= {\n strip,\n velocity: 0,\n frame: undefined,\n previousTime: undefined,\n };\n autoScroll.velocity = direction * speed;\n strip.dataset.tabAutoscroll = direction < 0 ? 'start' : 'end';\n autoScroll.frame ??= view.requestAnimationFrame(runAutoScroll);\n };\n let dragged: { barId: string; tabId: string } | undefined;\n const clearDropPositions = () =>\n root\n .querySelectorAll<HTMLElement>('[data-tab-drop-position]')\n .forEach((tab) => delete tab.dataset.tabDropPosition);\n const clear = () => {\n stopAutoScroll();\n dragged = undefined;\n root\n .querySelectorAll<HTMLElement>(\n '[data-tab-dragging], [data-tab-drop-position]',\n )\n .forEach((tab) => {\n delete tab.dataset.tabDragging;\n delete tab.dataset.tabDropPosition;\n });\n };\n let disposed = false;\n const afterControlledRender = (sourceBarId: string, sourceTabId: string) =>\n globalThis.queueMicrotask(() => {\n if (disposed) return;\n const tab = [\n ...root.querySelectorAll<TabRoot>('[data-component=\"app-tab\"]'),\n ].find((candidate) => {\n const candidateBar = tabBar(candidate);\n return (\n tabId(candidate) === sourceTabId &&\n candidateBar !== undefined &&\n barId(candidateBar) === sourceBarId\n );\n });\n const button = tab?.querySelector<HTMLButtonElement>('[role=\"tab\"]');\n button?.focus();\n reveal(button);\n });\n\n const onDragStart = (event: Event) => {\n const dragEvent = event as DragEvent;\n const tab = tabRoot(event.target);\n const bar = tab && tabBar(tab);\n const sourceId = tab && tabId(tab);\n const sourceBarId = bar && barId(bar);\n if (\n !tab ||\n tab.getAttribute('draggable') !== 'true' ||\n !sourceId ||\n !sourceBarId\n )\n return;\n dragged = { barId: sourceBarId, tabId: sourceId };\n tab.dataset.tabDragging = 'true';\n if (dragEvent.dataTransfer) {\n dragEvent.dataTransfer.effectAllowed = 'move';\n dragEvent.dataTransfer.setData(\n 'application/x-kerf-tab',\n `${sourceBarId}:${sourceId}`,\n );\n }\n };\n const onDragOver = (event: Event) => {\n const dragEvent = event as DragEvent;\n const tab = tabRoot(event.target);\n const bar =\n event.target instanceof Element\n ? (event.target.closest<TabBarRoot>('[data-component=\"tab-bar\"]') ??\n undefined)\n : undefined;\n const targetId = tab && tabId(tab);\n const targetBarId = bar && barId(bar);\n if (!dragged || !bar || targetBarId !== dragged.barId) {\n stopAutoScroll();\n clearDropPositions();\n return;\n }\n dragEvent.preventDefault();\n const strip = bar.querySelector<HTMLElement>('[data-kui-tab-list]');\n if (strip) updateAutoScroll(dragEvent, strip);\n else stopAutoScroll();\n clearDropPositions();\n if (!tab || !targetId || targetId === dragged.tabId) return;\n tab.dataset.tabDropPosition = positionFor(dragEvent, tab);\n if (dragEvent.dataTransfer) dragEvent.dataTransfer.dropEffect = 'move';\n };\n const onDrop = (event: Event) => {\n const dragEvent = event as DragEvent;\n const tab = tabRoot(event.target);\n const bar = tab && tabBar(tab);\n const targetId = tab && tabId(tab);\n const targetBarId = bar && barId(bar);\n if (\n !dragged ||\n !tab ||\n !targetId ||\n targetId === dragged.tabId ||\n targetBarId !== dragged.barId\n ) {\n clear();\n return;\n }\n dragEvent.preventDefault();\n const change: TabReorder = {\n barId: dragged.barId,\n sourceId: dragged.tabId,\n targetId,\n position: positionFor(dragEvent, tab),\n source: 'pointer',\n };\n clear();\n onReorder(change);\n afterControlledRender(change.barId, change.sourceId);\n };\n const onKeyDown = (event: Event) => {\n const keyboardEvent = event as KeyboardEvent;\n const button =\n event.target instanceof Element\n ? event.target.closest<HTMLButtonElement>('[role=\"tab\"]')\n : null;\n const tab = button && tabRoot(button);\n const bar = tab && tabBar(tab);\n if (!button || !tab || !bar) return;\n if (keyboardEvent.key === 'Delete' || keyboardEvent.key === 'Backspace') {\n const close = tab.querySelector<HTMLButtonElement>('.kui-app-tab__close');\n if (!close) return;\n keyboardEvent.preventDefault();\n close.click();\n return;\n }\n const tabs = tabsIn(bar);\n const current = tabs.indexOf(button);\n if (current < 0) return;\n if (\n keyboardEvent.altKey &&\n keyboardEvent.shiftKey &&\n (keyboardEvent.key === 'ArrowLeft' || keyboardEvent.key === 'ArrowRight')\n ) {\n const target =\n tabs[current + (keyboardEvent.key === 'ArrowLeft' ? -1 : 1)];\n const sourceId = tabId(tab);\n const targetRoot = target && tabRoot(target);\n const targetId = targetRoot && tabId(targetRoot);\n const sourceBarId = barId(bar);\n if (\n !target ||\n !sourceId ||\n !targetId ||\n !sourceBarId ||\n tab.getAttribute('draggable') !== 'true'\n )\n return;\n keyboardEvent.preventDefault();\n onReorder({\n barId: sourceBarId,\n sourceId,\n targetId,\n position: keyboardEvent.key === 'ArrowLeft' ? 'before' : 'after',\n source: 'keyboard',\n });\n afterControlledRender(sourceBarId, sourceId);\n return;\n }\n let next: number | undefined;\n if (keyboardEvent.key === 'ArrowRight') next = (current + 1) % tabs.length;\n else if (keyboardEvent.key === 'ArrowLeft')\n next = (current - 1 + tabs.length) % tabs.length;\n else if (keyboardEvent.key === 'Home') next = 0;\n else if (keyboardEvent.key === 'End') next = tabs.length - 1;\n if (next === undefined) return;\n keyboardEvent.preventDefault();\n // A per-bar data-tab-activation attribute overrides the wireTabBars option.\n const perBar = bar.dataset.tabActivation;\n const mode: TabActivation =\n perBar === 'manual' || perBar === 'automatic' ? perBar : activation;\n const target = tabs[next]!;\n target.focus();\n // Manual activation moves roving focus only; the user selects with Enter / Space\n // (native on the tab <button>) or click. Automatic also selects the focused tab.\n if (mode === 'automatic') {\n target.click();\n // Activation can synchronously replace the controlled strip. Resolve the\n // logical tab again after rendering instead of leaving focus on a dead node.\n if (!target.isConnected)\n afterControlledRender(\n bar.dataset.tabBarId!,\n tabRoot(target)!.dataset.tabId!,\n );\n }\n reveal(target);\n };\n const onFocusIn = (event: Event) => {\n const tab =\n event.target instanceof HTMLElement &&\n event.target.matches('[role=\"tab\"]')\n ? event.target\n : undefined;\n reveal(tab);\n };\n\n root.addEventListener('dragstart', onDragStart);\n root.addEventListener('dragover', onDragOver);\n root.addEventListener('drop', onDrop);\n root.addEventListener('dragend', clear);\n root.addEventListener('keydown', onKeyDown);\n root.addEventListener('focusin', onFocusIn);\n root\n .querySelectorAll<HTMLElement>(\n '[data-kui-tab-list] [role=\"tab\"][aria-selected=\"true\"]',\n )\n .forEach(reveal);\n\n return () => {\n disposed = true;\n clear();\n root.removeEventListener('dragstart', onDragStart);\n root.removeEventListener('dragover', onDragOver);\n root.removeEventListener('drop', onDrop);\n root.removeEventListener('dragend', clear);\n root.removeEventListener('keydown', onKeyDown);\n root.removeEventListener('focusin', onFocusIn);\n };\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { filterDataAttributes, filterControlAttributes } from './chunk-SRSJO5QE.js';
2
- import { Skeleton } from './chunk-PZQVSDLH.js';
2
+ import { Skeleton } from './chunk-RKVQEH4J.js';
3
+ import { LoadingSpinner } from './chunk-6WTETUZ6.js';
3
4
  import { jsxs, jsx } from 'kerfjs/jsx-runtime';
4
5
 
5
6
  var PROTECTED_ROOT_DATA_ATTRIBUTES = /* @__PURE__ */ new Set([
@@ -8,6 +9,10 @@ var PROTECTED_ROOT_DATA_ATTRIBUTES = /* @__PURE__ */ new Set([
8
9
  "data-item-id",
9
10
  "data-has-icon",
10
11
  "data-multiline",
12
+ "data-density",
13
+ "data-divider",
14
+ "data-busy",
15
+ "data-trailing-visibility",
11
16
  "data-state",
12
17
  "data-selected",
13
18
  "data-pressed"
@@ -19,6 +24,11 @@ var PROTECTED_TRAILING_DATA_ATTRIBUTES = /* @__PURE__ */ new Set([
19
24
  ]);
20
25
  function ListActionRow({
21
26
  label,
27
+ description,
28
+ status,
29
+ busy = false,
30
+ density = "standard",
31
+ divider = "none",
22
32
  icon,
23
33
  action,
24
34
  itemId,
@@ -36,6 +46,7 @@ function ListActionRow({
36
46
  trailingActionIcon,
37
47
  trailingActionDisabled = false,
38
48
  trailingActionTitle,
49
+ trailingActionVisibility = "always",
39
50
  className = "",
40
51
  style,
41
52
  rootAttributes = {},
@@ -59,11 +70,15 @@ function ListActionRow({
59
70
  "data-item-id": itemId,
60
71
  "data-has-icon": String(Boolean(icon)),
61
72
  "data-multiline": multiline ? "true" : void 0,
73
+ "data-density": density,
74
+ "data-divider": divider,
75
+ "data-busy": busy ? "true" : void 0,
76
+ "data-trailing-visibility": trailingActionVisibility,
62
77
  "data-state": state,
63
78
  "data-selected": String(selected),
64
79
  "data-pressed": pressed === void 0 ? void 0 : String(pressed),
65
80
  "data-placeholder": placeholder ? "true" : void 0,
66
- "aria-busy": placeholder ? "true" : void 0,
81
+ "aria-busy": placeholder || busy ? "true" : void 0,
67
82
  children: [
68
83
  /* @__PURE__ */ jsxs(
69
84
  "button",
@@ -80,7 +95,14 @@ function ListActionRow({
80
95
  "aria-pressed": pressed === void 0 ? void 0 : String(pressed),
81
96
  children: [
82
97
  icon && /* @__PURE__ */ jsx("span", { class: "kui-list-action-row__icon", children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "1em", height: "1em" }) : icon }),
83
- /* @__PURE__ */ jsx("span", { class: "kui-list-action-row__label", children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "9em" }) : label })
98
+ /* @__PURE__ */ jsxs("span", { class: "kui-list-action-row__label", children: [
99
+ /* @__PURE__ */ jsx("span", { class: "kui-list-action-row__primary-label", children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "9em" }) : label }),
100
+ !placeholder && description && /* @__PURE__ */ jsx("span", { class: "kui-list-action-row__description", children: description }),
101
+ !placeholder && (busy || status) && /* @__PURE__ */ jsxs("span", { class: "kui-list-action-row__status", children: [
102
+ busy && /* @__PURE__ */ jsx(LoadingSpinner, {}),
103
+ status
104
+ ] })
105
+ ] })
84
106
  ]
85
107
  }
86
108
  ),
@@ -105,4 +127,4 @@ function ListActionRow({
105
127
 
106
128
  export { ListActionRow };
107
129
 
108
- //# sourceMappingURL=chunk-BBRXX6PF.js.map
130
+ //# sourceMappingURL=chunk-VCE4MPVE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/list-action-row.tsx"],"names":[],"mappings":"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","file":"chunk-VCE4MPVE.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from './extension-attributes.js';\nimport { LoadingSpinner } from './loading-spinner.js';\nimport { Skeleton } from './skeleton.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-has-icon',\n 'data-multiline',\n 'data-density',\n 'data-divider',\n 'data-busy',\n 'data-trailing-visibility',\n 'data-state',\n 'data-selected',\n 'data-pressed',\n]);\nconst PROTECTED_TRAILING_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n]);\n\ntype ListActionRowRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-has-icon'?: never;\n 'data-multiline'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-busy'?: never;\n 'data-trailing-visibility'?: never;\n 'data-state'?: never;\n 'data-selected'?: never;\n 'data-pressed'?: never;\n }\n>;\n\ntype ListActionRowTrailingAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n popoverTarget?: string;\n popoverTargetAction?: 'toggle' | 'show' | 'hide';\n 'aria-controls'?: string;\n 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';\n }\n>;\n\nexport interface ListActionRowProps {\n /** Visible dormant content for the primary button. Must not contain interactive descendants. */\n label: string | SafeHtml;\n description?: string | SafeHtml;\n status?: string | SafeHtml;\n busy?: boolean;\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Decorative dormant content for the primary button. Must not contain interactive descendants. */\n icon?: SafeHtml;\n action: string;\n itemId?: string;\n selected?: boolean;\n pressed?: boolean;\n accessibleLabel?: string;\n title?: string;\n multiline?: boolean;\n state?: string;\n disabled?: boolean;\n tabIndex?: number;\n /** Render as an unanimated loading skeleton, disabling both actions. */\n placeholder?: boolean;\n trailingAction: string;\n trailingActionLabel: string;\n /** Decorative dormant content for the trailing button. Must not contain interactive descendants. */\n trailingActionIcon: SafeHtml;\n trailingActionDisabled?: boolean;\n trailingActionTitle?: string;\n trailingActionVisibility?: 'always' | 'interaction';\n className?: string;\n style?: string;\n rootAttributes?: ListActionRowRootAttributes;\n trailingActionAttributes?: ListActionRowTrailingAttributes;\n}\n\nexport function ListActionRow({\n label,\n description,\n status,\n busy = false,\n density = 'standard',\n divider = 'none',\n icon,\n action,\n itemId,\n selected = false,\n pressed,\n accessibleLabel,\n title,\n multiline = false,\n state,\n disabled = false,\n tabIndex,\n placeholder = false,\n trailingAction,\n trailingActionLabel,\n trailingActionIcon,\n trailingActionDisabled = false,\n trailingActionTitle,\n trailingActionVisibility = 'always',\n className = '',\n style,\n rootAttributes = {},\n trailingActionAttributes = {},\n}: ListActionRowProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTrailingAttributes = filterControlAttributes(\n trailingActionAttributes,\n PROTECTED_TRAILING_DATA_ATTRIBUTES,\n );\n\n return (\n <div\n {...extensionRootAttributes}\n class={`kui-list-action-row ${className}`.trim()}\n style={style}\n data-component=\"list-action-row\"\n data-item-id={itemId}\n data-has-icon={String(Boolean(icon))}\n data-multiline={multiline ? 'true' : undefined}\n data-density={density}\n data-divider={divider}\n data-busy={busy ? 'true' : undefined}\n data-trailing-visibility={trailingActionVisibility}\n data-state={state}\n data-selected={String(selected)}\n data-pressed={pressed === undefined ? undefined : String(pressed)}\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={placeholder || busy ? 'true' : undefined}\n >\n <button\n type=\"button\"\n class=\"kui-list-action-row__primary\"\n title={placeholder ? undefined : title}\n disabled={disabled || placeholder}\n tabindex={placeholder ? -1 : tabIndex}\n data-action={placeholder ? undefined : action}\n data-item-id={itemId}\n aria-label={accessibleLabel}\n aria-current={selected ? 'page' : undefined}\n aria-pressed={pressed === undefined ? undefined : String(pressed)}\n >\n {icon && (\n <span class=\"kui-list-action-row__icon\">\n {placeholder ? <Skeleton width=\"1em\" height=\"1em\" /> : icon}\n </span>\n )}\n <span class=\"kui-list-action-row__label\">\n <span class=\"kui-list-action-row__primary-label\">\n {placeholder ? <Skeleton width=\"9em\" /> : label}\n </span>\n {!placeholder && description && (\n <span class=\"kui-list-action-row__description\">{description}</span>\n )}\n {!placeholder && (busy || status) && (\n <span class=\"kui-list-action-row__status\">\n {busy && <LoadingSpinner />}\n {status}\n </span>\n )}\n </span>\n </button>\n <button\n {...extensionTrailingAttributes}\n type=\"button\"\n class=\"kui-list-action-row__trailing-action\"\n data-action={placeholder ? undefined : trailingAction}\n data-item-id={itemId}\n aria-label={trailingActionLabel}\n title={trailingActionTitle ?? trailingActionLabel}\n disabled={trailingActionDisabled || placeholder || undefined}\n >\n {trailingActionIcon}\n </button>\n </div>\n );\n}\n"]}
@@ -1,9 +1,10 @@
1
- import { Skeleton } from './chunk-PZQVSDLH.js';
1
+ import { Skeleton } from './chunk-RKVQEH4J.js';
2
2
  import { jsxs, jsx } from 'kerfjs/jsx-runtime';
3
3
 
4
4
  function StateBanner({
5
5
  title,
6
6
  detail,
7
+ badge,
7
8
  icon,
8
9
  action,
9
10
  tone = "info",
@@ -25,7 +26,8 @@ function StateBanner({
25
26
  icon && /* @__PURE__ */ jsx("span", { class: "kui-state-banner__icon", children: icon }),
26
27
  /* @__PURE__ */ jsxs("div", { class: "kui-state-banner__copy", children: [
27
28
  /* @__PURE__ */ jsx("strong", { children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "10em" }) : title }),
28
- (placeholder || detail) && /* @__PURE__ */ jsx("span", { children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "16em" }) : detail })
29
+ badge && /* @__PURE__ */ jsx("span", { class: "kui-state-banner__badge", children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "1.75em" }) : badge }),
30
+ (placeholder || detail) && /* @__PURE__ */ jsx("span", { class: "kui-state-banner__detail", children: placeholder ? /* @__PURE__ */ jsx(Skeleton, { width: "16em" }) : detail })
29
31
  ] }),
30
32
  action && /* @__PURE__ */ jsx("div", { class: "kui-state-banner__action", children: action })
31
33
  ]
@@ -35,4 +37,4 @@ function StateBanner({
35
37
 
36
38
  export { StateBanner };
37
39
 
38
- //# sourceMappingURL=chunk-VLYV65LK.js.map
40
+ //# sourceMappingURL=chunk-W5L2JSBY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/state-banner.tsx"],"names":[],"mappings":";;;AAsBO,SAAS,WAAA,CAAY;AAAA,EAC1B,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA,GAAO,MAAA;AAAA,EACP,OAAA,GAAU,QAAA;AAAA,EACV,SAAA,GAAY,EAAA;AAAA,EACZ,WAAA,GAAc;AAChB,CAAA,EAAqB;AACnB,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC5C,gBAAA,EAAe,cAAA;AAAA,MACf,WAAA,EAAW,IAAA;AAAA,MACX,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,MACzC,IAAA,EAAM,OAAA;AAAA,MACN,WAAA,EAAW,OAAA,KAAY,OAAA,GAAU,WAAA,GAAc,QAAA;AAAA,MAC/C,WAAA,EAAW,cAAc,MAAA,GAAS,MAAA;AAAA,MAEjC,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,wBAAA,EAA0B,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,wBACpD,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,wBAAA,EACT,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,YAAQ,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,YAAS,KAAA,EAAM,MAAA,EAAO,IAAK,KAAA,EAAM,CAAA;AAAA,UACxD,KAAA,oBACC,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,yBAAA,EACT,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,QAAA,EAAS,CAAA,GAAK,KAAA,EAC/C,CAAA;AAAA,UAAA,CAEA,WAAA,IAAe,MAAA,qBACf,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,0BAAA,EACT,QAAA,EAAA,WAAA,mBAAc,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,MAAA,EAAO,CAAA,GAAK,MAAA,EAC7C;AAAA,SAAA,EAEJ,CAAA;AAAA,QACC,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,4BAA4B,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,GAC3D;AAEJ","file":"chunk-W5L2JSBY.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { Skeleton } from './skeleton.js';\n\nexport type StateBannerTone =\n 'neutral' | 'info' | 'success' | 'warning' | 'danger';\nexport type StateBannerUrgency = 'status' | 'alert';\n\nexport interface StateBannerProps {\n title: string;\n detail?: string;\n /** Optional compact status or count shown beside the title. */\n badge?: string;\n icon?: SafeHtml;\n action?: SafeHtml;\n tone?: StateBannerTone;\n urgency?: StateBannerUrgency;\n className?: string;\n /** Render the title, badge, and detail as unanimated loading skeletons, keeping the icon and tone. */\n placeholder?: boolean;\n}\n\nexport function StateBanner({\n title,\n detail,\n badge,\n icon,\n action,\n tone = 'info',\n urgency = 'status',\n className = '',\n placeholder = false,\n}: StateBannerProps) {\n return (\n <section\n class={`kui-state-banner ${className}`.trim()}\n data-component=\"state-banner\"\n data-tone={tone}\n data-placeholder={placeholder ? 'true' : undefined}\n role={urgency}\n aria-live={urgency === 'alert' ? 'assertive' : 'polite'}\n aria-busy={placeholder ? 'true' : undefined}\n >\n {icon && <span class=\"kui-state-banner__icon\">{icon}</span>}\n <div class=\"kui-state-banner__copy\">\n <strong>{placeholder ? <Skeleton width=\"10em\" /> : title}</strong>\n {badge && (\n <span class=\"kui-state-banner__badge\">\n {placeholder ? <Skeleton width=\"1.75em\" /> : badge}\n </span>\n )}\n {(placeholder || detail) && (\n <span class=\"kui-state-banner__detail\">\n {placeholder ? <Skeleton width=\"16em\" /> : detail}\n </span>\n )}\n </div>\n {action && <div class=\"kui-state-banner__action\">{action}</div>}\n </section>\n );\n}\n"]}
@@ -10,7 +10,14 @@ function ToolbarControlGroup({
10
10
  appearance = "contained",
11
11
  tone = "default",
12
12
  buttonAppearance = "plain",
13
- shape = "pill"
13
+ shape = "pill",
14
+ size = "default",
15
+ density = "comfortable",
16
+ content = "icon",
17
+ selectedChrome = "raised",
18
+ selectedTone = "brand",
19
+ nestedDropdown = false,
20
+ scrim = false
14
21
  }) {
15
22
  return /* @__PURE__ */ jsx(
16
23
  "div",
@@ -25,6 +32,13 @@ function ToolbarControlGroup({
25
32
  "data-expanded": String(expanded),
26
33
  "data-single": String(single),
27
34
  "data-shape": shape,
35
+ "data-size": size,
36
+ "data-density": density,
37
+ "data-content": content,
38
+ "data-selected-chrome": selectedChrome,
39
+ "data-selected-tone": selectedTone,
40
+ "data-nested-dropdown": String(nestedDropdown),
41
+ "data-scrim": String(scrim),
28
42
  children
29
43
  }
30
44
  );
@@ -32,4 +46,4 @@ function ToolbarControlGroup({
32
46
 
33
47
  export { ToolbarControlGroup };
34
48
 
35
- //# sourceMappingURL=chunk-5VTB2BKP.js.map
49
+ //# sourceMappingURL=chunk-WNWD54GR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/toolbar-control-group.tsx"],"names":[],"mappings":";;;AAkCO,SAAS,mBAAA,CAAoB;AAAA,EAClC,QAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,QAAA,GAAW,KAAA;AAAA,EACX,MAAA,GAAS,KAAA;AAAA,EACT,UAAA,GAAa,WAAA;AAAA,EACb,IAAA,GAAO,SAAA;AAAA,EACP,gBAAA,GAAmB,OAAA;AAAA,EACnB,KAAA,GAAQ,MAAA;AAAA,EACR,IAAA,GAAO,SAAA;AAAA,EACP,OAAA,GAAU,aAAA;AAAA,EACV,OAAA,GAAU,MAAA;AAAA,EACV,cAAA,GAAiB,QAAA;AAAA,EACjB,YAAA,GAAe,OAAA;AAAA,EACf,cAAA,GAAiB,KAAA;AAAA,EACjB,KAAA,GAAQ;AACV,CAAA,EAA6B;AAC3B,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,0BAAA,EAA6B,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACrD,gBAAA,EAAe,uBAAA;AAAA,MACf,IAAA,EAAM,QAAQ,OAAA,GAAU,MAAA;AAAA,MACxB,YAAA,EAAY,KAAA;AAAA,MACZ,iBAAA,EAAiB,UAAA;AAAA,MACjB,WAAA,EAAW,IAAA;AAAA,MACX,wBAAA,EAAwB,gBAAA;AAAA,MACxB,eAAA,EAAe,OAAO,QAAQ,CAAA;AAAA,MAC9B,aAAA,EAAa,OAAO,MAAM,CAAA;AAAA,MAC1B,YAAA,EAAY,KAAA;AAAA,MACZ,WAAA,EAAW,IAAA;AAAA,MACX,cAAA,EAAc,OAAA;AAAA,MACd,cAAA,EAAc,OAAA;AAAA,MACd,sBAAA,EAAsB,cAAA;AAAA,MACtB,oBAAA,EAAoB,YAAA;AAAA,MACpB,sBAAA,EAAsB,OAAO,cAAc,CAAA;AAAA,MAC3C,YAAA,EAAY,OAAO,KAAK,CAAA;AAAA,MAEvB;AAAA;AAAA,GACH;AAEJ","file":"chunk-WNWD54GR.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nexport type ToolbarControlGroupAppearance = 'contained' | 'borderless';\nexport type ToolbarControlGroupTone = 'default' | 'dark';\nexport type ToolbarControlGroupButtonAppearance = 'plain' | 'push';\nexport type ToolbarControlGroupShape = 'pill' | 'rounded';\nexport type ToolbarControlGroupSize = 'default' | 'compact';\nexport type ToolbarControlGroupDensity = 'comfortable' | 'tight';\nexport type ToolbarControlGroupContent = 'icon' | 'text' | 'mixed' | 'avatar';\nexport type ToolbarControlGroupSelectedChrome = 'raised' | 'filled' | 'outline';\nexport type ToolbarControlGroupSelectedTone = 'brand' | 'neutral';\n\nexport interface ToolbarControlGroupProps {\n children: SafeHtml | SafeHtml[];\n label?: string;\n className?: string;\n expanded?: boolean;\n single?: boolean;\n appearance?: ToolbarControlGroupAppearance;\n tone?: ToolbarControlGroupTone;\n buttonAppearance?: ToolbarControlGroupButtonAppearance;\n /** Corner shape: fully round `pill` (default) or a softer `rounded` rectangle. */\n shape?: ToolbarControlGroupShape;\n size?: ToolbarControlGroupSize;\n density?: ToolbarControlGroupDensity;\n content?: ToolbarControlGroupContent;\n selectedChrome?: ToolbarControlGroupSelectedChrome;\n selectedTone?: ToolbarControlGroupSelectedTone;\n /** Size a nested Web Awesome dropdown trigger as part of this group. */\n nestedDropdown?: boolean;\n /** Add contrast behind photo-backed avatar content. */\n scrim?: boolean;\n}\n\nexport function ToolbarControlGroup({\n children,\n label,\n className = '',\n expanded = false,\n single = false,\n appearance = 'contained',\n tone = 'default',\n buttonAppearance = 'plain',\n shape = 'pill',\n size = 'default',\n density = 'comfortable',\n content = 'icon',\n selectedChrome = 'raised',\n selectedTone = 'brand',\n nestedDropdown = false,\n scrim = false,\n}: ToolbarControlGroupProps) {\n return (\n <div\n class={`kui-toolbar-control-group ${className}`.trim()}\n data-component=\"toolbar-control-group\"\n role={label ? 'group' : undefined}\n aria-label={label}\n data-appearance={appearance}\n data-tone={tone}\n data-button-appearance={buttonAppearance}\n data-expanded={String(expanded)}\n data-single={String(single)}\n data-shape={shape}\n data-size={size}\n data-density={density}\n data-content={content}\n data-selected-chrome={selectedChrome}\n data-selected-tone={selectedTone}\n data-nested-dropdown={String(nestedDropdown)}\n data-scrim={String(scrim)}\n >\n {children}\n </div>\n );\n}\n"]}
@@ -8,7 +8,10 @@ function TabBar({
8
8
  leading,
9
9
  trailing,
10
10
  className = "",
11
- activation
11
+ activation,
12
+ allocation = "intrinsic",
13
+ presentation = "rail",
14
+ trailingPlacement = "separate"
12
15
  }) {
13
16
  return /* @__PURE__ */ jsxs(
14
17
  "nav",
@@ -17,6 +20,9 @@ function TabBar({
17
20
  "data-component": "tab-bar",
18
21
  "data-tab-bar-id": id,
19
22
  "data-tab-activation": activation,
23
+ "data-allocation": allocation,
24
+ "data-presentation": presentation,
25
+ "data-trailing-placement": trailingPlacement,
20
26
  "aria-label": label,
21
27
  children: [
22
28
  leading && /* @__PURE__ */ jsx("div", { class: "kui-tab-bar__leading", children: leading }),
@@ -38,4 +44,4 @@ function TabBar({
38
44
 
39
45
  export { TabBar };
40
46
 
41
- //# sourceMappingURL=chunk-M7JBER5U.js.map
47
+ //# sourceMappingURL=chunk-X2U3QJCJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tab-bar.tsx"],"names":[],"mappings":";;;AA8BO,SAAS,MAAA,CAAO;AAAA,EACrB,EAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,UAAA;AAAA,EACA,UAAA,GAAa,WAAA;AAAA,EACb,YAAA,GAAe,MAAA;AAAA,EACf,iBAAA,GAAoB;AACtB,CAAA,EAAgB;AACd,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,YAAA,EAAe,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACvC,gBAAA,EAAe,SAAA;AAAA,MACf,iBAAA,EAAiB,EAAA;AAAA,MACjB,qBAAA,EAAqB,UAAA;AAAA,MACrB,iBAAA,EAAiB,UAAA;AAAA,MACjB,mBAAA,EAAmB,YAAA;AAAA,MACnB,yBAAA,EAAyB,iBAAA;AAAA,MACzB,YAAA,EAAY,KAAA;AAAA,MAEX,QAAA,EAAA;AAAA,QAAA,OAAA,oBAAW,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,sBAAA,EAAwB,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,wBACvD,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAM,mBAAA;AAAA,YACN,IAAA,EAAK,SAAA;AAAA,YACL,YAAA,EAAY,KAAA;AAAA,YACZ,mBAAA,EAAiB,IAAA;AAAA,YAEhB;AAAA;AAAA,SACH;AAAA,QACC,QAAA,oBAAY,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,yBAAyB,QAAA,EAAA,QAAA,EAAS;AAAA;AAAA;AAAA,GAC5D;AAEJ","file":"chunk-X2U3QJCJ.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nexport type TabActivation = 'automatic' | 'manual';\nexport type TabBarAllocation = 'intrinsic' | 'fill';\nexport type TabBarPresentation = 'rail' | 'segmented' | 'inspector';\nexport type TabBarTrailingPlacement = 'separate' | 'adjacent';\n\nexport interface TabBarProps {\n id: string;\n label: string;\n children: SafeHtml | readonly SafeHtml[];\n leading?: SafeHtml;\n trailing?: SafeHtml;\n className?: string;\n /**\n * Keyboard activation mode for this strip, emitted as `data-tab-activation` for\n * `wireTabBars` to read (overrides its `activation` option). `'automatic'` (default)\n * selects on arrow / Home / End; `'manual'` moves roving focus only and the user\n * selects with Enter / Space / click — use it when selecting a tab is a heavy action.\n */\n activation?: TabActivation;\n /** How available strip width is allocated across child AppTabs. */\n allocation?: TabBarAllocation;\n /** Named strip chrome for application rails, segmented tabs, or inspectors. */\n presentation?: TabBarPresentation;\n /** Keep a trailing action beside the final tab or at the far edge of the bar. */\n trailingPlacement?: TabBarTrailingPlacement;\n}\n\n/** Render a controlled tab strip. The application owns selection, order, and persistence. */\nexport function TabBar({\n id,\n label,\n children,\n leading,\n trailing,\n className = '',\n activation,\n allocation = 'intrinsic',\n presentation = 'rail',\n trailingPlacement = 'separate',\n}: TabBarProps) {\n return (\n <nav\n class={`kui-tab-bar ${className}`.trim()}\n data-component=\"tab-bar\"\n data-tab-bar-id={id}\n data-tab-activation={activation}\n data-allocation={allocation}\n data-presentation={presentation}\n data-trailing-placement={trailingPlacement}\n aria-label={label}\n >\n {leading && <div class=\"kui-tab-bar__leading\">{leading}</div>}\n <div\n class=\"kui-tab-bar__tabs\"\n role=\"tablist\"\n aria-label={label}\n data-kui-tab-list\n >\n {children}\n </div>\n {trailing && <div class=\"kui-tab-bar__trailing\">{trailing}</div>}\n </nav>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { resizeRegionFromPointer, clampRegionSize } from './chunk-NENBUYX5.js';
1
+ import { resizeRegionFromPointer, clampRegionSize } from './chunk-HP2B2L26.js';
2
2
  import { delegate } from 'kerfjs';
3
3
 
4
4
  function regionState(handle) {
@@ -13,7 +13,7 @@ function regionState(handle) {
13
13
  const min = Number(handle.getAttribute("aria-valuemin"));
14
14
  const max = Number(handle.getAttribute("aria-valuemax"));
15
15
  const size = Number(handle.getAttribute("aria-valuenow"));
16
- if (!id || axis !== "horizontal" && axis !== "vertical" || edge !== "start" && edge !== "end" || !Number.isFinite(min) || !Number.isFinite(max) || !Number.isFinite(size))
16
+ if (!id || region.dataset.collapsed === "true" || region.dataset.presentation !== "inline" || axis !== "horizontal" && axis !== "vertical" || edge !== "start" && edge !== "end" || !Number.isFinite(min) || !Number.isFinite(max) || !Number.isFinite(size))
17
17
  return void 0;
18
18
  return { region, handle, id, axis, edge, min, max, size };
19
19
  }
@@ -92,10 +92,12 @@ function wireResizableRegions(root, {
92
92
  root.removeEventListener("pointerup", finish);
93
93
  root.removeEventListener("pointercancel", finish);
94
94
  stopPointer = void 0;
95
+ delete state.region.dataset.resizing;
95
96
  onCommit({ id: state.id, size: next, source: "pointer" });
96
97
  };
97
98
  stopPointer?.();
98
99
  stopPointer = finish;
100
+ state.region.dataset.resizing = "true";
99
101
  root.addEventListener("pointermove", move);
100
102
  root.addEventListener("pointerup", finish, { once: true });
101
103
  root.addEventListener("pointercancel", finish, { once: true });
@@ -110,4 +112,4 @@ function wireResizableRegions(root, {
110
112
 
111
113
  export { wireResizableRegions };
112
114
 
113
- //# sourceMappingURL=chunk-DPDBVKNA.js.map
115
+ //# sourceMappingURL=chunk-YMKH5XTF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/wire-resizable-regions.ts"],"names":[],"mappings":"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","file":"chunk-YMKH5XTF.js","sourcesContent":["import { delegate } from 'kerfjs';\n\nimport {\n clampRegionSize,\n type ResizableRegionAxis,\n type ResizableRegionEdge,\n resizeRegionFromPointer,\n} from './resizable-region.js';\n\nexport interface ResizeCommit {\n id: string;\n size: number;\n source: 'keyboard' | 'pointer';\n}\n\nexport interface WireResizableRegionsOptions {\n step?: number;\n largeStep?: number;\n onPreview?: (change: ResizeCommit) => void;\n onCommit: (change: ResizeCommit) => void;\n}\n\ninterface RegionState {\n region: HTMLElement;\n handle: HTMLElement;\n id: string;\n axis: ResizableRegionAxis;\n edge: ResizableRegionEdge;\n min: number;\n max: number;\n size: number;\n}\n\nfunction regionState(handle: Element): RegionState | undefined {\n const region = handle.closest<HTMLElement>(\n '[data-component=\"resizable-region\"]',\n );\n if (!(region instanceof HTMLElement) || !(handle instanceof HTMLElement))\n return undefined;\n const id = region.dataset.regionId;\n const axis = region.dataset.axis;\n const edge = region.dataset.edge;\n const min = Number(handle.getAttribute('aria-valuemin'));\n const max = Number(handle.getAttribute('aria-valuemax'));\n const size = Number(handle.getAttribute('aria-valuenow'));\n if (\n !id ||\n region.dataset.collapsed === 'true' ||\n region.dataset.presentation !== 'inline' ||\n (axis !== 'horizontal' && axis !== 'vertical') ||\n (edge !== 'start' && edge !== 'end') ||\n !Number.isFinite(min) ||\n !Number.isFinite(max) ||\n !Number.isFinite(size)\n )\n return undefined;\n return { region, handle, id, axis, edge, min, max, size };\n}\n\nfunction preview(\n state: RegionState,\n size: number,\n onPreview?: (change: ResizeCommit) => void,\n) {\n const next = clampRegionSize(size, state.min, state.max);\n state.region.style.setProperty('--kui-resizable-region-size', `${next}px`);\n state.handle.setAttribute('aria-valuenow', String(next));\n onPreview?.({ id: state.id, size: next, source: 'pointer' });\n return next;\n}\n\n/** Wire pointer and separator-keyboard behavior for every ResizableRegion below root. */\nexport function wireResizableRegions(\n root: HTMLElement,\n {\n step = 16,\n largeStep = 64,\n onPreview,\n onCommit,\n }: WireResizableRegionsOptions,\n) {\n let stopPointer: (() => void) | undefined;\n\n const stopKeydown = delegate(\n root,\n 'keydown',\n '[data-kui-resize-handle]',\n (event, handle) => {\n const keyboardEvent = event as KeyboardEvent;\n const state = regionState(handle);\n if (!state) return;\n let next: number | undefined;\n if (keyboardEvent.key === 'Home') next = state.min;\n if (keyboardEvent.key === 'End') next = state.max;\n const increment = keyboardEvent.shiftKey ? largeStep : step;\n if (state.axis === 'horizontal' && keyboardEvent.key === 'ArrowLeft')\n next = resizeRegionFromPointer(state.size, -increment, state.edge);\n if (state.axis === 'horizontal' && keyboardEvent.key === 'ArrowRight')\n next = resizeRegionFromPointer(state.size, increment, state.edge);\n if (state.axis === 'vertical' && keyboardEvent.key === 'ArrowUp')\n next = resizeRegionFromPointer(state.size, -increment, state.edge);\n if (state.axis === 'vertical' && keyboardEvent.key === 'ArrowDown')\n next = resizeRegionFromPointer(state.size, increment, state.edge);\n if (next === undefined) return;\n keyboardEvent.preventDefault();\n const size = clampRegionSize(next, state.min, state.max);\n state.region.style.setProperty(\n '--kui-resizable-region-size',\n `${size}px`,\n );\n state.handle.setAttribute('aria-valuenow', String(size));\n onCommit({ id: state.id, size, source: 'keyboard' });\n },\n );\n\n const stopPointerDown = delegate(\n root,\n 'pointerdown',\n '[data-kui-resize-handle]',\n (event, handle) => {\n const pointerEvent = event as PointerEvent;\n if (pointerEvent.button !== 0) return;\n const state = regionState(handle);\n if (!state) return;\n pointerEvent.preventDefault();\n state.handle.setPointerCapture?.(pointerEvent.pointerId);\n const startCoordinate =\n state.axis === 'horizontal'\n ? pointerEvent.clientX\n : pointerEvent.clientY;\n let next = state.size;\n const move = (moveEvent: PointerEvent) => {\n const coordinate =\n state.axis === 'horizontal' ? moveEvent.clientX : moveEvent.clientY;\n next = preview(\n state,\n resizeRegionFromPointer(\n state.size,\n coordinate - startCoordinate,\n state.edge,\n ),\n onPreview,\n );\n };\n const finish = () => {\n root.removeEventListener('pointermove', move);\n root.removeEventListener('pointerup', finish);\n root.removeEventListener('pointercancel', finish);\n stopPointer = undefined;\n delete state.region.dataset.resizing;\n onCommit({ id: state.id, size: next, source: 'pointer' });\n };\n stopPointer?.();\n stopPointer = finish;\n state.region.dataset.resizing = 'true';\n root.addEventListener('pointermove', move);\n root.addEventListener('pointerup', finish, { once: true });\n root.addEventListener('pointercancel', finish, { once: true });\n },\n );\n\n return () => {\n stopPointer?.();\n stopKeydown();\n stopPointerDown();\n };\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { SafeHtml } from 'kerfjs';
2
2
  import { LucideIcon } from './lucide-icon.js';
3
+ import { ResizableRegionSeparator, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionPresentation, ResizableRegionRestorePosition } from './resizable-region.js';
3
4
  import 'lucide';
4
5
 
5
6
  /** Which edge a {@link CollapsiblePanel} docks to. */
@@ -49,6 +50,13 @@ interface CollapsiblePanelProps {
49
50
  label?: string;
50
51
  /** Panel content. */
51
52
  children?: SafeHtml | readonly SafeHtml[];
53
+ separator?: ResizableRegionSeparator;
54
+ collapseMotion?: ResizableRegionCollapseMotion;
55
+ contentOverflow?: ResizableRegionContentOverflow;
56
+ presentation?: ResizableRegionPresentation;
57
+ /** Control shown in a safe-area-aware viewport corner while collapsed. */
58
+ restoreControl?: SafeHtml;
59
+ restorePosition?: ResizableRegionRestorePosition;
52
60
  className?: string;
53
61
  }
54
62
  /**
@@ -61,6 +69,6 @@ interface CollapsiblePanelProps {
61
69
  * and persistence semantics, and with `CollapsiblePanelToggle` for the standard
62
70
  * affordance. See `docs/24-collapsible-panel.md`.
63
71
  */
64
- declare function CollapsiblePanel({ id, side, collapsed, size, label, children, className, }: CollapsiblePanelProps): SafeHtml;
72
+ declare function CollapsiblePanel({ id, side, collapsed, size, label, children, separator, collapseMotion, contentOverflow, presentation, restoreControl, restorePosition, className, }: CollapsiblePanelProps): SafeHtml;
65
73
 
66
74
  export { CollapsiblePanel, type CollapsiblePanelProps, type CollapsiblePanelSide, CollapsiblePanelToggle, type CollapsiblePanelToggleProps, collapsiblePanelToggleIcon };
@@ -1,6 +1,6 @@
1
1
  import { LucideIcon } from './chunk-W2FK7ZNY.js';
2
2
  import { PanelLeftOpen, PanelLeftClose, PanelRightOpen, PanelRightClose, PanelBottomOpen, PanelBottomClose } from 'lucide';
3
- import { jsx } from 'kerfjs/jsx-runtime';
3
+ import { jsx, jsxs, Fragment } from 'kerfjs/jsx-runtime';
4
4
 
5
5
  function collapsiblePanelToggleIcon(side, collapsed) {
6
6
  if (side === "left")
@@ -39,23 +39,44 @@ function CollapsiblePanel({
39
39
  size,
40
40
  label,
41
41
  children,
42
+ separator = "auto",
43
+ collapseMotion = "slide",
44
+ contentOverflow = "clip",
45
+ presentation = "inline",
46
+ restoreControl,
47
+ restorePosition = side === "left" ? "bottom-start" : "bottom-end",
42
48
  className = ""
43
49
  }) {
44
50
  const sizeVar = side === "bottom" ? "--kui-collapsible-panel-height" : "--kui-collapsible-panel-width";
45
- return /* @__PURE__ */ jsx(
46
- "aside",
47
- {
48
- class: `kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim(),
49
- "data-component": "collapsible-panel",
50
- "data-collapsible-panel": id,
51
- "data-side": side,
52
- "data-collapsed": String(collapsed),
53
- "aria-label": label || void 0,
54
- "aria-hidden": collapsed ? "true" : void 0,
55
- style: size ? `${sizeVar}: ${size}px` : void 0,
56
- children: /* @__PURE__ */ jsx("div", { class: "kui-collapsible-panel__content", children })
57
- }
58
- );
51
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
52
+ /* @__PURE__ */ jsx(
53
+ "aside",
54
+ {
55
+ class: `kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim(),
56
+ "data-component": "collapsible-panel",
57
+ "data-collapsible-panel": id,
58
+ "data-side": side,
59
+ "data-collapsed": String(collapsed),
60
+ "data-separator": separator,
61
+ "data-collapse-motion": collapseMotion,
62
+ "data-content-overflow": contentOverflow,
63
+ "data-presentation": presentation,
64
+ "aria-label": label || void 0,
65
+ "aria-hidden": collapsed || presentation === "hidden" ? "true" : void 0,
66
+ style: size ? `${sizeVar}: ${size}px` : void 0,
67
+ children: /* @__PURE__ */ jsx("div", { class: "kui-collapsible-panel__content", children })
68
+ }
69
+ ),
70
+ collapsed && restoreControl && presentation !== "hidden" && /* @__PURE__ */ jsx(
71
+ "div",
72
+ {
73
+ class: "kui-collapsible-panel__restore",
74
+ "data-panel-restore": id,
75
+ "data-position": restorePosition,
76
+ children: restoreControl
77
+ }
78
+ )
79
+ ] });
59
80
  }
60
81
 
61
82
  export { CollapsiblePanel, CollapsiblePanelToggle, collapsiblePanelToggleIcon };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/collapsible-panel.tsx"],"names":[],"mappings":";;;;AAsBO,SAAS,0BAAA,CACd,MACA,SAAA,EACkE;AAClE,EAAA,IAAI,IAAA,KAAS,MAAA;AACX,IAAA,OAAO,SAAA,GACH,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,iBAAA,EAAkB,GAC/C,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAM,kBAAA,EAAmB;AACvD,EAAA,IAAI,IAAA,KAAS,OAAA;AACX,IAAA,OAAO,SAAA,GACH,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAM,kBAAA,EAAmB,GACjD,EAAE,IAAA,EAAM,eAAA,EAAiB,IAAA,EAAM,mBAAA,EAAoB;AACzD,EAAA,OAAO,SAAA,GACH,EAAE,IAAA,EAAM,eAAA,EAAiB,IAAA,EAAM,mBAAA,EAAoB,GACnD,EAAE,IAAA,EAAM,gBAAA,EAAkB,IAAA,EAAM,oBAAA,EAAqB;AAC3D;AAuBO,SAAS,sBAAA,CAAuB;AAAA,EACrC,IAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA,GAAY;AACd,CAAA,EAAgC;AAC9B,EAAA,MAAM,KAAA,GAAQ,0BAAA,CAA2B,IAAA,EAAM,SAAS,CAAA;AACxD,EAAA,MAAM,UAAA,GAAa,KAAA,KAAU,SAAA,GAAY,QAAA,GAAW,UAAA,CAAA;AACpD,EAAA,uBACE,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,KAAA,EAAO,CAAA,8BAAA,EAAiC,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACzD,aAAA,EAAa,MAAA;AAAA,MACb,yBAAA,EAAyB,OAAA;AAAA,MACzB,eAAA,EAAe,MAAA,CAAO,CAAC,SAAS,CAAA;AAAA,MAChC,YAAA,EAAY,UAAA;AAAA,MAEZ,8BAAC,UAAA,EAAA,EAAW,IAAA,EAAM,MAAM,IAAA,EAAM,IAAA,EAAM,MAAM,IAAA,EAAM;AAAA;AAAA,GAClD;AAEJ;AA4BO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,EAAA;AAAA,EACA,IAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,IAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAAY;AACd,CAAA,EAA0B;AACxB,EAAA,MAAM,OAAA,GACJ,IAAA,KAAS,QAAA,GACL,gCAAA,GACA,+BAAA;AACN,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,OAAO,CAAA,6CAAA,EAAgD,IAAI,CAAA,CAAA,EAAI,SAAS,GAAG,IAAA,EAAK;AAAA,MAChF,gBAAA,EAAe,mBAAA;AAAA,MACf,wBAAA,EAAwB,EAAA;AAAA,MACxB,WAAA,EAAW,IAAA;AAAA,MACX,gBAAA,EAAgB,OAAO,SAAS,CAAA;AAAA,MAChC,cAAY,KAAA,IAAS,MAAA;AAAA,MACrB,aAAA,EAAa,YAAY,MAAA,GAAS,MAAA;AAAA,MAClC,OAAO,IAAA,GAAO,CAAA,EAAG,OAAO,CAAA,EAAA,EAAK,IAAI,CAAA,EAAA,CAAA,GAAO,MAAA;AAAA,MAExC,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,gCAAA,EAAkC,QAAA,EAAS;AAAA;AAAA,GACxD;AAEJ","file":"collapsible-panel.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\nimport {\n PanelBottomClose,\n PanelBottomOpen,\n PanelLeftClose,\n PanelLeftOpen,\n PanelRightClose,\n PanelRightOpen,\n} from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.js';\n\n/** Which edge a {@link CollapsiblePanel} docks to. */\nexport type CollapsiblePanelSide = 'left' | 'right' | 'bottom';\n\n/**\n * The standard collapse/expand icon for a panel `side` and `collapsed` state,\n * so every app's sidebars and drawers use one recognizable convention:\n * `PanelLeft*` for a left rail, `PanelRight*` for a right rail, `PanelBottom*`\n * for a bottom drawer — the `Close` glyph while open, the `Open` glyph while\n * collapsed. Exposed so an app can render its own toggle affordance.\n */\nexport function collapsiblePanelToggleIcon(\n side: CollapsiblePanelSide,\n collapsed: boolean,\n): { icon: Parameters<typeof LucideIcon>[0]['icon']; name: string } {\n if (side === 'left')\n return collapsed\n ? { icon: PanelLeftOpen, name: 'panel-left-open' }\n : { icon: PanelLeftClose, name: 'panel-left-close' };\n if (side === 'right')\n return collapsed\n ? { icon: PanelRightOpen, name: 'panel-right-open' }\n : { icon: PanelRightClose, name: 'panel-right-close' };\n return collapsed\n ? { icon: PanelBottomOpen, name: 'panel-bottom-open' }\n : { icon: PanelBottomClose, name: 'panel-bottom-close' };\n}\n\nexport interface CollapsiblePanelToggleProps {\n /** The panel this toggle controls. */\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state (drives the icon direction). */\n collapsed: boolean;\n /** `data-action` the button carries so `wireSidebar` can delegate its click. */\n action: string;\n /** The panel id the button targets (`data-tab-panel`-style: `data-collapsible-panel`). */\n panelId?: string;\n /** Accessible label; defaults to \"Collapse\"/\"Expand\". */\n label?: string;\n className?: string;\n}\n\n/**\n * A standard collapse/expand toggle button for a {@link CollapsiblePanel}: the\n * recognizable per-side icon (see {@link collapsiblePanelToggleIcon}) plus the\n * `data-action` / `aria-expanded` `wireSidebar` reads. Placement is the app's —\n * put it in the panel's own header (to collapse) and somewhere always-visible\n * (to expand while collapsed).\n */\nexport function CollapsiblePanelToggle({\n side,\n collapsed,\n action,\n panelId,\n label,\n className = '',\n}: CollapsiblePanelToggleProps) {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n const accessible = label ?? (collapsed ? 'Expand' : 'Collapse');\n return (\n <button\n type=\"button\"\n class={`kui-collapsible-panel__toggle ${className}`.trim()}\n data-action={action}\n data-collapsible-target={panelId}\n aria-expanded={String(!collapsed)}\n aria-label={accessible}\n >\n <LucideIcon icon={glyph.icon} name={glyph.name} />\n </button>\n );\n}\n\nexport interface CollapsiblePanelProps {\n /** A stable id for the panel — `wireSidebar` targets it and toggles reference it. */\n id: string;\n /** Which edge the panel docks to: a left/right rail or a bottom drawer. */\n side: CollapsiblePanelSide;\n /** Whether the panel is currently collapsed (the app owns this signal). */\n collapsed?: boolean;\n /** Rail width or drawer height in px. Overrides the CSS default. */\n size?: number;\n /** Accessible label for the panel region. */\n label?: string;\n /** Panel content. */\n children?: SafeHtml | readonly SafeHtml[];\n className?: string;\n}\n\n/**\n * A standalone collapsible side rail or bottom drawer, outside the full\n * {@link Workbench} shell. It owns only the presentation: a fixed-size content\n * area that stays laid out while the panel's track snaps to zero and the content\n * slides out via `transform` (one reflow, composited — the same technique\n * `Workbench` and the catalog sidebar use). The app owns the `collapsed` signal;\n * pair it with `wireSidebar` for the toggle, focus, compact-overlay, keyboard,\n * and persistence semantics, and with `CollapsiblePanelToggle` for the standard\n * affordance. See `docs/24-collapsible-panel.md`.\n */\nexport function CollapsiblePanel({\n id,\n side,\n collapsed = false,\n size,\n label,\n children,\n className = '',\n}: CollapsiblePanelProps) {\n const sizeVar =\n side === 'bottom'\n ? '--kui-collapsible-panel-height'\n : '--kui-collapsible-panel-width';\n return (\n <aside\n class={`kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim()}\n data-component=\"collapsible-panel\"\n data-collapsible-panel={id}\n data-side={side}\n data-collapsed={String(collapsed)}\n aria-label={label || undefined}\n aria-hidden={collapsed ? 'true' : undefined}\n style={size ? `${sizeVar}: ${size}px` : undefined}\n >\n <div class=\"kui-collapsible-panel__content\">{children}</div>\n </aside>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/collapsible-panel.tsx"],"names":[],"mappings":"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","file":"collapsible-panel.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\nimport {\n PanelBottomClose,\n PanelBottomOpen,\n PanelLeftClose,\n PanelLeftOpen,\n PanelRightClose,\n PanelRightOpen,\n} from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type {\n ResizableRegionCollapseMotion,\n ResizableRegionContentOverflow,\n ResizableRegionPresentation,\n ResizableRegionRestorePosition,\n ResizableRegionSeparator,\n} from './resizable-region.js';\n\n/** Which edge a {@link CollapsiblePanel} docks to. */\nexport type CollapsiblePanelSide = 'left' | 'right' | 'bottom';\n\n/**\n * The standard collapse/expand icon for a panel `side` and `collapsed` state,\n * so every app's sidebars and drawers use one recognizable convention:\n * `PanelLeft*` for a left rail, `PanelRight*` for a right rail, `PanelBottom*`\n * for a bottom drawer — the `Close` glyph while open, the `Open` glyph while\n * collapsed. Exposed so an app can render its own toggle affordance.\n */\nexport function collapsiblePanelToggleIcon(\n side: CollapsiblePanelSide,\n collapsed: boolean,\n): { icon: Parameters<typeof LucideIcon>[0]['icon']; name: string } {\n if (side === 'left')\n return collapsed\n ? { icon: PanelLeftOpen, name: 'panel-left-open' }\n : { icon: PanelLeftClose, name: 'panel-left-close' };\n if (side === 'right')\n return collapsed\n ? { icon: PanelRightOpen, name: 'panel-right-open' }\n : { icon: PanelRightClose, name: 'panel-right-close' };\n return collapsed\n ? { icon: PanelBottomOpen, name: 'panel-bottom-open' }\n : { icon: PanelBottomClose, name: 'panel-bottom-close' };\n}\n\nexport interface CollapsiblePanelToggleProps {\n /** The panel this toggle controls. */\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state (drives the icon direction). */\n collapsed: boolean;\n /** `data-action` the button carries so `wireSidebar` can delegate its click. */\n action: string;\n /** The panel id the button targets (`data-tab-panel`-style: `data-collapsible-panel`). */\n panelId?: string;\n /** Accessible label; defaults to \"Collapse\"/\"Expand\". */\n label?: string;\n className?: string;\n}\n\n/**\n * A standard collapse/expand toggle button for a {@link CollapsiblePanel}: the\n * recognizable per-side icon (see {@link collapsiblePanelToggleIcon}) plus the\n * `data-action` / `aria-expanded` `wireSidebar` reads. Placement is the app's —\n * put it in the panel's own header (to collapse) and somewhere always-visible\n * (to expand while collapsed).\n */\nexport function CollapsiblePanelToggle({\n side,\n collapsed,\n action,\n panelId,\n label,\n className = '',\n}: CollapsiblePanelToggleProps) {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n const accessible = label ?? (collapsed ? 'Expand' : 'Collapse');\n return (\n <button\n type=\"button\"\n class={`kui-collapsible-panel__toggle ${className}`.trim()}\n data-action={action}\n data-collapsible-target={panelId}\n aria-expanded={String(!collapsed)}\n aria-label={accessible}\n >\n <LucideIcon icon={glyph.icon} name={glyph.name} />\n </button>\n );\n}\n\nexport interface CollapsiblePanelProps {\n /** A stable id for the panel — `wireSidebar` targets it and toggles reference it. */\n id: string;\n /** Which edge the panel docks to: a left/right rail or a bottom drawer. */\n side: CollapsiblePanelSide;\n /** Whether the panel is currently collapsed (the app owns this signal). */\n collapsed?: boolean;\n /** Rail width or drawer height in px. Overrides the CSS default. */\n size?: number;\n /** Accessible label for the panel region. */\n label?: string;\n /** Panel content. */\n children?: SafeHtml | readonly SafeHtml[];\n separator?: ResizableRegionSeparator;\n collapseMotion?: ResizableRegionCollapseMotion;\n contentOverflow?: ResizableRegionContentOverflow;\n presentation?: ResizableRegionPresentation;\n /** Control shown in a safe-area-aware viewport corner while collapsed. */\n restoreControl?: SafeHtml;\n restorePosition?: ResizableRegionRestorePosition;\n className?: string;\n}\n\n/**\n * A standalone collapsible side rail or bottom drawer, outside the full\n * {@link Workbench} shell. It owns only the presentation: a fixed-size content\n * area that stays laid out while the panel's track snaps to zero and the content\n * slides out via `transform` (one reflow, composited — the same technique\n * `Workbench` and the catalog sidebar use). The app owns the `collapsed` signal;\n * pair it with `wireSidebar` for the toggle, focus, compact-overlay, keyboard,\n * and persistence semantics, and with `CollapsiblePanelToggle` for the standard\n * affordance. See `docs/24-collapsible-panel.md`.\n */\nexport function CollapsiblePanel({\n id,\n side,\n collapsed = false,\n size,\n label,\n children,\n separator = 'auto',\n collapseMotion = 'slide',\n contentOverflow = 'clip',\n presentation = 'inline',\n restoreControl,\n restorePosition = side === 'left' ? 'bottom-start' : 'bottom-end',\n className = '',\n}: CollapsiblePanelProps) {\n const sizeVar =\n side === 'bottom'\n ? '--kui-collapsible-panel-height'\n : '--kui-collapsible-panel-width';\n return (\n <>\n <aside\n class={`kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim()}\n data-component=\"collapsible-panel\"\n data-collapsible-panel={id}\n data-side={side}\n data-collapsed={String(collapsed)}\n data-separator={separator}\n data-collapse-motion={collapseMotion}\n data-content-overflow={contentOverflow}\n data-presentation={presentation}\n aria-label={label || undefined}\n aria-hidden={\n collapsed || presentation === 'hidden' ? 'true' : undefined\n }\n style={size ? `${sizeVar}: ${size}px` : undefined}\n >\n <div class=\"kui-collapsible-panel__content\">{children}</div>\n </aside>\n {collapsed && restoreControl && presentation !== 'hidden' && (\n <div\n class=\"kui-collapsible-panel__restore\"\n data-panel-restore={id}\n data-position={restorePosition}\n >\n {restoreControl}\n </div>\n )}\n </>\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ /** Canonical physical edge combinations for components that draw dividers. */
2
+ type DividerSides = '' | 't' | 'r' | 'b' | 'l' | 'tr' | 'tb' | 'tl' | 'rb' | 'rl' | 'bl' | 'trb' | 'trl' | 'tbl' | 'rbl' | 'trbl';
3
+
4
+ export type { DividerSides as D };