@kerfjs/ui 4.4.1 → 5.0.0-beta.11

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 (386) hide show
  1. package/README.md +241 -10
  2. package/ai/component-catalog.json +4828 -0
  3. package/ai/component-catalog.schema.json +79 -0
  4. package/ai/public-api-signatures-v1.md +1371 -0
  5. package/ai/skill.md +73 -11
  6. package/ai/webawesome-jsx-signatures-v1.md +106 -0
  7. package/dist/app-tab.d.ts +14 -2
  8. package/dist/app-tab.js +3 -1
  9. package/dist/browser/app-tab.js +3 -2
  10. package/dist/browser/disclosure-arrow.js +4 -0
  11. package/dist/browser/empty-state.js +3 -3
  12. package/dist/browser/floating-toolbar.js +3 -0
  13. package/dist/browser/list-action-row.js +4 -0
  14. package/dist/browser/list-header.js +6 -0
  15. package/dist/browser/list-item.js +4 -0
  16. package/dist/browser/loading-spinner.js +2 -2
  17. package/dist/browser/lucide-icon.js +2 -2
  18. package/dist/browser/panel-header.js +7 -0
  19. package/dist/browser/resizable-region.js +2 -2
  20. package/dist/browser/segmented-control.js +3 -2
  21. package/dist/browser/select.js +4 -3
  22. package/dist/browser/skeleton.js +3 -0
  23. package/dist/browser/state-banner.js +3 -2
  24. package/dist/browser/tab-bar.js +2 -2
  25. package/dist/browser/token-search-field.js +4 -0
  26. package/dist/browser/toolbar-control-group.js +2 -2
  27. package/dist/browser/toolbar-text.js +3 -2
  28. package/dist/browser/toolbar.js +2 -2
  29. package/dist/browser/value-table.js +3 -2
  30. package/dist/catalog.d.ts +119 -0
  31. package/dist/catalog.js +146 -0
  32. package/dist/catalog.js.map +1 -0
  33. package/dist/chunk-2Z5TWHKQ.js +34 -0
  34. package/dist/chunk-2Z5TWHKQ.js.map +1 -0
  35. package/dist/chunk-37T3VNIZ.js +19 -0
  36. package/dist/chunk-37T3VNIZ.js.map +1 -0
  37. package/dist/chunk-56RJXPHG.js +43 -0
  38. package/dist/chunk-56RJXPHG.js.map +1 -0
  39. package/dist/chunk-5ATCDSQS.js +42 -0
  40. package/dist/chunk-5ATCDSQS.js.map +1 -0
  41. package/dist/chunk-5E2HVJ33.js +10 -0
  42. package/dist/chunk-5E2HVJ33.js.map +1 -0
  43. package/dist/chunk-7BR3DO2A.js +31 -0
  44. package/dist/chunk-7BR3DO2A.js.map +1 -0
  45. package/dist/chunk-7JB7VPRI.js +34 -0
  46. package/dist/chunk-7JB7VPRI.js.map +1 -0
  47. package/dist/chunk-7LDCTU7D.js +134 -0
  48. package/dist/chunk-7LDCTU7D.js.map +1 -0
  49. package/dist/{chunk-4HHCYSGT.js → chunk-AQNKJRFH.js} +2 -2
  50. package/dist/{chunk-4HHCYSGT.js.map → chunk-AQNKJRFH.js.map} +1 -1
  51. package/dist/{chunk-MBR3TYNL.js → chunk-AVZHJN6C.js} +3 -3
  52. package/dist/chunk-AVZHJN6C.js.map +1 -0
  53. package/dist/chunk-B24C4A6T.js +22 -0
  54. package/dist/chunk-B24C4A6T.js.map +1 -0
  55. package/dist/chunk-BLK3UEEI.js +23 -0
  56. package/dist/chunk-BLK3UEEI.js.map +1 -0
  57. package/dist/chunk-CH4SQ6H5.js +39 -0
  58. package/dist/chunk-CH4SQ6H5.js.map +1 -0
  59. package/dist/chunk-I7INRJO4.js +17 -0
  60. package/dist/chunk-I7INRJO4.js.map +1 -0
  61. package/dist/chunk-L4OKFDJY.js +24 -0
  62. package/dist/chunk-L4OKFDJY.js.map +1 -0
  63. package/dist/chunk-LCOBDOCC.js +265 -0
  64. package/dist/chunk-LCOBDOCC.js.map +1 -0
  65. package/dist/{chunk-3O7ZEUW2.js → chunk-M5JRI6MN.js} +3 -3
  66. package/dist/chunk-M5JRI6MN.js.map +1 -0
  67. package/dist/{chunk-MFKMHK5W.js → chunk-RNPGFQ33.js} +3 -3
  68. package/dist/chunk-RNPGFQ33.js.map +1 -0
  69. package/dist/chunk-RUNWEPR4.js +10 -0
  70. package/dist/chunk-RUNWEPR4.js.map +1 -0
  71. package/dist/chunk-XE5ZLPCC.js +20 -0
  72. package/dist/chunk-XE5ZLPCC.js.map +1 -0
  73. package/dist/{chunk-MQIZAD4A.js → chunk-XXMOARTH.js} +5 -3
  74. package/dist/chunk-XXMOARTH.js.map +1 -0
  75. package/dist/{chunk-TRNBHPNW.js → chunk-YGN7OMLT.js} +11 -8
  76. package/dist/chunk-YGN7OMLT.js.map +1 -0
  77. package/dist/collapsible-panel.d.ts +66 -0
  78. package/dist/collapsible-panel.js +22 -0
  79. package/dist/collapsible-panel.js.map +1 -0
  80. package/dist/device-class.d.ts +62 -0
  81. package/dist/device-class.js +75 -0
  82. package/dist/device-class.js.map +1 -0
  83. package/dist/disclosure-arrow.d.ts +14 -0
  84. package/dist/disclosure-arrow.js +4 -0
  85. package/dist/disclosure-arrow.js.map +1 -0
  86. package/dist/floating-toolbar.d.ts +28 -0
  87. package/dist/floating-toolbar.js +3 -0
  88. package/dist/floating-toolbar.js.map +1 -0
  89. package/dist/index.d.ts +11 -6
  90. package/dist/index.js +22 -16
  91. package/dist/list-action-row.d.ts +52 -0
  92. package/dist/list-action-row.js +5 -0
  93. package/dist/list-action-row.js.map +1 -0
  94. package/dist/list-header.d.ts +43 -0
  95. package/dist/list-header.js +7 -0
  96. package/dist/list-header.js.map +1 -0
  97. package/dist/list-item.d.ts +33 -0
  98. package/dist/list-item.js +5 -0
  99. package/dist/list-item.js.map +1 -0
  100. package/dist/nav-stack.d.ts +38 -0
  101. package/dist/nav-stack.js +5 -0
  102. package/dist/nav-stack.js.map +1 -0
  103. package/dist/panel-header.d.ts +36 -0
  104. package/dist/panel-header.js +7 -0
  105. package/dist/panel-header.js.map +1 -0
  106. package/dist/resizable-region.d.ts +3 -1
  107. package/dist/resizable-region.js +1 -1
  108. package/dist/segmented-control.d.ts +3 -1
  109. package/dist/segmented-control.js +2 -1
  110. package/dist/select-register.d.ts +5 -1
  111. package/dist/select-register.js +3 -0
  112. package/dist/select-register.js.map +1 -1
  113. package/dist/select.d.ts +5 -2
  114. package/dist/select.js +2 -1
  115. package/dist/skeleton.d.ts +24 -0
  116. package/dist/skeleton.js +3 -0
  117. package/dist/skeleton.js.map +1 -0
  118. package/dist/split-view.d.ts +42 -0
  119. package/dist/split-view.js +21 -0
  120. package/dist/split-view.js.map +1 -0
  121. package/dist/state-banner.d.ts +3 -1
  122. package/dist/state-banner.js +2 -1
  123. package/dist/styles/app-tab.css +152 -0
  124. package/dist/styles/catalog.css +522 -0
  125. package/dist/styles/collapsible-panel.css +146 -0
  126. package/dist/styles/disclosure-arrow.css +23 -0
  127. package/dist/styles/empty-state.css +47 -0
  128. package/dist/styles/floating-toolbar.css +38 -0
  129. package/dist/styles/foundation.css +347 -0
  130. package/dist/styles/layout.css +73 -0
  131. package/dist/styles/list-action-row.css +160 -0
  132. package/dist/styles/list-header.css +160 -0
  133. package/dist/styles/list-item.css +123 -0
  134. package/dist/styles/loading-spinner.css +21 -0
  135. package/dist/styles/lucide-icon.css +6 -0
  136. package/dist/styles/nav-stack.css +111 -0
  137. package/dist/styles/panel-header.css +64 -0
  138. package/dist/styles/resizable-region.css +111 -0
  139. package/{src → dist/styles}/segmented-control.css +62 -31
  140. package/dist/styles/select.css +138 -0
  141. package/dist/styles/skeleton.css +31 -0
  142. package/dist/styles/split-view.css +35 -0
  143. package/dist/styles/state-banner.css +173 -0
  144. package/dist/styles/styles.css +23 -0
  145. package/dist/styles/tab-bar.css +45 -0
  146. package/dist/styles/tab-scaffold.css +84 -0
  147. package/dist/styles/token-search-field.css +289 -0
  148. package/dist/styles/toolbar-control-group.css +225 -0
  149. package/dist/styles/toolbar-text.css +40 -0
  150. package/dist/styles/toolbar.css +61 -0
  151. package/dist/styles/value-table.css +75 -0
  152. package/{src → dist/styles}/webawesome.css +119 -29
  153. package/dist/styles/workbench.css +94 -0
  154. package/dist/tab-bar.d.ts +8 -1
  155. package/dist/tab-bar.js +1 -1
  156. package/dist/tab-scaffold.d.ts +30 -0
  157. package/dist/tab-scaffold.js +16 -0
  158. package/dist/tab-scaffold.js.map +1 -0
  159. package/dist/token-search-field.d.ts +43 -0
  160. package/dist/token-search-field.js +4 -0
  161. package/dist/token-search-field.js.map +1 -0
  162. package/dist/toolbar-control-group.d.ts +3 -1
  163. package/dist/toolbar-control-group.js +1 -1
  164. package/dist/toolbar-text.d.ts +15 -3
  165. package/dist/toolbar-text.js +2 -1
  166. package/dist/value-table.d.ts +12 -2
  167. package/dist/value-table.js +2 -1
  168. package/dist/webawesome.d.ts +100 -0
  169. package/dist/webawesome.js +3 -0
  170. package/dist/webawesome.js.map +1 -0
  171. package/dist/wire-catalog.d.ts +26 -0
  172. package/dist/wire-catalog.js +48 -0
  173. package/dist/wire-catalog.js.map +1 -0
  174. package/dist/wire-nav-stack.d.ts +15 -0
  175. package/dist/wire-nav-stack.js +88 -0
  176. package/dist/wire-nav-stack.js.map +1 -0
  177. package/dist/wire-resizable-regions.js +1 -1
  178. package/dist/wire-sidebar.d.ts +43 -0
  179. package/dist/wire-sidebar.js +117 -0
  180. package/dist/wire-sidebar.js.map +1 -0
  181. package/dist/wire-tab-bars.d.ts +15 -2
  182. package/dist/wire-tab-bars.js +1 -1
  183. package/dist/wire-tab-scaffold.d.ts +11 -0
  184. package/dist/wire-tab-scaffold.js +16 -0
  185. package/dist/wire-tab-scaffold.js.map +1 -0
  186. package/dist/wire-token-search-fields.d.ts +106 -0
  187. package/dist/wire-token-search-fields.js +5 -0
  188. package/dist/wire-token-search-fields.js.map +1 -0
  189. package/dist/workbench.d.ts +33 -0
  190. package/dist/workbench.js +17 -0
  191. package/dist/workbench.js.map +1 -0
  192. package/docs/accessibility.md +112 -3
  193. package/docs/app-layouts.md +61 -0
  194. package/docs/catalog.md +155 -0
  195. package/docs/collapsible-panel.md +102 -0
  196. package/docs/component-contract.md +169 -4
  197. package/docs/component-selection.md +186 -0
  198. package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
  199. package/docs/design/templates/empty-state/filtered.svg +1 -0
  200. package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
  201. package/docs/design/templates/empty-state/with-action.svg +1 -0
  202. package/docs/design/templates/empty-state-dark.svg +7 -0
  203. package/docs/design/templates/empty-state.svg +7 -0
  204. package/docs/design/templates/list-action-row/default-dark.svg +1 -0
  205. package/docs/design/templates/list-action-row/default.svg +1 -0
  206. package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
  207. package/docs/design/templates/list-action-row/selected.svg +1 -0
  208. package/docs/design/templates/list-action-row-dark.svg +7 -0
  209. package/docs/design/templates/list-action-row.svg +7 -0
  210. package/docs/design/templates/list-header/action-dark.svg +1 -0
  211. package/docs/design/templates/list-header/action.svg +1 -0
  212. package/docs/design/templates/list-header/count-dark.svg +1 -0
  213. package/docs/design/templates/list-header/count.svg +1 -0
  214. package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
  215. package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
  216. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
  217. package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
  218. package/docs/design/templates/list-header-dark.svg +11 -0
  219. package/docs/design/templates/list-header.svg +11 -0
  220. package/docs/design/templates/list-item/default-dark.svg +1 -0
  221. package/docs/design/templates/list-item/default.svg +1 -0
  222. package/docs/design/templates/list-item/multiline-dark.svg +1 -0
  223. package/docs/design/templates/list-item/multiline.svg +1 -0
  224. package/docs/design/templates/list-item/selected-dark.svg +1 -0
  225. package/docs/design/templates/list-item/selected.svg +1 -0
  226. package/docs/design/templates/list-item/trailing-dark.svg +1 -0
  227. package/docs/design/templates/list-item/trailing.svg +1 -0
  228. package/docs/design/templates/list-item-dark.svg +11 -0
  229. package/docs/design/templates/list-item.svg +11 -0
  230. package/docs/design/templates/panel-header/icon-actions-dark.svg +1 -0
  231. package/docs/design/templates/panel-header/icon-actions.svg +1 -0
  232. package/docs/design/templates/panel-header/icon-summary-actions-dark.svg +1 -0
  233. package/docs/design/templates/panel-header/icon-summary-actions.svg +1 -0
  234. package/docs/design/templates/panel-header/no-icon-dark.svg +1 -0
  235. package/docs/design/templates/panel-header/no-icon.svg +1 -0
  236. package/docs/design/templates/panel-header/page-heading-dark.svg +1 -0
  237. package/docs/design/templates/panel-header/page-heading.svg +1 -0
  238. package/docs/design/templates/panel-header/title-only-dark.svg +1 -0
  239. package/docs/design/templates/panel-header/title-only.svg +1 -0
  240. package/docs/design/templates/panel-header-dark.svg +13 -0
  241. package/docs/design/templates/panel-header.svg +13 -0
  242. package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
  243. package/docs/design/templates/segmented-control/equal.svg +1 -0
  244. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
  245. package/docs/design/templates/segmented-control/pill-small.svg +1 -0
  246. package/docs/design/templates/segmented-control-dark.svg +7 -0
  247. package/docs/design/templates/segmented-control.svg +7 -0
  248. package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
  249. package/docs/design/templates/skeleton/avatar.svg +1 -0
  250. package/docs/design/templates/skeleton/block-dark.svg +1 -0
  251. package/docs/design/templates/skeleton/block.svg +1 -0
  252. package/docs/design/templates/skeleton/lines-dark.svg +1 -0
  253. package/docs/design/templates/skeleton/lines.svg +1 -0
  254. package/docs/design/templates/skeleton-dark.svg +9 -0
  255. package/docs/design/templates/skeleton.svg +9 -0
  256. package/docs/design/templates/state-banner/danger-dark.svg +1 -0
  257. package/docs/design/templates/state-banner/danger.svg +1 -0
  258. package/docs/design/templates/state-banner/info-dark.svg +1 -0
  259. package/docs/design/templates/state-banner/info.svg +1 -0
  260. package/docs/design/templates/state-banner/success-dark.svg +1 -0
  261. package/docs/design/templates/state-banner/success.svg +1 -0
  262. package/docs/design/templates/state-banner/warning-dark.svg +1 -0
  263. package/docs/design/templates/state-banner/warning.svg +1 -0
  264. package/docs/design/templates/state-banner-dark.svg +11 -0
  265. package/docs/design/templates/state-banner.svg +11 -0
  266. package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
  267. package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
  268. package/docs/design/templates/tab-bar-dark.svg +5 -0
  269. package/docs/design/templates/tab-bar.svg +5 -0
  270. package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
  271. package/docs/design/templates/token-search-field/empty.svg +1 -0
  272. package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
  273. package/docs/design/templates/token-search-field/tokens.svg +1 -0
  274. package/docs/design/templates/token-search-field-dark.svg +7 -0
  275. package/docs/design/templates/token-search-field.svg +7 -0
  276. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
  277. package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
  278. package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
  279. package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
  280. package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
  281. package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
  282. package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
  283. package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
  284. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
  285. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
  286. package/docs/design/templates/toolbar-control-group-dark.svg +11 -0
  287. package/docs/design/templates/toolbar-control-group.svg +11 -0
  288. package/docs/design/templates/toolbar-dark.svg +5 -0
  289. package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
  290. package/docs/design/templates/toolbar-text/default.svg +1 -0
  291. package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
  292. package/docs/design/templates/toolbar-text/large.svg +1 -0
  293. package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
  294. package/docs/design/templates/toolbar-text/small.svg +1 -0
  295. package/docs/design/templates/toolbar-text-dark.svg +9 -0
  296. package/docs/design/templates/toolbar-text.svg +9 -0
  297. package/docs/design/templates/toolbar.svg +5 -0
  298. package/docs/design/templates/value-table/details-dark.svg +1 -0
  299. package/docs/design/templates/value-table/details.svg +1 -0
  300. package/docs/design/templates/value-table-dark.svg +5 -0
  301. package/docs/design/templates/value-table.svg +5 -0
  302. package/docs/design/templates.md +114 -0
  303. package/docs/design-philosophy.md +61 -1
  304. package/docs/device-class.md +54 -0
  305. package/docs/examples/command-palette-adapter.tsx +70 -0
  306. package/docs/layout.md +131 -0
  307. package/docs/nav-stack.md +47 -0
  308. package/docs/recipes.md +167 -0
  309. package/docs/split-view.md +49 -0
  310. package/docs/tab-scaffold.md +41 -0
  311. package/docs/ux-demo.md +23 -9
  312. package/docs/webawesome-theme.md +15 -0
  313. package/docs/workbench.md +47 -0
  314. package/llms.txt +123 -14
  315. package/package.json +147 -44
  316. package/ux-demo/recipes/app-shell.tsx +32 -0
  317. package/ux-demo/recipes/collapsible-sidebar.tsx +100 -0
  318. package/ux-demo/recipes/compact-toolbar.tsx +43 -0
  319. package/ux-demo/recipes/composer-form.tsx +63 -0
  320. package/ux-demo/recipes/list-detail-dialog.tsx +45 -0
  321. package/ux-demo/recipes/list-workspace-states.tsx +26 -0
  322. package/ux-demo/recipes/loaders.ts +33 -0
  323. package/ux-demo/recipes/loading-inspector.tsx +81 -0
  324. package/ux-demo/recipes/mount-recipe.ts +43 -0
  325. package/ux-demo/recipes/navigation-sidebar.tsx +26 -0
  326. package/ux-demo/recipes/navigation-stack.tsx +76 -0
  327. package/ux-demo/recipes/recipes.css +448 -0
  328. package/ux-demo/recipes/types.ts +17 -0
  329. package/ux-demo/recipes/workspace-header.tsx +12 -0
  330. package/dist/browser/dialog-header.js +0 -3
  331. package/dist/browser/menu-header.js +0 -3
  332. package/dist/browser/menu-item.js +0 -3
  333. package/dist/browser/page-header.js +0 -3
  334. package/dist/chunk-2PES33HS.js +0 -13
  335. package/dist/chunk-2PES33HS.js.map +0 -1
  336. package/dist/chunk-3O7ZEUW2.js.map +0 -1
  337. package/dist/chunk-723YNJBH.js +0 -17
  338. package/dist/chunk-723YNJBH.js.map +0 -1
  339. package/dist/chunk-GY5WH7TO.js +0 -10
  340. package/dist/chunk-GY5WH7TO.js.map +0 -1
  341. package/dist/chunk-MBR3TYNL.js.map +0 -1
  342. package/dist/chunk-MFKMHK5W.js.map +0 -1
  343. package/dist/chunk-MQIZAD4A.js.map +0 -1
  344. package/dist/chunk-NHXX4JI5.js +0 -28
  345. package/dist/chunk-NHXX4JI5.js.map +0 -1
  346. package/dist/chunk-OPCJRCYO.js +0 -19
  347. package/dist/chunk-OPCJRCYO.js.map +0 -1
  348. package/dist/chunk-T5XNMVOI.js +0 -24
  349. package/dist/chunk-T5XNMVOI.js.map +0 -1
  350. package/dist/chunk-TRNBHPNW.js.map +0 -1
  351. package/dist/chunk-VHW5YNIB.js +0 -17
  352. package/dist/chunk-VHW5YNIB.js.map +0 -1
  353. package/dist/chunk-VKH2JLDZ.js +0 -10
  354. package/dist/chunk-VKH2JLDZ.js.map +0 -1
  355. package/dist/chunk-WY4CAEPG.js +0 -14
  356. package/dist/chunk-WY4CAEPG.js.map +0 -1
  357. package/dist/dialog-header.d.ts +0 -14
  358. package/dist/dialog-header.js +0 -3
  359. package/dist/dialog-header.js.map +0 -1
  360. package/dist/menu-header.d.ts +0 -15
  361. package/dist/menu-header.js +0 -3
  362. package/dist/menu-header.js.map +0 -1
  363. package/dist/menu-item.d.ts +0 -22
  364. package/dist/menu-item.js +0 -3
  365. package/dist/menu-item.js.map +0 -1
  366. package/dist/page-header.d.ts +0 -9
  367. package/dist/page-header.js +0 -3
  368. package/dist/page-header.js.map +0 -1
  369. package/src/app-tab.css +0 -20
  370. package/src/dialog-header.css +0 -9
  371. package/src/empty-state.css +0 -6
  372. package/src/foundation.css +0 -106
  373. package/src/loading-spinner.css +0 -4
  374. package/src/lucide-icon.css +0 -1
  375. package/src/menu-header.css +0 -13
  376. package/src/menu-item.css +0 -12
  377. package/src/page-header.css +0 -3
  378. package/src/resizable-region.css +0 -19
  379. package/src/select.css +0 -18
  380. package/src/state-banner.css +0 -31
  381. package/src/styles.css +0 -18
  382. package/src/tab-bar.css +0 -4
  383. package/src/toolbar-control-group.css +0 -25
  384. package/src/toolbar-text.css +0 -4
  385. package/src/toolbar.css +0 -9
  386. package/src/value-table.css +0 -5
