@kerfjs/ui 5.0.0-beta.103 → 5.0.0-beta.105

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 (759) hide show
  1. package/README.md +163 -116
  2. package/ai/application-ui-profile.defaults.json +125 -4
  3. package/ai/compile-time-contracts-v1.json +11 -11
  4. package/ai/component-catalog.json +2606 -627
  5. package/ai/component-composition-rules.json +11 -10
  6. package/ai/component-composition.json +1689 -300
  7. package/ai/components/README.md +66 -48
  8. package/ai/components/application-tabs.md +4 -4
  9. package/ai/components/badge.md +1 -0
  10. package/ai/components/button.md +91 -0
  11. package/ai/components/checkbox.md +89 -0
  12. package/ai/components/choice-chips.md +9 -3
  13. package/ai/components/color-field.md +92 -0
  14. package/ai/components/color-picker.md +90 -0
  15. package/ai/components/color-swatches.md +82 -0
  16. package/ai/components/combobox.md +6 -4
  17. package/ai/components/content-item.md +5 -2
  18. package/ai/components/disclosure.md +83 -0
  19. package/ai/components/file-picker.md +1 -0
  20. package/ai/components/foundation.md +1 -1
  21. package/ai/components/list-action-row.md +3 -3
  22. package/ai/components/list-detail-dialog.md +90 -0
  23. package/ai/components/list.md +2 -0
  24. package/ai/components/lucide-icon.md +2 -0
  25. package/ai/components/{composer.md → message-composer.md} +17 -16
  26. package/ai/components/pane.md +3 -1
  27. package/ai/components/popup-menu.md +12 -9
  28. package/ai/components/progress-bar.md +82 -0
  29. package/ai/components/progress-ring.md +80 -0
  30. package/ai/components/radio-group.md +88 -0
  31. package/ai/components/recipe-list-detail-dialog.md +5 -5
  32. package/ai/components/search-field.md +108 -0
  33. package/ai/components/select.md +15 -13
  34. package/ai/components/slider.md +84 -0
  35. package/ai/components/surface-scaffold.md +16 -13
  36. package/ai/components/switch.md +81 -0
  37. package/ai/components/tab-bar.md +6 -6
  38. package/ai/components/tab-navigator.md +2 -2
  39. package/ai/components/tabs.md +7 -7
  40. package/ai/components/tag-field.md +86 -0
  41. package/ai/components/text-field.md +98 -0
  42. package/ai/components/text.md +1 -0
  43. package/ai/components/toast.md +85 -0
  44. package/ai/components/toolbar-control-group.md +3 -3
  45. package/ai/components/tooltip.md +81 -0
  46. package/ai/components/wa-accordion-item.md +11 -5
  47. package/ai/components/wa-accordion.md +11 -5
  48. package/ai/components/wa-animated-image.md +2 -1
  49. package/ai/components/wa-animation.md +1 -0
  50. package/ai/components/wa-avatar.md +1 -0
  51. package/ai/components/wa-badge.md +10 -3
  52. package/ai/components/wa-breadcrumb-item.md +1 -0
  53. package/ai/components/wa-breadcrumb.md +1 -0
  54. package/ai/components/wa-button-group.md +6 -4
  55. package/ai/components/wa-button.md +7 -5
  56. package/ai/components/wa-callout.md +7 -5
  57. package/ai/components/wa-card.md +12 -4
  58. package/ai/components/wa-carousel-item.md +1 -0
  59. package/ai/components/wa-carousel.md +1 -0
  60. package/ai/components/wa-checkbox-group.md +11 -4
  61. package/ai/components/wa-checkbox.md +10 -4
  62. package/ai/components/wa-color-picker.md +13 -5
  63. package/ai/components/wa-comparison.md +2 -1
  64. package/ai/components/wa-copy-button.md +1 -0
  65. package/ai/components/wa-details.md +11 -5
  66. package/ai/components/wa-dialog.md +10 -4
  67. package/ai/components/wa-divider.md +1 -0
  68. package/ai/components/wa-drawer.md +12 -5
  69. package/ai/components/wa-dropdown-item.md +8 -6
  70. package/ai/components/wa-dropdown.md +8 -6
  71. package/ai/components/wa-format-bytes.md +1 -0
  72. package/ai/components/wa-format-date.md +1 -0
  73. package/ai/components/wa-format-number.md +1 -0
  74. package/ai/components/wa-icon.md +2 -1
  75. package/ai/components/wa-include.md +6 -4
  76. package/ai/components/wa-input.md +9 -6
  77. package/ai/components/wa-intersection-observer.md +1 -0
  78. package/ai/components/wa-known-date.md +1 -0
  79. package/ai/components/wa-markdown.md +1 -0
  80. package/ai/components/wa-mutation-observer.md +1 -0
  81. package/ai/components/wa-number-input.md +1 -0
  82. package/ai/components/wa-option.md +7 -5
  83. package/ai/components/wa-otp-input.md +1 -0
  84. package/ai/components/wa-page.md +13 -4
  85. package/ai/components/wa-pagination.md +1 -0
  86. package/ai/components/wa-popover.md +11 -5
  87. package/ai/components/wa-popup.md +11 -4
  88. package/ai/components/wa-progress-bar.md +11 -4
  89. package/ai/components/wa-progress-ring.md +11 -4
  90. package/ai/components/wa-qr-code.md +1 -0
  91. package/ai/components/wa-radio-group.md +12 -4
  92. package/ai/components/wa-radio.md +10 -4
  93. package/ai/components/wa-random-content.md +1 -0
  94. package/ai/components/wa-rating.md +1 -0
  95. package/ai/components/wa-relative-time.md +1 -0
  96. package/ai/components/wa-resize-observer.md +1 -0
  97. package/ai/components/wa-scroller.md +12 -4
  98. package/ai/components/wa-select.md +7 -5
  99. package/ai/components/wa-skeleton.md +10 -3
  100. package/ai/components/wa-slider.md +11 -5
  101. package/ai/components/wa-spinner.md +7 -5
  102. package/ai/components/wa-split-panel.md +7 -5
  103. package/ai/components/wa-step.md +56 -0
  104. package/ai/components/wa-stepper.md +56 -0
  105. package/ai/components/wa-switch.md +10 -3
  106. package/ai/components/wa-tab-group.md +8 -6
  107. package/ai/components/wa-tab-panel.md +7 -5
  108. package/ai/components/wa-tab.md +8 -6
  109. package/ai/components/wa-tag-input.md +62 -0
  110. package/ai/components/wa-tag.md +9 -6
  111. package/ai/components/wa-textarea.md +10 -3
  112. package/ai/components/wa-time-input.md +1 -0
  113. package/ai/components/wa-toast-item.md +9 -7
  114. package/ai/components/wa-toast.md +9 -7
  115. package/ai/components/wa-tooltip.md +11 -5
  116. package/ai/components/wa-tree-item.md +2 -1
  117. package/ai/components/wa-tree.md +2 -1
  118. package/ai/components/wa-zoomable-frame.md +2 -1
  119. package/ai/components/workbench-dialog.md +90 -0
  120. package/ai/public-api-signatures-v1.md +1577 -245
  121. package/ai/skill.md +83 -50
  122. package/ai/webawesome-jsx-signatures-v1.md +4 -1
  123. package/dist/badge.d.ts +9 -1
  124. package/dist/badge.js +1 -1
  125. package/dist/browser/button.js +5 -0
  126. package/dist/browser/catalog.js +3 -2
  127. package/dist/browser/{icon-button.js → checkbox.js} +2 -2
  128. package/dist/browser/color-field.js +4 -0
  129. package/dist/browser/color-picker.js +5 -0
  130. package/dist/browser/color-swatches.js +3 -0
  131. package/dist/browser/disclosure.js +5 -0
  132. package/dist/browser/list-action-row.js +1 -0
  133. package/dist/browser/list-detail-dialog.js +14 -0
  134. package/dist/browser/message-composer.js +5 -0
  135. package/dist/browser/popup-menu.js +1 -0
  136. package/dist/browser/progress-bar.js +3 -0
  137. package/dist/browser/progress-ring.js +3 -0
  138. package/dist/browser/radio-group.js +3 -0
  139. package/dist/browser/search-field.js +4 -0
  140. package/dist/browser/slider.js +3 -0
  141. package/dist/browser/surface-scaffold.js +1 -0
  142. package/dist/browser/switch.js +3 -0
  143. package/dist/browser/tab-bar-item.js +4 -0
  144. package/dist/browser/tag-field.js +5 -0
  145. package/dist/browser/text-field.js +4 -0
  146. package/dist/browser/workbench-dialog.js +15 -0
  147. package/dist/button.d.ts +108 -0
  148. package/dist/button.js +7 -0
  149. package/dist/button.js.map +1 -0
  150. package/dist/catalog-resources.d.ts +1 -1
  151. package/dist/catalog.d.ts +3 -3
  152. package/dist/catalog.js +57 -27
  153. package/dist/catalog.js.map +1 -1
  154. package/dist/checkbox.d.ts +45 -0
  155. package/dist/checkbox.js +6 -0
  156. package/dist/checkbox.js.map +1 -0
  157. package/dist/choice-chips.d.ts +49 -15
  158. package/dist/choice-chips.js +1 -1
  159. package/dist/chunk-23PPPNH6.js +93 -0
  160. package/dist/chunk-23PPPNH6.js.map +1 -0
  161. package/dist/{chunk-FNZQOUZ5.js → chunk-2FW7D4IG.js} +2 -2
  162. package/dist/{chunk-FNZQOUZ5.js.map → chunk-2FW7D4IG.js.map} +1 -1
  163. package/dist/{chunk-ZYU5WRC3.js → chunk-3GLYIIFR.js} +2 -2
  164. package/dist/{chunk-ZYU5WRC3.js.map → chunk-3GLYIIFR.js.map} +1 -1
  165. package/dist/{chunk-5NQF35VO.js → chunk-4RECPEHI.js} +2 -2
  166. package/dist/{chunk-5NQF35VO.js.map → chunk-4RECPEHI.js.map} +1 -1
  167. package/dist/{chunk-7IUEBNCO.js → chunk-5USKCWGL.js} +8 -3
  168. package/dist/chunk-5USKCWGL.js.map +1 -0
  169. package/dist/chunk-6VVIW7VB.js +69 -0
  170. package/dist/chunk-6VVIW7VB.js.map +1 -0
  171. package/dist/{chunk-LL45C7BB.js → chunk-7K6U6FCN.js} +1 -1
  172. package/dist/chunk-7K6U6FCN.js.map +1 -0
  173. package/dist/{chunk-HQZYKJ56.js → chunk-7W3GKMN4.js} +110 -74
  174. package/dist/chunk-7W3GKMN4.js.map +1 -0
  175. package/dist/chunk-ACUKTVS3.js +371 -0
  176. package/dist/chunk-ACUKTVS3.js.map +1 -0
  177. package/dist/{chunk-YQ2AC4E2.js → chunk-AMIHGFLP.js} +2 -2
  178. package/dist/{chunk-YQ2AC4E2.js.map → chunk-AMIHGFLP.js.map} +1 -1
  179. package/dist/chunk-ATGAJVZ6.js +268 -0
  180. package/dist/chunk-ATGAJVZ6.js.map +1 -0
  181. package/dist/chunk-AYPGXR2E.js +20 -0
  182. package/dist/chunk-AYPGXR2E.js.map +1 -0
  183. package/dist/{chunk-ETCWQLJV.js → chunk-BKUMG2KB.js} +38 -28
  184. package/dist/chunk-BKUMG2KB.js.map +1 -0
  185. package/dist/chunk-C26Q6P4Q.js +76 -0
  186. package/dist/chunk-C26Q6P4Q.js.map +1 -0
  187. package/dist/chunk-C3RLKKFQ.js +452 -0
  188. package/dist/chunk-C3RLKKFQ.js.map +1 -0
  189. package/dist/{chunk-IM3GKYOG.js → chunk-CIAUILRR.js} +52 -32
  190. package/dist/chunk-CIAUILRR.js.map +1 -0
  191. package/dist/chunk-CNM6ZWP2.js +38 -0
  192. package/dist/chunk-CNM6ZWP2.js.map +1 -0
  193. package/dist/{chunk-LPHU44S3.js → chunk-CTQUDCY5.js} +3 -1
  194. package/dist/chunk-CTQUDCY5.js.map +1 -0
  195. package/dist/{chunk-MXNIVEVL.js → chunk-D4MXSAMI.js} +5 -3
  196. package/dist/chunk-D4MXSAMI.js.map +1 -0
  197. package/dist/{chunk-YBWQR2OK.js → chunk-DDSCVEO5.js} +10 -9
  198. package/dist/chunk-DDSCVEO5.js.map +1 -0
  199. package/dist/{chunk-SIW64V65.js → chunk-DF2YKGIX.js} +3 -3
  200. package/dist/{chunk-SIW64V65.js.map → chunk-DF2YKGIX.js.map} +1 -1
  201. package/dist/{chunk-3SKAEPPZ.js → chunk-ECFCAKWE.js} +4 -4
  202. package/dist/{chunk-3SKAEPPZ.js.map → chunk-ECFCAKWE.js.map} +1 -1
  203. package/dist/chunk-EKBMUXFV.js +298 -0
  204. package/dist/chunk-EKBMUXFV.js.map +1 -0
  205. package/dist/{chunk-IXLUZHGT.js → chunk-FG6U7KQQ.js} +5 -5
  206. package/dist/{chunk-IXLUZHGT.js.map → chunk-FG6U7KQQ.js.map} +1 -1
  207. package/dist/chunk-FKKJHGN5.js +147 -0
  208. package/dist/chunk-FKKJHGN5.js.map +1 -0
  209. package/dist/{chunk-FDZNYD4C.js → chunk-GCAK23PU.js} +34 -3
  210. package/dist/chunk-GCAK23PU.js.map +1 -0
  211. package/dist/chunk-GXSX6Q6O.js +42 -0
  212. package/dist/chunk-GXSX6Q6O.js.map +1 -0
  213. package/dist/{chunk-LOSRXZAH.js → chunk-HJXVVFBT.js} +14 -6
  214. package/dist/chunk-HJXVVFBT.js.map +1 -0
  215. package/dist/{chunk-M5KZ26VV.js → chunk-HQZG3OFL.js} +11 -1
  216. package/dist/chunk-HQZG3OFL.js.map +1 -0
  217. package/dist/{chunk-ELCMSQNJ.js → chunk-HTERKONR.js} +8 -8
  218. package/dist/chunk-HTERKONR.js.map +1 -0
  219. package/dist/chunk-HYORKKYP.js +8 -0
  220. package/dist/chunk-HYORKKYP.js.map +1 -0
  221. package/dist/chunk-IO27YTL3.js +73 -0
  222. package/dist/chunk-IO27YTL3.js.map +1 -0
  223. package/dist/chunk-ITUQC4FW.js +163 -0
  224. package/dist/chunk-ITUQC4FW.js.map +1 -0
  225. package/dist/chunk-K57NINLH.js +137 -0
  226. package/dist/chunk-K57NINLH.js.map +1 -0
  227. package/dist/chunk-KC6WUSNS.js +34 -0
  228. package/dist/chunk-KC6WUSNS.js.map +1 -0
  229. package/dist/{chunk-W4IK7AWD.js → chunk-KDQZ3E5C.js} +3 -1
  230. package/dist/chunk-KDQZ3E5C.js.map +1 -0
  231. package/dist/{chunk-2MSPNRWJ.js → chunk-KK3S5OTW.js} +27 -11
  232. package/dist/chunk-KK3S5OTW.js.map +1 -0
  233. package/dist/chunk-LTBVP6VN.js +59 -0
  234. package/dist/chunk-LTBVP6VN.js.map +1 -0
  235. package/dist/chunk-OHPYT2BH.js +82 -0
  236. package/dist/chunk-OHPYT2BH.js.map +1 -0
  237. package/dist/{chunk-HZPHCSCS.js → chunk-OY2MXIBB.js} +8 -2
  238. package/dist/chunk-OY2MXIBB.js.map +1 -0
  239. package/dist/chunk-PE2KPZDW.js +85 -0
  240. package/dist/chunk-PE2KPZDW.js.map +1 -0
  241. package/dist/{chunk-QTSMHH5J.js → chunk-QPTJ5DOO.js} +5 -3
  242. package/dist/chunk-QPTJ5DOO.js.map +1 -0
  243. package/dist/{chunk-JOR5LGYE.js → chunk-RFLW4FPL.js} +1 -1
  244. package/dist/chunk-RFLW4FPL.js.map +1 -0
  245. package/dist/{chunk-U6QYTMDB.js → chunk-RMWNO6BA.js} +6 -2
  246. package/dist/chunk-RMWNO6BA.js.map +1 -0
  247. package/dist/{chunk-TDMHA7C3.js → chunk-SQ2Q3OQI.js} +112 -63
  248. package/dist/chunk-SQ2Q3OQI.js.map +1 -0
  249. package/dist/{chunk-K4AT3V3J.js → chunk-T74YB76U.js} +13 -11
  250. package/dist/chunk-T74YB76U.js.map +1 -0
  251. package/dist/{chunk-BYFTHA4I.js → chunk-TAHR457X.js} +53 -6
  252. package/dist/chunk-TAHR457X.js.map +1 -0
  253. package/dist/{chunk-3VXDSIBJ.js → chunk-TKNVL53O.js} +2 -2
  254. package/dist/{chunk-3VXDSIBJ.js.map → chunk-TKNVL53O.js.map} +1 -1
  255. package/dist/chunk-TNJLNLVE.js +115 -0
  256. package/dist/chunk-TNJLNLVE.js.map +1 -0
  257. package/dist/chunk-TUID42UE.js +15 -0
  258. package/dist/chunk-TUID42UE.js.map +1 -0
  259. package/dist/{chunk-PKL6QJKK.js → chunk-UMNHJSIO.js} +93 -80
  260. package/dist/chunk-UMNHJSIO.js.map +1 -0
  261. package/dist/chunk-UTCAOOXU.js +116 -0
  262. package/dist/chunk-UTCAOOXU.js.map +1 -0
  263. package/dist/{chunk-MF6ZUUJZ.js → chunk-VEME3D7K.js} +38 -40
  264. package/dist/chunk-VEME3D7K.js.map +1 -0
  265. package/dist/{chunk-HLDRH23D.js → chunk-WJKHLOP5.js} +2 -2
  266. package/dist/{chunk-HLDRH23D.js.map → chunk-WJKHLOP5.js.map} +1 -1
  267. package/dist/chunk-WU57BYYM.js +115 -0
  268. package/dist/chunk-WU57BYYM.js.map +1 -0
  269. package/dist/{chunk-TGLUDQP2.js → chunk-ZCDRLN3B.js} +11 -11
  270. package/dist/chunk-ZCDRLN3B.js.map +1 -0
  271. package/dist/chunk-ZX2QQJXD.js +249 -0
  272. package/dist/chunk-ZX2QQJXD.js.map +1 -0
  273. package/dist/{chunk-6E2H2E5A.js → chunk-ZXZAECHZ.js} +6 -6
  274. package/dist/{chunk-6E2H2E5A.js.map → chunk-ZXZAECHZ.js.map} +1 -1
  275. package/dist/collapsible-panel.js +3 -3
  276. package/dist/color-field.d.ts +51 -0
  277. package/dist/color-field.js +92 -0
  278. package/dist/color-field.js.map +1 -0
  279. package/dist/color-picker.d.ts +88 -0
  280. package/dist/color-picker.js +8 -0
  281. package/dist/color-picker.js.map +1 -0
  282. package/dist/color-swatches.d.ts +56 -0
  283. package/dist/color-swatches.js +4 -0
  284. package/dist/color-swatches.js.map +1 -0
  285. package/dist/combobox.js +1 -1
  286. package/dist/content-item.d.ts +13 -1
  287. package/dist/content-item.js +1 -1
  288. package/dist/disclosure-arrow.js +1 -1
  289. package/dist/disclosure.d.ts +57 -0
  290. package/dist/disclosure.js +51 -0
  291. package/dist/disclosure.js.map +1 -0
  292. package/dist/file-picker.d.ts +7 -0
  293. package/dist/file-picker.js +1 -1
  294. package/dist/help-tags-register.d.ts +8 -8
  295. package/dist/help-tags-register.js +3 -2
  296. package/dist/help-tags-register.js.map +1 -1
  297. package/dist/index.d.ts +16 -9
  298. package/dist/index.js +58 -46
  299. package/dist/list-action-row.js +4 -1
  300. package/dist/list-detail-dialog.d.ts +117 -0
  301. package/dist/list-detail-dialog.js +165 -0
  302. package/dist/list-detail-dialog.js.map +1 -0
  303. package/dist/list-header.js +1 -1
  304. package/dist/list-item.js +1 -1
  305. package/dist/list.d.ts +17 -2
  306. package/dist/list.js +1 -1
  307. package/dist/lucide-icon.d.ts +9 -1
  308. package/dist/lucide-icon.js +1 -1
  309. package/dist/{composer.d.ts → message-composer.d.ts} +20 -12
  310. package/dist/message-composer.js +6 -0
  311. package/dist/message-composer.js.map +1 -0
  312. package/dist/nav-stack.js +1 -1
  313. package/dist/pane.d.ts +36 -3
  314. package/dist/pane.js +1 -1
  315. package/dist/popup-menu-register.d.ts +6 -5
  316. package/dist/popup-menu-register.js +3 -326
  317. package/dist/popup-menu-register.js.map +1 -1
  318. package/dist/popup-menu.d.ts +41 -23
  319. package/dist/popup-menu.js +5 -1
  320. package/dist/progress-bar.d.ts +52 -0
  321. package/dist/progress-bar.js +68 -0
  322. package/dist/progress-bar.js.map +1 -0
  323. package/dist/progress-ring.d.ts +44 -0
  324. package/dist/progress-ring.js +73 -0
  325. package/dist/progress-ring.js.map +1 -0
  326. package/dist/radio-group.d.ts +62 -0
  327. package/dist/radio-group.js +4 -0
  328. package/dist/radio-group.js.map +1 -0
  329. package/dist/row.js +1 -1
  330. package/dist/{token-search-model-aYR0YAei.d.ts → search-field-CrGTN5sa.d.ts} +67 -43
  331. package/dist/search-field-model.d.ts +3 -0
  332. package/dist/search-field-model.js +3 -0
  333. package/dist/search-field-model.js.map +1 -0
  334. package/dist/search-field.d.ts +3 -0
  335. package/dist/search-field.js +5 -0
  336. package/dist/search-field.js.map +1 -0
  337. package/dist/select-register.d.ts +6 -3
  338. package/dist/select-register.js +383 -241
  339. package/dist/select-register.js.map +1 -1
  340. package/dist/select.d.ts +30 -6
  341. package/dist/select.js +3 -1
  342. package/dist/selection.d.ts +54 -0
  343. package/dist/selection.js +3 -0
  344. package/dist/selection.js.map +1 -0
  345. package/dist/slider.d.ts +74 -0
  346. package/dist/slider.js +103 -0
  347. package/dist/slider.js.map +1 -0
  348. package/dist/split-button.js +1 -1
  349. package/dist/split-view.d.ts +5 -2
  350. package/dist/split-view.js +18 -159
  351. package/dist/split-view.js.map +1 -1
  352. package/dist/state-banner.js +1 -1
  353. package/dist/styles/badge.css +18 -6
  354. package/dist/styles/button.css +230 -0
  355. package/dist/styles/catalog/components/catalog-example.css +13 -4
  356. package/dist/styles/checkbox.css +121 -0
  357. package/dist/styles/choice-chips.css +58 -7
  358. package/dist/styles/color-field.css +125 -0
  359. package/dist/styles/color-picker.css +331 -0
  360. package/dist/styles/color-swatches.css +122 -0
  361. package/dist/styles/combobox.css +7 -5
  362. package/dist/styles/components/actions/button/button.css +230 -0
  363. package/dist/styles/components/actions/popup-menu/popup-menu.css +326 -198
  364. package/dist/styles/components/actions/toolbar/toolbar.css +25 -3
  365. package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +67 -104
  366. package/dist/styles/components/actions/toolbar-text/toolbar-text.css +5 -18
  367. package/dist/styles/components/collections/list/list.css +37 -0
  368. package/dist/styles/components/feedback/badge/badge.css +18 -6
  369. package/dist/styles/components/feedback/progress-bar/progress-bar.css +168 -0
  370. package/dist/styles/components/feedback/progress-ring/progress-ring.css +91 -0
  371. package/dist/styles/components/feedback/state-banner/state-banner.css +18 -3
  372. package/dist/styles/components/forms/checkbox/checkbox.css +121 -0
  373. package/dist/styles/components/forms/choice-chips/choice-chips.css +58 -7
  374. package/dist/styles/components/forms/color-field/color-field.css +125 -0
  375. package/dist/styles/components/forms/color-picker/color-picker.css +331 -0
  376. package/dist/styles/components/forms/color-swatches/color-swatches.css +122 -0
  377. package/dist/styles/components/forms/combobox/combobox.css +7 -5
  378. package/dist/styles/components/forms/{composer/composer.css → message-composer/message-composer.css} +17 -33
  379. package/dist/styles/components/forms/radio-group/radio-group.css +156 -0
  380. package/dist/styles/{token-search-field.css → components/forms/search-field/search-field.css} +111 -102
  381. package/dist/styles/components/forms/select/select.css +370 -249
  382. package/dist/styles/components/forms/slider/slider.css +241 -0
  383. package/dist/styles/components/forms/switch/switch.css +132 -0
  384. package/dist/styles/components/forms/tag-field/tag-field.css +8 -0
  385. package/dist/styles/components/forms/text-field/text-field.css +193 -0
  386. package/dist/styles/components/layout/pane/pane.css +254 -0
  387. package/dist/styles/components/layout/resizable-region/resizable-region.css +3 -2
  388. package/dist/styles/components/layout/row/row.css +11 -0
  389. package/dist/styles/components/layout/split-view/split-view.css +25 -0
  390. package/dist/styles/components/layout/workbench/workbench.css +12 -4
  391. package/dist/styles/components/navigation/disclosure-arrow/disclosure-arrow.css +20 -0
  392. package/dist/styles/components/navigation/tab-bar/tab-bar.css +7 -7
  393. package/dist/styles/components/navigation/{app-tab/app-tab.css → tab-bar-item/tab-bar-item.css} +95 -90
  394. package/dist/styles/components/surfaces/disclosure/disclosure.css +98 -0
  395. package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +263 -116
  396. package/dist/styles/components/typography/text/text.css +14 -12
  397. package/dist/styles/disclosure-arrow.css +20 -0
  398. package/dist/styles/disclosure.css +98 -0
  399. package/dist/styles/foundation.css +6 -4
  400. package/dist/styles/list-detail-dialog.css +11 -0
  401. package/dist/styles/list.css +37 -0
  402. package/dist/styles/{composer.css → message-composer.css} +17 -33
  403. package/dist/styles/overlay-toast.css +149 -0
  404. package/dist/styles/overlay-tooltip.css +55 -0
  405. package/dist/styles/pane.css +254 -0
  406. package/dist/styles/popup-menu.css +326 -198
  407. package/dist/styles/progress-bar.css +168 -0
  408. package/dist/styles/progress-ring.css +91 -0
  409. package/dist/styles/radio-group.css +156 -0
  410. package/dist/styles/resizable-region.css +3 -2
  411. package/dist/styles/row.css +11 -0
  412. package/dist/styles/{components/forms/token-search-field/token-search-field.css → search-field.css} +111 -102
  413. package/dist/styles/select.css +370 -249
  414. package/dist/styles/slider.css +241 -0
  415. package/dist/styles/split-view.css +25 -0
  416. package/dist/styles/state-banner.css +18 -3
  417. package/dist/styles/styles.css +16 -5
  418. package/dist/styles/surface-scaffold.css +263 -116
  419. package/dist/styles/switch.css +132 -0
  420. package/dist/styles/{app-tab.css → tab-bar-item.css} +95 -90
  421. package/dist/styles/tab-bar.css +7 -7
  422. package/dist/styles/tag-field.css +8 -0
  423. package/dist/styles/text-field.css +193 -0
  424. package/dist/styles/text.css +14 -12
  425. package/dist/styles/toolbar-control-group.css +67 -104
  426. package/dist/styles/toolbar-text.css +5 -18
  427. package/dist/styles/toolbar.css +25 -3
  428. package/dist/styles/webawesome.css +9 -0
  429. package/dist/styles/workbench-dialog.css +10 -0
  430. package/dist/styles/workbench.css +12 -4
  431. package/dist/surface-scaffold-register.d.ts +7 -5
  432. package/dist/surface-scaffold-register.js +2 -246
  433. package/dist/surface-scaffold-register.js.map +1 -1
  434. package/dist/surface-scaffold.d.ts +70 -7
  435. package/dist/surface-scaffold.js +5 -1
  436. package/dist/switch.d.ts +38 -0
  437. package/dist/switch.js +4 -0
  438. package/dist/switch.js.map +1 -0
  439. package/dist/{app-tab.d.ts → tab-bar-item.d.ts} +11 -11
  440. package/dist/tab-bar-item.js +6 -0
  441. package/dist/tab-bar-item.js.map +1 -0
  442. package/dist/tab-bar.d.ts +3 -3
  443. package/dist/tab-bar.js +1 -1
  444. package/dist/tab-navigator.js +1 -1
  445. package/dist/tag-field.d.ts +52 -0
  446. package/dist/tag-field.js +6 -0
  447. package/dist/tag-field.js.map +1 -0
  448. package/dist/text-field.d.ts +83 -0
  449. package/dist/text-field.js +6 -0
  450. package/dist/text-field.js.map +1 -0
  451. package/dist/text.d.ts +6 -1
  452. package/dist/text.js +1 -1
  453. package/dist/{types-CVgIwSdq.d.ts → types-DmHWkSd6.d.ts} +19 -1
  454. package/dist/webawesome.d.ts +3 -0
  455. package/dist/wire-catalog.d.ts +8 -2
  456. package/dist/wire-catalog.js +16 -4
  457. package/dist/wire-catalog.js.map +1 -1
  458. package/dist/wire-checkboxes.d.ts +10 -0
  459. package/dist/wire-checkboxes.js +3 -0
  460. package/dist/{wire-composers.js.map → wire-checkboxes.js.map} +1 -1
  461. package/dist/wire-choice-chips.d.ts +17 -0
  462. package/dist/wire-choice-chips.js +4 -0
  463. package/dist/{wire-token-search-fields.js.map → wire-choice-chips.js.map} +1 -1
  464. package/dist/wire-color-fields.d.ts +33 -0
  465. package/dist/wire-color-fields.js +82 -0
  466. package/dist/wire-color-fields.js.map +1 -0
  467. package/dist/wire-color-pickers.d.ts +34 -0
  468. package/dist/wire-color-pickers.js +9 -0
  469. package/dist/wire-color-pickers.js.map +1 -0
  470. package/dist/wire-comboboxes.js +2 -1
  471. package/dist/wire-content-items.d.ts +5 -1
  472. package/dist/wire-content-items.js +84 -15
  473. package/dist/wire-content-items.js.map +1 -1
  474. package/dist/wire-file-pickers.d.ts +3 -2
  475. package/dist/wire-file-pickers.js +1 -1
  476. package/dist/{wire-composers.d.ts → wire-message-composers.d.ts} +5 -4
  477. package/dist/wire-message-composers.js +3 -0
  478. package/dist/wire-message-composers.js.map +1 -0
  479. package/dist/wire-overlay-sheets.js +1 -1
  480. package/dist/wire-pane-chrome.d.ts +21 -0
  481. package/dist/wire-pane-chrome.js +67 -0
  482. package/dist/wire-pane-chrome.js.map +1 -0
  483. package/dist/{wire-token-search-fields.d.ts → wire-search-fields.d.ts} +25 -25
  484. package/dist/wire-search-fields.js +6 -0
  485. package/dist/wire-search-fields.js.map +1 -0
  486. package/dist/wire-sliders.d.ts +12 -0
  487. package/dist/wire-sliders.js +31 -0
  488. package/dist/wire-sliders.js.map +1 -0
  489. package/dist/wire-tab-bars.js +1 -1
  490. package/dist/wire-tag-fields.d.ts +41 -0
  491. package/dist/wire-tag-fields.js +258 -0
  492. package/dist/wire-tag-fields.js.map +1 -0
  493. package/dist/wire-text-fields.d.ts +12 -0
  494. package/dist/wire-text-fields.js +3 -0
  495. package/dist/wire-text-fields.js.map +1 -0
  496. package/dist/workbench-dialog.d.ts +97 -0
  497. package/dist/workbench-dialog.js +124 -0
  498. package/dist/workbench-dialog.js.map +1 -0
  499. package/dist/workbench.d.ts +5 -0
  500. package/dist/workbench.js +1 -1
  501. package/docs/accessibility.md +181 -97
  502. package/docs/anchored-surface.md +8 -7
  503. package/docs/app-layouts.md +28 -0
  504. package/docs/catalog.md +14 -5
  505. package/docs/color-field.md +65 -0
  506. package/docs/color-picker.md +71 -0
  507. package/docs/color-swatches.md +46 -0
  508. package/docs/component-contract.md +31 -32
  509. package/docs/component-selection.md +232 -165
  510. package/docs/design/templates/button/emphasis-dark.svg +1 -0
  511. package/docs/design/templates/button/emphasis.svg +1 -0
  512. package/docs/design/templates/button/icons-dark.svg +1 -0
  513. package/docs/design/templates/button/icons.svg +1 -0
  514. package/docs/design/templates/button/pill-dark.svg +1 -0
  515. package/docs/design/templates/button/pill.svg +1 -0
  516. package/docs/design/templates/button/states-dark.svg +1 -0
  517. package/docs/design/templates/button/states.svg +1 -0
  518. package/docs/design/templates/button/toggles-dark.svg +1 -0
  519. package/docs/design/templates/button/toggles.svg +1 -0
  520. package/docs/design/templates/button/tones-dark.svg +1 -0
  521. package/docs/design/templates/button/tones.svg +1 -0
  522. package/docs/design/templates/button-dark.svg +1 -0
  523. package/docs/design/templates/button.svg +1 -0
  524. package/docs/design/templates/checkbox/compact-dark.svg +1 -0
  525. package/docs/design/templates/checkbox/compact.svg +1 -0
  526. package/docs/design/templates/checkbox/error-dark.svg +1 -0
  527. package/docs/design/templates/checkbox/error.svg +1 -0
  528. package/docs/design/templates/checkbox/mixed-dark.svg +1 -0
  529. package/docs/design/templates/checkbox/mixed.svg +1 -0
  530. package/docs/design/templates/checkbox/states-dark.svg +1 -0
  531. package/docs/design/templates/checkbox/states.svg +1 -0
  532. package/docs/design/templates/checkbox-dark.svg +1 -0
  533. package/docs/design/templates/checkbox.svg +1 -0
  534. package/docs/design/templates/choice-chips/color-palette-dark.svg +1 -1
  535. package/docs/design/templates/choice-chips/color-palette.svg +1 -1
  536. package/docs/design/templates/choice-chips/compact-icons-dark.svg +1 -1
  537. package/docs/design/templates/choice-chips/compact-icons.svg +1 -1
  538. package/docs/design/templates/choice-chips/multiple-dark.svg +1 -1
  539. package/docs/design/templates/choice-chips/multiple.svg +1 -1
  540. package/docs/design/templates/choice-chips-dark.svg +1 -1
  541. package/docs/design/templates/choice-chips.svg +1 -1
  542. package/docs/design/templates/color-field/compact-dark.svg +1 -0
  543. package/docs/design/templates/color-field/compact.svg +1 -0
  544. package/docs/design/templates/color-field/error-dark.svg +1 -0
  545. package/docs/design/templates/color-field/error.svg +1 -0
  546. package/docs/design/templates/color-field/hint-dark.svg +1 -0
  547. package/docs/design/templates/color-field/hint.svg +1 -0
  548. package/docs/design/templates/color-field-dark.svg +1 -0
  549. package/docs/design/templates/color-field.svg +1 -0
  550. package/docs/design/templates/color-picker/gray-dark.svg +1 -0
  551. package/docs/design/templates/color-picker/gray.svg +1 -0
  552. package/docs/design/templates/color-picker/rgb-dark.svg +1 -0
  553. package/docs/design/templates/color-picker/rgb.svg +1 -0
  554. package/docs/design/templates/color-picker-dark.svg +1 -0
  555. package/docs/design/templates/color-picker.svg +1 -0
  556. package/docs/design/templates/color-swatches/palette-dark.svg +1 -0
  557. package/docs/design/templates/color-swatches/palette.svg +1 -0
  558. package/docs/design/templates/color-swatches-dark.svg +1 -0
  559. package/docs/design/templates/color-swatches.svg +1 -0
  560. package/docs/design/templates/disclosure/framed-sunken-dark.svg +1 -0
  561. package/docs/design/templates/disclosure/framed-sunken.svg +1 -0
  562. package/docs/design/templates/disclosure/plain-dark.svg +1 -0
  563. package/docs/design/templates/disclosure/plain.svg +1 -0
  564. package/docs/design/templates/disclosure-dark.svg +1 -0
  565. package/docs/design/templates/disclosure.svg +1 -0
  566. package/docs/design/templates/list-header/size-l-dark.svg +1 -1
  567. package/docs/design/templates/list-header/size-l.svg +1 -1
  568. package/docs/design/templates/list-header/size-m-dark.svg +1 -1
  569. package/docs/design/templates/list-header/size-m.svg +1 -1
  570. package/docs/design/templates/list-header/size-xl-dark.svg +1 -1
  571. package/docs/design/templates/list-header/size-xl.svg +1 -1
  572. package/docs/design/templates/list-header-dark.svg +1 -1
  573. package/docs/design/templates/list-header.svg +1 -1
  574. package/docs/design/templates/message-composer/chat-dark.svg +1 -0
  575. package/docs/design/templates/message-composer/chat.svg +1 -0
  576. package/docs/design/templates/{composer → message-composer}/prompt-dark.svg +1 -1
  577. package/docs/design/templates/{composer → message-composer}/prompt.svg +1 -1
  578. package/docs/design/templates/message-composer-dark.svg +1 -0
  579. package/docs/design/templates/message-composer.svg +1 -0
  580. package/docs/design/templates/progress-bar/determinate-dark.svg +1 -0
  581. package/docs/design/templates/progress-bar/determinate.svg +1 -0
  582. package/docs/design/templates/progress-bar/tones-dark.svg +1 -0
  583. package/docs/design/templates/progress-bar/tones.svg +1 -0
  584. package/docs/design/templates/progress-bar-dark.svg +1 -0
  585. package/docs/design/templates/progress-bar.svg +1 -0
  586. package/docs/design/templates/progress-ring/sizes-dark.svg +1 -0
  587. package/docs/design/templates/progress-ring/sizes.svg +1 -0
  588. package/docs/design/templates/progress-ring/tones-dark.svg +1 -0
  589. package/docs/design/templates/progress-ring/tones.svg +1 -0
  590. package/docs/design/templates/progress-ring-dark.svg +1 -0
  591. package/docs/design/templates/progress-ring.svg +1 -0
  592. package/docs/design/templates/radio-group/horizontal-dark.svg +1 -0
  593. package/docs/design/templates/radio-group/horizontal.svg +1 -0
  594. package/docs/design/templates/radio-group/vertical-dark.svg +1 -0
  595. package/docs/design/templates/radio-group/vertical.svg +1 -0
  596. package/docs/design/templates/radio-group-dark.svg +1 -0
  597. package/docs/design/templates/radio-group.svg +1 -0
  598. package/docs/design/templates/segmented-control/equal-dark.svg +1 -1
  599. package/docs/design/templates/segmented-control/equal.svg +1 -1
  600. package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -1
  601. package/docs/design/templates/segmented-control/pill-small.svg +1 -1
  602. package/docs/design/templates/segmented-control-dark.svg +1 -1
  603. package/docs/design/templates/segmented-control.svg +1 -1
  604. package/docs/design/templates/select/compact-dark.svg +1 -0
  605. package/docs/design/templates/select/compact.svg +1 -0
  606. package/docs/design/templates/select/form-dark.svg +1 -0
  607. package/docs/design/templates/select/form.svg +1 -0
  608. package/docs/design/templates/select/icons-dark.svg +1 -0
  609. package/docs/design/templates/select/icons.svg +1 -0
  610. package/docs/design/templates/select-dark.svg +1 -0
  611. package/docs/design/templates/select.svg +1 -0
  612. package/docs/design/templates/slider/compact-dark.svg +1 -0
  613. package/docs/design/templates/slider/compact.svg +1 -0
  614. package/docs/design/templates/slider/readout-dark.svg +1 -0
  615. package/docs/design/templates/slider/readout.svg +1 -0
  616. package/docs/design/templates/slider/ticks-dark.svg +1 -0
  617. package/docs/design/templates/slider/ticks.svg +1 -0
  618. package/docs/design/templates/slider-dark.svg +1 -0
  619. package/docs/design/templates/slider.svg +1 -0
  620. package/docs/design/templates/switch/compact-dark.svg +1 -0
  621. package/docs/design/templates/switch/compact.svg +1 -0
  622. package/docs/design/templates/switch/states-dark.svg +1 -0
  623. package/docs/design/templates/switch/states.svg +1 -0
  624. package/docs/design/templates/switch-dark.svg +1 -0
  625. package/docs/design/templates/switch.svg +1 -0
  626. package/docs/design/templates/tag-field/error-dark.svg +1 -0
  627. package/docs/design/templates/tag-field/error.svg +1 -0
  628. package/docs/design/templates/tag-field/tags-dark.svg +1 -0
  629. package/docs/design/templates/tag-field/tags.svg +1 -0
  630. package/docs/design/templates/tag-field-dark.svg +1 -0
  631. package/docs/design/templates/tag-field.svg +1 -0
  632. package/docs/design/templates/text-field/compact-dark.svg +1 -0
  633. package/docs/design/templates/text-field/compact.svg +1 -0
  634. package/docs/design/templates/text-field/error-dark.svg +1 -0
  635. package/docs/design/templates/text-field/error.svg +1 -0
  636. package/docs/design/templates/text-field/labeled-dark.svg +1 -0
  637. package/docs/design/templates/text-field/labeled.svg +1 -0
  638. package/docs/design/templates/text-field/multiline-dark.svg +1 -0
  639. package/docs/design/templates/text-field/multiline.svg +1 -0
  640. package/docs/design/templates/text-field/search-dark.svg +1 -0
  641. package/docs/design/templates/text-field/search.svg +1 -0
  642. package/docs/design/templates/text-field-dark.svg +1 -0
  643. package/docs/design/templates/text-field.svg +1 -0
  644. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
  645. package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
  646. package/docs/design/templates/toolbar/width-visibility-320-dark.svg +1 -1
  647. package/docs/design/templates/toolbar/width-visibility-320.svg +1 -1
  648. package/docs/design/templates/toolbar/width-visibility-600-dark.svg +1 -1
  649. package/docs/design/templates/toolbar/width-visibility-600.svg +1 -1
  650. package/docs/design/templates/toolbar-dark.svg +1 -1
  651. package/docs/design/templates/toolbar.svg +1 -1
  652. package/docs/design/templates/value-table/details-dark.svg +1 -1
  653. package/docs/design/templates/value-table/details.svg +1 -1
  654. package/docs/design/templates/value-table-dark.svg +1 -1
  655. package/docs/design/templates/value-table.svg +1 -1
  656. package/docs/design/templates.md +19 -6
  657. package/docs/design-philosophy.md +6 -6
  658. package/docs/disclosure.md +63 -0
  659. package/docs/examples/component-catalog-extension.json +2 -2
  660. package/docs/layout.md +16 -7
  661. package/docs/list-detail-dialog.md +96 -0
  662. package/docs/manual-test-plan.md +1 -1
  663. package/docs/{composer.md → message-composer.md} +41 -28
  664. package/docs/overlay-toast.md +62 -0
  665. package/docs/overlay-tooltip.md +53 -0
  666. package/docs/progress.md +62 -0
  667. package/docs/recipes.md +15 -21
  668. package/docs/slider.md +64 -0
  669. package/docs/surface-scaffold.md +155 -88
  670. package/docs/tag-field.md +66 -0
  671. package/docs/type-contracts.md +8 -8
  672. package/docs/ui-analyzer.md +1 -1
  673. package/docs/ui-doctor.md +11 -6
  674. package/docs/ux-demo.md +6 -6
  675. package/docs/webawesome-migration.md +80 -0
  676. package/docs/webawesome-theme.md +57 -35
  677. package/docs/workbench-dialog.md +85 -0
  678. package/docs/workbench.md +10 -6
  679. package/docs/writing.md +10 -8
  680. package/doctor/copy-capitalization-checks.mjs +18 -9
  681. package/llms.txt +131 -57
  682. package/package.json +156 -39
  683. package/ux-demo/recipes/composer-form.tsx +18 -19
  684. package/ux-demo/recipes/list-detail-dialog.tsx +55 -162
  685. package/ux-demo/recipes/mount-recipe.ts +7 -6
  686. package/ux-demo/recipes/types.ts +1 -0
  687. package/ai/components/icon-button.md +0 -82
  688. package/ai/components/icon-toggle-button.md +0 -80
  689. package/ai/components/token-search-field.md +0 -107
  690. package/dist/app-tab.js +0 -6
  691. package/dist/app-tab.js.map +0 -1
  692. package/dist/browser/app-tab.js +0 -4
  693. package/dist/browser/composer.js +0 -4
  694. package/dist/browser/icon-toggle-button.js +0 -4
  695. package/dist/browser/token-search-field.js +0 -4
  696. package/dist/chunk-2MSPNRWJ.js.map +0 -1
  697. package/dist/chunk-7IUEBNCO.js.map +0 -1
  698. package/dist/chunk-AV7CPAPT.js +0 -82
  699. package/dist/chunk-AV7CPAPT.js.map +0 -1
  700. package/dist/chunk-BYFTHA4I.js.map +0 -1
  701. package/dist/chunk-CA7LNX3J.js +0 -44
  702. package/dist/chunk-CA7LNX3J.js.map +0 -1
  703. package/dist/chunk-ELCMSQNJ.js.map +0 -1
  704. package/dist/chunk-ETCWQLJV.js.map +0 -1
  705. package/dist/chunk-FDZNYD4C.js.map +0 -1
  706. package/dist/chunk-FR76ZJQC.js +0 -90
  707. package/dist/chunk-FR76ZJQC.js.map +0 -1
  708. package/dist/chunk-HQZYKJ56.js.map +0 -1
  709. package/dist/chunk-HZPHCSCS.js.map +0 -1
  710. package/dist/chunk-IM3GKYOG.js.map +0 -1
  711. package/dist/chunk-JOR5LGYE.js.map +0 -1
  712. package/dist/chunk-K4AT3V3J.js.map +0 -1
  713. package/dist/chunk-LL45C7BB.js.map +0 -1
  714. package/dist/chunk-LOSRXZAH.js.map +0 -1
  715. package/dist/chunk-LPHU44S3.js.map +0 -1
  716. package/dist/chunk-M5KZ26VV.js.map +0 -1
  717. package/dist/chunk-MF6ZUUJZ.js.map +0 -1
  718. package/dist/chunk-MXNIVEVL.js.map +0 -1
  719. package/dist/chunk-NS762OVM.js +0 -222
  720. package/dist/chunk-NS762OVM.js.map +0 -1
  721. package/dist/chunk-PKL6QJKK.js.map +0 -1
  722. package/dist/chunk-QTSMHH5J.js.map +0 -1
  723. package/dist/chunk-TDMHA7C3.js.map +0 -1
  724. package/dist/chunk-TGLUDQP2.js.map +0 -1
  725. package/dist/chunk-U6QYTMDB.js.map +0 -1
  726. package/dist/chunk-VFYO3UGZ.js +0 -45
  727. package/dist/chunk-VFYO3UGZ.js.map +0 -1
  728. package/dist/chunk-W4IK7AWD.js.map +0 -1
  729. package/dist/chunk-YBWQR2OK.js.map +0 -1
  730. package/dist/composer.js +0 -5
  731. package/dist/composer.js.map +0 -1
  732. package/dist/icon-button.d.ts +0 -46
  733. package/dist/icon-button.js +0 -6
  734. package/dist/icon-button.js.map +0 -1
  735. package/dist/icon-toggle-button.d.ts +0 -42
  736. package/dist/icon-toggle-button.js +0 -6
  737. package/dist/icon-toggle-button.js.map +0 -1
  738. package/dist/styles/components/actions/icon-button/icon-button.css +0 -22
  739. package/dist/styles/components/actions/icon-toggle-button/icon-toggle-button.css +0 -83
  740. package/dist/styles/icon-button.css +0 -22
  741. package/dist/styles/icon-toggle-button.css +0 -83
  742. package/dist/token-search-field.d.ts +0 -3
  743. package/dist/token-search-field.js +0 -5
  744. package/dist/token-search-field.js.map +0 -1
  745. package/dist/token-search-model.d.ts +0 -3
  746. package/dist/token-search-model.js +0 -3
  747. package/dist/token-search-model.js.map +0 -1
  748. package/dist/wire-composers.js +0 -3
  749. package/dist/wire-token-search-fields.js +0 -6
  750. package/docs/design/templates/composer/chat-dark.svg +0 -1
  751. package/docs/design/templates/composer/chat.svg +0 -1
  752. package/docs/design/templates/composer-dark.svg +0 -1
  753. package/docs/design/templates/composer.svg +0 -1
  754. /package/docs/design/templates/{token-search-field → search-field}/empty-dark.svg +0 -0
  755. /package/docs/design/templates/{token-search-field → search-field}/empty.svg +0 -0
  756. /package/docs/design/templates/{token-search-field → search-field}/tokens-dark.svg +0 -0
  757. /package/docs/design/templates/{token-search-field → search-field}/tokens.svg +0 -0
  758. /package/docs/design/templates/{token-search-field-dark.svg → search-field-dark.svg} +0 -0
  759. /package/docs/design/templates/{token-search-field.svg → search-field.svg} +0 -0
@@ -1,6 +1,6 @@
1
1
  # Public API signatures for the UI authoring corpus
2
2
 
3
- Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.103` and `kerfjs@5.0.0-beta.103`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
3
+ Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.105` and `kerfjs@5.0.0-beta.105`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
4
4
 
5
5
  ## `@kerfjs/ui/css-values`
6
6
 
@@ -518,9 +518,9 @@ interface PopupMenuItem {
518
518
  label: string;
519
519
  /** Delegated `data-action` the app handles when the item is chosen. */
520
520
  action?: string;
521
- /** Native `wa-dropdown-item` value, reported by its `wa-select` event. */
521
+ /** The item's value, reported in the menu's `kui-menu-select` event. */
522
522
  value?: string;
523
- /** Leading icon, typically a `LucideIcon`; it is placed in the item's icon slot. */
523
+ /** Leading icon, typically a `LucideIcon`, before the label. */
524
524
  icon?: SafeHtml;
525
525
  /** A checkbox choice, including nested choices; omit for a plain command. */
526
526
  checked?: boolean;
@@ -550,13 +550,30 @@ type PopupMenuTriggerName = {
550
550
  /** Visible trigger text, which is also its accessible name. */
551
551
  text: string;
552
552
  label?: never;
553
+ triggerContent?: never;
553
554
  } | {
554
555
  text?: never;
555
556
  /**
556
557
  * Accessible name of an icon-only trigger, rendered as visually hidden
557
- * slotted text (a Web Awesome button takes its name from its content).
558
+ * text inside the trigger button.
558
559
  */
559
560
  label: string;
561
+ triggerContent?: never;
562
+ } | {
563
+ text?: never;
564
+ /**
565
+ * The trigger's accessible name ("Status: Started"); the visible
566
+ * content is hidden from assistive technology.
567
+ */
568
+ label: string;
569
+ /**
570
+ * Visible content that is the whole trigger, such as a `Badge` showing
571
+ * the current status. Kerf owns the bare button around it (no chrome,
572
+ * a pill focus ring, the pointer cursor, `aria-haspopup`), and the
573
+ * caret is off unless `caret` is set.
574
+ */
575
+ triggerContent: KerfUiContent;
576
+ icon?: never;
560
577
  };
561
578
  /** A context PopupMenu's viewport anchor point. */
562
579
  interface PopupMenuAnchor {
@@ -569,6 +586,7 @@ type PopupMenuTrigger = (PopupMenuTriggerName & {
569
586
  }) | {
570
587
  context: true;
571
588
  label: string;
589
+ triggerContent?: never;
572
590
  /**
573
591
  * The viewport point (CSS pixels, as in `MouseEvent.clientX/Y`) the
574
592
  * menu opens from. Rendered into the menu itself, so it survives
@@ -594,37 +612,37 @@ type PopupMenuProps = PopupMenuTrigger & {
594
612
  /** Native named-slot assignment when composed inside a web component. */
595
613
  slot?: string;
596
614
  };
597
- /** A rendered context PopupMenu with Web Awesome's controlled open state. */
598
- type PopupMenuElement = HTMLElement & {
599
- open: boolean;
600
- };
615
+ /** A rendered PopupMenu root, the element the open and close helpers take. */
616
+ type PopupMenuElement = HTMLElement;
601
617
  /**
602
618
  * Open a PopupMenu at viewport pointer coordinates. A `context` menu rendered
603
619
  * without `anchor` moves its invisible anchor there (a menu rendered with
604
- * `anchor` opens with `openPopupMenu` instead). A button-triggered menu (such as a `ListActionRow`
605
- * trailing menu) anchors its popup at the point, opening `bottom-start` like a
606
- * context menu, for this opening only; once the menu has closed it returns to
607
- * its trigger and placement. Before Web Awesome upgrades it, the menu opens at
608
- * its trigger.
620
+ * `anchor` opens with `openPopupMenu` instead). A button-triggered menu (such
621
+ * as a `ListActionRow` trailing menu) opens `bottom-start` from the point,
622
+ * like a context menu, for this opening only; its next opening returns to its
623
+ * trigger and placement. Needs the `/register` entry.
609
624
  */
610
625
  declare function openPopupMenuAt(menu: PopupMenuElement, x: number, y: number): void;
611
626
  /**
612
- * Open a context PopupMenu at the `anchor` it was rendered with (or the
613
- * point a previous `openPopupMenuAt` set).
627
+ * Open a PopupMenu from its trigger, or a context PopupMenu at the `anchor`
628
+ * it was rendered with (or the point a previous `openPopupMenuAt` set).
629
+ * Needs the `/register` entry.
614
630
  */
615
631
  declare function openPopupMenu(menu: PopupMenuElement): void;
616
- /** Close a programmatically opened PopupMenu. */
632
+ /** Close an open PopupMenu, and any submenu it shows. */
617
633
  declare function closePopupMenu(menu: PopupMenuElement): void;
618
634
  /**
619
- * An action menu: a trigger button that opens a list of commands. Renders the
620
- * `wa-dropdown` root directly, so a `single` `ToolbarControlGroup` (with
621
- * `nestedDropdown`) or a `PopupSurface` sizes and insets it as usual. Items
622
- * dispatch through delegated `data-action`s; the app owns the commands and any
623
- * open-state reaction. Import `@kerfjs/ui/popup-menu/register` once to register
624
- * the Web Awesome elements. At viewport widths up to 480px, submenus appear
625
- * above or below their parent menu so their rows do not cover the parent list.
635
+ * An action menu: a trigger button that opens a list of commands in the top
636
+ * layer. A `single` `ToolbarControlGroup` (with `nestedDropdown`) or a
637
+ * `PopupSurface` sizes and insets it as usual. Items dispatch through
638
+ * delegated `data-action`s, and the root reports each choice as a bubbling
639
+ * `kui-menu-select` event; the app owns the commands and any open-state reaction.
640
+ * Import `@kerfjs/ui/popup-menu/register` once to wire opening, keyboard
641
+ * navigation, submenus, and dismissal. At viewport widths up to 480px,
642
+ * submenus appear above or below their parent menu so their rows do not cover
643
+ * the parent list.
626
644
  */
627
- declare function PopupMenu({ text, label, icon, items, placement, caret, disabled, rootAttributes, slot, context, anchor, }: PopupMenuProps): SafeHtml;
645
+ declare function PopupMenu({ text, label, icon, triggerContent, items, placement, caret, disabled, rootAttributes, slot, context, anchor, }: PopupMenuProps): SafeHtml;
628
646
 
629
647
  export { PopupMenu, type PopupMenuAnchor, type PopupMenuDivider, type PopupMenuElement, type PopupMenuEntry, type PopupMenuHeading, type PopupMenuItem, type PopupMenuPlacement, type PopupMenuProps, closePopupMenu, openPopupMenu, openPopupMenuAt };
630
648
  ```
@@ -757,6 +775,8 @@ type ListRootAttributes = StructuralRootAttributes & Readonly<{
757
775
  'data-frame'?: never;
758
776
  'data-surface'?: never;
759
777
  'data-inset'?: never;
778
+ 'data-content-width'?: never;
779
+ 'data-content-align'?: never;
760
780
  'data-text-insets'?: never;
761
781
  'data-control-insets'?: never;
762
782
  }>;
@@ -772,6 +792,12 @@ type ListSurface = 'base' | 'raised';
772
792
  * 16px inline below 576px. It replaces any `textInsets`/`controlInsets`.
773
793
  */
774
794
  type ListInset = 'document';
795
+ /**
796
+ * A readable measure for a page's content column: `compact` 440px, `medium`
797
+ * 640px, or `wide` 864px of content, the same steps as a catalog example's
798
+ * `contentWidth`.
799
+ */
800
+ type ListContentWidth = 'compact' | 'medium' | 'wide';
775
801
  interface ListProps {
776
802
  children?: KerfUiContent;
777
803
  /** Make this list a labeled multi-select grid for `ContentItem selectionMode="multiple"` rows. */
@@ -837,6 +863,13 @@ interface ListProps {
837
863
  /** Physical divider edges in canonical top/right/bottom/left order. */
838
864
  dividerSides?: Sides;
839
865
  /** A preset four-sided inset; see `ListInset`. */
866
+ /**
867
+ * Cap the list's content at a readable measure, plus its insets, so a page
868
+ * column needs no application CSS. Composes with `inset="document"`.
869
+ */
870
+ contentWidth?: ListContentWidth;
871
+ /** Where a `contentWidth` column sits: `center` (default) or `start`. */
872
+ contentAlign?: 'start' | 'center';
840
873
  inset?: ListInset;
841
874
  /** Physical sides that receive the standard 17px text inset. */
842
875
  textInsets?: Sides;
@@ -860,9 +893,9 @@ interface ListProps {
860
893
  */
861
894
  type ListConfig = Pick<ListProps, 'gap' | 'hAlign' | 'vAlign' | 'dividerSides' | 'textInsets' | 'controlInsets'>;
862
895
  /** A stretch-aligned vertical stack with optional gap, flex, fill, scroll, and dividers. */
863
- declare function List({ children, selectionMode, ariaLabel, gap, flex, fill, hAlign, vAlign, scrollable, scrollClearance, frame, maxHeight, minHeight, surface, inset, dividerSides, textInsets, controlInsets, className, rootAttributes, slot, }: ListProps): kerfjs.SafeHtml;
896
+ declare function List({ children, selectionMode, ariaLabel, gap, flex, fill, hAlign, vAlign, scrollable, scrollClearance, frame, maxHeight, minHeight, surface, inset, contentWidth, contentAlign, dividerSides, textInsets, controlInsets, className, rootAttributes, slot, }: ListProps): kerfjs.SafeHtml;
864
897
 
865
- export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, List, type ListConfig, type ListInset, type ListProps, type ListSurface, ListVerticalAlignment, ScrollClearance, Sides, UiGap };
898
+ export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, List, type ListConfig, type ListContentWidth, type ListInset, type ListProps, type ListSurface, ListVerticalAlignment, ScrollClearance, Sides, UiGap };
866
899
  ```
867
900
 
868
901
  ## `@kerfjs/ui/list-action-row`
@@ -1152,12 +1185,14 @@ type ContentItemRootAttributes = Readonly<Record<`data-${string}`, string | unde
1152
1185
  'data-appearance'?: never;
1153
1186
  'data-outlined'?: never;
1154
1187
  'data-bubble'?: never;
1188
+ 'data-grid-row'?: never;
1155
1189
  }>;
1156
1190
  type ContentItemInteractiveRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
1157
1191
  'data-component'?: never;
1158
1192
  'data-appearance'?: never;
1159
1193
  'data-outlined'?: never;
1160
1194
  'data-bubble'?: never;
1195
+ 'data-grid-row'?: never;
1161
1196
  'data-action'?: never;
1162
1197
  'data-item-id'?: never;
1163
1198
  'data-interactive'?: never;
@@ -1219,6 +1254,14 @@ type ContentItemProps = ContentItemBaseProps & ({
1219
1254
  disabled?: never;
1220
1255
  /** Opt into keyboard (`0`) or programmatic (`-1`) focus. */
1221
1256
  tabIndex?: 0 | -1;
1257
+ /**
1258
+ * A non-selectable row of a multi-select `List` or `Grid`: renders
1259
+ * `role="row"` around a `gridcell`, with no `aria-selected` and no
1260
+ * Tab stop of its own, for content between selectable rows (an
1261
+ * activity group, a "messages skipped" divider). Its controls stay
1262
+ * reachable by Tab; arrow keys skip it.
1263
+ */
1264
+ gridRow?: boolean;
1222
1265
  /** Existing static `data-*` metadata remains available. */
1223
1266
  rootAttributes?: ContentItemRootAttributes;
1224
1267
  } | {
@@ -1231,6 +1274,8 @@ type ContentItemProps = ContentItemBaseProps & ({
1231
1274
  selected?: boolean;
1232
1275
  disabled?: boolean;
1233
1276
  tabIndex?: never;
1277
+ /** An interactive item is already a row in a multi-select grid. */
1278
+ gridRow?: never;
1234
1279
  /** Safe app metadata; interaction attributes are component-owned. */
1235
1280
  rootAttributes?: ContentItemInteractiveRootAttributes;
1236
1281
  });
@@ -1239,7 +1284,7 @@ type ContentItemProps = ContentItemBaseProps & ({
1239
1284
  * border (transparent unless `framed`), 8px padding, and a rounded or pill
1240
1285
  * radius. It owns that whole geometry, so wrappers must not add more.
1241
1286
  */
1242
- declare function ContentItem({ appearance, children, frame, flush, shape, bubble, title, ariaLabel, focusTarget, outlined, tabIndex, interactive, action, itemId, selectionMode, selected, disabled, className, rootAttributes, slot, }: ContentItemProps): kerfjs.SafeHtml;
1287
+ declare function ContentItem({ appearance, children, frame, flush, shape, bubble, title, ariaLabel, focusTarget, outlined, tabIndex, gridRow, interactive, action, itemId, selectionMode, selected, disabled, className, rootAttributes, slot, }: ContentItemProps): kerfjs.SafeHtml;
1243
1288
 
1244
1289
  export { ContentItem, type ContentItemAppearance, type ContentItemBubble, type ContentItemFrame, type ContentItemProps, type ContentItemSelectionMode, type ContentItemShape, SemanticTone };
1245
1290
  ```
@@ -1295,13 +1340,13 @@ declare function ValueTable({ label, density, labelWidth, presentation, stackBel
1295
1340
  export { ValueTable, type ValueTablePresentation, type ValueTableProps, ValueTableRow, type ValueTableRowProps, type ValueTableStackBelow };
1296
1341
  ```
1297
1342
 
1298
- ## `@kerfjs/ui/app-tab`
1343
+ ## `@kerfjs/ui/tab-bar-item`
1299
1344
 
1300
1345
  ```ts
1301
1346
  import { SafeHtml } from 'kerfjs';
1302
1347
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
1303
1348
 
1304
- type AppTabRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
1349
+ type TabBarItemRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
1305
1350
  'data-component'?: never;
1306
1351
  'data-action'?: never;
1307
1352
  'data-tab-id'?: never;
@@ -1313,10 +1358,10 @@ type AppTabRootAttributes = Readonly<Record<`data-${string}`, string | undefined
1313
1358
  'data-name-overflow'?: never;
1314
1359
  'data-pinned'?: never;
1315
1360
  }>;
1316
- type AppTabPresentation = 'pill' | 'segmented' | 'icon-only';
1317
- type AppTabSize = 'default' | 'compact';
1318
- type AppTabNameOverflow = 'ellipsis' | 'visible';
1319
- interface AppTabProps {
1361
+ type TabBarItemPresentation = 'pill' | 'segmented' | 'icon-only';
1362
+ type TabBarItemSize = 'default' | 'compact';
1363
+ type TabBarItemNameOverflow = 'ellipsis' | 'visible';
1364
+ interface TabBarItemProps {
1320
1365
  id: string;
1321
1366
  name: string;
1322
1367
  selected?: boolean;
@@ -1331,13 +1376,13 @@ interface AppTabProps {
1331
1376
  leading?: KerfUiContent;
1332
1377
  trailing?: KerfUiContent;
1333
1378
  /** Visual treatment within a TabBar. Icon-only tabs retain `name` as their accessible name. */
1334
- presentation?: AppTabPresentation;
1379
+ presentation?: TabBarItemPresentation;
1335
1380
  /** Compact tabs use the 32px application-rail height. */
1336
- size?: AppTabSize;
1381
+ size?: TabBarItemSize;
1337
1382
  /** Maximum visible label width in CSS pixels before ellipsis. */
1338
1383
  labelMaxWidth?: number;
1339
1384
  /** Keep the full name visible for an inline loading treatment. */
1340
- nameOverflow?: AppTabNameOverflow;
1385
+ nameOverflow?: TabBarItemNameOverflow;
1341
1386
  /** Decorative dormant content for the close button. Must not contain interactive descendants. */
1342
1387
  closeIcon?: SafeHtml;
1343
1388
  selectAction?: string;
@@ -1356,13 +1401,13 @@ interface AppTabProps {
1356
1401
  * `placeholder` wins when both are set.
1357
1402
  */
1358
1403
  pending?: boolean;
1359
- rootAttributes?: AppTabRootAttributes;
1404
+ rootAttributes?: TabBarItemRootAttributes;
1360
1405
  /** Native named-slot assignment when composed inside a web component. */
1361
1406
  slot?: string;
1362
1407
  }
1363
- declare function AppTab({ id, name, selected, attention, dropTarget, pinned, closable, draggable, leading, trailing, presentation, size, labelMaxWidth, nameOverflow, closeIcon, selectAction, closeAction, className, placeholder, pending, rootAttributes, slot, }: AppTabProps): SafeHtml;
1408
+ declare function TabBarItem({ id, name, selected, attention, dropTarget, pinned, closable, draggable, leading, trailing, presentation, size, labelMaxWidth, nameOverflow, closeIcon, selectAction, closeAction, className, placeholder, pending, rootAttributes, slot, }: TabBarItemProps): SafeHtml;
1364
1409
 
1365
- export { AppTab, type AppTabNameOverflow, type AppTabPresentation, type AppTabProps, type AppTabSize };
1410
+ export { TabBarItem, type TabBarItemNameOverflow, type TabBarItemPresentation, type TabBarItemProps, type TabBarItemSize };
1366
1411
  ```
1367
1412
 
1368
1413
  ## `@kerfjs/ui/tab-bar`
@@ -1375,7 +1420,7 @@ type TabActivation = 'automatic' | 'manual';
1375
1420
  type TabBarAllocation = 'intrinsic' | 'fill';
1376
1421
  type TabBarPresentation = 'rail' | 'segmented' | 'inspector';
1377
1422
  type TabBarTrailingPlacement = 'separate' | 'adjacent';
1378
- /** Tablist width where segmented AppTabs switch to icon-only. */
1423
+ /** Tablist width where segmented TabBarItems switch to icon-only. */
1379
1424
  type TabBarIconOnlyAt = 'wide' | 'narrow' | 'compact';
1380
1425
  interface TabBarProps {
1381
1426
  id: string;
@@ -1398,11 +1443,11 @@ interface TabBarProps {
1398
1443
  * selects with Enter / Space / click — use it when selecting a tab is a heavy action.
1399
1444
  */
1400
1445
  activation?: TabActivation;
1401
- /** How available strip width is allocated across child AppTabs. */
1446
+ /** How available strip width is allocated across child TabBarItems. */
1402
1447
  allocation?: TabBarAllocation;
1403
1448
  /** Named strip chrome for application rails, segmented tabs, or inspectors. */
1404
1449
  presentation?: TabBarPresentation;
1405
- /** Switch segmented AppTabs to icon-only at tablist widths of 832, 704, or 448px. Each tab needs a leading icon. */
1450
+ /** Switch segmented TabBarItems to icon-only at tablist widths of 832, 704, or 448px. Each tab needs a leading icon. */
1406
1451
  iconOnlyAt?: TabBarIconOnlyAt;
1407
1452
  /** Keep a trailing action beside the final tab or at the far edge of the bar. */
1408
1453
  trailingPlacement?: TabBarTrailingPlacement;
@@ -1715,8 +1760,11 @@ interface SplitViewResizable extends Pick<ResizableRegionProps, 'separator' | 'h
1715
1760
  min: number;
1716
1761
  max: number;
1717
1762
  }
1718
- /** One compact view's top- and bottom-toolbar content (see `NavStackView`). */
1719
- type SplitViewCompactViewToolbars = Pick<NavStackView, 'toolbar' | 'bottomToolbar'>;
1763
+ /**
1764
+ * One compact view's top- and bottom-toolbar content and pinned footer (see
1765
+ * `NavStackView`).
1766
+ */
1767
+ type SplitViewCompactViewToolbars = Pick<NavStackView, 'toolbar' | 'bottomToolbar' | 'footer'>;
1720
1768
  /**
1721
1769
  * The compact `NavStack`'s configuration: its toolbar configuration, back
1722
1770
  * control, persistent bottom toolbar, chrome dividers, and chrome and
@@ -1859,9 +1907,27 @@ type PaneRootAttributes = Readonly<Record<`data-${string}`, string | undefined>
1859
1907
  'data-scroll-edge'?: never;
1860
1908
  'data-scroll-edge-distance'?: never;
1861
1909
  'data-header-overlay'?: never;
1910
+ 'data-compact-header'?: never;
1911
+ 'data-compact-footer'?: never;
1912
+ 'data-compact-header-open'?: never;
1913
+ 'data-compact-footer-open'?: never;
1862
1914
  }>;
1863
1915
  /** How a Pane's header and footer relate to its scrolling content. */
1864
1916
  type PaneChromePlacement = 'fixed' | 'auto';
1917
+ /**
1918
+ * How a header or footer behaves when the pane's container presents
1919
+ * compactly (a `NavStack` view, a `TabNavigator` scene, a full-screen dialog,
1920
+ * or a compact `Workbench`): `fixed` stays docked and shrinks the content
1921
+ * area; `scroll` sits inline with the content (a footer settles at the end
1922
+ * and scrolls past when the content is longer); `overlay` lies over the
1923
+ * content on the chrome material, shown only while the app opens it.
1924
+ */
1925
+ type PaneCompactChrome = 'fixed' | 'scroll' | 'overlay';
1926
+ /** The compact chrome policy for a Pane's header and footer. */
1927
+ interface PaneCompactChromePolicy {
1928
+ header?: PaneCompactChrome;
1929
+ footer?: PaneCompactChrome;
1930
+ }
1865
1931
  /**
1866
1932
  * When a Pane draws the divider between its pinned header or footer and its
1867
1933
  * scrolling content: `scroll` while content is scrolled away beneath that
@@ -1922,6 +1988,21 @@ interface PaneProps {
1922
1988
  * text in the normal text color: quiet text can fall below AA over the
1923
1989
  * content passing beneath it.
1924
1990
  */
1991
+ /**
1992
+ * What the header and footer do when the pane's container presents
1993
+ * compactly (default `fixed`); roomy containers ignore it. The container
1994
+ * interprets it, so set it on panes inside a `NavStack`, `TabNavigator`,
1995
+ * full-screen dialog, or `Workbench`.
1996
+ */
1997
+ compactChrome?: PaneCompactChromePolicy;
1998
+ /**
1999
+ * Which `overlay` compact chrome is showing. The app owns it and flips it
2000
+ * from a control the person can reach while the chrome is hidden.
2001
+ */
2002
+ compactChromeOpen?: {
2003
+ header?: boolean;
2004
+ footer?: boolean;
2005
+ };
1925
2006
  headerPresentation?: PaneHeaderPresentation;
1926
2007
  /**
1927
2008
  * With `headerPresentation="clear"`, `material` fades the chrome material
@@ -2005,16 +2086,16 @@ interface PaneProps {
2005
2086
  * or a CollapsiblePanel) forwards, so the app configures that pane instead of
2006
2087
  * styling it. An omitted or `undefined` field keeps the composite's default.
2007
2088
  */
2008
- type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers' | 'headerPresentation' | 'scrollEdge' | 'scrollEdgeDistance' | 'appearance' | 'background' | 'tint' | 'deepInset' | 'scrollClearance' | 'tabIndex' | 'outlined'>;
2089
+ type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers' | 'compactChrome' | 'compactChromeOpen' | 'headerPresentation' | 'scrollEdge' | 'scrollEdgeDistance' | 'appearance' | 'background' | 'tint' | 'deepInset' | 'scrollClearance' | 'tabIndex' | 'outlined'>;
2009
2090
  /**
2010
2091
  * An unpadded application column with optional fixed header/footer slots and one
2011
2092
  * scrolling vertical content owner. Separator lines are independently opt-in on
2012
2093
  * each logical edge, so the same component works as a sidebar, main area,
2013
2094
  * inspector, or dialog column.
2014
2095
  */
2015
- declare function Pane({ header, children, footer, chromePlacement, chromeDividers, headerPresentation, scrollEdge, scrollEdgeDistance, appearance, background, tint, deepInset, scrollClearance, tabIndex, outlined, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
2096
+ declare function Pane({ header, children, footer, chromePlacement, chromeDividers, compactChrome, compactChromeOpen, headerPresentation, scrollEdge, scrollEdgeDistance, appearance, background, tint, deepInset, scrollClearance, tabIndex, outlined, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
2016
2097
 
2017
- export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlacement, type PaneConfig, type PaneContentElement, type PaneElement, type PaneHeaderPresentation, type PaneProps, type PaneSeparatorSide, ScrollClearance, type ScrollEdge, type SurfaceTint, type SurfaceTintScheme };
2098
+ export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlacement, type PaneCompactChrome, type PaneCompactChromePolicy, type PaneConfig, type PaneContentElement, type PaneElement, type PaneHeaderPresentation, type PaneProps, type PaneSeparatorSide, ScrollClearance, type ScrollEdge, type SurfaceTint, type SurfaceTintScheme };
2018
2099
  ```
2019
2100
 
2020
2101
  ## `@kerfjs/ui/workbench`
@@ -2064,6 +2145,11 @@ interface WorkbenchMainToolbar extends ToolbarConfig {
2064
2145
  center?: KerfUiContent;
2065
2146
  /** Groups at the trailing edge, before a collapsed right rail's groups. */
2066
2147
  trailing?: KerfUiContent;
2148
+ /**
2149
+ * Groups after a collapsed right rail's groups, so they stay outermost,
2150
+ * such as a dialog's close control.
2151
+ */
2152
+ end?: KerfUiContent;
2067
2153
  }
2068
2154
  /**
2069
2155
  * The work area's bottom toolbar; a collapsed drawer adds its groups to it.
@@ -2964,8 +3050,8 @@ export { DEFAULT_BREAKPOINTS, type DeviceBreakpoints, type DeviceClass, type Dev
2964
3050
  ```ts
2965
3051
  import * as kerfjs from 'kerfjs';
2966
3052
  import { SafeHtml } from 'kerfjs';
2967
- import { b as CatalogProps } from './types-CVgIwSdq.js';
2968
- export { a as CatalogBackgroundStyle, c as CatalogBrand, d as CatalogEntry, e as CatalogRelated, C as CatalogResource, f as CatalogSecondaryGroup, g as CatalogSection, h as CatalogSettingsConfig, i as CatalogStageRootAttributes, j as CatalogUxReview } from './types-CVgIwSdq.js';
3053
+ import { b as CatalogProps } from './types-DmHWkSd6.js';
3054
+ export { a as CatalogBackgroundStyle, c as CatalogBrand, d as CatalogEntry, e as CatalogRelated, C as CatalogResource, f as CatalogSecondaryGroup, g as CatalogSection, h as CatalogSettingsConfig, i as CatalogStageRootAttributes, j as CatalogTagFilter, k as CatalogUxReview } from './types-DmHWkSd6.js';
2969
3055
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2970
3056
  import './toolbar.js';
2971
3057
  import './sides-BPSWde0A.js';
@@ -2992,7 +3078,7 @@ import './resizable-region.js';
2992
3078
  * An entry's `settings` render in a right-rail settings pane beside the stage,
2993
3079
  * with the same toggle relocation and small-screen overlay.
2994
3080
  */
2995
- declare function Catalog({ id, brand, sections, active, content, collapsed, theme, increasedContrast, reducedMotion, backgroundControl, headerActions, settings, settingsCollapsed, settingsPanel, uxReview, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, toggleSettingsAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
3081
+ declare function Catalog({ id, brand, sections, active, content, collapsed, theme, increasedContrast, reducedMotion, backgroundControl, headerActions, settings, settingsCollapsed, settingsPanel, uxReview, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, toggleSecondaryFilterAction, toggleSettingsAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
2996
3082
 
2997
3083
  /** How a specimen aligns its visible edge with its `ListHeader` label. */
2998
3084
  type CatalogExampleAlign = 'glyph' | 'inline-control' | 'text-trigger' | 'none';
@@ -3119,7 +3205,7 @@ export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleP
3119
3205
  ## `@kerfjs/ui/catalog-resources`
3120
3206
 
3121
3207
  ```ts
3122
- import { C as CatalogResource } from './types-CVgIwSdq.js';
3208
+ import { C as CatalogResource } from './types-DmHWkSd6.js';
3123
3209
  import './toolbar.js';
3124
3210
  import 'kerfjs';
3125
3211
  import './semantic-content-BbzjvSu9.js';
@@ -3175,7 +3261,7 @@ export { type CatalogGuidanceKind, type CatalogResourceKind, type CatalogResourc
3175
3261
 
3176
3262
  ```ts
3177
3263
  import { Signal } from 'kerfjs';
3178
- import { a as CatalogBackgroundStyle } from './types-CVgIwSdq.js';
3264
+ import { a as CatalogBackgroundStyle } from './types-DmHWkSd6.js';
3179
3265
  import './toolbar.js';
3180
3266
  import './semantic-content-BbzjvSu9.js';
3181
3267
  import './sides-BPSWde0A.js';
@@ -3213,6 +3299,11 @@ interface WireCatalogOptions {
3213
3299
  onToggleSettings?: () => void;
3214
3300
  /** Invoked when the secondary (ecosystem) group's disclosure toggle is activated. */
3215
3301
  onToggleSecondary?: () => void;
3302
+ /**
3303
+ * Invoked with the switch's new state when the secondary group's tag-filter
3304
+ * switch changes; the app updates `tagFilter.show`.
3305
+ */
3306
+ onToggleSecondaryFilter?: (show: boolean) => void;
3216
3307
  /** When set, `?<urlParam>=<id>` is written on select via `history.replaceState`. */
3217
3308
  urlParam?: string;
3218
3309
  /**
@@ -3227,6 +3318,7 @@ interface WireCatalogOptions {
3227
3318
  toggleMotionAction?: string;
3228
3319
  selectBackgroundAction?: string;
3229
3320
  toggleSecondaryAction?: string;
3321
+ toggleSecondaryFilterAction?: string;
3230
3322
  toggleSettingsAction?: string;
3231
3323
  /**
3232
3324
  * The sidebar's app-owned collapsed flag. With it, the catalog's Workbench
@@ -3303,7 +3395,7 @@ declare function revealCatalogEntry(root: HTMLElement, id: string, { block, inli
3303
3395
  * catalog's panes and every example in it show their chrome dividers only
3304
3396
  * while scrolled. Returns a disposer.
3305
3397
  */
3306
- declare function wireCatalog(root: HTMLElement, { onSelect, onToggleSidebar, onToggleTheme, onToggleContrast, onToggleMotion, onSelectBackground, onToggleSecondary, onToggleSettings, urlParam, revealSelection, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, toggleSettingsAction, collapsed, sidebarSize, sidebarStorageKey, settingsCollapsed, settingsSize, settingsStorageKey, id: catalogId, onUxReviewProject, }: WireCatalogOptions): () => void;
3398
+ declare function wireCatalog(root: HTMLElement, { onSelect, onToggleSidebar, onToggleTheme, onToggleContrast, onToggleMotion, onSelectBackground, onToggleSecondary, onToggleSecondaryFilter, onToggleSettings, urlParam, revealSelection, selectAction, toggleSidebarAction, toggleThemeAction, toggleContrastAction, toggleMotionAction, selectBackgroundAction, toggleSecondaryAction, toggleSecondaryFilterAction, toggleSettingsAction, collapsed, sidebarSize, sidebarStorageKey, settingsCollapsed, settingsSize, settingsStorageKey, id: catalogId, onUxReviewProject, }: WireCatalogOptions): () => void;
3307
3399
 
3308
3400
  export { type CatalogRevealOptions, type WireCatalogOptions, revealCatalogEntry, wireCatalog };
3309
3401
  ```
@@ -3350,9 +3442,15 @@ export { SegmentedControl, type SegmentedControlAppearance, type SegmentedContro
3350
3442
 
3351
3443
  ```ts
3352
3444
  import { SafeHtml } from 'kerfjs';
3353
- import { CssColor } from './css-values.js';
3445
+ import { CssColor, CssLength } from './css-values.js';
3354
3446
 
3355
3447
  type ChoiceChipsSize = 'default' | 'compact';
3448
+ /**
3449
+ * `chips` (default) are labeled pills; `icons` are square 36px icon-only
3450
+ * choices (an icon picker), each named by its hidden label, which is also
3451
+ * its hover title.
3452
+ */
3453
+ type ChoiceChipsPresentation = 'chips' | 'icons';
3356
3454
  /**
3357
3455
  * A leading color dot: a {@link CssColor} from `uiColor()`, `colorVar()`, or
3358
3456
  * `fillColor()`, or `'transparent'` for the no-color swatch (an outlined
@@ -3373,14 +3471,23 @@ interface ChoiceChipsChoice<Value extends string = string> {
3373
3471
  }
3374
3472
  interface ChoiceChipsCommonProps<Value extends string> {
3375
3473
  /**
3376
- * Native input `name`: the form field the selected value (or, with
3377
- * `multiple`, every checked value) submits under.
3474
+ * Form field name: the selected value (or, with `multiple`, every selected
3475
+ * value) submits under it.
3378
3476
  */
3379
3477
  name: string;
3380
3478
  choices: readonly ChoiceChipsChoice<Value>[];
3381
- /** Delegated `data-action` on every input; listen for `change`. */
3479
+ /**
3480
+ * Delegated `data-action`; listen for `change`. It sits on every native
3481
+ * input, or for `multiple: true` on the group, which `wireChoiceChips`
3482
+ * fires `change` on.
3483
+ */
3382
3484
  action?: string;
3383
3485
  size?: ChoiceChipsSize;
3486
+ presentation?: ChoiceChipsPresentation;
3487
+ /**
3488
+ * Cap the group's height; past it the group scrolls (a long icon grid).
3489
+ */
3490
+ maxHeight?: CssLength;
3384
3491
  /** Disable the whole group. */
3385
3492
  disabled?: boolean;
3386
3493
  /** Associate the inputs with a form outside their ancestor chain. */
@@ -3400,18 +3507,34 @@ interface ChoiceChipsSingleProps<Value extends string = string> {
3400
3507
  }
3401
3508
  /**
3402
3509
  * Any number of values, backed by native checkboxes: each pill is its own Tab
3403
- * stop, Space toggles it, and every checked value submits under `name`.
3510
+ * stop, a click or Space toggles it alone, and every checked value submits
3511
+ * under `name`.
3404
3512
  */
3405
- interface ChoiceChipsMultipleProps<Value extends string = string> {
3406
- multiple: true;
3513
+ interface ChoiceChipsToggleProps<Value extends string = string> {
3514
+ multiple: 'toggle';
3407
3515
  /** The checked values. Omit (or pass `[]`) for none. */
3408
3516
  value?: readonly NoInfer<Value>[];
3409
3517
  /**
3410
- * Native `required` on a checkbox demands that one box, so a multiple group
3518
+ * Native `required` on a checkbox demands that one box, so a toggle group
3411
3519
  * has no "at least one" requirement; validate the checked set in the app.
3412
3520
  */
3413
3521
  required?: never;
3414
3522
  }
3523
+ /**
3524
+ * Any number of values with the conventional desktop selection model, as an
3525
+ * ARIA multi-select listbox: a click selects one chip, Cmd (Apple) or Ctrl
3526
+ * (elsewhere) toggles one, and Shift extends a range. The group is one Tab
3527
+ * stop; arrows move the selection, Shift+arrows extend it, Cmd/Ctrl+arrows
3528
+ * move focus alone, Space toggles, and Cmd/Ctrl+A selects all. Hidden inputs
3529
+ * submit every selected value under `name`. Requires `wireChoiceChips`.
3530
+ */
3531
+ interface ChoiceChipsMultipleProps<Value extends string = string> {
3532
+ multiple: true;
3533
+ /** The selected values. Omit (or pass `[]`) for none. */
3534
+ value?: readonly NoInfer<Value>[];
3535
+ /** Validate the selected set in the app; a listbox has no native `required`. */
3536
+ required?: never;
3537
+ }
3415
3538
  /** A group is named either by a string or by a visible heading's id. */
3416
3539
  type ChoiceChipsNaming = {
3417
3540
  label: string;
@@ -3420,31 +3543,34 @@ type ChoiceChipsNaming = {
3420
3543
  labelledBy: string;
3421
3544
  label?: never;
3422
3545
  };
3423
- type ChoiceChipsProps<Value extends string = string> = ChoiceChipsCommonProps<Value> & (ChoiceChipsSingleProps<Value> | ChoiceChipsMultipleProps<Value>) & ChoiceChipsNaming;
3546
+ type ChoiceChipsProps<Value extends string = string> = ChoiceChipsCommonProps<Value> & (ChoiceChipsSingleProps<Value> | ChoiceChipsToggleProps<Value> | ChoiceChipsMultipleProps<Value>) & ChoiceChipsNaming;
3547
+ /** Which selection model a ChoiceChips group renders. */
3548
+ type ChoiceChipsSelectionMode = 'single' | 'toggle' | 'multiple';
3424
3549
  /**
3425
- * A wrapping set of pill chips backed by native inputs. By default it is an
3426
- * exclusive radio group: one Tab stop, arrow-key selection, and a real form
3427
- * value. With `multiple` it is a checkbox group: each pill toggles on its own
3428
- * and every checked value submits. Each choice may lead with a color swatch
3429
- * (including a struck-through transparent swatch) or an icon.
3550
+ * A wrapping set of pill chips. By default it is an exclusive radio group:
3551
+ * one Tab stop, arrow-key selection, and a real form value. With
3552
+ * `multiple: 'toggle'` it is a checkbox group: each pill toggles on its own.
3553
+ * With `multiple: true` it is a multi-select listbox with modifier-key
3554
+ * selection (wire it with `wireChoiceChips`). Each choice may lead with a
3555
+ * color swatch (including a struck-through transparent swatch) or an icon.
3430
3556
  */
3431
3557
  declare function ChoiceChips<Value extends string>(props: ChoiceChipsProps<Value>): SafeHtml;
3432
3558
 
3433
- export { ChoiceChips, type ChoiceChipsChoice, type ChoiceChipsMultipleProps, type ChoiceChipsNaming, type ChoiceChipsProps, type ChoiceChipsSingleProps, type ChoiceChipsSize, type ChoiceChipsSwatch };
3559
+ export { ChoiceChips, type ChoiceChipsChoice, type ChoiceChipsMultipleProps, type ChoiceChipsNaming, type ChoiceChipsPresentation, type ChoiceChipsProps, type ChoiceChipsSelectionMode, type ChoiceChipsSingleProps, type ChoiceChipsSize, type ChoiceChipsSwatch, type ChoiceChipsToggleProps };
3434
3560
  ```
3435
3561
 
3436
- ## `@kerfjs/ui/composer`
3562
+ ## `@kerfjs/ui/message-composer`
3437
3563
 
3438
3564
  ```ts
3439
3565
  import * as kerfjs from 'kerfjs';
3440
3566
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
3441
3567
 
3442
3568
  /**
3443
- * Application `data-*` identity on the Composer root, such as `data-key`;
3569
+ * Application `data-*` identity on the MessageComposer root, such as `data-key`;
3444
3570
  * the composer's own configuration attributes stay protected.
3445
3571
  */
3446
- type ComposerRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
3447
- interface ComposerProps {
3572
+ type MessageComposerRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
3573
+ interface MessageComposerProps {
3448
3574
  /** The message field's accessible name, in title style ("Message"). */
3449
3575
  label: string;
3450
3576
  /** Native textarea `name`: the form field the message submits under. */
@@ -3468,14 +3594,22 @@ interface ComposerProps {
3468
3594
  * `minRows`.
3469
3595
  */
3470
3596
  maxRows?: number;
3471
- /** Quiet, sentence-style supporting copy at the start of the action row. */
3597
+ /**
3598
+ * Quiet, sentence-style supporting copy in the action row's leading zone,
3599
+ * after any `leading` controls.
3600
+ */
3472
3601
  hint?: string;
3602
+ /**
3603
+ * Controls at the start of the action row, such as an attach button or a
3604
+ * model `Select`, normally in a `ToolbarControlGroup`.
3605
+ */
3606
+ leading?: KerfUiContent;
3473
3607
  /** Trailing controls in the action row, normally one brand Send button. */
3474
- actions: KerfUiContent;
3608
+ trailing: KerfUiContent;
3475
3609
  /** Disable the field; the app disables its own actions. */
3476
3610
  disabled?: boolean;
3477
3611
  /**
3478
- * Opt in to Enter-to-send: with `wireComposers` running over an ancestor,
3612
+ * Opt in to Enter-to-send: with `wireMessageComposers` running over an ancestor,
3479
3613
  * Enter (or Cmd/Ctrl+Enter) in the field activates the first trailing
3480
3614
  * action, Shift+Enter inserts a newline, and an Enter that commits an IME
3481
3615
  * composition or meets an empty message does not send. The field announces
@@ -3483,7 +3617,7 @@ interface ComposerProps {
3483
3617
  */
3484
3618
  submitOnEnter?: boolean;
3485
3619
  /** Safe `data-*` identity on the root. */
3486
- rootAttributes?: ComposerRootAttributes;
3620
+ rootAttributes?: MessageComposerRootAttributes;
3487
3621
  className?: string;
3488
3622
  /** Native named-slot assignment, such as a `wa-dialog`'s `footer`. */
3489
3623
  slot?: string;
@@ -3491,45 +3625,63 @@ interface ComposerProps {
3491
3625
  /**
3492
3626
  * A chat or prompt composer: a raised frame whose border turns brand while
3493
3627
  * focus is within, holding a borderless message field that grows with its
3494
- * content between `minRows` and `maxRows` lines, above an action row with an
3495
- * optional hint and trailing actions. The app owns the value and sending;
3496
- * `submitOnEnter` with `wireComposers` adds Enter-to-send.
3628
+ * content between `minRows` and `maxRows` lines, above a compact `Toolbar`
3629
+ * action row: optional `leading` controls and `hint`, then `trailing` actions. The app owns the value and sending;
3630
+ * `submitOnEnter` with `wireMessageComposers` adds Enter-to-send.
3497
3631
  */
3498
- declare function Composer({ label, name, id, value, placeholder, minRows, maxRows, hint, actions, disabled, submitOnEnter, rootAttributes, className, slot, }: ComposerProps): kerfjs.SafeHtml;
3632
+ declare function MessageComposer({ label, name, id, value, placeholder, minRows, maxRows, hint, leading, trailing, disabled, submitOnEnter, rootAttributes, className, slot, }: MessageComposerProps): kerfjs.SafeHtml;
3499
3633
 
3500
- export { Composer, type ComposerProps, type ComposerRootAttributes };
3634
+ export { MessageComposer, type MessageComposerProps, type MessageComposerRootAttributes };
3501
3635
  ```
3502
3636
 
3503
- ## `@kerfjs/ui/wire-composers`
3637
+ ## `@kerfjs/ui/wire-message-composers`
3504
3638
 
3505
3639
  ```ts
3506
3640
  type Root = HTMLElement | Document;
3507
3641
  /**
3508
- * Enter-to-send for every `Composer` rendered with `submitOnEnter` below
3642
+ * Enter-to-send for every `MessageComposer` rendered with `submitOnEnter` below
3509
3643
  * root. In its field, Enter (alone or with Cmd or Ctrl) activates the
3510
3644
  * composer's first trailing action, so a keyboard send runs the same
3511
3645
  * delegated handler as a click. Shift+Enter and Alt+Enter insert a newline.
3512
3646
  * Nothing is sent, and no newline is inserted, when the message is empty or
3513
3647
  * whitespace-only, the key is auto-repeating, or the first action is
3514
- * disabled, loading, or `aria-disabled`. An Enter that commits an IME
3648
+ * disabled, loading (a busy `Button` reports `aria-busy`), or
3649
+ * `aria-disabled`. An Enter that commits an IME
3515
3650
  * composition (`isComposing`, keyCode 229, or between `compositionstart` and
3516
3651
  * `compositionend`) is left to the input method. Dispose with the owning
3517
3652
  * application.
3518
3653
  */
3519
- declare function wireComposers(root: Root): () => void;
3654
+ declare function wireMessageComposers(root: Root): () => void;
3520
3655
 
3521
- export { wireComposers };
3656
+ export { wireMessageComposers };
3522
3657
  ```
3523
3658
 
3524
3659
  ## `@kerfjs/ui/select`
3525
3660
 
3526
3661
  ```ts
3527
3662
  import { SafeHtml } from 'kerfjs';
3663
+ import { KerfCustomElement } from 'kerfjs/jsx-runtime';
3528
3664
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
3529
- import { CssForegroundColor } from './css-values.js';
3665
+ import { CssForegroundColor, CssLength } from './css-values.js';
3530
3666
  import { LucideNode } from './lucide-icon.js';
3531
3667
  import 'lucide';
3532
3668
 
3669
+ declare module 'kerfjs/jsx-runtime' {
3670
+ namespace JSX {
3671
+ interface IntrinsicElements {
3672
+ /** The Select root: a light-DOM form control defined by `select/register`. */
3673
+ 'kui-select': KerfCustomElement & {
3674
+ class?: string;
3675
+ name?: string;
3676
+ value?: string;
3677
+ multiple?: boolean;
3678
+ disabled?: boolean;
3679
+ style?: string;
3680
+ slot?: string;
3681
+ };
3682
+ }
3683
+ }
3684
+ }
3533
3685
  interface SelectChoice<Value extends string = string> {
3534
3686
  value: Value;
3535
3687
  label: string;
@@ -3571,9 +3723,9 @@ interface SelectBaseProps<Value extends string = string> {
3571
3723
  name: string;
3572
3724
  choices: readonly SelectChoice<Value>[];
3573
3725
  className?: string;
3574
- /** Empty-value hint text shown in the closed control (the native select placeholder). */
3726
+ /** Empty-value hint text shown in the closed control. */
3575
3727
  placeholderText?: string;
3576
- /** Supporting text shown below the control and associated with its combobox. */
3728
+ /** Supporting text shown below the control and announced as its description. */
3577
3729
  hint?: string;
3578
3730
  disabled?: boolean;
3579
3731
  /** Match menu width to the trigger; default menus grow to content within viewport gutters. */
@@ -3585,6 +3737,13 @@ interface SelectBaseProps<Value extends string = string> {
3585
3737
  size?: SelectSize;
3586
3738
  /** Closed trigger width; omit to keep the presentation's default. */
3587
3739
  triggerWidth?: SelectTriggerWidth;
3740
+ /**
3741
+ * The widest the closed trigger grows, under any presentation; its value
3742
+ * (or `renderSelected` content) ellipsizes inside it and the caret stays.
3743
+ */
3744
+ maxTriggerWidth?: CssLength;
3745
+ /** The narrowest the closed trigger gets. */
3746
+ minTriggerWidth?: CssLength;
3588
3747
  /** Show the disclosure caret (default); omit it for a compact icon-only trigger. */
3589
3748
  caret?: boolean;
3590
3749
  /** Let an enclosing ToolbarControlGroup paint the composed focus ring. */
@@ -3609,8 +3768,8 @@ interface SelectSingleValueProps<Value extends string = string> {
3609
3768
  }
3610
3769
  /**
3611
3770
  * Any number of chosen values. The popup stays open while the person toggles
3612
- * choices and closes on an outside click, Escape, or focus leaving; the closed
3613
- * control summarizes the chosen labels in choice order.
3771
+ * choices and closes on an outside press, Escape, or Tab; the closed control
3772
+ * summarizes the chosen labels in choice order.
3614
3773
  */
3615
3774
  interface SelectMultipleLabelProps<Value extends string = string> {
3616
3775
  multiple: true;
@@ -3627,7 +3786,7 @@ interface SelectMultipleLabelProps<Value extends string = string> {
3627
3786
  * A multiple Select drawn as an icon-only toolbar trigger, such as a
3628
3787
  * "Filter by label" funnel. No single choice is selected, so the trigger shows
3629
3788
  * a fixed `triggerIcon` naming the menu's purpose; while any choice is chosen
3630
- * a count badge sits beside it, and the combobox's accessible name ends with
3789
+ * a count badge sits beside it, and the trigger's accessible name ends with
3631
3790
  * the chosen labels in choice order.
3632
3791
  */
3633
3792
  interface SelectMultipleIconProps<Value extends string = string> {
@@ -3833,27 +3992,27 @@ declare function SunkenPanel({ children, ariaLabel, shape, flex, fill, tabIndex,
3833
3992
  export { SunkenPanel, type SunkenPanelProps, type SunkenPanelShape, ensureSunkenTexture };
3834
3993
  ```
3835
3994
 
3836
- ## `@kerfjs/ui/token-search-field`
3995
+ ## `@kerfjs/ui/search-field`
3837
3996
 
3838
3997
  ```ts
3839
- export { T as TokenSearchEditorAttributes, a as TokenSearchField, b as TokenSearchFieldProps, c as TokenSearchFieldValue, j as TokenSearchToken, k as TokenSearchTrailingAction, l as TokenSearchTrailingActionAttributes, p as placeTokenSearchCaret, r as readTokenSearchField } from './token-search-model-aYR0YAei.js';
3998
+ export { S as SearchField, a as SearchFieldEditorAttributes, d as SearchFieldProps, j as SearchFieldToken, k as SearchFieldTrailingAction, l as SearchFieldTrailingActionAttributes, m as SearchFieldValue, p as placeSearchFieldCaret, r as readSearchField } from './search-field-CrGTN5sa.js';
3840
3999
  import 'kerfjs';
3841
4000
  import './semantic-content-BbzjvSu9.js';
3842
4001
  ```
3843
4002
 
3844
- ## `@kerfjs/ui/wire-token-search-fields`
4003
+ ## `@kerfjs/ui/wire-search-fields`
3845
4004
 
3846
4005
  ```ts
3847
4006
  import { Signal } from 'kerfjs';
3848
- import { d as TokenSearchModel } from './token-search-model-aYR0YAei.js';
4007
+ import { b as SearchFieldModel } from './search-field-CrGTN5sa.js';
3849
4008
  import './semantic-content-BbzjvSu9.js';
3850
4009
 
3851
- interface TokenSearchSubmit {
4010
+ interface SearchFieldSubmit {
3852
4011
  id: string;
3853
4012
  editor: HTMLElement;
3854
4013
  }
3855
- /** Reported to {@link WireTokenSearchFieldsOptions.onEdit} on every editor input. */
3856
- interface TokenSearchEdit extends TokenSearchSubmit {
4014
+ /** Reported to {@link WireSearchFieldsOptions.onEdit} on every editor input. */
4015
+ interface SearchFieldEdit extends SearchFieldSubmit {
3857
4016
  /**
3858
4017
  * The `InputEvent` that mutated the editor — read `event.inputType` / `event.data`
3859
4018
  * to gate commit behavior (e.g. only parse a chip on whitespace-terminated input)
@@ -3862,7 +4021,7 @@ interface TokenSearchEdit extends TokenSearchSubmit {
3862
4021
  event: InputEvent;
3863
4022
  }
3864
4023
  /** Reported when adjacent-token keyboard deletion asks the app to drop a chip. */
3865
- interface TokenSearchTokenRemoval {
4024
+ interface SearchFieldTokenRemoval {
3866
4025
  id: string;
3867
4026
  /** The `data-token-value` of the token the app should remove from its state. */
3868
4027
  value: string;
@@ -3873,11 +4032,11 @@ interface TokenSearchTokenRemoval {
3873
4032
  /**
3874
4033
  * Opt-in keyboard behavior for the atomic token chips. Off unless `keyboard` is
3875
4034
  * set; each piece defaults on once opted in. The helper never mutates app state:
3876
- * a removal is reported through {@link TokenSearchKeyboardOptions.onRemoveToken}
4035
+ * a removal is reported through {@link SearchFieldKeyboardOptions.onRemoveToken}
3877
4036
  * for the caller to apply, while caret movement past a chip is a pure ephemeral
3878
4037
  * mechanic the helper performs itself.
3879
4038
  */
3880
- interface TokenSearchKeyboardBaseOptions {
4039
+ interface SearchFieldKeyboardBaseOptions {
3881
4040
  /**
3882
4041
  * From a collapsed caret with no selection, Backspace removes the token
3883
4042
  * immediately before it and Delete the token immediately after — reported via
@@ -3889,20 +4048,20 @@ interface TokenSearchKeyboardBaseOptions {
3889
4048
  */
3890
4049
  moveCaretPastToken?: boolean;
3891
4050
  }
3892
- type TokenSearchKeyboardOptions = TokenSearchKeyboardBaseOptions & ({
4051
+ type SearchFieldKeyboardOptions = SearchFieldKeyboardBaseOptions & ({
3893
4052
  removeAdjacentToken?: true;
3894
4053
  /** Apply the reported removal to your controlled state, then re-render. */
3895
- onRemoveToken: (removal: TokenSearchTokenRemoval) => void;
4054
+ onRemoveToken: (removal: SearchFieldTokenRemoval) => void;
3896
4055
  } | {
3897
4056
  removeAdjacentToken: false;
3898
4057
  onRemoveToken?: never;
3899
4058
  });
3900
4059
  /**
3901
- * Managed collapsible behavior for the iconic TokenSearchField. Every piece is on
4060
+ * Managed collapsible behavior for the iconic SearchField. Every piece is on
3902
4061
  * by default; disable a specific one to own it in the app. Provide `signals` to
3903
4062
  * drive app-owned `expanded` signals per field id instead of helper-created ones.
3904
4063
  */
3905
- interface TokenSearchCollapsibleOptions {
4064
+ interface SearchFieldCollapsibleOptions {
3906
4065
  /** Expand the field and focus its editor when the iconic trigger is activated. Default: true. */
3907
4066
  expandOnActivate?: boolean;
3908
4067
  /** Collapse the field when focus leaves it while it is empty. Default: true. */
@@ -3915,7 +4074,7 @@ interface TokenSearchCollapsibleOptions {
3915
4074
  * Keep an empty field expanded when focus moves to a caller-owned surface
3916
4075
  * rendered outside the field — a suggestions dropdown, date picker, or help
3917
4076
  * popover shown beside it. Return true for any focus target that must NOT
3918
- * trigger collapse-on-empty-blur. An element carrying `data-token-search-keep-open`
4077
+ * trigger collapse-on-empty-blur. An element carrying `data-search-field-keep-open`
3919
4078
  * (or any node inside one) is always exempt, so this predicate is only needed
3920
4079
  * for surfaces you cannot mark declaratively.
3921
4080
  */
@@ -3923,24 +4082,24 @@ interface TokenSearchCollapsibleOptions {
3923
4082
  /** App-owned `expanded` signals keyed by field id; adopted instead of helper-created. */
3924
4083
  signals?: Readonly<Record<string, Signal<boolean>>>;
3925
4084
  }
3926
- interface WireTokenSearchFieldsOptions {
3927
- /** Optional automatic grammar/suggestion models, keyed by TokenSearchField id. */
3928
- models?: Readonly<Record<string, TokenSearchModel>>;
3929
- onSubmit?: (submission: TokenSearchSubmit) => void;
4085
+ interface WireSearchFieldsOptions {
4086
+ /** Optional automatic grammar/suggestion models, keyed by SearchField id. */
4087
+ models?: Readonly<Record<string, SearchFieldModel>>;
4088
+ onSubmit?: (submission: SearchFieldSubmit) => void;
3930
4089
  /** Fired on every editor `input`, after the browser mutates it, so a caller can drop its own `input` listener. */
3931
- onEdit?: (edit: TokenSearchEdit) => void;
4090
+ onEdit?: (edit: SearchFieldEdit) => void;
3932
4091
  /** Managed collapsible transient behavior. `true`/omitted = on with defaults; `false` = fully off. */
3933
- collapsible?: boolean | TokenSearchCollapsibleOptions;
4092
+ collapsible?: boolean | SearchFieldCollapsibleOptions;
3934
4093
  /** Opt-in atomic-chip keyboard behavior (off by default). */
3935
- keyboard?: false | TokenSearchKeyboardOptions;
4094
+ keyboard?: false | SearchFieldKeyboardOptions;
3936
4095
  }
3937
4096
  /**
3938
- * The value returned from {@link wireTokenSearchFields}: call it (or `dispose()`) to
4097
+ * The value returned from {@link wireSearchFields}: call it (or `dispose()`) to
3939
4098
  * tear down. When collapsible behavior is managed, it also exposes the transient
3940
4099
  * `expanded` state per field id so the app can read it in render, hand in its own
3941
4100
  * signal, or drive it imperatively.
3942
4101
  */
3943
- interface TokenSearchFieldsHandle {
4102
+ interface SearchFieldsHandle {
3944
4103
  (): void;
3945
4104
  dispose(): void;
3946
4105
  /** The managed `expanded` signal for a field id (adopted or helper-created); undefined when unmanaged. */
@@ -3951,14 +4110,14 @@ interface TokenSearchFieldsHandle {
3951
4110
  close(id: string): void;
3952
4111
  }
3953
4112
  /**
3954
- * Wire every TokenSearchField under `root`: submit on Enter, preserve the caret across
4113
+ * Wire every SearchField under `root`: submit on Enter, preserve the caret across
3955
4114
  * controlled token deletion, and (by default) manage the collapsible field's transient
3956
- * expand/collapse/focus. Returns a {@link TokenSearchFieldsHandle} — a disposer that also
4115
+ * expand/collapse/focus. Returns a {@link SearchFieldsHandle} — a disposer that also
3957
4116
  * exposes the managed `expanded` state per field id.
3958
4117
  */
3959
- declare function wireTokenSearchFields(root: HTMLElement, { models, onSubmit, onEdit, collapsible, keyboard, }?: WireTokenSearchFieldsOptions): TokenSearchFieldsHandle;
4118
+ declare function wireSearchFields(root: HTMLElement, { models, onSubmit, onEdit, collapsible, keyboard, }?: WireSearchFieldsOptions): SearchFieldsHandle;
3960
4119
 
3961
- export { type TokenSearchCollapsibleOptions, type TokenSearchEdit, type TokenSearchFieldsHandle, type TokenSearchKeyboardOptions, type TokenSearchSubmit, type TokenSearchTokenRemoval, type WireTokenSearchFieldsOptions, wireTokenSearchFields };
4120
+ export { type SearchFieldCollapsibleOptions, type SearchFieldEdit, type SearchFieldKeyboardOptions, type SearchFieldSubmit, type SearchFieldTokenRemoval, type SearchFieldsHandle, type WireSearchFieldsOptions, wireSearchFields };
3962
4121
  ```
3963
4122
 
3964
4123
  ## `kerfjs/actions`
@@ -4060,9 +4219,17 @@ type BadgeRootAttributes = Readonly<Record<`data-${string}`, string | undefined>
4060
4219
  'data-size'?: never;
4061
4220
  'data-has-icon'?: never;
4062
4221
  'data-truncate'?: never;
4222
+ 'data-placement'?: never;
4063
4223
  }>;
4224
+ /**
4225
+ * `inline` (default) flows with its content; `corner` pins the badge to the
4226
+ * top-trailing corner of the control it sits in (an icon-only `Button`, or a
4227
+ * button in a `ToolbarControlGroup`), out of the pointer's way.
4228
+ */
4229
+ type BadgePlacement = 'inline' | 'corner';
4064
4230
  interface BadgeCommonProps {
4065
4231
  tone?: SemanticTone;
4232
+ placement?: BadgePlacement;
4066
4233
  /** Native tooltip text that explains the badge on hover. */
4067
4234
  title?: string;
4068
4235
  /** Safe `data-*` identity, such as a status band, on the badge root. */
@@ -4123,7 +4290,7 @@ type BadgeProps = BadgeTextProps | BadgeDotProps;
4123
4290
  /** Compact, non-interactive metadata whose tone, emphasis, and shape are configured by props. */
4124
4291
  declare function Badge(props: BadgeProps): SafeHtml;
4125
4292
 
4126
- export { Badge, type BadgeAppearance, type BadgeDotProps, type BadgeProps, type BadgeRootAttributes, type BadgeShape, type BadgeSize, type BadgeTextProps, type BadgeTone, SemanticTone };
4293
+ export { Badge, type BadgeAppearance, type BadgeDotProps, type BadgePlacement, type BadgeProps, type BadgeRootAttributes, type BadgeShape, type BadgeSize, type BadgeTextProps, type BadgeTone, SemanticTone };
4127
4294
  ```
4128
4295
 
4129
4296
  ## `@kerfjs/ui/chip`
@@ -4249,14 +4416,22 @@ interface LucideIconProps {
4249
4416
  color?: CssForegroundColor;
4250
4417
  /** Flow with surrounding text instead of occupying a block. */
4251
4418
  inline?: boolean;
4419
+ /** The icon's accessible name; without it the icon is decorative. */
4252
4420
  label?: string;
4421
+ /**
4422
+ * Hover text, as an SVG `<title>`: a status icon's explanation ("Session
4423
+ * halted"). With `label`, the label stays the accessible name; alone, the
4424
+ * title also names the icon. The whole icon box shows it, not just its
4425
+ * strokes.
4426
+ */
4427
+ title?: string;
4253
4428
  /** Named icon scale or positive pixel size, converted to rem. Omit for 1em. */
4254
4429
  size?: LucideIconSize;
4255
4430
  /** Native named-slot assignment when composed inside a web component. */
4256
4431
  slot?: string;
4257
4432
  }
4258
4433
  /** Render a Lucide-compatible icon node without copying icon SVG strings. */
4259
- declare function LucideIcon({ icon, name, appearance, className, color, inline, label, size, slot, }: LucideIconProps): SafeHtml;
4434
+ declare function LucideIcon({ icon, name, appearance, className, color, inline, label, title, size, slot, }: LucideIconProps): SafeHtml;
4260
4435
 
4261
4436
  export { LucideIcon, type LucideIconProps, type LucideIconSize, type LucideNode };
4262
4437
  ```
@@ -4423,6 +4598,27 @@ import * as kerfjs from 'kerfjs';
4423
4598
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
4424
4599
  import { CssLength } from './css-values.js';
4425
4600
 
4601
+ /** What asked an open DialogSurface to close. */
4602
+ type DialogCloseSource = 'close-button' | 'escape' | 'backdrop';
4603
+ /** The detail of a DialogSurface's cancelable `kui-request-close` event. */
4604
+ interface DialogRequestCloseDetail {
4605
+ readonly source: DialogCloseSource;
4606
+ }
4607
+ /**
4608
+ * Open a DialogSurface as a modal dialog: in the top layer, the rest of the
4609
+ * page inert, focus on its `autofocus` element or else the panel. It plays
4610
+ * its enter motion and, with the controller installed here, keeps its
4611
+ * measured chrome, sheet height, and keyboard clearance across application
4612
+ * re-renders. Opening an open dialog does nothing.
4613
+ */
4614
+ declare function openDialog(dialog: HTMLDialogElement): void;
4615
+ /**
4616
+ * Close an open DialogSurface after its exit motion. The application's own
4617
+ * close is never refused: no `kui-request-close` is dispatched. The native
4618
+ * `close` event fires once it has closed.
4619
+ */
4620
+ declare function closeDialog(dialog: HTMLDialogElement): void;
4621
+
4426
4622
  type DialogSurfaceSize = 'small' | 'medium' | 'large';
4427
4623
  /**
4428
4624
  * How the dialog is presented: `modal` (default) centered on the screen,
@@ -4433,7 +4629,7 @@ type DialogSurfaceSize = 'small' | 'medium' | 'large';
4433
4629
  type DialogSurfacePresentation = 'modal' | 'side-sheet' | 'fullscreen' | 'bottom-sheet';
4434
4630
  /**
4435
4631
  * How a bottom sheet appears or leaves: `slide` (default) moves the panel in
4436
- * from, or out to, the bottom edge; `standard` keeps Web Awesome's
4632
+ * from, or out to, the bottom edge; `standard` keeps the dialog's
4437
4633
  * scale-and-fade. Both honor `prefers-reduced-motion`.
4438
4634
  */
4439
4635
  type DialogSurfaceSheetMotion = 'slide' | 'standard';
@@ -4467,8 +4663,42 @@ type DialogSurfaceHeaderPresentation = 'docked' | 'floating';
4467
4663
  * `data-key`; the surface's own configuration attributes stay protected.
4468
4664
  */
4469
4665
  type DialogSurfaceRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
4470
- interface DialogSurfaceProps {
4666
+ /**
4667
+ * The dialog's accessible name: its `label` text (also the default title), or
4668
+ * the id of an element that names it, such as a `heading` ToolbarText.
4669
+ */
4670
+ type DialogSurfaceName = {
4671
+ label: string;
4672
+ labelledBy?: never;
4673
+ } | {
4674
+ label?: never;
4675
+ labelledBy: string;
4676
+ };
4677
+ type DialogSurfaceProps = DialogSurfaceName & DialogSurfaceOptions;
4678
+ interface DialogSurfaceOptions {
4679
+ /** The dialog's id, for `openDialog(document.getElementById(id))`. */
4680
+ id?: string;
4681
+ /** The body content. */
4471
4682
  children: KerfUiContent;
4683
+ /**
4684
+ * Header title content in place of the `label` text, such as an xl
4685
+ * `ToolbarText` with a description. The dialog keeps its `label` (or
4686
+ * `labelledBy`) name.
4687
+ */
4688
+ heading?: KerfUiContent;
4689
+ /** Controls before the close button in the header. */
4690
+ headerActions?: KerfUiContent;
4691
+ /** The footer, below the body (or floating over it); usually its buttons. */
4692
+ footer?: KerfUiContent;
4693
+ /**
4694
+ * Render no header: no title and no close button. The content then owns its
4695
+ * heading and a way to close (an element with `data-dialog-close`).
4696
+ */
4697
+ withoutHeader?: boolean;
4698
+ /** Close on a press on the backdrop; otherwise the panel pulses. */
4699
+ lightDismiss?: boolean;
4700
+ /** The close button's accessible name (default `Close`). */
4701
+ closeLabel?: string;
4472
4702
  size?: DialogSurfaceSize;
4473
4703
  presentation?: DialogSurfacePresentation;
4474
4704
  /** Modal preferred width. Takes precedence over size, within the viewport cap. */
@@ -4553,8 +4783,16 @@ interface DialogSurfaceProps {
4553
4783
  /** Native named-slot assignment when composed inside a web component. */
4554
4784
  slot?: string;
4555
4785
  }
4556
- /** Configure recurring Web Awesome dialog geometry without consumer ::part() CSS. */
4557
- declare function DialogSurface({ children, size, presentation, preferredWidth, bodyInset, footerInset, viewportGutter, maxHeight, height, minHeight, resizable, enterMotion, exitMotion, bodyLayout, headerPresentation, footerPresentation, footerOffset, rootAttributes, className, slot, }: DialogSurfaceProps): kerfjs.SafeHtml;
4786
+ /**
4787
+ * A modal dialog: a native `<dialog>` with Kerf's header, body, and footer
4788
+ * chrome, sized and presented by its props. Render it closed, then open it
4789
+ * with `openDialog()` and close it with `closeDialog()`, the close button, an
4790
+ * element with `data-dialog-close`, Escape, or (with `lightDismiss`) a press
4791
+ * on the backdrop. Import `@kerfjs/ui/surface-scaffold/register` for the
4792
+ * floating header and footer measurement, the bottom sheet's keyboard
4793
+ * clearance and grabber, and re-render resilience while open.
4794
+ */
4795
+ declare function DialogSurface({ id, label, labelledBy, heading, headerActions, footer, withoutHeader, lightDismiss, closeLabel, children, size, presentation, preferredWidth, bodyInset, footerInset, viewportGutter, maxHeight, height, minHeight, resizable, enterMotion, exitMotion, bodyLayout, headerPresentation, footerPresentation, footerOffset, rootAttributes, className, slot, }: DialogSurfaceProps): kerfjs.SafeHtml;
4558
4796
  /** Where a PopoverDialogSurface appears: the top layer, or in flow. */
4559
4797
  type PopoverDialogSurfacePresentation = 'overlay' | 'embedded';
4560
4798
  /** Application `data-*` metadata on the surface root. */
@@ -4606,8 +4844,8 @@ type PopoverDialogSurfaceProps = PopoverDialogSurfaceName & {
4606
4844
  * A non-modal dialog surface on the native Popover API: Kerf's dialog chrome,
4607
4845
  * viewport-bounded size, and single-child fill without application CSS.
4608
4846
  * Open it with a `popovertarget` control or `showPopover()`; it light
4609
- * dismisses and leaves the page interactive. Use `DialogSurface` with
4610
- * `wa-dialog` when the task must block the page.
4847
+ * dismisses and leaves the page interactive. Use `DialogSurface` when the
4848
+ * task must block the page.
4611
4849
  */
4612
4850
  declare function PopoverDialogSurface({ id, children, label, labelledBy, describedBy, presentation, size, preferredWidth, height, maxHeight, viewportGutter, bodyLayout, rootAttributes, className, slot, }: PopoverDialogSurfaceProps): kerfjs.SafeHtml;
4613
4851
  type PopupSurfaceInset = 'standard' | 'compact' | 'list-zero';
@@ -4621,7 +4859,231 @@ interface PopupSurfaceProps {
4621
4859
  /** Configure recurring Web Awesome dropdown-menu geometry without consumer ::part() CSS. */
4622
4860
  declare function PopupSurface({ children, inset, className, slot, }: PopupSurfaceProps): kerfjs.SafeHtml;
4623
4861
 
4624
- export { DialogSurface, type DialogSurfaceBodyLayout, type DialogSurfaceFooterPresentation, type DialogSurfaceHeaderPresentation, type DialogSurfaceHeight, type DialogSurfaceMaxHeight, type DialogSurfacePresentation, type DialogSurfaceProps, type DialogSurfaceRootAttributes, type DialogSurfaceSheetMotion, type DialogSurfaceSize, PopoverDialogSurface, type PopoverDialogSurfaceDataAttributes, type PopoverDialogSurfacePresentation, type PopoverDialogSurfaceProps, PopupSurface, type PopupSurfaceInset, type PopupSurfaceProps, type SurfaceInset };
4862
+ export { type DialogCloseSource, type DialogRequestCloseDetail, DialogSurface, type DialogSurfaceBodyLayout, type DialogSurfaceFooterPresentation, type DialogSurfaceHeaderPresentation, type DialogSurfaceHeight, type DialogSurfaceMaxHeight, type DialogSurfaceName, type DialogSurfaceOptions, type DialogSurfacePresentation, type DialogSurfaceProps, type DialogSurfaceRootAttributes, type DialogSurfaceSheetMotion, type DialogSurfaceSize, PopoverDialogSurface, type PopoverDialogSurfaceDataAttributes, type PopoverDialogSurfacePresentation, type PopoverDialogSurfaceProps, PopupSurface, type PopupSurfaceInset, type PopupSurfaceProps, type SurfaceInset, closeDialog, openDialog };
4863
+ ```
4864
+
4865
+ ## `@kerfjs/ui/list-detail-dialog`
4866
+
4867
+ ```ts
4868
+ import * as kerfjs from 'kerfjs';
4869
+ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
4870
+ import { CssLength } from './css-values.js';
4871
+ import { SplitViewListWidth } from './split-view.js';
4872
+ import { DialogSurfaceSize, DialogSurfaceHeight, DialogSurfaceMaxHeight, DialogSurfaceRootAttributes } from './surface-scaffold.js';
4873
+ export { DialogCloseSource, DialogRequestCloseDetail, closeDialog, openDialog } from './surface-scaffold.js';
4874
+ import './nav-stack-CU_0dKtI.js';
4875
+ import './pane.js';
4876
+ import './scroll-clearance-BikHljTc.js';
4877
+ import './list.js';
4878
+ import './extension-attributes-mu8MFUl0.js';
4879
+ import './flex-alignment-4ms8ZbV8.js';
4880
+ import './sides-BPSWde0A.js';
4881
+ import './panel-toolbar-vg6Ir5Dy.js';
4882
+ import './toolbar.js';
4883
+ import './lucide-icon.js';
4884
+ import 'lucide';
4885
+ import './toolbar-text.js';
4886
+ import './resizable-region.js';
4887
+
4888
+ /** The list column: a secondary title, its own controls, and the list. */
4889
+ interface ListDetailDialogList {
4890
+ /**
4891
+ * The column's title, at the default toolbar size so it reads as pane
4892
+ * identity beside the detail's primary title. On compact devices it titles
4893
+ * the root view.
4894
+ */
4895
+ title: string;
4896
+ /** Controls after the title in the column's header, such as a `ToolbarControlGroup`. */
4897
+ toolbar?: KerfUiContent;
4898
+ /** The list, usually a `List` of selectable `ListItem`s. */
4899
+ content: KerfUiContent;
4900
+ /** Content pinned below the list, such as an add control. */
4901
+ footer?: KerfUiContent;
4902
+ /**
4903
+ * The column's width on roomy devices (default 280px, at most 40% of the
4904
+ * dialog's width).
4905
+ */
4906
+ width?: SplitViewListWidth;
4907
+ }
4908
+ /** The detail column: the dialog's primary title, actions, and close control. */
4909
+ interface ListDetailDialogDetail {
4910
+ /**
4911
+ * The dialog's primary title: an xl heading at the top of the detail
4912
+ * column on roomy devices, and the pushed view's title on compact devices.
4913
+ */
4914
+ title: string;
4915
+ /** A short supporting line under the roomy title. */
4916
+ description?: string;
4917
+ /**
4918
+ * Header controls before the close control, such as a
4919
+ * `ToolbarControlGroup`. Primary record actions usually go in `footer`.
4920
+ */
4921
+ actions?: KerfUiContent;
4922
+ /** The selected item's detail. */
4923
+ content: KerfUiContent;
4924
+ /** Content pinned below the detail, usually its buttons. */
4925
+ footer?: KerfUiContent;
4926
+ }
4927
+ /**
4928
+ * Application `data-*` identity on the dialog root, such as `data-key`; the
4929
+ * dialog's own configuration attributes stay protected.
4930
+ */
4931
+ type ListDetailDialogRootAttributes = DialogSurfaceRootAttributes;
4932
+ interface ListDetailDialogProps {
4933
+ /**
4934
+ * The dialog's id, for `openDialog(document.getElementById(id))`. Also
4935
+ * prefixes the ids of the split and the detail title.
4936
+ */
4937
+ id: string;
4938
+ /** The dialog's accessible name. */
4939
+ label: string;
4940
+ list: ListDetailDialogList;
4941
+ detail: ListDetailDialogDetail;
4942
+ /**
4943
+ * One pane at a time: derive from `deviceClass().value.compact`. The dialog
4944
+ * fills the screen and drills from the list into the detail as a
4945
+ * `NavStack`; every view keeps the close control.
4946
+ */
4947
+ compact?: boolean;
4948
+ /** On compact devices, whether the detail is pushed over the list. */
4949
+ detailActive?: boolean;
4950
+ /** The compact back control's accessible name (default `Back`). */
4951
+ backLabel?: string;
4952
+ /** The close control's accessible name (default `Close`). */
4953
+ closeLabel?: string;
4954
+ /** Close on a press on the backdrop; otherwise the panel pulses. */
4955
+ lightDismiss?: boolean;
4956
+ /** Roomy preferred width preset (default `large`). */
4957
+ size?: DialogSurfaceSize;
4958
+ /** Roomy preferred width; takes precedence over `size`. */
4959
+ preferredWidth?: CssLength;
4960
+ /** Roomy definite height (default 560px), bounded by the viewport. */
4961
+ height?: DialogSurfaceHeight;
4962
+ /** Roomy height cap in place of a definite height. */
4963
+ maxHeight?: DialogSurfaceMaxHeight;
4964
+ /** Roomy edge clearance from the viewport. */
4965
+ viewportGutter?: CssLength;
4966
+ rootAttributes?: ListDetailDialogRootAttributes;
4967
+ className?: string;
4968
+ /** Native named-slot assignment when composed inside a web component. */
4969
+ slot?: string;
4970
+ }
4971
+ /**
4972
+ * A list-detail dialog: a modal whose list column and detail column each run
4973
+ * its full height. The list column carries a secondary title and its own
4974
+ * controls; the detail column carries the dialog's primary title, its
4975
+ * actions, and the close control, so the divider between them runs from top
4976
+ * to bottom. On compact devices it fills the screen and becomes a `NavStack`
4977
+ * that drills from the list into the detail. Open it with `openDialog()`;
4978
+ * the app owns the selection and, on compact devices, `detailActive` (the
4979
+ * stack's back control dispatches `nav-back`). Built from `DialogSurface`,
4980
+ * `SplitView`, and `Pane`.
4981
+ */
4982
+ declare function ListDetailDialog({ id, label, list, detail, compact, detailActive, backLabel, closeLabel, lightDismiss, size, preferredWidth, height, maxHeight, viewportGutter, rootAttributes, className, slot, }: ListDetailDialogProps): kerfjs.SafeHtml;
4983
+
4984
+ export { ListDetailDialog, type ListDetailDialogDetail, type ListDetailDialogList, type ListDetailDialogProps, type ListDetailDialogRootAttributes };
4985
+ ```
4986
+
4987
+ ## `@kerfjs/ui/workbench-dialog`
4988
+
4989
+ ```ts
4990
+ import * as kerfjs from 'kerfjs';
4991
+ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
4992
+ import { CssLength } from './css-values.js';
4993
+ import { WorkbenchMainBottomToolbar, WorkbenchPanel } from './workbench.js';
4994
+ import { DialogSurfaceSize, DialogSurfaceHeight, DialogSurfaceMaxHeight, DialogSurfaceRootAttributes } from './surface-scaffold.js';
4995
+ export { DialogCloseSource, DialogRequestCloseDetail, closeDialog, openDialog } from './surface-scaffold.js';
4996
+ import './nav-stack-CU_0dKtI.js';
4997
+ import './pane.js';
4998
+ import './scroll-clearance-BikHljTc.js';
4999
+ import './list.js';
5000
+ import './extension-attributes-mu8MFUl0.js';
5001
+ import './flex-alignment-4ms8ZbV8.js';
5002
+ import './sides-BPSWde0A.js';
5003
+ import './panel-toolbar-vg6Ir5Dy.js';
5004
+ import './toolbar.js';
5005
+ import './lucide-icon.js';
5006
+ import 'lucide';
5007
+ import './toolbar-text.js';
5008
+ import './resizable-region.js';
5009
+
5010
+ /**
5011
+ * Application `data-*` identity on the dialog root, such as `data-key`; the
5012
+ * dialog's own configuration attributes stay protected.
5013
+ */
5014
+ type WorkbenchDialogRootAttributes = DialogSurfaceRootAttributes;
5015
+ interface WorkbenchDialogProps {
5016
+ /**
5017
+ * The dialog's id, for `openDialog(document.getElementById(id))`. The
5018
+ * Workbench inside is `<id>-workbench`, so its rails are
5019
+ * `<id>-workbench-left-rail` and `<id>-workbench-right-rail`.
5020
+ */
5021
+ id: string;
5022
+ /** The dialog's accessible name. */
5023
+ label: string;
5024
+ /** The dialog's primary title: an xl heading in the work area's toolbar. */
5025
+ title: string;
5026
+ /** A short supporting line under the title. */
5027
+ description?: string;
5028
+ /** Groups after the title in the work area's toolbar. */
5029
+ leading?: KerfUiContent;
5030
+ /** Header controls before the close control, such as a `ToolbarControlGroup`. */
5031
+ actions?: KerfUiContent;
5032
+ /** The work area. */
5033
+ main: KerfUiContent;
5034
+ /** Fixed content over the work area's bottom toolbar, such as a status line. */
5035
+ mainFooter?: KerfUiContent;
5036
+ /** The work area's bottom toolbar, usually the dialog's buttons. */
5037
+ mainBottomToolbar?: WorkbenchMainBottomToolbar;
5038
+ /**
5039
+ * Side rails with their own toolbars. On compact devices each presents as
5040
+ * an overlay over the work area; the app starts it collapsed and its
5041
+ * `toolbar.toggle` shows it.
5042
+ */
5043
+ leftRail?: WorkbenchPanel;
5044
+ rightRail?: WorkbenchPanel;
5045
+ /** A bottom drawer under the work area. */
5046
+ bottomDrawer?: WorkbenchPanel;
5047
+ /**
5048
+ * Fill the screen with the rails as overlays: derive from
5049
+ * `deviceClass().value.compact`.
5050
+ */
5051
+ compact?: boolean;
5052
+ /** The close control's accessible name (default `Close`). */
5053
+ closeLabel?: string;
5054
+ /** Close on a press on the backdrop; otherwise the panel pulses. */
5055
+ lightDismiss?: boolean;
5056
+ /** Roomy preferred width preset (default `large`). */
5057
+ size?: DialogSurfaceSize;
5058
+ /** Roomy preferred width; takes precedence over `size`. */
5059
+ preferredWidth?: CssLength;
5060
+ /** Roomy definite height (default 560px), bounded by the viewport. */
5061
+ height?: DialogSurfaceHeight;
5062
+ /** Roomy height cap in place of a definite height. */
5063
+ maxHeight?: DialogSurfaceMaxHeight;
5064
+ /** Roomy edge clearance from the viewport. */
5065
+ viewportGutter?: CssLength;
5066
+ /** Minimum work-area width beside inline rails, in px (Workbench default 320). */
5067
+ mainMinSize?: number;
5068
+ rootAttributes?: WorkbenchDialogRootAttributes;
5069
+ className?: string;
5070
+ /** Native named-slot assignment when composed inside a web component. */
5071
+ slot?: string;
5072
+ }
5073
+ /**
5074
+ * A workbench dialog: a modal whose body is a `Workbench`. The work area's
5075
+ * toolbar carries the dialog's primary title, its actions, and the close
5076
+ * control; side rails keep their own toolbars and run the dialog's full
5077
+ * height. On compact devices it fills the screen and its rails become
5078
+ * overlays over the work area, shown by their toolbar toggles, so the work
5079
+ * area keeps its width. Open it with `openDialog()`; the app owns each
5080
+ * rail's `collapsed` state, and `wireWorkbench` closes an overlay rail on
5081
+ * Escape or a press outside it before the dialog sees the Escape. Built from
5082
+ * `DialogSurface` and `Workbench`.
5083
+ */
5084
+ declare function WorkbenchDialog({ id, label, title, description, leading, actions, main, mainFooter, mainBottomToolbar, leftRail, rightRail, bottomDrawer, compact, closeLabel, lightDismiss, size, preferredWidth, height, maxHeight, viewportGutter, mainMinSize, rootAttributes, className, slot, }: WorkbenchDialogProps): kerfjs.SafeHtml;
5085
+
5086
+ export { WorkbenchDialog, type WorkbenchDialogProps, type WorkbenchDialogRootAttributes };
4625
5087
  ```
4626
5088
 
4627
5089
  ## `@kerfjs/ui/text`
@@ -4643,7 +5105,12 @@ declare function FieldLabel({ children, class: classValue, className, ...attribu
4643
5105
 
4644
5106
  type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span';
4645
5107
  type TextTone = 'default' | 'quiet' | 'danger';
4646
- type TextSize = 'compact' | 'default' | 'large' | 'xlarge';
5108
+ /**
5109
+ * `compact` (xs), `default` (the element's own size), `medium` (the 16px
5110
+ * body size, for a heading such as an in-list group title), `large`, or
5111
+ * `xlarge`.
5112
+ */
5113
+ type TextSize = 'compact' | 'default' | 'medium' | 'large' | 'xlarge';
4647
5114
  type TextFont = 'default' | 'monospace';
4648
5115
  type TextBorder = 'transparent' | 'none';
4649
5116
  type TextLineHeight = 'default' | 'tight';
@@ -5069,57 +5536,794 @@ declare function Spacer({ flex, width, height, className, slot, }: SpacerProps):
5069
5536
  export { CssLength, Spacer, type SpacerProps, UiSpaceName };
5070
5537
  ```
5071
5538
 
5072
- ## `@kerfjs/ui/token-search-model`
5539
+ ## `@kerfjs/ui/selection`
5073
5540
 
5074
5541
  ```ts
5075
- export { d as TokenSearchModel, e as TokenSearchModelOptions, f as TokenSearchResolvedToken, g as TokenSearchRule, h as TokenSearchState, i as TokenSearchSuggestion, m as createTokenSearchModel } from './token-search-model-aYR0YAei.js';
5076
- import 'kerfjs';
5077
- import './semantic-content-BbzjvSu9.js';
5542
+ /**
5543
+ * What a pointer or key activation does to a multi-selection:
5544
+ * - `replace`: select only the target (a plain click or Enter);
5545
+ * - `toggle`: add or remove the target, keeping the rest (Cmd on Apple
5546
+ * platforms, Ctrl elsewhere);
5547
+ * - `extend`: select the range from the anchor to the target (Shift).
5548
+ */
5549
+ type SelectionGesture = 'replace' | 'toggle' | 'extend';
5550
+ /** The modifier state of a `MouseEvent` or `KeyboardEvent`. */
5551
+ interface SelectionModifiers {
5552
+ readonly shiftKey: boolean;
5553
+ readonly metaKey: boolean;
5554
+ readonly ctrlKey: boolean;
5555
+ }
5556
+ /** True on macOS, iOS, and iPadOS, where Cmd (not Ctrl) toggles one item. */
5557
+ declare function isApplePlatform(navigatorLike?: Pick<Navigator, 'platform' | 'userAgent'> | undefined): boolean;
5558
+ /**
5559
+ * Map an activation's modifiers to a {@link SelectionGesture}, normalized for
5560
+ * the host platform: Shift extends; Cmd on Apple platforms, Ctrl elsewhere,
5561
+ * toggles; anything else replaces.
5562
+ */
5563
+ declare function selectionGesture(modifiers: SelectionModifiers, apple?: boolean): SelectionGesture;
5564
+ interface ApplySelectionOptions<Id> {
5565
+ /** Every selectable id, in display order (leave out disabled items). */
5566
+ readonly items: readonly Id[];
5567
+ /** The current selection. */
5568
+ readonly selected: readonly Id[];
5569
+ /**
5570
+ * The last replaced or toggled item; a Shift range starts here. Without
5571
+ * one, the range starts at the first selected item, then at the target.
5572
+ */
5573
+ readonly anchor?: Id;
5574
+ /** The activated item. */
5575
+ readonly target: Id;
5576
+ readonly gesture: SelectionGesture;
5577
+ }
5578
+ interface SelectionResult<Id> {
5579
+ /** The new selection, in display order. */
5580
+ readonly selected: Id[];
5581
+ /** The anchor for the next Shift range. */
5582
+ readonly anchor: Id;
5583
+ }
5584
+ /**
5585
+ * Apply one selection gesture to a multi-selection, the conventional desktop
5586
+ * list model: `replace` selects only the target, `toggle` flips it and keeps
5587
+ * the rest, and `extend` selects the range from the anchor (the first
5588
+ * selected item when there is none, else the target) to the target. The anchor moves to the target on
5589
+ * `replace` and `toggle` and stays put on `extend`, so successive Shift
5590
+ * activations pivot around one item. A target missing from `items` (such as a
5591
+ * disabled item) leaves the selection unchanged.
5592
+ */
5593
+ declare function applySelection<Id>({ items, selected, anchor, target, gesture, }: ApplySelectionOptions<Id>): SelectionResult<Id>;
5594
+
5595
+ export { type ApplySelectionOptions, type SelectionGesture, type SelectionModifiers, type SelectionResult, applySelection, isApplePlatform, selectionGesture };
5078
5596
  ```
5079
5597
 
5080
- ## `@kerfjs/ui/combobox`
5598
+ ## `@kerfjs/ui/disclosure`
5081
5599
 
5082
5600
  ```ts
5083
5601
  import * as kerfjs from 'kerfjs';
5602
+ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
5084
5603
 
5085
- /** A suggestion: a plain string, or a value with a distinct visible label. */
5086
- type ComboboxSuggestion = string | {
5087
- value: string;
5088
- label: string;
5089
- };
5090
- interface ComboboxProps {
5091
- /** Unique id; it also identifies the field in `wireComboboxes` reports. */
5092
- id: string;
5093
- /** Visible field label. */
5094
- label: string;
5095
- /** Suggestions to filter as the person types. */
5096
- suggestions: readonly ComboboxSuggestion[];
5097
- /** Initial text; the field owns its text while the person types. */
5098
- value?: string;
5099
- placeholder?: string;
5100
- /** Optional hint below the field, such as "Press Enter to add". */
5101
- hint?: string;
5102
- /** Form field name. */
5604
+ /**
5605
+ * The Disclosure's surface: `plain` (default) on the surrounding surface,
5606
+ * `framed` with the standard neutral border, or `sunken` on the lowered,
5607
+ * textured work surface with a border.
5608
+ */
5609
+ type DisclosureAppearance = 'plain' | 'framed' | 'sunken';
5610
+ /**
5611
+ * Application `data-*` identity on the `<details>` root, such as `data-key`;
5612
+ * the Disclosure's own configuration attributes stay protected.
5613
+ */
5614
+ type DisclosureRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
5615
+ interface DisclosureProps {
5616
+ /** The always-visible summary: a short title for the hidden content. */
5617
+ title: KerfUiContent | string;
5618
+ /** A quiet line after the title in the summary, such as a count. */
5619
+ detail?: KerfUiContent | string;
5620
+ /** The content shown while open. */
5621
+ children: KerfUiContent | string;
5622
+ /**
5623
+ * Render it open. The open state belongs to the native `<details>` once it
5624
+ * is on the page: a person toggles it, a re-render that passes `open` opens
5625
+ * it, and a re-render never closes it (kerf's morph leaves a `<details>`
5626
+ * element's live `open` alone). Close it from code with `element.open = false`.
5627
+ */
5628
+ open?: boolean;
5629
+ /**
5630
+ * An exclusive group: Disclosures sharing a `name` behave as an accordion,
5631
+ * where opening one closes the others (the native `<details name>`).
5632
+ */
5103
5633
  name?: string;
5634
+ appearance?: DisclosureAppearance;
5104
5635
  /**
5105
- * Offer to create the typed text when it matches no suggestion; the option
5106
- * reads `createLabel` with `{value}` replaced. Omit to only allow
5107
- * suggestions. Default `Create “{value}”`.
5636
+ * A `data-action` value on the `<details>` root, for a delegated listener of
5637
+ * the native `toggle` event (it does not bubble: listen in the capture phase,
5638
+ * for example with `delegateCapture`). `event.newState` is `open` or `closed`.
5108
5639
  */
5109
- createLabel?: string | false;
5110
- disabled?: boolean;
5640
+ toggleAction?: string;
5641
+ id?: string;
5642
+ rootAttributes?: DisclosureRootAttributes;
5111
5643
  className?: string;
5644
+ /** Native named-slot assignment when composed inside a web component. */
5645
+ slot?: string;
5112
5646
  }
5113
5647
  /**
5114
- * A free-text field with a filtered suggestion list that can also create a new
5115
- * value: the ARIA combobox pattern on a native input with the themed Web
5116
- * Awesome field chrome. `wireComboboxes` filters, moves the active option,
5117
- * and reports commits (Enter, comma, or a click). Use `Select` when only
5118
- * existing values are allowed and nothing is typed.
5648
+ * Content a person shows and hides under a summary row: a native `<details>`
5649
+ * with a `<summary>` that carries a `DisclosureArrow` and the title, on the
5650
+ * shared content-item geometry (8px inline margin, a 1px border, 8px
5651
+ * padding, the rounded radius). Keyboard and screen-reader behavior is the
5652
+ * platform's: the summary is a button that Enter and Space toggle, and it
5653
+ * reports its expanded state. Disclosures sharing a `name` form an accordion.
5119
5654
  */
5120
- declare function Combobox({ id, label, suggestions, value, placeholder, hint, name, createLabel, disabled, className, }: ComboboxProps): kerfjs.SafeHtml;
5655
+ declare function Disclosure({ title, detail, children, open, name, appearance, toggleAction, id, rootAttributes, className, slot, }: DisclosureProps): kerfjs.SafeHtml;
5121
5656
 
5122
- export { Combobox, type ComboboxProps, type ComboboxSuggestion };
5657
+ export { Disclosure, type DisclosureAppearance, type DisclosureProps, type DisclosureRootAttributes };
5658
+ ```
5659
+
5660
+ ## `@kerfjs/ui/wire-choice-chips`
5661
+
5662
+ ```ts
5663
+ /** The selected values of a `multiple: true` ChoiceChips group, in choice order. */
5664
+ declare function readChoiceChips(group: Element): string[];
5665
+ /**
5666
+ * Give every `multiple: true` ChoiceChips group under `root` its listbox
5667
+ * behavior: a click selects one chip, Cmd (Apple platforms) or Ctrl
5668
+ * (elsewhere) toggles one, and Shift extends a range from the last plain or
5669
+ * toggled chip. On the keyboard the group is one Tab stop: arrows, Home, and
5670
+ * End move the selection, Shift with them extends it, Cmd/Ctrl with them
5671
+ * moves focus alone, Space toggles the focused chip (Shift+Space extends to
5672
+ * it), and Cmd/Ctrl+A selects every chip. Disabled chips keep their state.
5673
+ * Each change updates `aria-selected` and the hidden form inputs, then fires
5674
+ * a bubbling `change` on the group, whose `data-action` is the group's
5675
+ * `action`; read the new set with `readChoiceChips`. Returns a disposer.
5676
+ */
5677
+ declare function wireChoiceChips(root: HTMLElement | Document): () => void;
5678
+
5679
+ export { readChoiceChips, wireChoiceChips };
5680
+ ```
5681
+
5682
+ ## `@kerfjs/ui/color-swatches`
5683
+
5684
+ ```ts
5685
+ import * as kerfjs from 'kerfjs';
5686
+ import { CssColor } from './css-values.js';
5687
+
5688
+ /** `default` is a 24px swatch; `compact` is 20px. */
5689
+ type ColorSwatchesSize = 'default' | 'compact';
5690
+ /** One color in the palette. */
5691
+ interface ColorSwatch {
5692
+ /** The submitted value, such as `#0a84ff` or `blue`. */
5693
+ value: string;
5694
+ /** The color's name: the swatch's accessible name and its hover hint. */
5695
+ label: string;
5696
+ /**
5697
+ * The swatch's paint: a `CssColor` from `uiColor()`, `colorVar()`, or
5698
+ * `fillColor()` (`@kerfjs/ui/css-values`), or `'transparent'` for the
5699
+ * no-color swatch, drawn outlined and struck through.
5700
+ */
5701
+ color: CssColor | 'transparent';
5702
+ }
5703
+ /** Application `data-*` metadata; the group's own markers stay protected. */
5704
+ type ColorSwatchesRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
5705
+ type ColorSwatchesProps = {
5706
+ /** The radio group name the chosen value submits under. */
5707
+ name: string;
5708
+ swatches: readonly ColorSwatch[];
5709
+ /** The chosen swatch's value. */
5710
+ value?: string;
5711
+ size?: ColorSwatchesSize;
5712
+ disabled?: boolean;
5713
+ /** Delegated `data-action` on each radio; listen for `change`. */
5714
+ action?: string;
5715
+ /** Associate the radios with a form outside their ancestor chain. */
5716
+ form?: string;
5717
+ /** The group's id. */
5718
+ id?: string;
5719
+ className?: string;
5720
+ rootAttributes?: ColorSwatchesRootAttributes;
5721
+ /** Native named-slot assignment when composed inside a web component. */
5722
+ slot?: string;
5723
+ } & ({
5724
+ label: string;
5725
+ ariaLabel?: never;
5726
+ } | {
5727
+ label?: never;
5728
+ ariaLabel: string;
5729
+ });
5730
+ /**
5731
+ * A fixed palette: a group of round color swatches with no visible text, one
5732
+ * of which is chosen. It is a native radio group, so arrow keys move the
5733
+ * choice, Tab reaches it once, and the chosen value submits under `name`.
5734
+ * Each swatch is named by its color's label (also its hover hint), and the
5735
+ * chosen one wears a ring that does not rely on its hue. A `'transparent'`
5736
+ * swatch offers "no color".
5737
+ */
5738
+ declare function ColorSwatches({ name, swatches, value, label, ariaLabel, size, disabled, action, form, id, className, rootAttributes, slot, }: ColorSwatchesProps): kerfjs.SafeHtml;
5739
+
5740
+ export { type ColorSwatch, ColorSwatches, type ColorSwatchesProps, type ColorSwatchesRootAttributes, type ColorSwatchesSize };
5741
+ ```
5742
+
5743
+ ## `@kerfjs/ui/color-picker`
5744
+
5745
+ ```ts
5746
+ import * as kerfjs from 'kerfjs';
5747
+ import { ColorSwatch } from './color-swatches.js';
5748
+ import './css-values.js';
5749
+
5750
+ /** Hue 0–360, saturation and value (brightness) 0–1, and alpha 0–1. */
5751
+ interface Hsva {
5752
+ h: number;
5753
+ s: number;
5754
+ v: number;
5755
+ a: number;
5756
+ }
5757
+
5758
+ /** The channel fields the picker shows: RGB, HSL, HSB (HSV), or one gray level. */
5759
+ type ColorPickerMode = 'rgb' | 'hsl' | 'hsb' | 'gray';
5760
+ /** A titled group of app-owned colors, such as "Document Colors". */
5761
+ interface ColorPickerSamples {
5762
+ title: string;
5763
+ swatches: readonly ColorSwatch[];
5764
+ }
5765
+ /** Application `data-*` metadata; the picker's own markers stay protected. */
5766
+ type ColorPickerRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
5767
+ /** The delegated action every preset and sample swatch carries. */
5768
+ declare const COLOR_PICKER_SWATCH_ACTION = "kui-color-picker-swatch";
5769
+ interface ColorPickerProps {
5770
+ /** The picker's id; it also prefixes its inner ids. */
5771
+ id: string;
5772
+ /** The picker's accessible name. */
5773
+ label: string;
5774
+ /**
5775
+ * The color, as CSS color text (`#rrggbb[aa]`, `rgb()`, `hsl()`); invalid
5776
+ * text shows black. The picker reports `#rrggbb`, or `#rrggbbaa` below
5777
+ * full opacity.
5778
+ */
5779
+ value: string;
5780
+ /** The channel fields shown (default `rgb`). */
5781
+ mode?: ColorPickerMode;
5782
+ /** Offer opacity: an alpha slider and field (default true). */
5783
+ alpha?: boolean;
5784
+ /** A form field name the hex value submits under. */
5785
+ name?: string;
5786
+ /** Associate the hidden input with a form outside its ancestor chain. */
5787
+ form?: string;
5788
+ /**
5789
+ * Offer a button that samples a color from the screen, where the browser
5790
+ * provides the EyeDropper API (default true; hidden elsewhere).
5791
+ */
5792
+ eyedropper?: boolean;
5793
+ /** A preset row of swatches under the controls. */
5794
+ presets?: readonly ColorSwatch[];
5795
+ /** Titled groups of app-owned colors under the presets. */
5796
+ samples?: readonly ColorPickerSamples[];
5797
+ /**
5798
+ * A `data-action` for an "Add to Samples" button in the controls row; the
5799
+ * app reads the picker's current value and adds it to its samples.
5800
+ */
5801
+ addSampleAction?: string;
5802
+ disabled?: boolean;
5803
+ className?: string;
5804
+ rootAttributes?: ColorPickerRootAttributes;
5805
+ /** Native named-slot assignment when composed inside a web component. */
5806
+ slot?: string;
5807
+ }
5808
+ /** The labels, accessible names, and maximum of each channel field per mode. */
5809
+ declare const COLOR_PICKER_CHANNELS: Record<ColorPickerMode, readonly {
5810
+ short: string;
5811
+ name: string;
5812
+ max: number;
5813
+ }[]>;
5814
+ /** The rounded channel values a mode shows for an HSV color. */
5815
+ declare function colorPickerChannels(mode: ColorPickerMode, hsv: Hsva): number[];
5816
+ /** The area's spoken value. */
5817
+ declare function colorPickerAreaText(hsv: Hsva): string;
5818
+ /** The CSS custom properties that place the thumbs and paint the tracks. */
5819
+ declare function colorPickerStyle(hsv: Hsva): string;
5820
+ /**
5821
+ * A full color picker panel: a saturation and brightness area, a hue slider,
5822
+ * an optional opacity slider on a checkerboard, a color-model menu (RGB, HSL,
5823
+ * HSB, Grayscale) with its channel fields, a hex field (8 digits below full
5824
+ * opacity) and an opacity field, an optional screen sampler (EyeDropper), and
5825
+ * optional preset and sample swatches. The controlled `value` renders it;
5826
+ * wire `wireColorPickers` from `@kerfjs/ui/wire-color-pickers` to make it
5827
+ * interactive. The interactive surface belongs to that wiring after the first
5828
+ * render, so a drag never fights a re-render; a new `value` from the app
5829
+ * resynchronizes it.
5830
+ */
5831
+ declare function ColorPicker({ id, label, value, mode, alpha, name, form, eyedropper, presets, samples, addSampleAction, disabled, className, rootAttributes, slot, }: ColorPickerProps): kerfjs.SafeHtml;
5832
+
5833
+ export { COLOR_PICKER_CHANNELS, COLOR_PICKER_SWATCH_ACTION, ColorPicker, type ColorPickerMode, type ColorPickerProps, type ColorPickerRootAttributes, type ColorPickerSamples, colorPickerAreaText, colorPickerChannels, colorPickerStyle };
5834
+ ```
5835
+
5836
+ ## `@kerfjs/ui/color-field`
5837
+
5838
+ ```ts
5839
+ import * as kerfjs from 'kerfjs';
5840
+ import { ColorPickerMode } from './color-picker.js';
5841
+ import './color-swatches.js';
5842
+ import './css-values.js';
5843
+
5844
+ /** `default` matches TextField's box; `compact` its compact size. */
5845
+ type ColorFieldSize = 'default' | 'compact';
5846
+ /** Application `data-*` metadata; the field's own markers stay protected. */
5847
+ type ColorFieldRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
5848
+ type ColorFieldProps = {
5849
+ /** The trigger's id; it also prefixes the hint and error ids. */
5850
+ id: string;
5851
+ /** CSS color text; invalid text shows black. */
5852
+ value: string;
5853
+ /** The picker's model when it opens (default `rgb`). */
5854
+ mode?: ColorPickerMode;
5855
+ /** Offer opacity in the picker (default true). */
5856
+ alpha?: boolean;
5857
+ /** A form field name the hex value submits under. */
5858
+ name?: string;
5859
+ /** Associate the hidden input with a form outside its ancestor chain. */
5860
+ form?: string;
5861
+ /** Supporting text below the field, also its description. */
5862
+ hint?: string;
5863
+ /** An error below the field that marks it invalid. */
5864
+ error?: string;
5865
+ size?: ColorFieldSize;
5866
+ disabled?: boolean;
5867
+ required?: boolean;
5868
+ className?: string;
5869
+ rootAttributes?: ColorFieldRootAttributes;
5870
+ /** Native named-slot assignment when composed inside a web component. */
5871
+ slot?: string;
5872
+ } & ({
5873
+ label: string;
5874
+ ariaLabel?: never;
5875
+ } | {
5876
+ label?: never;
5877
+ ariaLabel: string;
5878
+ });
5879
+ /**
5880
+ * A form field for a color: a label above a trigger that shows the current
5881
+ * color as a swatch and its hex value. Pressing it opens a ColorPicker in an
5882
+ * AnchoredSurface anchored to the field; Escape or a press outside closes it
5883
+ * and focus returns to the trigger. Wire `wireColorFields` from
5884
+ * `@kerfjs/ui/wire-color-fields`; it previews edits on the trigger, reports
5885
+ * them, and the app re-renders with the new value.
5886
+ */
5887
+ declare function ColorField({ id, value, mode, alpha, name, form, label, ariaLabel, hint, error, size, disabled, required, className, rootAttributes, slot, }: ColorFieldProps): kerfjs.SafeHtml;
5888
+
5889
+ export { ColorField, type ColorFieldProps, type ColorFieldRootAttributes, type ColorFieldSize };
5890
+ ```
5891
+
5892
+ ## `@kerfjs/ui/search-field-model`
5893
+
5894
+ ```ts
5895
+ export { b as SearchFieldModel, c as SearchFieldModelOptions, e as SearchFieldResolvedToken, f as SearchFieldRule, g as SearchFieldState, h as SearchFieldStructure, i as SearchFieldSuggestion, n as createSearchFieldModel } from './search-field-CrGTN5sa.js';
5896
+ import 'kerfjs';
5897
+ import './semantic-content-BbzjvSu9.js';
5898
+ ```
5899
+
5900
+ ## `@kerfjs/ui/tag-field`
5901
+
5902
+ ```ts
5903
+ import * as kerfjs from 'kerfjs';
5904
+ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
5905
+
5906
+ /** The delegated actions a TagField's controls carry; `wireTagFields` handles them. */
5907
+ declare const tagFieldActions: {
5908
+ readonly edit: "edit-tag-field-tag";
5909
+ readonly remove: "remove-tag-field-tag";
5910
+ readonly clear: "clear-tag-field";
5911
+ };
5912
+ interface TagFieldProps {
5913
+ /** The field's id: the editor's identity and the prefix of its label and hint ids. */
5914
+ id: string;
5915
+ /** The visible label, which also names the field. */
5916
+ label: string;
5917
+ /** The tags, in order. Each is submitted as its own `name` value. */
5918
+ tags: readonly string[];
5919
+ /** The form field name each tag submits under. */
5920
+ name?: string;
5921
+ /** Associate the hidden inputs with a form outside their ancestor chain. */
5922
+ form?: string;
5923
+ /** Placeholder while the field is empty (default `Add tag…`). */
5924
+ placeholder?: string;
5925
+ /** Placeholder after the last tag (default `Add another…`). */
5926
+ morePlaceholder?: string;
5927
+ /** Supporting text below the field, also its description. */
5928
+ hint?: string;
5929
+ /** An error that replaces the hint and marks the field invalid. */
5930
+ error?: string;
5931
+ /** The most tags it accepts; `wireTagFields` refuses more. */
5932
+ max?: number;
5933
+ required?: boolean;
5934
+ disabled?: boolean;
5935
+ /** The leading glyph (default a Lucide `tag`). */
5936
+ icon?: KerfUiContent;
5937
+ /** The clear button's accessible name (default `Clear Tags`). */
5938
+ clearLabel?: string;
5939
+ className?: string;
5940
+ /** Native named-slot assignment when composed inside a web component. */
5941
+ slot?: string;
5942
+ }
5943
+ /**
5944
+ * A form field that collects short values as removable tags: SearchField's
5945
+ * token editor in its `form-field` presentation, with each tag a chip and a
5946
+ * hidden input that submits it under `name`. Typing then Enter (or a
5947
+ * delimiter such as a comma) adds a tag; Backspace at the start removes the
5948
+ * last one; each chip's label edits it and its × removes it. The app owns
5949
+ * the tag list: wire `wireTagFields` from `@kerfjs/ui/wire-tag-fields` and
5950
+ * re-render with the list its `onChange` reports.
5951
+ */
5952
+ declare function TagField({ id, label, tags, name, form, placeholder, morePlaceholder, hint, error, max, required, disabled, icon, clearLabel, className, slot, }: TagFieldProps): kerfjs.SafeHtml;
5953
+
5954
+ export { TagField, type TagFieldProps, tagFieldActions };
5955
+ ```
5956
+
5957
+ ## `@kerfjs/ui/combobox`
5958
+
5959
+ ```ts
5960
+ import * as kerfjs from 'kerfjs';
5961
+
5962
+ /** A suggestion: a plain string, or a value with a distinct visible label. */
5963
+ type ComboboxSuggestion = string | {
5964
+ value: string;
5965
+ label: string;
5966
+ };
5967
+ interface ComboboxProps {
5968
+ /** Unique id; it also identifies the field in `wireComboboxes` reports. */
5969
+ id: string;
5970
+ /** Visible field label. */
5971
+ label: string;
5972
+ /** Suggestions to filter as the person types. */
5973
+ suggestions: readonly ComboboxSuggestion[];
5974
+ /** Initial text; the field owns its text while the person types. */
5975
+ value?: string;
5976
+ placeholder?: string;
5977
+ /** Optional hint below the field, such as "Press Enter to add". */
5978
+ hint?: string;
5979
+ /** Form field name. */
5980
+ name?: string;
5981
+ /**
5982
+ * Offer to create the typed text when it matches no suggestion; the option
5983
+ * reads `createLabel` with `{value}` replaced. Omit to only allow
5984
+ * suggestions. Default `Create “{value}”`.
5985
+ */
5986
+ createLabel?: string | false;
5987
+ disabled?: boolean;
5988
+ className?: string;
5989
+ }
5990
+ /**
5991
+ * A free-text field with a filtered suggestion list that can also create a new
5992
+ * value: the ARIA combobox pattern on a native input with the themed Web
5993
+ * Awesome field chrome. `wireComboboxes` filters, moves the active option,
5994
+ * and reports commits (Enter, comma, or a click). Use `Select` when only
5995
+ * existing values are allowed and nothing is typed.
5996
+ */
5997
+ declare function Combobox({ id, label, suggestions, value, placeholder, hint, name, createLabel, disabled, className, }: ComboboxProps): kerfjs.SafeHtml;
5998
+
5999
+ export { Combobox, type ComboboxProps, type ComboboxSuggestion };
6000
+ ```
6001
+
6002
+ ## `@kerfjs/ui/text-field`
6003
+
6004
+ ```ts
6005
+ import * as kerfjs from 'kerfjs';
6006
+ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
6007
+
6008
+ /** `default` is the 44px control height; `compact` is 33px with smaller text. */
6009
+ type TextFieldSize = 'default' | 'compact';
6010
+ /** The kinds of single-line value a TextField takes. */
6011
+ type TextFieldType = 'text' | 'email' | 'password' | 'search' | 'url' | 'tel' | 'number';
6012
+ /** Application `data-*` metadata; the TextField's own markers stay protected. */
6013
+ type TextFieldRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
6014
+ /**
6015
+ * The field's accessible name: a visible `label`, or `ariaLabel` when the
6016
+ * surrounding content already names it.
6017
+ */
6018
+ type TextFieldName = {
6019
+ label: string;
6020
+ ariaLabel?: never;
6021
+ } | {
6022
+ label?: never;
6023
+ ariaLabel: string;
6024
+ };
6025
+ type TextFieldProps = TextFieldName & TextFieldOptions;
6026
+ interface TextFieldOptions {
6027
+ /** The controlled value. */
6028
+ value?: string;
6029
+ name?: string;
6030
+ placeholder?: string;
6031
+ /** Supporting text below the field, also its accessible description. */
6032
+ hint?: string;
6033
+ /**
6034
+ * A validation message: shown below the field in the danger color, added
6035
+ * to its description, and marking it `aria-invalid`.
6036
+ */
6037
+ error?: string;
6038
+ size?: TextFieldSize;
6039
+ /** A leading decorative icon, such as a `LucideIcon` (single-line only). */
6040
+ icon?: KerfUiContent;
6041
+ /**
6042
+ * A clear button while the field has a value (single-line only). Needs
6043
+ * `wireTextFields(root)`, which clears the field and announces `input`.
6044
+ */
6045
+ clearable?: boolean;
6046
+ /** The clear button's accessible name (default `Clear`). */
6047
+ clearLabel?: string;
6048
+ /** The most characters the field accepts (native `maxlength`). */
6049
+ maxLength?: number;
6050
+ /**
6051
+ * Show a live `count / maxLength` below the field. Needs `maxLength` and
6052
+ * `wireTextFields(root)`, which updates it as people type.
6053
+ */
6054
+ showCount?: boolean;
6055
+ /** Single-line value kind (default `text`). */
6056
+ type?: TextFieldType;
6057
+ /** A multi-line field: a `<textarea>`. */
6058
+ multiline?: boolean;
6059
+ /** A multi-line field's height in lines (default 3). */
6060
+ rows?: number;
6061
+ /**
6062
+ * Grow a multi-line field with its content from `rows` up to this many
6063
+ * lines, then scroll.
6064
+ */
6065
+ maxRows?: number;
6066
+ disabled?: boolean;
6067
+ readOnly?: boolean;
6068
+ required?: boolean;
6069
+ autocomplete?: string;
6070
+ /** The input's id, for an external label or form. */
6071
+ id?: string;
6072
+ className?: string;
6073
+ /** Safe `data-*` metadata (a `data-key`). */
6074
+ rootAttributes?: TextFieldRootAttributes;
6075
+ /** Native named-slot assignment when composed inside a web component. */
6076
+ slot?: string;
6077
+ }
6078
+ /**
6079
+ * A text input with its label above, an optional leading icon and clear
6080
+ * button, and supporting or error text below, at the 44px control height or
6081
+ * compact. `multiline` makes it a textarea that can grow with its content.
6082
+ * The whole field is one `<label>`, so clicking anywhere on it focuses the
6083
+ * input; the input is named by `label` (or `ariaLabel`) directly.
6084
+ */
6085
+ declare function TextField({ label, ariaLabel, value, name, placeholder, hint, error, size, icon, clearable, clearLabel, maxLength, showCount, type, multiline, rows, maxRows, disabled, readOnly, required, autocomplete, id, className, rootAttributes, slot, }: TextFieldProps): kerfjs.SafeHtml;
6086
+
6087
+ export { TextField, type TextFieldName, type TextFieldOptions, type TextFieldProps, type TextFieldRootAttributes, type TextFieldSize, type TextFieldType };
6088
+ ```
6089
+
6090
+ ## `@kerfjs/ui/checkbox`
6091
+
6092
+ ```ts
6093
+ import * as kerfjs from 'kerfjs';
6094
+
6095
+ /** `default` is a 20px box beside 16px text; `compact` an 18px box and 14px text. */
6096
+ type CheckboxSize = 'default' | 'compact';
6097
+ /** Application `data-*` metadata; the Checkbox's own markers stay protected. */
6098
+ type CheckboxRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
6099
+ interface CheckboxProps {
6100
+ /** The visible label, which is also the checkbox's accessible name. */
6101
+ label: string;
6102
+ checked?: boolean;
6103
+ /**
6104
+ * A mixed state, such as a parent of partly checked children. Needs
6105
+ * `wireCheckboxes(root)`, which sets the native `indeterminate` property.
6106
+ */
6107
+ indeterminate?: boolean;
6108
+ name?: string;
6109
+ /** The value submitted while checked (native default `on`). */
6110
+ value?: string;
6111
+ /** Supporting text below the label, also the checkbox's description. */
6112
+ hint?: string;
6113
+ /** A validation message: shown in the danger color and marking it invalid. */
6114
+ error?: string;
6115
+ size?: CheckboxSize;
6116
+ disabled?: boolean;
6117
+ required?: boolean;
6118
+ /** Delegated `data-action` on the input; listen for `change`. */
6119
+ action?: string;
6120
+ /** Associate the input with a form outside its ancestor chain. */
6121
+ form?: string;
6122
+ /** The input's id. */
6123
+ id?: string;
6124
+ className?: string;
6125
+ /** Safe `data-*` metadata (a `data-key`). */
6126
+ rootAttributes?: CheckboxRootAttributes;
6127
+ /** Native named-slot assignment when composed inside a web component. */
6128
+ slot?: string;
6129
+ }
6130
+ /**
6131
+ * A native checkbox drawn as a Kerf box beside its label, with optional hint
6132
+ * and error text aligned under the label, a mixed (indeterminate) state, and
6133
+ * native form participation.
6134
+ */
6135
+ declare function Checkbox({ label, checked, indeterminate, name, value, hint, error, size, disabled, required, action, form, id, className, rootAttributes, slot, }: CheckboxProps): kerfjs.SafeHtml;
6136
+
6137
+ export { Checkbox, type CheckboxProps, type CheckboxRootAttributes, type CheckboxSize };
6138
+ ```
6139
+
6140
+ ## `@kerfjs/ui/radio-group`
6141
+
6142
+ ```ts
6143
+ import * as kerfjs from 'kerfjs';
6144
+
6145
+ /** `default` is a 20px circle beside 16px text; `compact` 18px and 14px. */
6146
+ type RadioGroupSize = 'default' | 'compact';
6147
+ /** `vertical` stacks the choices; `horizontal` lines them up and wraps. */
6148
+ type RadioGroupOrientation = 'vertical' | 'horizontal';
6149
+ /** Application `data-*` metadata; the RadioGroup's own markers stay protected. */
6150
+ type RadioGroupRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
6151
+ interface RadioGroupChoice<Value extends string = string> {
6152
+ value: Value;
6153
+ /** Visible label; it is also the radio's accessible name. */
6154
+ label: string;
6155
+ /** Supporting text under this choice's label, also its description. */
6156
+ hint?: string;
6157
+ disabled?: boolean;
6158
+ }
6159
+ /** A group is named by a visible `label` (its legend) or by `ariaLabel`. */
6160
+ type RadioGroupName = {
6161
+ label: string;
6162
+ ariaLabel?: never;
6163
+ } | {
6164
+ label?: never;
6165
+ ariaLabel: string;
6166
+ };
6167
+ interface RadioGroupOptions<Value extends string = string> {
6168
+ /** Native input `name`: the form field the selected value submits under. */
6169
+ name: string;
6170
+ choices: readonly RadioGroupChoice<Value>[];
6171
+ /** The selected value. Omit for no selection. */
6172
+ value?: NoInfer<Value>;
6173
+ /** Supporting text below the choices, also the group's description. */
6174
+ hint?: string;
6175
+ /** A validation message: shown in the danger color and marking it invalid. */
6176
+ error?: string;
6177
+ size?: RadioGroupSize;
6178
+ orientation?: RadioGroupOrientation;
6179
+ /** Require a selection for native form validation. */
6180
+ required?: boolean;
6181
+ /** Disable the whole group. */
6182
+ disabled?: boolean;
6183
+ /** Delegated `data-action` on every radio; listen for `change`. */
6184
+ action?: string;
6185
+ /** Associate the radios with a form outside their ancestor chain. */
6186
+ form?: string;
6187
+ /** The fieldset's id. */
6188
+ id?: string;
6189
+ className?: string;
6190
+ /** Safe `data-*` metadata (a `data-key`). */
6191
+ rootAttributes?: RadioGroupRootAttributes;
6192
+ /** Native named-slot assignment when composed inside a web component. */
6193
+ slot?: string;
6194
+ }
6195
+ type RadioGroupProps<Value extends string = string> = RadioGroupName & RadioGroupOptions<Value>;
6196
+ /**
6197
+ * One exclusive choice among a few visible options: a native fieldset of
6198
+ * radios, each drawn as a Kerf circle beside its label, with the group label
6199
+ * above and hint and error text below. The browser owns the interaction: one
6200
+ * Tab stop, arrow keys move and select, and the checked value submits.
6201
+ */
6202
+ declare function RadioGroup<Value extends string>({ label, ariaLabel, name, choices, value, hint, error, size, orientation, required, disabled, action, form, id, className, rootAttributes, slot, }: RadioGroupProps<Value>): kerfjs.SafeHtml;
6203
+
6204
+ export { RadioGroup, type RadioGroupChoice, type RadioGroupName, type RadioGroupOptions, type RadioGroupOrientation, type RadioGroupProps, type RadioGroupRootAttributes, type RadioGroupSize };
6205
+ ```
6206
+
6207
+ ## `@kerfjs/ui/switch`
6208
+
6209
+ ```ts
6210
+ import * as kerfjs from 'kerfjs';
6211
+
6212
+ /** `default` is a 35×20 track beside 16px text; `compact` 31.5×18 and 14px. */
6213
+ type SwitchSize = 'default' | 'compact';
6214
+ /** Application `data-*` metadata; the Switch's own markers stay protected. */
6215
+ type SwitchRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
6216
+ interface SwitchProps {
6217
+ /** The visible label, which is also the switch's accessible name. */
6218
+ label: string;
6219
+ /** Whether the setting is on. */
6220
+ checked?: boolean;
6221
+ name?: string;
6222
+ /** The value submitted while on (native default `on`). */
6223
+ value?: string;
6224
+ /** Supporting text below the label, also the switch's description. */
6225
+ hint?: string;
6226
+ size?: SwitchSize;
6227
+ disabled?: boolean;
6228
+ /** Delegated `data-action` on the input; listen for `change`. */
6229
+ action?: string;
6230
+ /** Associate the input with a form outside its ancestor chain. */
6231
+ form?: string;
6232
+ /** The input's id. */
6233
+ id?: string;
6234
+ className?: string;
6235
+ /** Safe `data-*` metadata (a `data-key`). */
6236
+ rootAttributes?: SwitchRootAttributes;
6237
+ /** Native named-slot assignment when composed inside a web component. */
6238
+ slot?: string;
6239
+ }
6240
+ /**
6241
+ * An on/off setting that applies immediately: a native checkbox with
6242
+ * `role="switch"`, drawn as a track and thumb beside its label, with an
6243
+ * optional hint aligned under the label.
6244
+ */
6245
+ declare function Switch({ label, checked, name, value, hint, size, disabled, action, form, id, className, rootAttributes, slot, }: SwitchProps): kerfjs.SafeHtml;
6246
+
6247
+ export { Switch, type SwitchProps, type SwitchRootAttributes, type SwitchSize };
6248
+ ```
6249
+
6250
+ ## `@kerfjs/ui/slider`
6251
+
6252
+ ```ts
6253
+ import * as kerfjs from 'kerfjs';
6254
+ import { CssLength } from './css-values.js';
6255
+
6256
+ /** `default` is a 4px track with a 20px thumb at 16px text; `compact` 3px, 16px, and 14px. */
6257
+ type SliderSize = 'default' | 'compact';
6258
+ /** `horizontal` (default), or `vertical` with its minimum at the bottom. */
6259
+ type SliderOrientation = 'horizontal' | 'vertical';
6260
+ /**
6261
+ * A labeled stop under the track: a value and the text shown for it. The
6262
+ * labels are visual; the input still reports its value to assistive
6263
+ * technology. (No `<datalist>`: Chromium shrinks a styled range's track when
6264
+ * the input has a `list`.)
6265
+ */
6266
+ interface SliderTick {
6267
+ value: number;
6268
+ label?: string;
6269
+ }
6270
+ /** Application `data-*` metadata; the Slider's own markers stay protected. */
6271
+ type SliderRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
6272
+ type SliderProps = {
6273
+ /** The input's id; it also derives the readout, hint, and tick ids. */
6274
+ id: string;
6275
+ /** The current value (default the midpoint of `min` and `max`, snapped to `step`). */
6276
+ value?: number;
6277
+ /** The lowest value (default 0). */
6278
+ min?: number;
6279
+ /** The highest value (default 100). */
6280
+ max?: number;
6281
+ /** The step between values (default 1). */
6282
+ step?: number;
6283
+ name?: string;
6284
+ /** Show the current value at the end of the label row, live while dragging. */
6285
+ showValue?: boolean;
6286
+ /** Text after the readout's number, such as `%` or ` px`. */
6287
+ unit?: string;
6288
+ /** Supporting text below the slider, also its description. */
6289
+ hint?: string;
6290
+ /** Labeled stops under the track. */
6291
+ ticks?: readonly SliderTick[];
6292
+ /**
6293
+ * `vertical` stands the slider up (a volume control in a popup), minimum at
6294
+ * the bottom, `length` tall; it takes no `ticks`.
6295
+ */
6296
+ orientation?: SliderOrientation;
6297
+ /** A vertical slider's length (default 160px). */
6298
+ length?: CssLength;
6299
+ size?: SliderSize;
6300
+ disabled?: boolean;
6301
+ /** Delegated `data-action` on the input; listen for `input` or `change`. */
6302
+ action?: string;
6303
+ /** Associate the input with a form outside its ancestor chain. */
6304
+ form?: string;
6305
+ className?: string;
6306
+ rootAttributes?: SliderRootAttributes;
6307
+ /** Native named-slot assignment when composed inside a web component. */
6308
+ slot?: string;
6309
+ } & ({
6310
+ label: string;
6311
+ ariaLabel?: never;
6312
+ } | {
6313
+ label?: never;
6314
+ ariaLabel: string;
6315
+ });
6316
+ /**
6317
+ * A value on a continuous or stepped range: a native `<input type="range">`
6318
+ * drawn as a track, a brand fill up to the value, and a thumb, with a label
6319
+ * row, an optional live readout (`<output>`), labeled tick stops, and a hint.
6320
+ * Keyboard, pointer, and screen-reader behavior are the platform's. Wire
6321
+ * `wireSliders` from `@kerfjs/ui/wire-sliders` above it so the fill and the
6322
+ * readout follow a drag before the app re-renders.
6323
+ */
6324
+ declare function Slider({ id, value, min, max, step, name, label, ariaLabel, showValue, unit, hint, ticks, size, orientation, length, disabled, action, form, className, rootAttributes, slot, }: SliderProps): kerfjs.SafeHtml;
6325
+
6326
+ export { Slider, type SliderOrientation, type SliderProps, type SliderRootAttributes, type SliderSize, type SliderTick };
5123
6327
  ```
5124
6328
 
5125
6329
  ## `@kerfjs/ui/anchored-surface`
@@ -5196,102 +6400,117 @@ declare function openAnchoredSurfaceAt(point: AnchoredSurfacePoint, content: Ove
5196
6400
  export { type AnchoredSurfaceOptions, type AnchoredSurfacePoint, type AnchoredSurfaceTone, openAnchoredSurface, openAnchoredSurfaceAt };
5197
6401
  ```
5198
6402
 
5199
- ## `@kerfjs/ui/icon-button`
6403
+ ## `@kerfjs/ui/button`
5200
6404
 
5201
6405
  ```ts
5202
6406
  import * as kerfjs from 'kerfjs';
5203
- import { LucideNode } from './lucide-icon.js';
5204
- import 'lucide';
6407
+ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
6408
+ import { BadgeTone } from './badge.js';
5205
6409
  import './css-values.js';
6410
+ import './semantic-tone-CdW013KF.js';
5206
6411
 
5207
- type IconButtonAppearance = 'accent' | 'filled' | 'outlined' | 'filled-outlined' | 'plain';
5208
- type IconButtonVariant = 'neutral' | 'brand' | 'success' | 'warning' | 'danger';
5209
- type IconButtonSize = 'xs' | 's' | 'm' | 'l' | 'xl';
5210
- type IconButtonRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
5211
- 'data-component'?: never;
5212
- 'data-action'?: never;
5213
- }>;
5214
- interface IconButtonProps {
5215
- /** The Lucide-compatible icon node shown alone in the button. */
5216
- icon: LucideNode;
5217
- /** The icon's stable name, as `LucideIcon` takes it. */
5218
- iconName: string;
5219
- /** Accessible name; the button has no visible text, so it is required. */
5220
- label: string;
5221
- /** Delegated `data-action` the application handles. */
5222
- action?: string;
5223
- /** Web Awesome appearance; defaults to Web Awesome's own. */
5224
- appearance?: IconButtonAppearance;
5225
- /** Web Awesome semantic variant; defaults to Web Awesome's own. */
5226
- variant?: IconButtonVariant;
5227
- /** Web Awesome control size; the square follows its control height. */
5228
- size?: IconButtonSize;
5229
- type?: 'button' | 'submit' | 'reset';
5230
- disabled?: boolean;
5231
- id?: string;
5232
- className?: string;
5233
- /** Safe `data-*` metadata; `data-component` and `data-action` stay owned. */
5234
- rootAttributes?: IconButtonRootAttributes;
5235
- /** Native named-slot assignment when composed inside a web component. */
5236
- slot?: string;
5237
- }
6412
+ /** The color family: `neutral` (default), `brand` for the main action, `danger` for a destructive one. */
6413
+ type ButtonTone = 'neutral' | 'brand' | 'danger';
5238
6414
  /**
5239
- * An icon-only Web Awesome button with a `LucideIcon`: square, one form
5240
- * control height on each side, so it matches an adjacent `wa-input` or
5241
- * `Select`. Web Awesome squares a button only for a lone `wa-icon`; this is
5242
- * the Kerf form for Lucide icons. Register `wa-button` once
5243
- * (`@awesome.me/webawesome/dist/components/button/button.js`).
6415
+ * How loudly it asks: `primary` (default) fills the button, `secondary`
6416
+ * outlines it, and `plain` shows only its text until hovered.
5244
6417
  */
5245
- declare function IconButton({ icon, iconName, label, action, appearance, variant, size, type, disabled, id, className, rootAttributes, slot, }: IconButtonProps): kerfjs.SafeHtml;
5246
-
5247
- export { IconButton, type IconButtonAppearance, type IconButtonProps, type IconButtonSize, type IconButtonVariant };
5248
- ```
5249
-
5250
- ## `@kerfjs/ui/icon-toggle-button`
5251
-
5252
- ```ts
5253
- import * as kerfjs from 'kerfjs';
5254
- import { LucideNode } from './lucide-icon.js';
5255
- import 'lucide';
5256
- import './css-values.js';
5257
-
5258
- /** Corner shape: fully round `pill` (default) or a softer `rounded` square. */
5259
- type IconToggleButtonShape = 'pill' | 'rounded';
5260
- type IconToggleButtonRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
5261
- 'data-component'?: never;
5262
- 'data-action'?: never;
5263
- 'data-shape'?: never;
5264
- }>;
5265
- interface IconToggleButtonProps {
5266
- /** The Lucide-compatible icon node. */
5267
- icon: LucideNode;
5268
- /** The icon's stable name, as `LucideIcon` takes it. */
5269
- iconName: string;
5270
- /** Accessible name and hover help tag; required because no text is shown. */
5271
- label: string;
5272
- /** Pressed state, exposed as `aria-pressed`; the application owns it. */
5273
- pressed: boolean;
5274
- /** Delegated `data-action` the application handles to flip `pressed`. */
5275
- action?: string;
5276
- shape?: IconToggleButtonShape;
6418
+ type ButtonEmphasis = 'primary' | 'secondary' | 'plain';
6419
+ /** `default` is the 44px control height; `compact` is 33px with smaller text. */
6420
+ type ButtonSize = 'default' | 'compact';
6421
+ /** Corner shape: the shared `rounded` control radius (default) or a full `pill`. */
6422
+ type ButtonShape = 'rounded' | 'pill';
6423
+ /** What a form button does: `button` (default), `submit`, or `reset`. */
6424
+ type ButtonType = 'button' | 'submit' | 'reset';
6425
+ /** Application `data-*` metadata; the Button's own markers stay protected. */
6426
+ type ButtonRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
6427
+ /** A Button's visible label: text or rendered content, never empty. */
6428
+ type ButtonLabel = string | Exclude<KerfUiContent, null | undefined | boolean>;
6429
+ /**
6430
+ * A labeled button (its label names it; `ariaLabel` only when the label is
6431
+ * not enough), or an icon-only square named by `ariaLabel`.
6432
+ */
6433
+ type ButtonContent = {
6434
+ /** The label. */
6435
+ children: ButtonLabel;
6436
+ /** A leading icon, such as a `LucideIcon`; it is decorative. */
6437
+ icon?: KerfUiContent;
6438
+ ariaLabel?: string;
6439
+ } | {
6440
+ children?: undefined;
6441
+ /** The icon of an icon-only square button. */
6442
+ icon: KerfUiContent;
6443
+ /** The accessible name an icon-only button needs. */
6444
+ ariaLabel: string;
6445
+ };
6446
+ type ButtonProps = ButtonContent & ButtonOptions;
6447
+ interface ButtonOptions {
6448
+ tone?: ButtonTone;
6449
+ emphasis?: ButtonEmphasis;
6450
+ size?: ButtonSize;
6451
+ /** Corner shape (default `rounded`). */
6452
+ shape?: ButtonShape;
6453
+ /**
6454
+ * Make it a toggle: `aria-pressed` reports the state, and a pressed look is
6455
+ * drawn on top of the tone and emphasis. The application owns the state and
6456
+ * flips it in its `action` handler. A link (`href`) cannot be a toggle.
6457
+ */
6458
+ pressed?: boolean;
6459
+ /**
6460
+ * Busy: a spinner replaces the label (which still names it) and the button
6461
+ * reports `aria-busy`. Presses still reach it; the application decides
6462
+ * what a press does while it is busy.
6463
+ */
6464
+ loading?: boolean;
5277
6465
  disabled?: boolean;
6466
+ /** A form button's behavior (default `button`, which never submits). */
6467
+ type?: ButtonType;
6468
+ name?: string;
6469
+ value?: string;
6470
+ /** The id of the form it belongs to, when it sits outside that form. */
6471
+ form?: string;
6472
+ /** Render a link with button styling instead of a `<button>`. */
6473
+ href?: string;
6474
+ /** Where a link opens. */
6475
+ target?: '_self' | '_blank' | '_parent' | '_top';
6476
+ /** Delegated `data-action` the application handles. */
6477
+ action?: string;
6478
+ /**
6479
+ * A count, short text, or `true` for a text-free dot over the button's
6480
+ * top-trailing corner, such as how many items a filter hides. It stays out
6481
+ * of the accessible name unless `badgeLabel` names it.
6482
+ */
6483
+ badge?: number | string | true;
6484
+ /** Words for the badge ("3 hidden"), added to the button's name. */
6485
+ badgeLabel?: string;
6486
+ /** The badge's tone (default `danger`). */
6487
+ badgeTone?: BadgeTone;
6488
+ /**
6489
+ * Native hover text that says more than the name, such as "More Actions
6490
+ * for report.pdf". An icon-only Button already gets a help tag with its
6491
+ * `ariaLabel` (with `@kerfjs/ui/help-tags-register`); a `title` replaces
6492
+ * that tag.
6493
+ */
6494
+ title?: string;
5278
6495
  id?: string;
5279
6496
  className?: string;
5280
- /** Safe `data-*` metadata; IconToggleButton-owned markers stay protected. */
5281
- rootAttributes?: IconToggleButtonRootAttributes;
6497
+ /** Safe `data-*` metadata (a `data-key`, `data-dialog-close`). */
6498
+ rootAttributes?: ButtonRootAttributes;
5282
6499
  /** Native named-slot assignment when composed inside a web component. */
5283
6500
  slot?: string;
5284
6501
  }
5285
6502
  /**
5286
- * A standalone, icon-only toggle: a native `<button aria-pressed>` with the
5287
- * geometry and pressed chrome of a single contained `ToolbarControlGroup`
5288
- * (44px, a 2px-inset face that rises when pressed), for content and pane
5289
- * footers where no `Toolbar` belongs. Inside a toolbar, use a
5290
- * `ToolbarControlGroup` instead.
6503
+ * A standalone action button: a native `<button>` (or a link with `href`)
6504
+ * in one of three tones and three emphases, at the 44px control height or
6505
+ * compact, with a label or as an icon-only square, rounded or pill-shaped,
6506
+ * and optionally a `pressed` toggle. Inside a
6507
+ * `ToolbarControlGroup`, use a plain `<button>`, which the group styles; use
6508
+ * Button for a dialog footer, a form, or a standalone action beside other
6509
+ * content.
5291
6510
  */
5292
- declare function IconToggleButton({ icon, iconName, label, pressed, action, shape, disabled, id, className, rootAttributes, slot, }: IconToggleButtonProps): kerfjs.SafeHtml;
6511
+ declare function Button({ children, tone, emphasis, size, shape, pressed, icon, loading, disabled, type, name, value, form, href, target, action, badge, badgeLabel, badgeTone, ariaLabel, title, id, className, rootAttributes, slot, }: ButtonProps): kerfjs.SafeHtml;
5293
6512
 
5294
- export { IconToggleButton, type IconToggleButtonProps, type IconToggleButtonShape };
6513
+ export { Button, type ButtonContent, type ButtonEmphasis, type ButtonLabel, type ButtonOptions, type ButtonProps, type ButtonRootAttributes, type ButtonShape, type ButtonSize, type ButtonTone, type ButtonType };
5295
6514
  ```
5296
6515
 
5297
6516
  ## `@kerfjs/ui/split-button`
@@ -5390,6 +6609,13 @@ interface FileDropZoneProps extends FileInputProps {
5390
6609
  icon?: SafeHtml;
5391
6610
  /** Accessible name of the file input when it should say more than `title`. */
5392
6611
  accessibleLabel?: string;
6612
+ /**
6613
+ * A selector for an enclosing element (the zone's ancestor) that also
6614
+ * takes drops, such as an attachments panel: while files are dragged over
6615
+ * any part of it the zone is highlighted, and files dropped there are
6616
+ * reported for this zone (`via: 'drop'`).
6617
+ */
6618
+ dropScope?: string;
5393
6619
  }
5394
6620
  /**
5395
6621
  * A compact, link-toned trigger that opens the native file chooser: a label
@@ -5481,3 +6707,109 @@ declare function EdgeActivityIndicator({ busy, message, tone, inset, className,
5481
6707
 
5482
6708
  export { EdgeActivityIndicator, type EdgeActivityIndicatorProps };
5483
6709
  ```
6710
+
6711
+ ## `@kerfjs/ui/progress-bar`
6712
+
6713
+ ```ts
6714
+ import * as kerfjs from 'kerfjs';
6715
+
6716
+ /** The fill color: `brand` (default), or a status tone. */
6717
+ type ProgressTone = 'brand' | 'success' | 'warning' | 'danger';
6718
+ /** `default` is a 6px track; `compact` is 4px, for a row or table cell. */
6719
+ type ProgressBarSize = 'default' | 'compact';
6720
+ /**
6721
+ * Application `data-*` identity on the ProgressBar root, such as `data-key`;
6722
+ * its own configuration attributes stay protected.
6723
+ */
6724
+ type ProgressBarRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
6725
+ type ProgressBarProps = {
6726
+ /**
6727
+ * Work done so far, from 0 to `max`. Omit it for indeterminate progress
6728
+ * (work whose size is unknown), which animates instead.
6729
+ */
6730
+ value?: number;
6731
+ /** The amount that means done (default 1). */
6732
+ max?: number;
6733
+ /**
6734
+ * Spoken progress in place of the percentage, such as "3 of 12 files". With
6735
+ * `showValue` it is also the visible text.
6736
+ */
6737
+ valueText?: string;
6738
+ /** Show the value (or `valueText`) at the end of the label row. */
6739
+ showValue?: boolean;
6740
+ tone?: ProgressTone;
6741
+ size?: ProgressBarSize;
6742
+ id?: string;
6743
+ rootAttributes?: ProgressBarRootAttributes;
6744
+ className?: string;
6745
+ /** Native named-slot assignment when composed inside a web component. */
6746
+ slot?: string;
6747
+ } & ({
6748
+ /** A visible label above the bar that also names it. */
6749
+ label: string;
6750
+ ariaLabel?: never;
6751
+ } | {
6752
+ label?: never;
6753
+ /** The bar's accessible name when it shows no visible label. */
6754
+ ariaLabel: string;
6755
+ });
6756
+ /**
6757
+ * A linear progress indicator on the native `<progress>` element: determinate
6758
+ * (`value` of `max`) or indeterminate (no `value`, an animated sweep), named
6759
+ * by a visible `label` or an `ariaLabel`, toned, and in two track sizes. The
6760
+ * native element carries the progressbar role and its value to assistive
6761
+ * technology; `valueText` replaces the spoken percentage.
6762
+ */
6763
+ declare function ProgressBar({ value, max, valueText, showValue, label, ariaLabel, tone, size, id, rootAttributes, className, slot, }: ProgressBarProps): kerfjs.SafeHtml;
6764
+
6765
+ export { ProgressBar, type ProgressBarProps, type ProgressBarRootAttributes, type ProgressBarSize, type ProgressTone };
6766
+ ```
6767
+
6768
+ ## `@kerfjs/ui/progress-ring`
6769
+
6770
+ ```ts
6771
+ import * as kerfjs from 'kerfjs';
6772
+ import { ProgressTone } from './progress-bar.js';
6773
+
6774
+ /**
6775
+ * The ring's diameter: `small` (16px) sits in a line of text, `medium` (24px,
6776
+ * the default) beside an icon in a row or toolbar, and `large` (40px) on its
6777
+ * own.
6778
+ */
6779
+ type ProgressRingSize = 'small' | 'medium' | 'large';
6780
+ /**
6781
+ * Application `data-*` identity on the ProgressRing root, such as `data-key`;
6782
+ * its own configuration attributes stay protected.
6783
+ */
6784
+ type ProgressRingRootAttributes = Readonly<Record<`data-${string}`, string | undefined>>;
6785
+ interface ProgressRingProps {
6786
+ /**
6787
+ * Work done so far, from 0 to `max`. Omit it for indeterminate progress,
6788
+ * which spins a short arc instead.
6789
+ */
6790
+ value?: number;
6791
+ /** The amount that means done (default 1). */
6792
+ max?: number;
6793
+ /** The ring's accessible name, such as "Claim time remaining". */
6794
+ label: string;
6795
+ /** Spoken progress in place of the percentage, such as "12 minutes left". */
6796
+ valueText?: string;
6797
+ tone?: ProgressTone;
6798
+ size?: ProgressRingSize;
6799
+ id?: string;
6800
+ rootAttributes?: ProgressRingRootAttributes;
6801
+ className?: string;
6802
+ /** Native named-slot assignment when composed inside a web component. */
6803
+ slot?: string;
6804
+ }
6805
+ /**
6806
+ * A circular progress indicator: an SVG track and arc, determinate (`value`
6807
+ * of `max`, filling clockwise from the top) or indeterminate (no `value`, a
6808
+ * spinning arc), sized to sit inline in text, a row, or a toolbar. It is a
6809
+ * `role="progressbar"` named by `label`, with `aria-valuenow` (as a
6810
+ * percentage) or `valueText`.
6811
+ */
6812
+ declare function ProgressRing({ value, max, label, valueText, tone, size, id, rootAttributes, className, slot, }: ProgressRingProps): kerfjs.SafeHtml;
6813
+
6814
+ export { ProgressRing, type ProgressRingProps, type ProgressRingRootAttributes, type ProgressRingSize, ProgressTone };
6815
+ ```