@@ -0,0 +1,66 @@
1
+ import { SafeHtml } from 'kerfjs';
2
+ import { LucideIcon } from './lucide-icon.js';
3
+ import 'lucide';
4
+
5
+ /** Which edge a {@link CollapsiblePanel} docks to. */
6
+ type CollapsiblePanelSide = 'left' | 'right' | 'bottom';
7
+ /**
8
+ * The standard collapse/expand icon for a panel `side` and `collapsed` state,
9
+ * so every app's sidebars and drawers use one recognizable convention:
10
+ * `PanelLeft*` for a left rail, `PanelRight*` for a right rail, `PanelBottom*`
11
+ * for a bottom drawer — the `Close` glyph while open, the `Open` glyph while
12
+ * collapsed. Exposed so an app can render its own toggle affordance.
13
+ */
14
+ declare function collapsiblePanelToggleIcon(side: CollapsiblePanelSide, collapsed: boolean): {
15
+ icon: Parameters<typeof LucideIcon>[0]['icon'];
16
+ name: string;
17
+ };
18
+ interface CollapsiblePanelToggleProps {
19
+ /** The panel this toggle controls. */
20
+ side: CollapsiblePanelSide;
21
+ /** The panel's current collapsed state (drives the icon direction). */
22
+ collapsed: boolean;
23
+ /** `data-action` the button carries so `wireSidebar` can delegate its click. */
24
+ action: string;
25
+ /** The panel id the button targets (`data-tab-panel`-style: `data-collapsible-panel`). */
26
+ panelId?: string;
27
+ /** Accessible label; defaults to "Collapse"/"Expand". */
28
+ label?: string;
29
+ className?: string;
30
+ }
31
+ /**
32
+ * A standard collapse/expand toggle button for a {@link CollapsiblePanel}: the
33
+ * recognizable per-side icon (see {@link collapsiblePanelToggleIcon}) plus the
34
+ * `data-action` / `aria-expanded` `wireSidebar` reads. Placement is the app's —
35
+ * put it in the panel's own header (to collapse) and somewhere always-visible
36
+ * (to expand while collapsed).
37
+ */
38
+ declare function CollapsiblePanelToggle({ side, collapsed, action, panelId, label, className }: CollapsiblePanelToggleProps): SafeHtml;
39
+ interface CollapsiblePanelProps {
40
+ /** A stable id for the panel — `wireSidebar` targets it and toggles reference it. */
41
+ id: string;
42
+ /** Which edge the panel docks to: a left/right rail or a bottom drawer. */
43
+ side: CollapsiblePanelSide;
44
+ /** Whether the panel is currently collapsed (the app owns this signal). */
45
+ collapsed?: boolean;
46
+ /** Rail width or drawer height in px. Overrides the CSS default. */
47
+ size?: number;
48
+ /** Accessible label for the panel region. */
49
+ label?: string;
50
+ /** Panel content. */
51
+ children?: SafeHtml | readonly SafeHtml[];
52
+ className?: string;
53
+ }
54
+ /**
55
+ * A standalone collapsible side rail or bottom drawer, outside the full
56
+ * {@link Workbench} shell. It owns only the presentation: a fixed-size content
57
+ * area that stays laid out while the panel's track snaps to zero and the content
58
+ * slides out via `transform` (one reflow, composited — the same technique
59
+ * `Workbench` and the catalog sidebar use). The app owns the `collapsed` signal;
60
+ * pair it with `wireSidebar` for the toggle, focus, compact-overlay, keyboard,
61
+ * and persistence semantics, and with `CollapsiblePanelToggle` for the standard
62
+ * affordance. See `docs/24-collapsible-panel.md`.
63
+ */
64
+ declare function CollapsiblePanel({ id, side, collapsed, size, label, children, className }: CollapsiblePanelProps): SafeHtml;
65
+
66
+ export { CollapsiblePanel, type CollapsiblePanelProps, type CollapsiblePanelSide, CollapsiblePanelToggle, type CollapsiblePanelToggleProps, collapsiblePanelToggleIcon };
@@ -0,0 +1,22 @@
1
+ import { LucideIcon } from './chunk-W2FK7ZNY.js';
2
+ import { PanelLeftOpen, PanelLeftClose, PanelRightOpen, PanelRightClose, PanelBottomOpen, PanelBottomClose } from 'lucide';
3
+ import { jsx } from 'kerfjs/jsx-runtime';
4
+
5
+ function collapsiblePanelToggleIcon(side, collapsed) {
6
+ if (side === "left") return collapsed ? { icon: PanelLeftOpen, name: "panel-left-open" } : { icon: PanelLeftClose, name: "panel-left-close" };
7
+ if (side === "right") return collapsed ? { icon: PanelRightOpen, name: "panel-right-open" } : { icon: PanelRightClose, name: "panel-right-close" };
8
+ return collapsed ? { icon: PanelBottomOpen, name: "panel-bottom-open" } : { icon: PanelBottomClose, name: "panel-bottom-close" };
9
+ }
10
+ function CollapsiblePanelToggle({ side, collapsed, action, panelId, label, className = "" }) {
11
+ const glyph = collapsiblePanelToggleIcon(side, collapsed);
12
+ const accessible = label ?? (collapsed ? "Expand" : "Collapse");
13
+ return /* @__PURE__ */ jsx("button", { type: "button", class: `kui-collapsible-panel__toggle ${className}`.trim(), "data-action": action, "data-collapsible-target": panelId, "aria-expanded": String(!collapsed), "aria-label": accessible, children: /* @__PURE__ */ jsx(LucideIcon, { icon: glyph.icon, name: glyph.name }) });
14
+ }
15
+ function CollapsiblePanel({ id, side, collapsed = false, size, label, children, className = "" }) {
16
+ const sizeVar = side === "bottom" ? "--kui-collapsible-panel-height" : "--kui-collapsible-panel-width";
17
+ return /* @__PURE__ */ jsx("aside", { class: `kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim(), "data-component": "collapsible-panel", "data-collapsible-panel": id, "data-side": side, "data-collapsed": String(collapsed), "aria-label": label || void 0, "aria-hidden": collapsed ? "true" : void 0, style: size ? `${sizeVar}: ${size}px` : void 0, children: /* @__PURE__ */ jsx("div", { class: "kui-collapsible-panel__content", children }) });
18
+ }
19
+
20
+ export { CollapsiblePanel, CollapsiblePanelToggle, collapsiblePanelToggleIcon };
21
+
22
+ //# sourceMappingURL=collapsible-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/collapsible-panel.tsx"],"names":[],"mappings":";;;;AAeO,SAAS,0BAAA,CAA2B,MAA4B,SAAA,EAAsF;AAC3J,EAAA,IAAI,IAAA,KAAS,MAAA,EAAQ,OAAO,SAAA,GAAY,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,iBAAA,EAAkB,GAAI,EAAE,IAAA,EAAM,cAAA,EAAgB,MAAM,kBAAA,EAAmB;AAC5I,EAAA,IAAI,IAAA,KAAS,OAAA,EAAS,OAAO,SAAA,GAAY,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAM,kBAAA,EAAmB,GAAI,EAAE,IAAA,EAAM,eAAA,EAAiB,MAAM,mBAAA,EAAoB;AACjJ,EAAA,OAAO,SAAA,GAAY,EAAE,IAAA,EAAM,eAAA,EAAiB,IAAA,EAAM,mBAAA,EAAoB,GAAI,EAAE,IAAA,EAAM,gBAAA,EAAkB,IAAA,EAAM,oBAAA,EAAqB;AACjI;AAuBO,SAAS,sBAAA,CAAuB,EAAE,IAAA,EAAM,SAAA,EAAW,QAAQ,OAAA,EAAS,KAAA,EAAO,SAAA,GAAY,EAAA,EAAG,EAAgC;AAC/H,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,uBAAO,GAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,KAAA,EAAO,CAAA,8BAAA,EAAiC,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK,EAAG,aAAA,EAAa,MAAA,EAAQ,yBAAA,EAAyB,OAAA,EAAS,eAAA,EAAe,MAAA,CAAO,CAAC,SAAS,CAAA,EAAG,YAAA,EAAY,UAAA,EAAY,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,IAAA,EAAM,KAAA,CAAM,IAAA,EAAM,IAAA,EAAM,KAAA,CAAM,MAAM,CAAA,EAAE,CAAA;AAC/P;AA4BO,SAAS,gBAAA,CAAiB,EAAE,EAAA,EAAI,IAAA,EAAM,SAAA,GAAY,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,QAAA,EAAU,SAAA,GAAY,EAAA,EAAG,EAA0B;AAC9H,EAAA,MAAM,OAAA,GAAU,IAAA,KAAS,QAAA,GAAW,gCAAA,GAAmC,+BAAA;AACvE,EAAA,2BAAQ,OAAA,EAAA,EAAM,KAAA,EAAO,gDAAgD,IAAI,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK,EAAG,gBAAA,EAAe,qBAAoB,wBAAA,EAAwB,EAAA,EAAI,aAAW,IAAA,EAAM,gBAAA,EAAgB,OAAO,SAAS,CAAA,EAAG,YAAA,EAAY,KAAA,IAAS,QAAW,aAAA,EAAa,SAAA,GAAY,SAAS,MAAA,EAAW,KAAA,EAAO,OAAO,CAAA,EAAG,OAAO,CAAA,EAAA,EAAK,IAAI,OAAO,MAAA,EACvU,QAAA,kBAAA,GAAA,CAAC,SAAI,KAAA,EAAM,gCAAA,EAAkC,UAAS,CAAA,EACxD,CAAA;AACF","file":"collapsible-panel.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\nimport { PanelBottomClose, PanelBottomOpen, PanelLeftClose, PanelLeftOpen, PanelRightClose, PanelRightOpen } 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(side: CollapsiblePanelSide, collapsed: boolean): { icon: Parameters<typeof LucideIcon>[0]['icon']; name: string } {\n if (side === 'left') return collapsed ? { icon: PanelLeftOpen, name: 'panel-left-open' } : { icon: PanelLeftClose, name: 'panel-left-close' };\n if (side === 'right') return collapsed ? { icon: PanelRightOpen, name: 'panel-right-open' } : { icon: PanelRightClose, name: 'panel-right-close' };\n return collapsed ? { icon: PanelBottomOpen, name: 'panel-bottom-open' } : { 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({ side, collapsed, action, panelId, label, className = '' }: CollapsiblePanelToggleProps) {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n const accessible = label ?? (collapsed ? 'Expand' : 'Collapse');\n return <button type=\"button\" class={`kui-collapsible-panel__toggle ${className}`.trim()} data-action={action} data-collapsible-target={panelId} aria-expanded={String(!collapsed)} aria-label={accessible}><LucideIcon icon={glyph.icon} name={glyph.name} /></button>;\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({ id, side, collapsed = false, size, label, children, className = '' }: CollapsiblePanelProps) {\n const sizeVar = side === 'bottom' ? '--kui-collapsible-panel-height' : '--kui-collapsible-panel-width';\n return <aside class={`kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim()} data-component=\"collapsible-panel\" data-collapsible-panel={id} data-side={side} data-collapsed={String(collapsed)} aria-label={label || undefined} aria-hidden={collapsed ? 'true' : undefined} style={size ? `${sizeVar}: ${size}px` : undefined}>\n <div class=\"kui-collapsible-panel__content\">{children}</div>\n </aside>;\n}\n"]}
@@ -0,0 +1,62 @@
1
+ import { ReadonlySignal } from 'kerfjs';
2
+
3
+ /**
4
+ * Reactive device-class detection for `@kerfjs/ui` (see `docs/23-app-layouts.md`
5
+ * §2). `deviceClass()` returns a `ReadonlySignal<DeviceClass>` describing the
6
+ * current viewport as a size bucket × orientation × viewport-segment count, so a
7
+ * layout can pick its presentation reactively instead of hand-wiring `matchMedia`.
8
+ *
9
+ * One shared viewport source backs every reader; the pure `classifyViewport`
10
+ * core is DOM-free and directly unit-tested.
11
+ */
12
+ type DeviceSize = 'xs-mobile' | 'mobile' | 'tablet' | 'desktop' | 'xl-desktop';
13
+ type DeviceOrientation = 'portrait' | 'landscape';
14
+ /** Minimum widths (px) at which each larger bucket begins. `xs-mobile` is 0. */
15
+ interface DeviceBreakpoints {
16
+ mobile: number;
17
+ tablet: number;
18
+ desktop: number;
19
+ 'xl-desktop': number;
20
+ }
21
+ interface DeviceClass {
22
+ size: DeviceSize;
23
+ orientation: DeviceOrientation;
24
+ /** Horizontal viewport segments (foldables / dual-screen); 1 on ordinary devices. */
25
+ segments: number;
26
+ /** Vertical viewport segments; 1 on ordinary devices. */
27
+ verticalSegments: number;
28
+ /** Small phones — `xs-mobile` or `mobile`. */
29
+ handset: boolean;
30
+ /** "One pane at a time" — a handset or a portrait tablet. */
31
+ compact: boolean;
32
+ /** True when the current size is `size` or larger, e.g. `atLeast('tablet')`. */
33
+ atLeast(size: DeviceSize): boolean;
34
+ }
35
+ /** A raw viewport snapshot, before breakpoints are applied. */
36
+ interface Viewport {
37
+ width: number;
38
+ height: number;
39
+ segments: number;
40
+ verticalSegments: number;
41
+ }
42
+ interface DeviceClassOptions {
43
+ /** Override any of the default bucket thresholds. */
44
+ breakpoints?: Partial<DeviceBreakpoints>;
45
+ /** The viewport assumed when there is no DOM (SSR). Defaults to 1024×768, one segment. */
46
+ ssr?: Partial<Viewport>;
47
+ }
48
+ declare const DEFAULT_BREAKPOINTS: DeviceBreakpoints;
49
+ /**
50
+ * Classify a raw viewport into a {@link DeviceClass}. Pure and DOM-free — the
51
+ * single source of truth for the bucketing rules.
52
+ */
53
+ declare function classifyViewport(width: number, orientation: DeviceOrientation, segments?: number, verticalSegments?: number, breakpoints?: DeviceBreakpoints): DeviceClass;
54
+ /**
55
+ * A reactive signal of the current {@link DeviceClass}. Reading it inside an
56
+ * `effect`/`computed` re-runs when the viewport crosses a breakpoint, rotates,
57
+ * or changes its segment count. Without a DOM it resolves to `options.ssr`
58
+ * (default 1024×768, landscape, one segment).
59
+ */
60
+ declare function deviceClass(options?: DeviceClassOptions): ReadonlySignal<DeviceClass>;
61
+
62
+ export { DEFAULT_BREAKPOINTS, type DeviceBreakpoints, type DeviceClass, type DeviceClassOptions, type DeviceOrientation, type DeviceSize, type Viewport, classifyViewport, deviceClass };
@@ -0,0 +1,75 @@
1
+ import { computed, signal } from 'kerfjs';
2
+
3
+ // src/device-class.ts
4
+ var DEFAULT_BREAKPOINTS = {
5
+ mobile: 360,
6
+ tablet: 720,
7
+ desktop: 1024,
8
+ "xl-desktop": 1440
9
+ };
10
+ var SIZE_ORDER = ["xs-mobile", "mobile", "tablet", "desktop", "xl-desktop"];
11
+ var SSR_VIEWPORT = { width: 1024, height: 768, segments: 1, verticalSegments: 1 };
12
+ function classifyViewport(width, orientation, segments = 1, verticalSegments = 1, breakpoints = DEFAULT_BREAKPOINTS) {
13
+ const size = width >= breakpoints["xl-desktop"] ? "xl-desktop" : width >= breakpoints.desktop ? "desktop" : width >= breakpoints.tablet ? "tablet" : width >= breakpoints.mobile ? "mobile" : "xs-mobile";
14
+ const rank = SIZE_ORDER.indexOf(size);
15
+ return {
16
+ size,
17
+ orientation,
18
+ segments,
19
+ verticalSegments,
20
+ handset: rank <= 1,
21
+ compact: rank <= 1 || size === "tablet" && orientation === "portrait",
22
+ atLeast: (target) => rank >= SIZE_ORDER.indexOf(target)
23
+ };
24
+ }
25
+ function countSegments(axis, view) {
26
+ const mq = view.matchMedia;
27
+ if (typeof mq !== "function") return 1;
28
+ for (let n = 4; n >= 2; n--) {
29
+ if (mq.call(view, `(${axis}-viewport-segments: ${n})`).matches) return n;
30
+ }
31
+ return 1;
32
+ }
33
+ function readViewport(view) {
34
+ return {
35
+ width: view.innerWidth,
36
+ height: view.innerHeight,
37
+ segments: countSegments("horizontal", view),
38
+ verticalSegments: countSegments("vertical", view)
39
+ };
40
+ }
41
+ function browserWindow() {
42
+ return typeof window === "undefined" ? void 0 : window;
43
+ }
44
+ var sharedSource;
45
+ function viewportSource(view) {
46
+ if (sharedSource) return sharedSource;
47
+ const source = signal(readViewport(view));
48
+ sharedSource = source;
49
+ const update = () => {
50
+ source.value = readViewport(view);
51
+ };
52
+ view.addEventListener("resize", update);
53
+ view.addEventListener("orientationchange", update);
54
+ return source;
55
+ }
56
+ function orientationOf(view) {
57
+ return view.height > view.width ? "portrait" : "landscape";
58
+ }
59
+ function deviceClass(options = {}) {
60
+ const breakpoints = { ...DEFAULT_BREAKPOINTS, ...options.breakpoints };
61
+ const view = browserWindow();
62
+ if (!view) {
63
+ const snapshot = { ...SSR_VIEWPORT, ...options.ssr };
64
+ return computed(() => classifyViewport(snapshot.width, orientationOf(snapshot), snapshot.segments, snapshot.verticalSegments, breakpoints));
65
+ }
66
+ const source = viewportSource(view);
67
+ return computed(() => {
68
+ const v = source.value;
69
+ return classifyViewport(v.width, orientationOf(v), v.segments, v.verticalSegments, breakpoints);
70
+ });
71
+ }
72
+
73
+ export { DEFAULT_BREAKPOINTS, classifyViewport, deviceClass };
74
+
75
+ //# sourceMappingURL=device-class.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/device-class.ts"],"names":[],"mappings":"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","file":"device-class.js","sourcesContent":["import { computed, type ReadonlySignal, signal } from 'kerfjs';\n\n/**\n * Reactive device-class detection for `@kerfjs/ui` (see `docs/23-app-layouts.md`\n * §2). `deviceClass()` returns a `ReadonlySignal<DeviceClass>` describing the\n * current viewport as a size bucket × orientation × viewport-segment count, so a\n * layout can pick its presentation reactively instead of hand-wiring `matchMedia`.\n *\n * One shared viewport source backs every reader; the pure `classifyViewport`\n * core is DOM-free and directly unit-tested.\n */\n\nexport type DeviceSize = 'xs-mobile' | 'mobile' | 'tablet' | 'desktop' | 'xl-desktop';\nexport type DeviceOrientation = 'portrait' | 'landscape';\n\n/** Minimum widths (px) at which each larger bucket begins. `xs-mobile` is 0. */\nexport interface DeviceBreakpoints {\n mobile: number;\n tablet: number;\n desktop: number;\n 'xl-desktop': number;\n}\n\nexport interface DeviceClass {\n size: DeviceSize;\n orientation: DeviceOrientation;\n /** Horizontal viewport segments (foldables / dual-screen); 1 on ordinary devices. */\n segments: number;\n /** Vertical viewport segments; 1 on ordinary devices. */\n verticalSegments: number;\n /** Small phones — `xs-mobile` or `mobile`. */\n handset: boolean;\n /** \"One pane at a time\" — a handset or a portrait tablet. */\n compact: boolean;\n /** True when the current size is `size` or larger, e.g. `atLeast('tablet')`. */\n atLeast(size: DeviceSize): boolean;\n}\n\n/** A raw viewport snapshot, before breakpoints are applied. */\nexport interface Viewport {\n width: number;\n height: number;\n segments: number;\n verticalSegments: number;\n}\n\nexport interface DeviceClassOptions {\n /** Override any of the default bucket thresholds. */\n breakpoints?: Partial<DeviceBreakpoints>;\n /** The viewport assumed when there is no DOM (SSR). Defaults to 1024×768, one segment. */\n ssr?: Partial<Viewport>;\n}\n\nexport const DEFAULT_BREAKPOINTS: DeviceBreakpoints = {\n mobile: 360,\n tablet: 720,\n desktop: 1024,\n 'xl-desktop': 1440,\n};\n\nconst SIZE_ORDER: readonly DeviceSize[] = ['xs-mobile', 'mobile', 'tablet', 'desktop', 'xl-desktop'];\n\nconst SSR_VIEWPORT: Viewport = { width: 1024, height: 768, segments: 1, verticalSegments: 1 };\n\n/**\n * Classify a raw viewport into a {@link DeviceClass}. Pure and DOM-free — the\n * single source of truth for the bucketing rules.\n */\nexport function classifyViewport(\n width: number,\n orientation: DeviceOrientation,\n segments = 1,\n verticalSegments = 1,\n breakpoints: DeviceBreakpoints = DEFAULT_BREAKPOINTS,\n): DeviceClass {\n const size: DeviceSize =\n width >= breakpoints['xl-desktop']\n ? 'xl-desktop'\n : width >= breakpoints.desktop\n ? 'desktop'\n : width >= breakpoints.tablet\n ? 'tablet'\n : width >= breakpoints.mobile\n ? 'mobile'\n : 'xs-mobile';\n const rank = SIZE_ORDER.indexOf(size);\n return {\n size,\n orientation,\n segments,\n verticalSegments,\n handset: rank <= 1,\n compact: rank <= 1 || (size === 'tablet' && orientation === 'portrait'),\n atLeast: (target) => rank >= SIZE_ORDER.indexOf(target),\n };\n}\n\n/** Count viewport segments along one axis, feature-detecting the media query. */\nfunction countSegments(axis: 'horizontal' | 'vertical', view: Window): number {\n const mq = view.matchMedia;\n if (typeof mq !== 'function') return 1;\n for (let n = 4; n >= 2; n--) {\n if (mq.call(view, `(${axis}-viewport-segments: ${n})`).matches) return n;\n }\n return 1;\n}\n\n/** Read the current viewport from a browser window. */\nfunction readViewport(view: Window): Viewport {\n return {\n width: view.innerWidth,\n height: view.innerHeight,\n segments: countSegments('horizontal', view),\n verticalSegments: countSegments('vertical', view),\n };\n}\n\n/** The browser window, or `undefined` when running without a DOM (SSR). */\nfunction browserWindow(): Window | undefined {\n return typeof window === 'undefined' ? undefined : window;\n}\n\nlet sharedSource: ReturnType<typeof signal<Viewport>> | undefined;\n\n/**\n * The shared reactive viewport source. Installed lazily on first read and kept\n * for the life of the page — there is only ever one viewport, so a single\n * listener set backs every `deviceClass()` reader.\n */\nfunction viewportSource(view: Window): ReturnType<typeof signal<Viewport>> {\n if (sharedSource) return sharedSource;\n const source = signal(readViewport(view));\n sharedSource = source;\n const update = (): void => {\n source.value = readViewport(view);\n };\n view.addEventListener('resize', update);\n view.addEventListener('orientationchange', update);\n return source;\n}\n\nfunction orientationOf(view: Viewport): DeviceOrientation {\n return view.height > view.width ? 'portrait' : 'landscape';\n}\n\n/**\n * A reactive signal of the current {@link DeviceClass}. Reading it inside an\n * `effect`/`computed` re-runs when the viewport crosses a breakpoint, rotates,\n * or changes its segment count. Without a DOM it resolves to `options.ssr`\n * (default 1024×768, landscape, one segment).\n */\nexport function deviceClass(options: DeviceClassOptions = {}): ReadonlySignal<DeviceClass> {\n const breakpoints: DeviceBreakpoints = { ...DEFAULT_BREAKPOINTS, ...options.breakpoints };\n const view = browserWindow();\n if (!view) {\n const snapshot: Viewport = { ...SSR_VIEWPORT, ...options.ssr };\n return computed(() => classifyViewport(snapshot.width, orientationOf(snapshot), snapshot.segments, snapshot.verticalSegments, breakpoints));\n }\n const source = viewportSource(view);\n return computed(() => {\n const v = source.value;\n return classifyViewport(v.width, orientationOf(v), v.segments, v.verticalSegments, breakpoints);\n });\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import { SafeHtml } from 'kerfjs';
2
+
3
+ type DisclosureDirection = 'up' | 'down' | 'left' | 'right';
4
+ interface DisclosureArrowProps {
5
+ open: boolean;
6
+ openDirection?: DisclosureDirection;
7
+ closedDirection?: DisclosureDirection;
8
+ /** Replacement icons should use right as their unrotated orientation. */
9
+ icon?: SafeHtml;
10
+ className?: string;
11
+ }
12
+ declare function DisclosureArrow({ open, openDirection, closedDirection, icon, className, }: DisclosureArrowProps): SafeHtml;
13
+
14
+ export { DisclosureArrow, type DisclosureArrowProps, type DisclosureDirection };
@@ -0,0 +1,4 @@
1
+ export { DisclosureArrow } from './chunk-56RJXPHG.js';
2
+
3
+
4
+ //# sourceMappingURL=disclosure-arrow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"disclosure-arrow.js"}
@@ -0,0 +1,28 @@
1
+ import { SafeHtml } from 'kerfjs';
2
+
3
+ /** Where a {@link FloatingToolbar} floats within its positioned container. */
4
+ type FloatingToolbarPosition = 'bottom' | 'bottom-start' | 'bottom-end' | 'top' | 'top-start' | 'top-end';
5
+ interface FloatingToolbarProps {
6
+ /** Toolbar contents — normally one or more `ToolbarControlGroup`s. */
7
+ children: SafeHtml | SafeHtml[];
8
+ /** Accessible name for the toolbar (required — it exposes `role="toolbar"`). */
9
+ label: string;
10
+ /**
11
+ * Corner or edge it floats to inside its nearest positioned ancestor.
12
+ * Default: `'bottom-end'`.
13
+ */
14
+ position?: FloatingToolbarPosition;
15
+ className?: string;
16
+ }
17
+ /**
18
+ * A toolbar that floats above the main content of its nearest positioned
19
+ * ancestor — a transparent, forced-dark cluster of controls (e.g. a drawer
20
+ * restore button) that sits over the content but NOT over dialogs or overlays
21
+ * (it is not in the top layer). It is inset from the container edges by
22
+ * `--kui-floating-toolbar-inset` (default `--kui-space-m`, i.e. 8px more than a
23
+ * top toolbar's own inset); override that token to move it. The app owns the
24
+ * controls and their behavior — wire them with `delegate()` as usual.
25
+ */
26
+ declare function FloatingToolbar({ children, label, position, className }: FloatingToolbarProps): SafeHtml;
27
+
28
+ export { FloatingToolbar, type FloatingToolbarPosition, type FloatingToolbarProps };
@@ -0,0 +1,3 @@
1
+ export { FloatingToolbar } from './chunk-5E2HVJ33.js';
2
+
3
+ //# sourceMappingURL=floating-toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"floating-toolbar.js"}
package/dist/index.d.ts CHANGED
@@ -1,21 +1,26 @@
1
1
  export { AppTab, AppTabProps } from './app-tab.js';
2
- export { DialogHeader, DialogHeaderProps } from './dialog-header.js';
2
+ export { DisclosureArrow, DisclosureArrowProps, DisclosureDirection } from './disclosure-arrow.js';
3
3
  export { EmptyState, EmptyStateProps } from './empty-state.js';
4
+ export { FloatingToolbar, FloatingToolbarPosition, FloatingToolbarProps } from './floating-toolbar.js';
5
+ export { ListActionRow, ListActionRowProps } from './list-action-row.js';
6
+ export { ListHeader, ListHeaderProps } from './list-header.js';
7
+ export { ListItem, ListItemProps } from './list-item.js';
4
8
  export { LoadingSpinner, LoadingSpinnerProps } from './loading-spinner.js';
5
9
  export { LucideIcon, LucideIconProps, LucideNode } from './lucide-icon.js';
6
- export { MenuHeader, MenuHeaderProps } from './menu-header.js';
7
- export { MenuItem, MenuItemProps } from './menu-item.js';
8
- export { PageHeader, PageHeaderProps } from './page-header.js';
10
+ export { PanelHeader, PanelHeaderProps } from './panel-header.js';
9
11
  export { ResizableRegion, ResizableRegionAxis, ResizableRegionEdge, ResizableRegionProps, clampRegionSize, resizeRegionFromPointer } from './resizable-region.js';
10
12
  export { SegmentedControl, SegmentedControlAppearance, SegmentedControlChoice, SegmentedControlLayout, SegmentedControlProps, SegmentedControlShape, SegmentedControlSize } from './segmented-control.js';
11
13
  export { Select, SelectChoice, SelectProps } from './select.js';
14
+ export { Skeleton, SkeletonProps } from './skeleton.js';
12
15
  export { StateBanner, StateBannerProps, StateBannerTone } from './state-banner.js';
13
16
  export { TabBar, TabBarProps } from './tab-bar.js';
17
+ export { TokenSearchField, TokenSearchFieldProps, TokenSearchFieldValue, TokenSearchToken, placeTokenSearchCaret, readTokenSearchField } from './token-search-field.js';
14
18
  export { Toolbar, ToolbarProps } from './toolbar.js';
15
19
  export { ToolbarControlGroup, ToolbarControlGroupProps } from './toolbar-control-group.js';
16
- export { ToolbarText, ToolbarTextProps, ToolbarTextSize } from './toolbar-text.js';
17
- export { ValueTable, ValueTableProps } from './value-table.js';
20
+ export { HeadingLevel, ToolbarText, ToolbarTextProps, ToolbarTextSize } from './toolbar-text.js';
21
+ export { ValueTable, ValueTableProps, ValueTableRow, ValueTableRowProps } from './value-table.js';
18
22
  export { ResizeCommit, WireResizableRegionsOptions, wireResizableRegions } from './wire-resizable-regions.js';
19
23
  export { TabDropPosition, TabReorder, TabReorderSource, WireTabBarsOptions, reorderTabs, wireTabBars } from './wire-tab-bars.js';
24
+ export { TokenSearchCollapsibleOptions, TokenSearchEdit, TokenSearchFieldsHandle, TokenSearchSubmit, WireTokenSearchFieldsOptions, wireTokenSearchFields } from './wire-token-search-fields.js';
20
25
  import 'kerfjs';
21
26
  import 'lucide';
package/dist/index.js CHANGED
@@ -1,21 +1,27 @@
1
- export { ToolbarText } from './chunk-GY5WH7TO.js';
1
+ export { wireResizableRegions } from './chunk-AQNKJRFH.js';
2
+ export { reorderTabs, wireTabBars } from './chunk-XXMOARTH.js';
3
+ export { wireTokenSearchFields } from './chunk-LCOBDOCC.js';
4
+ export { TokenSearchField, placeTokenSearchCaret, readTokenSearchField } from './chunk-7LDCTU7D.js';
5
+ export { ValueTable, ValueTableRow } from './chunk-37T3VNIZ.js';
6
+ export { SegmentedControl } from './chunk-YGN7OMLT.js';
7
+ export { Select } from './chunk-CH4SQ6H5.js';
8
+ export { StateBanner } from './chunk-I7INRJO4.js';
9
+ export { TabBar } from './chunk-AVZHJN6C.js';
10
+ export { ListActionRow } from './chunk-7JB7VPRI.js';
11
+ export { PanelHeader } from './chunk-XE5ZLPCC.js';
12
+ export { ToolbarText } from './chunk-RUNWEPR4.js';
13
+ export { ResizableRegion, clampRegionSize, resizeRegionFromPointer } from './chunk-M5JRI6MN.js';
14
+ export { AppTab } from './chunk-2Z5TWHKQ.js';
15
+ export { ListHeader } from './chunk-5ATCDSQS.js';
16
+ export { ListItem } from './chunk-L4OKFDJY.js';
17
+ export { ToolbarControlGroup } from './chunk-RNPGFQ33.js';
2
18
  export { Toolbar } from './chunk-DAFFDO33.js';
3
- export { ValueTable } from './chunk-VKH2JLDZ.js';
4
- export { wireResizableRegions } from './chunk-4HHCYSGT.js';
5
- export { reorderTabs, wireTabBars } from './chunk-MQIZAD4A.js';
6
- export { PageHeader } from './chunk-2PES33HS.js';
7
- export { ResizableRegion, clampRegionSize, resizeRegionFromPointer } from './chunk-3O7ZEUW2.js';
8
- export { SegmentedControl } from './chunk-TRNBHPNW.js';
9
- export { Select } from './chunk-NHXX4JI5.js';
10
- export { StateBanner } from './chunk-VHW5YNIB.js';
11
- export { TabBar } from './chunk-MBR3TYNL.js';
12
- export { ToolbarControlGroup } from './chunk-MFKMHK5W.js';
13
- export { AppTab } from './chunk-T5XNMVOI.js';
14
- export { DialogHeader } from './chunk-723YNJBH.js';
19
+
20
+ export { Skeleton } from './chunk-B24C4A6T.js';
21
+ export { DisclosureArrow } from './chunk-56RJXPHG.js';
22
+ export { LucideIcon } from './chunk-W2FK7ZNY.js';
15
23
  export { EmptyState } from './chunk-WVPYVDXY.js';
16
24
  export { LoadingSpinner } from './chunk-55DATV3A.js';
17
- export { LucideIcon } from './chunk-W2FK7ZNY.js';
18
- export { MenuHeader } from './chunk-OPCJRCYO.js';
19
- export { MenuItem } from './chunk-WY4CAEPG.js';
25
+ export { FloatingToolbar } from './chunk-5E2HVJ33.js';
20
26
 
21
27
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,52 @@
1
+ import { SafeHtml } from 'kerfjs';
2
+
3
+ type ListActionRowRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
4
+ 'data-component'?: never;
5
+ 'data-action'?: never;
6
+ 'data-item-id'?: never;
7
+ 'data-has-icon'?: never;
8
+ 'data-multiline'?: never;
9
+ 'data-state'?: never;
10
+ 'data-selected'?: never;
11
+ 'data-pressed'?: never;
12
+ }>;
13
+ type ListActionRowTrailingAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
14
+ 'data-component'?: never;
15
+ 'data-action'?: never;
16
+ 'data-item-id'?: never;
17
+ popoverTarget?: string;
18
+ popoverTargetAction?: 'toggle' | 'show' | 'hide';
19
+ 'aria-controls'?: string;
20
+ 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';
21
+ }>;
22
+ interface ListActionRowProps {
23
+ /** Visible dormant content for the primary button. Must not contain interactive descendants. */
24
+ label: string | SafeHtml;
25
+ /** Decorative dormant content for the primary button. Must not contain interactive descendants. */
26
+ icon?: SafeHtml;
27
+ action: string;
28
+ itemId?: string;
29
+ selected?: boolean;
30
+ pressed?: boolean;
31
+ accessibleLabel?: string;
32
+ title?: string;
33
+ multiline?: boolean;
34
+ state?: string;
35
+ disabled?: boolean;
36
+ tabIndex?: number;
37
+ /** Render as an unanimated loading skeleton, disabling both actions. */
38
+ placeholder?: boolean;
39
+ trailingAction: string;
40
+ trailingActionLabel: string;
41
+ /** Decorative dormant content for the trailing button. Must not contain interactive descendants. */
42
+ trailingActionIcon: SafeHtml;
43
+ trailingActionDisabled?: boolean;
44
+ trailingActionTitle?: string;
45
+ className?: string;
46
+ style?: string;
47
+ rootAttributes?: ListActionRowRootAttributes;
48
+ trailingActionAttributes?: ListActionRowTrailingAttributes;
49
+ }
50
+ declare function ListActionRow({ label, icon, action, itemId, selected, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, placeholder, trailingAction, trailingActionLabel, trailingActionIcon, trailingActionDisabled, trailingActionTitle, className, style, rootAttributes, trailingActionAttributes }: ListActionRowProps): SafeHtml;
51
+
52
+ export { ListActionRow, type ListActionRowProps };
@@ -0,0 +1,5 @@
1
+ export { ListActionRow } from './chunk-7JB7VPRI.js';
2
+
3
+
4
+
5
+ //# sourceMappingURL=list-action-row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"list-action-row.js"}
@@ -0,0 +1,43 @@
1
+ import { SafeHtml } from 'kerfjs';
2
+
3
+ type ListHeaderRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
4
+ 'data-component'?: never;
5
+ 'data-action'?: never;
6
+ 'data-has-badge'?: never;
7
+ 'data-has-count'?: never;
8
+ 'data-toggle'?: never;
9
+ }>;
10
+ type ListHeaderTriggerAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
11
+ 'data-action'?: never;
12
+ popoverTarget?: string;
13
+ popoverTargetAction?: 'toggle' | 'show' | 'hide';
14
+ 'aria-controls'?: string;
15
+ 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';
16
+ }>;
17
+ interface ListHeaderBaseProps {
18
+ label: string;
19
+ action?: string;
20
+ actionLabel?: string;
21
+ actionIcon?: SafeHtml;
22
+ actionDisabled?: boolean;
23
+ disabledReason?: string;
24
+ expanded?: boolean;
25
+ toggle?: boolean;
26
+ /** Render as an unanimated loading skeleton: keep the label and action affordance, disable interaction. */
27
+ placeholder?: boolean;
28
+ rootAttributes?: ListHeaderRootAttributes;
29
+ triggerAttributes?: ListHeaderTriggerAttributes;
30
+ }
31
+ type ListHeaderIndicatorProps = {
32
+ count: number;
33
+ countLabel: string;
34
+ badge?: never;
35
+ } | {
36
+ count?: never;
37
+ countLabel?: never;
38
+ badge?: SafeHtml;
39
+ };
40
+ type ListHeaderProps = ListHeaderBaseProps & ListHeaderIndicatorProps;
41
+ declare function ListHeader({ label, count, countLabel, badge, action, actionLabel, actionIcon, actionDisabled, disabledReason, expanded, toggle, placeholder, rootAttributes, triggerAttributes }: ListHeaderProps): SafeHtml;
42
+
43
+ export { ListHeader, type ListHeaderProps };
@@ -0,0 +1,7 @@
1
+ export { ListHeader } from './chunk-5ATCDSQS.js';
2
+
3
+
4
+
5
+
6
+
7
+ //# sourceMappingURL=list-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"list-header.js"}
@@ -0,0 +1,33 @@
1
+ import { SafeHtml } from 'kerfjs';
2
+
3
+ type ListItemRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
4
+ 'data-component'?: never;
5
+ 'data-action'?: never;
6
+ 'data-item-id'?: never;
7
+ 'data-has-icon'?: never;
8
+ 'data-multiline'?: never;
9
+ 'data-state'?: never;
10
+ }>;
11
+ interface ListItemProps {
12
+ label: string | SafeHtml;
13
+ icon?: SafeHtml;
14
+ trailing?: SafeHtml;
15
+ selected?: boolean;
16
+ action: string;
17
+ itemId?: string;
18
+ className?: string;
19
+ style?: string;
20
+ pressed?: boolean;
21
+ accessibleLabel?: string;
22
+ title?: string;
23
+ multiline?: boolean;
24
+ state?: string;
25
+ disabled?: boolean;
26
+ tabIndex?: number;
27
+ /** Render the row as an unanimated loading skeleton, disabling its action. */
28
+ placeholder?: boolean;
29
+ rootAttributes?: ListItemRootAttributes;
30
+ }
31
+ declare function ListItem({ label, icon, trailing, selected, action, itemId, className, style, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, placeholder, rootAttributes }: ListItemProps): SafeHtml;
32
+
33
+ export { ListItem, type ListItemProps };
@@ -0,0 +1,5 @@
1
+ export { ListItem } from './chunk-L4OKFDJY.js';
2
+
3
+
4
+
5
+ //# sourceMappingURL=list-item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"list-item.js"}
@@ -0,0 +1,38 @@
1
+ import { SafeHtml } from 'kerfjs';
2
+
3
+ /**
4
+ * One entry in a {@link NavStack}. The app owns the stack as an array (usually a
5
+ * signal); `NavStack` renders it and `wireNavStack` animates the transitions.
6
+ */
7
+ interface NavStackView {
8
+ /** Stable identity for keyed reconcile and transition direction. */
9
+ key: string;
10
+ content: SafeHtml;
11
+ /** Title shown in the top toolbar for this view. */
12
+ title?: string;
13
+ /** Trailing actions for this view's top toolbar. */
14
+ toolbar?: SafeHtml;
15
+ }
16
+ interface NavStackProps {
17
+ id: string;
18
+ /** Accessible name for the stack region. */
19
+ label: string;
20
+ /** The stack, root first; the last entry is the active top view. */
21
+ views: NavStackView[];
22
+ /** Accessible label for the back control (default "Back"). */
23
+ backLabel?: string;
24
+ /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */
25
+ hideToolbar?: boolean;
26
+ /** Optional persistent bottom toolbar. */
27
+ bottomToolbar?: SafeHtml;
28
+ className?: string;
29
+ }
30
+ /**
31
+ * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last
32
+ * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and
33
+ * cross-fades the chrome across a change. A single-pane layout is a `NavStack`
34
+ * with one entry. See `docs/23-app-layouts.md` §3.1.
35
+ */
36
+ declare function NavStack({ id, label, views, backLabel, hideToolbar, bottomToolbar, className }: NavStackProps): SafeHtml;
37
+
38
+ export { NavStack, type NavStackProps, type NavStackView };
@@ -0,0 +1,5 @@
1
+ export { NavStack } from './chunk-BLK3UEEI.js';
2
+
3
+
4
+
5
+ //# sourceMappingURL=nav-stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"nav-stack.js"}