@womp/kookie-ui 0.22.1 → 0.24.0

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 (500) hide show
  1. package/components.css +247 -187
  2. package/dist/cjs/components/_internal/base-button.d.ts +11 -1
  3. package/dist/cjs/components/_internal/base-button.d.ts.map +1 -1
  4. package/dist/cjs/components/_internal/base-button.js +1 -1
  5. package/dist/cjs/components/_internal/base-button.js.map +4 -4
  6. package/dist/cjs/components/_internal/menu-context.d.ts +2 -0
  7. package/dist/cjs/components/_internal/menu-context.d.ts.map +1 -1
  8. package/dist/cjs/components/_internal/menu-context.js +1 -1
  9. package/dist/cjs/components/_internal/menu-context.js.map +3 -3
  10. package/dist/cjs/components/_internal/pane-chrome.d.ts +17 -2
  11. package/dist/cjs/components/_internal/pane-chrome.d.ts.map +1 -1
  12. package/dist/cjs/components/_internal/pane-chrome.js +1 -1
  13. package/dist/cjs/components/_internal/pane-chrome.js.map +4 -4
  14. package/dist/cjs/components/_internal/shell-sidebar.js +1 -1
  15. package/dist/cjs/components/_internal/shell-sidebar.js.map +4 -4
  16. package/dist/cjs/components/accordion.d.ts +2 -2
  17. package/dist/cjs/components/accordion.d.ts.map +1 -1
  18. package/dist/cjs/components/accordion.js +1 -1
  19. package/dist/cjs/components/accordion.js.map +4 -4
  20. package/dist/cjs/components/alert-dialog.d.ts.map +1 -1
  21. package/dist/cjs/components/alert-dialog.js +1 -1
  22. package/dist/cjs/components/alert-dialog.js.map +3 -3
  23. package/dist/cjs/components/avatar.d.ts +1 -1
  24. package/dist/cjs/components/avatar.d.ts.map +1 -1
  25. package/dist/cjs/components/avatar.js +1 -1
  26. package/dist/cjs/components/avatar.js.map +3 -3
  27. package/dist/cjs/components/avatar.props.d.ts +8 -0
  28. package/dist/cjs/components/avatar.props.d.ts.map +1 -1
  29. package/dist/cjs/components/avatar.props.js +1 -1
  30. package/dist/cjs/components/avatar.props.js.map +2 -2
  31. package/dist/cjs/components/blockquote.d.ts +1 -1
  32. package/dist/cjs/components/blockquote.d.ts.map +1 -1
  33. package/dist/cjs/components/blockquote.js +1 -1
  34. package/dist/cjs/components/blockquote.js.map +4 -4
  35. package/dist/cjs/components/button.js +1 -1
  36. package/dist/cjs/components/button.js.map +4 -4
  37. package/dist/cjs/components/chatbar.d.ts.map +1 -1
  38. package/dist/cjs/components/chatbar.js +1 -1
  39. package/dist/cjs/components/chatbar.js.map +4 -4
  40. package/dist/cjs/components/checkbox-group.d.ts.map +1 -1
  41. package/dist/cjs/components/checkbox-group.js +1 -1
  42. package/dist/cjs/components/checkbox-group.js.map +3 -3
  43. package/dist/cjs/components/checkbox-group.primitive.d.ts +12 -5
  44. package/dist/cjs/components/checkbox-group.primitive.d.ts.map +1 -1
  45. package/dist/cjs/components/checkbox-group.primitive.js +1 -1
  46. package/dist/cjs/components/checkbox-group.primitive.js.map +3 -3
  47. package/dist/cjs/components/checkbox.js +1 -1
  48. package/dist/cjs/components/checkbox.js.map +3 -3
  49. package/dist/cjs/components/chip.d.ts.map +1 -1
  50. package/dist/cjs/components/chip.js +1 -1
  51. package/dist/cjs/components/chip.js.map +3 -3
  52. package/dist/cjs/components/code.d.ts.map +1 -1
  53. package/dist/cjs/components/code.js +1 -1
  54. package/dist/cjs/components/code.js.map +2 -2
  55. package/dist/cjs/components/combobox.js +1 -1
  56. package/dist/cjs/components/combobox.js.map +3 -3
  57. package/dist/cjs/components/context-menu.d.ts.map +1 -1
  58. package/dist/cjs/components/context-menu.js +1 -1
  59. package/dist/cjs/components/context-menu.js.map +4 -4
  60. package/dist/cjs/components/dialog.d.ts +1 -1
  61. package/dist/cjs/components/dialog.d.ts.map +1 -1
  62. package/dist/cjs/components/dialog.js +1 -1
  63. package/dist/cjs/components/dialog.js.map +3 -3
  64. package/dist/cjs/components/dropdown-menu.d.ts.map +1 -1
  65. package/dist/cjs/components/dropdown-menu.js +1 -1
  66. package/dist/cjs/components/dropdown-menu.js.map +4 -4
  67. package/dist/cjs/components/icons.d.ts +3 -1
  68. package/dist/cjs/components/icons.d.ts.map +1 -1
  69. package/dist/cjs/components/icons.js +1 -1
  70. package/dist/cjs/components/icons.js.map +3 -3
  71. package/dist/cjs/components/image.d.ts +23 -0
  72. package/dist/cjs/components/image.d.ts.map +1 -0
  73. package/dist/cjs/components/image.js +2 -0
  74. package/dist/cjs/components/image.js.map +7 -0
  75. package/dist/cjs/components/image.props.d.ts +19 -0
  76. package/dist/cjs/components/image.props.d.ts.map +1 -0
  77. package/dist/cjs/components/image.props.js +2 -0
  78. package/dist/cjs/components/image.props.js.map +7 -0
  79. package/dist/cjs/components/index.d.ts +2 -1
  80. package/dist/cjs/components/index.d.ts.map +1 -1
  81. package/dist/cjs/components/index.js +2 -10
  82. package/dist/cjs/components/index.js.map +4 -4
  83. package/dist/cjs/components/message-scroller.d.ts.map +1 -1
  84. package/dist/cjs/components/message-scroller.js +1 -1
  85. package/dist/cjs/components/message-scroller.js.map +4 -4
  86. package/dist/cjs/components/navbar.d.ts.map +1 -1
  87. package/dist/cjs/components/navbar.js +1 -1
  88. package/dist/cjs/components/navbar.js.map +3 -3
  89. package/dist/cjs/components/notice.d.ts +4 -1
  90. package/dist/cjs/components/notice.d.ts.map +1 -1
  91. package/dist/cjs/components/notice.js +1 -1
  92. package/dist/cjs/components/notice.js.map +4 -4
  93. package/dist/cjs/components/progress.d.ts.map +1 -1
  94. package/dist/cjs/components/progress.js +1 -1
  95. package/dist/cjs/components/progress.js.map +3 -3
  96. package/dist/cjs/components/schemas/button.schema.d.ts +2 -2
  97. package/dist/cjs/components/schemas/toggle.schema.d.ts +1 -1
  98. package/dist/cjs/components/scroll-area.d.ts +3 -1
  99. package/dist/cjs/components/scroll-area.d.ts.map +1 -1
  100. package/dist/cjs/components/scroll-area.js +1 -1
  101. package/dist/cjs/components/scroll-area.js.map +4 -4
  102. package/dist/cjs/components/segmented-control.d.ts +3 -1
  103. package/dist/cjs/components/segmented-control.d.ts.map +1 -1
  104. package/dist/cjs/components/segmented-control.js +1 -1
  105. package/dist/cjs/components/segmented-control.js.map +3 -3
  106. package/dist/cjs/components/select.d.ts +1 -2
  107. package/dist/cjs/components/select.d.ts.map +1 -1
  108. package/dist/cjs/components/select.js +1 -1
  109. package/dist/cjs/components/select.js.map +3 -3
  110. package/dist/cjs/components/separator.d.ts.map +1 -1
  111. package/dist/cjs/components/separator.js +1 -1
  112. package/dist/cjs/components/separator.js.map +3 -3
  113. package/dist/cjs/components/sheet.d.ts +1 -0
  114. package/dist/cjs/components/sheet.d.ts.map +1 -1
  115. package/dist/cjs/components/sheet.js +1 -1
  116. package/dist/cjs/components/sheet.js.map +3 -3
  117. package/dist/cjs/components/shell.d.ts +12 -1
  118. package/dist/cjs/components/shell.d.ts.map +1 -1
  119. package/dist/cjs/components/shell.js +1 -1
  120. package/dist/cjs/components/shell.js.map +4 -4
  121. package/dist/cjs/components/sidebar.d.ts.map +1 -1
  122. package/dist/cjs/components/sidebar.js +1 -1
  123. package/dist/cjs/components/sidebar.js.map +4 -4
  124. package/dist/cjs/components/slider.d.ts.map +1 -1
  125. package/dist/cjs/components/slider.js +1 -1
  126. package/dist/cjs/components/slider.js.map +3 -3
  127. package/dist/cjs/components/spinner.d.ts.map +1 -1
  128. package/dist/cjs/components/spinner.js +1 -1
  129. package/dist/cjs/components/spinner.js.map +3 -3
  130. package/dist/cjs/components/table.d.ts.map +1 -1
  131. package/dist/cjs/components/table.js +1 -1
  132. package/dist/cjs/components/table.js.map +4 -4
  133. package/dist/cjs/components/tabs.d.ts.map +1 -1
  134. package/dist/cjs/components/tabs.js +1 -1
  135. package/dist/cjs/components/tabs.js.map +2 -2
  136. package/dist/cjs/components/text-area.js +1 -1
  137. package/dist/cjs/components/text-area.js.map +2 -2
  138. package/dist/cjs/components/text-field.js +2 -2
  139. package/dist/cjs/components/text-field.js.map +2 -2
  140. package/dist/cjs/components/toggle.d.ts +3 -2
  141. package/dist/cjs/components/toggle.d.ts.map +1 -1
  142. package/dist/cjs/components/toggle.js +1 -9
  143. package/dist/cjs/components/toggle.js.map +4 -4
  144. package/dist/cjs/components/toolbar.d.ts +80 -8
  145. package/dist/cjs/components/toolbar.d.ts.map +1 -1
  146. package/dist/cjs/components/toolbar.js +1 -1
  147. package/dist/cjs/components/toolbar.js.map +4 -4
  148. package/dist/cjs/components/virtual-menu.d.ts +3 -5
  149. package/dist/cjs/components/virtual-menu.d.ts.map +1 -1
  150. package/dist/cjs/components/virtual-menu.js +1 -1
  151. package/dist/cjs/components/virtual-menu.js.map +3 -3
  152. package/dist/cjs/helpers/extract-margin-props.d.ts +7 -7
  153. package/dist/cjs/hooks/use-scroll-edges.d.ts +4 -2
  154. package/dist/cjs/hooks/use-scroll-edges.d.ts.map +1 -1
  155. package/dist/cjs/hooks/use-scroll-edges.js +1 -1
  156. package/dist/cjs/hooks/use-scroll-edges.js.map +3 -3
  157. package/dist/cjs/index.js +5 -5
  158. package/dist/cjs/index.js.map +4 -4
  159. package/dist/cjs/props/index.js +1 -1
  160. package/dist/cjs/props/index.js.map +2 -2
  161. package/dist/esm/chunk-3VTS4C63.js +2 -0
  162. package/dist/esm/chunk-3VTS4C63.js.map +7 -0
  163. package/dist/esm/chunk-3WE4E2WQ.js +2 -0
  164. package/dist/esm/chunk-3WE4E2WQ.js.map +7 -0
  165. package/dist/esm/chunk-3XUY5WFA.js +2 -0
  166. package/dist/esm/chunk-3XUY5WFA.js.map +7 -0
  167. package/dist/esm/chunk-3XZOE2IQ.js +2 -0
  168. package/dist/esm/chunk-3XZOE2IQ.js.map +7 -0
  169. package/dist/esm/chunk-432YLNB3.js +2 -0
  170. package/dist/esm/chunk-432YLNB3.js.map +7 -0
  171. package/dist/esm/chunk-4QKZYCCH.js +2 -0
  172. package/dist/esm/chunk-4QKZYCCH.js.map +7 -0
  173. package/dist/esm/chunk-4R5EMVB3.js +2 -0
  174. package/dist/esm/chunk-4R5EMVB3.js.map +7 -0
  175. package/dist/esm/chunk-4ZOVV3TY.js +2 -0
  176. package/dist/esm/chunk-4ZOVV3TY.js.map +7 -0
  177. package/dist/esm/{chunk-IX5HIHVI.js → chunk-62ZGP4ET.js} +2 -2
  178. package/dist/esm/{chunk-IX5HIHVI.js.map → chunk-62ZGP4ET.js.map} +3 -3
  179. package/dist/esm/chunk-BGAJ2MDF.js +2 -0
  180. package/dist/esm/chunk-BGAJ2MDF.js.map +7 -0
  181. package/dist/esm/chunk-CHPT42BY.js +2 -0
  182. package/dist/esm/{chunk-Y3JYEEFB.js.map → chunk-CHPT42BY.js.map} +2 -2
  183. package/dist/esm/{chunk-KS4U4VPH.js → chunk-CMHUK7OG.js} +2 -2
  184. package/dist/esm/{chunk-KS4U4VPH.js.map → chunk-CMHUK7OG.js.map} +2 -2
  185. package/dist/esm/chunk-CN6F4REJ.js +2 -0
  186. package/dist/esm/chunk-CN6F4REJ.js.map +7 -0
  187. package/dist/esm/chunk-DUTZUWZP.js +2 -0
  188. package/dist/esm/chunk-DUTZUWZP.js.map +7 -0
  189. package/dist/esm/chunk-EZYXYLR2.js +2 -0
  190. package/dist/esm/chunk-EZYXYLR2.js.map +7 -0
  191. package/dist/esm/chunk-FDJV5RXX.js +2 -0
  192. package/dist/esm/chunk-FDJV5RXX.js.map +7 -0
  193. package/dist/esm/chunk-G2JD52O5.js +2 -0
  194. package/dist/esm/{chunk-23KT3D2Z.js.map → chunk-G2JD52O5.js.map} +3 -3
  195. package/dist/esm/{chunk-PNAB6KCN.js → chunk-G4ETY2NP.js} +2 -2
  196. package/dist/esm/{chunk-PNAB6KCN.js.map → chunk-G4ETY2NP.js.map} +1 -1
  197. package/dist/esm/chunk-GPOCLDBR.js +2 -0
  198. package/dist/esm/chunk-GPOCLDBR.js.map +7 -0
  199. package/dist/esm/chunk-GYP66ZK2.js +2 -0
  200. package/dist/esm/chunk-GYP66ZK2.js.map +7 -0
  201. package/dist/esm/chunk-H5BYPX6V.js +2 -0
  202. package/dist/esm/chunk-H5BYPX6V.js.map +7 -0
  203. package/dist/esm/chunk-H5G7UECV.js +2 -0
  204. package/dist/esm/chunk-H5G7UECV.js.map +7 -0
  205. package/dist/esm/chunk-I4FLQELQ.js +2 -0
  206. package/dist/esm/chunk-I4FLQELQ.js.map +7 -0
  207. package/dist/esm/chunk-JYQGCXXI.js +2 -0
  208. package/dist/esm/chunk-JYQGCXXI.js.map +7 -0
  209. package/dist/esm/chunk-KA5UE2VN.js +2 -0
  210. package/dist/esm/chunk-KA5UE2VN.js.map +7 -0
  211. package/dist/esm/{chunk-T62PRLPN.js → chunk-KEGCX5VM.js} +2 -2
  212. package/dist/esm/chunk-KVHKPUZ2.js +2 -0
  213. package/dist/esm/chunk-KVHKPUZ2.js.map +7 -0
  214. package/dist/esm/chunk-M7I6ISPL.js +2 -0
  215. package/dist/esm/chunk-M7I6ISPL.js.map +7 -0
  216. package/dist/esm/chunk-MYYXOFU5.js +1 -0
  217. package/dist/esm/{chunk-FFG32ERA.js → chunk-N3WBEQWL.js} +3 -3
  218. package/dist/esm/chunk-N3WBEQWL.js.map +7 -0
  219. package/dist/esm/{chunk-HKPXDQ2B.js → chunk-NC3CJUE3.js} +2 -2
  220. package/dist/esm/chunk-P2MV6HLA.js +2 -0
  221. package/dist/esm/{chunk-7SS4UUJH.js.map → chunk-P2MV6HLA.js.map} +3 -3
  222. package/dist/esm/chunk-PALE5UWK.js +2 -0
  223. package/dist/esm/{chunk-DSPYHO3L.js.map → chunk-PALE5UWK.js.map} +2 -2
  224. package/dist/esm/chunk-PDMCLVYT.js +2 -0
  225. package/dist/esm/chunk-PDMCLVYT.js.map +7 -0
  226. package/dist/esm/chunk-PM6QY3JO.js +2 -0
  227. package/dist/esm/{chunk-TJL47GIO.js.map → chunk-PM6QY3JO.js.map} +3 -3
  228. package/dist/esm/chunk-RKZVXVBN.js +2 -0
  229. package/dist/esm/chunk-RKZVXVBN.js.map +7 -0
  230. package/dist/esm/chunk-TXQZ5HLV.js +2 -0
  231. package/dist/esm/chunk-TXQZ5HLV.js.map +7 -0
  232. package/dist/esm/chunk-UKASIY6M.js +2 -0
  233. package/dist/esm/chunk-UKASIY6M.js.map +7 -0
  234. package/dist/esm/{chunk-OJQNLROL.js → chunk-UY6WJUNA.js} +2 -2
  235. package/dist/esm/chunk-V5O3TF57.js +2 -0
  236. package/dist/esm/{chunk-3KQE2PSJ.js.map → chunk-V5O3TF57.js.map} +3 -3
  237. package/dist/esm/chunk-VUNCI6A6.js +2 -0
  238. package/dist/esm/chunk-VUNCI6A6.js.map +7 -0
  239. package/dist/esm/{chunk-JBHRV364.js → chunk-VUPIJNG2.js} +2 -2
  240. package/dist/esm/chunk-W6BN5QLH.js +2 -0
  241. package/dist/esm/{chunk-ZNDCZM5A.js.map → chunk-W6BN5QLH.js.map} +2 -2
  242. package/dist/esm/chunk-WG5ORTIW.js +2 -0
  243. package/dist/esm/chunk-WG5ORTIW.js.map +7 -0
  244. package/dist/esm/chunk-WMVR2XBR.js +2 -0
  245. package/dist/esm/{chunk-XKSU3NLG.js.map → chunk-WMVR2XBR.js.map} +2 -2
  246. package/dist/esm/{chunk-NNZTSXKH.js → chunk-WX7SX5BN.js} +2 -2
  247. package/dist/esm/chunk-XOACTIBL.js +2 -0
  248. package/dist/esm/chunk-XOACTIBL.js.map +7 -0
  249. package/dist/esm/components/_internal/base-button.d.ts +11 -1
  250. package/dist/esm/components/_internal/base-button.d.ts.map +1 -1
  251. package/dist/esm/components/_internal/base-button.js +1 -1
  252. package/dist/esm/components/_internal/menu-context.d.ts +2 -0
  253. package/dist/esm/components/_internal/menu-context.d.ts.map +1 -1
  254. package/dist/esm/components/_internal/menu-context.js +1 -1
  255. package/dist/esm/components/_internal/pane-chrome.d.ts +17 -2
  256. package/dist/esm/components/_internal/pane-chrome.d.ts.map +1 -1
  257. package/dist/esm/components/_internal/pane-chrome.js +1 -1
  258. package/dist/esm/components/_internal/shell-bottom.js +1 -1
  259. package/dist/esm/components/_internal/shell-inspector.js +1 -1
  260. package/dist/esm/components/_internal/shell-sidebar.js +1 -1
  261. package/dist/esm/components/accordion.d.ts +2 -2
  262. package/dist/esm/components/accordion.d.ts.map +1 -1
  263. package/dist/esm/components/accordion.js +1 -1
  264. package/dist/esm/components/alert-dialog.d.ts.map +1 -1
  265. package/dist/esm/components/alert-dialog.js +1 -1
  266. package/dist/esm/components/avatar.d.ts +1 -1
  267. package/dist/esm/components/avatar.d.ts.map +1 -1
  268. package/dist/esm/components/avatar.js +1 -1
  269. package/dist/esm/components/avatar.props.d.ts +8 -0
  270. package/dist/esm/components/avatar.props.d.ts.map +1 -1
  271. package/dist/esm/components/avatar.props.js +1 -1
  272. package/dist/esm/components/blockquote.d.ts +1 -1
  273. package/dist/esm/components/blockquote.d.ts.map +1 -1
  274. package/dist/esm/components/blockquote.js +1 -1
  275. package/dist/esm/components/button.js +1 -1
  276. package/dist/esm/components/chatbar.d.ts.map +1 -1
  277. package/dist/esm/components/chatbar.js +1 -1
  278. package/dist/esm/components/checkbox-group.d.ts.map +1 -1
  279. package/dist/esm/components/checkbox-group.js +1 -1
  280. package/dist/esm/components/checkbox-group.primitive.d.ts +12 -5
  281. package/dist/esm/components/checkbox-group.primitive.d.ts.map +1 -1
  282. package/dist/esm/components/checkbox-group.primitive.js +1 -1
  283. package/dist/esm/components/checkbox.js +1 -1
  284. package/dist/esm/components/chip.d.ts.map +1 -1
  285. package/dist/esm/components/chip.js +1 -1
  286. package/dist/esm/components/code.d.ts.map +1 -1
  287. package/dist/esm/components/code.js +1 -1
  288. package/dist/esm/components/combobox.js +1 -1
  289. package/dist/esm/components/context-menu.d.ts.map +1 -1
  290. package/dist/esm/components/context-menu.js +1 -1
  291. package/dist/esm/components/dialog.d.ts +1 -1
  292. package/dist/esm/components/dialog.d.ts.map +1 -1
  293. package/dist/esm/components/dialog.js +1 -1
  294. package/dist/esm/components/dropdown-menu.d.ts.map +1 -1
  295. package/dist/esm/components/dropdown-menu.js +1 -1
  296. package/dist/esm/components/icons.d.ts +3 -1
  297. package/dist/esm/components/icons.d.ts.map +1 -1
  298. package/dist/esm/components/icons.js +1 -1
  299. package/dist/esm/components/image.d.ts +23 -0
  300. package/dist/esm/components/image.d.ts.map +1 -0
  301. package/dist/esm/components/image.js +2 -0
  302. package/dist/esm/components/image.js.map +7 -0
  303. package/dist/esm/components/image.props.d.ts +19 -0
  304. package/dist/esm/components/image.props.d.ts.map +1 -0
  305. package/dist/esm/components/image.props.js +2 -0
  306. package/dist/esm/components/image.props.js.map +7 -0
  307. package/dist/esm/components/index.d.ts +2 -1
  308. package/dist/esm/components/index.d.ts.map +1 -1
  309. package/dist/esm/components/index.js +1 -1
  310. package/dist/esm/components/message-scroller.d.ts.map +1 -1
  311. package/dist/esm/components/message-scroller.js +1 -1
  312. package/dist/esm/components/navbar.d.ts.map +1 -1
  313. package/dist/esm/components/navbar.js +1 -1
  314. package/dist/esm/components/notice.d.ts +4 -1
  315. package/dist/esm/components/notice.d.ts.map +1 -1
  316. package/dist/esm/components/notice.js +1 -1
  317. package/dist/esm/components/progress.d.ts.map +1 -1
  318. package/dist/esm/components/progress.js +1 -1
  319. package/dist/esm/components/schemas/button.schema.d.ts +2 -2
  320. package/dist/esm/components/schemas/toggle.schema.d.ts +1 -1
  321. package/dist/esm/components/scroll-area.d.ts +3 -1
  322. package/dist/esm/components/scroll-area.d.ts.map +1 -1
  323. package/dist/esm/components/scroll-area.js +1 -1
  324. package/dist/esm/components/segmented-control.d.ts +3 -1
  325. package/dist/esm/components/segmented-control.d.ts.map +1 -1
  326. package/dist/esm/components/segmented-control.js +1 -1
  327. package/dist/esm/components/select.d.ts +1 -2
  328. package/dist/esm/components/select.d.ts.map +1 -1
  329. package/dist/esm/components/select.js +1 -1
  330. package/dist/esm/components/separator.d.ts.map +1 -1
  331. package/dist/esm/components/separator.js +1 -1
  332. package/dist/esm/components/sheet.d.ts +1 -0
  333. package/dist/esm/components/sheet.d.ts.map +1 -1
  334. package/dist/esm/components/sheet.js +1 -1
  335. package/dist/esm/components/shell.d.ts +12 -1
  336. package/dist/esm/components/shell.d.ts.map +1 -1
  337. package/dist/esm/components/shell.js +1 -1
  338. package/dist/esm/components/sidebar.d.ts.map +1 -1
  339. package/dist/esm/components/sidebar.js +1 -1
  340. package/dist/esm/components/slider.d.ts.map +1 -1
  341. package/dist/esm/components/slider.js +1 -1
  342. package/dist/esm/components/spinner.d.ts.map +1 -1
  343. package/dist/esm/components/spinner.js +1 -1
  344. package/dist/esm/components/table.d.ts.map +1 -1
  345. package/dist/esm/components/table.js +1 -1
  346. package/dist/esm/components/tabs.d.ts.map +1 -1
  347. package/dist/esm/components/tabs.js +1 -1
  348. package/dist/esm/components/text-area.js +1 -1
  349. package/dist/esm/components/text-field.js +1 -1
  350. package/dist/esm/components/toggle.d.ts +3 -2
  351. package/dist/esm/components/toggle.d.ts.map +1 -1
  352. package/dist/esm/components/toggle.js +1 -1
  353. package/dist/esm/components/toolbar.d.ts +80 -8
  354. package/dist/esm/components/toolbar.d.ts.map +1 -1
  355. package/dist/esm/components/toolbar.js +1 -1
  356. package/dist/esm/components/virtual-menu.d.ts +3 -5
  357. package/dist/esm/components/virtual-menu.d.ts.map +1 -1
  358. package/dist/esm/components/virtual-menu.js +1 -1
  359. package/dist/esm/helpers/extract-margin-props.d.ts +7 -7
  360. package/dist/esm/helpers/index.js +1 -1
  361. package/dist/esm/hooks/index.js +1 -1
  362. package/dist/esm/hooks/use-scroll-edges.d.ts +4 -2
  363. package/dist/esm/hooks/use-scroll-edges.d.ts.map +1 -1
  364. package/dist/esm/hooks/use-scroll-edges.js +1 -1
  365. package/dist/esm/index.js +1 -1
  366. package/dist/esm/props/index.js +1 -1
  367. package/package.json +1 -1
  368. package/src/components/_internal/base-button.css +6 -0
  369. package/src/components/_internal/base-button.tsx +56 -17
  370. package/src/components/_internal/base-sidebar-menu.css +8 -0
  371. package/src/components/_internal/menu-context.tsx +11 -0
  372. package/src/components/_internal/pane-chrome.tsx +45 -8
  373. package/src/components/accordion.css +35 -4
  374. package/src/components/accordion.tsx +12 -16
  375. package/src/components/alert-dialog.tsx +59 -161
  376. package/src/components/avatar.props.tsx +6 -0
  377. package/src/components/avatar.tsx +57 -71
  378. package/src/components/blockquote.tsx +8 -9
  379. package/src/components/chatbar.tsx +27 -20
  380. package/src/components/checkbox-group.primitive.tsx +40 -51
  381. package/src/components/checkbox-group.tsx +1 -9
  382. package/src/components/chip.css +18 -20
  383. package/src/components/chip.tsx +3 -4
  384. package/src/components/code.tsx +3 -2
  385. package/src/components/combobox.css +13 -0
  386. package/src/components/context-menu.tsx +23 -5
  387. package/src/components/dialog.tsx +59 -160
  388. package/src/components/dropdown-menu.tsx +8 -5
  389. package/src/components/icons.tsx +11 -1
  390. package/src/components/image.css +33 -0
  391. package/src/components/image.props.ts +18 -0
  392. package/src/components/image.tsx +71 -0
  393. package/src/components/index.css +1 -0
  394. package/src/components/index.tsx +8 -0
  395. package/src/components/message-scroller.tsx +48 -26
  396. package/src/components/navbar.tsx +34 -69
  397. package/src/components/notice.tsx +6 -3
  398. package/src/components/progress.tsx +6 -3
  399. package/src/components/scroll-area.css +28 -2
  400. package/src/components/scroll-area.tsx +49 -3
  401. package/src/components/segmented-control.css +8 -130
  402. package/src/components/segmented-control.tsx +36 -5
  403. package/src/components/select.tsx +100 -32
  404. package/src/components/separator.tsx +13 -1
  405. package/src/components/sheet.css +7 -6
  406. package/src/components/sheet.tsx +76 -143
  407. package/src/components/shell.css +26 -0
  408. package/src/components/shell.tsx +29 -8
  409. package/src/components/sidebar.tsx +27 -16
  410. package/src/components/slider.css +1 -0
  411. package/src/components/slider.tsx +54 -44
  412. package/src/components/spinner.css +19 -1
  413. package/src/components/spinner.tsx +21 -11
  414. package/src/components/table.tsx +18 -5
  415. package/src/components/tabs.css +34 -0
  416. package/src/components/tabs.tsx +0 -2
  417. package/src/components/text-area.css +2 -1
  418. package/src/components/text-area.tsx +1 -1
  419. package/src/components/text-field.tsx +1 -1
  420. package/src/components/toggle.tsx +21 -39
  421. package/src/components/toolbar.css +34 -0
  422. package/src/components/toolbar.tsx +432 -23
  423. package/src/components/virtual-menu.tsx +110 -37
  424. package/src/hooks/use-scroll-edges.ts +11 -2
  425. package/src/styles/tokens/color.css +1 -22
  426. package/src/styles/utilities/truncate.css +10 -0
  427. package/styles.css +252 -208
  428. package/tokens/base.css +0 -21
  429. package/tokens.css +0 -21
  430. package/utilities.css +5 -0
  431. package/dist/esm/chunk-23KT3D2Z.js +0 -2
  432. package/dist/esm/chunk-3JA7SJDT.js +0 -2
  433. package/dist/esm/chunk-3JA7SJDT.js.map +0 -7
  434. package/dist/esm/chunk-3KQE2PSJ.js +0 -2
  435. package/dist/esm/chunk-3YWVE5GL.js +0 -2
  436. package/dist/esm/chunk-3YWVE5GL.js.map +0 -7
  437. package/dist/esm/chunk-5BWLY27A.js +0 -2
  438. package/dist/esm/chunk-5BWLY27A.js.map +0 -7
  439. package/dist/esm/chunk-6CK7UTNH.js +0 -2
  440. package/dist/esm/chunk-6CK7UTNH.js.map +0 -7
  441. package/dist/esm/chunk-6RK26HIY.js +0 -2
  442. package/dist/esm/chunk-6RK26HIY.js.map +0 -7
  443. package/dist/esm/chunk-7ESWH773.js +0 -2
  444. package/dist/esm/chunk-7ESWH773.js.map +0 -7
  445. package/dist/esm/chunk-7SS4UUJH.js +0 -2
  446. package/dist/esm/chunk-A3YQIJDA.js +0 -2
  447. package/dist/esm/chunk-A3YQIJDA.js.map +0 -7
  448. package/dist/esm/chunk-AB3QCCUM.js +0 -2
  449. package/dist/esm/chunk-AB3QCCUM.js.map +0 -7
  450. package/dist/esm/chunk-BEP4AH5V.js +0 -2
  451. package/dist/esm/chunk-BEP4AH5V.js.map +0 -7
  452. package/dist/esm/chunk-D3U4MWDZ.js +0 -1
  453. package/dist/esm/chunk-DBROSD2J.js +0 -2
  454. package/dist/esm/chunk-DBROSD2J.js.map +0 -7
  455. package/dist/esm/chunk-DSPYHO3L.js +0 -2
  456. package/dist/esm/chunk-E2D2VWUI.js +0 -2
  457. package/dist/esm/chunk-E2D2VWUI.js.map +0 -7
  458. package/dist/esm/chunk-EMNSA65L.js +0 -2
  459. package/dist/esm/chunk-EMNSA65L.js.map +0 -7
  460. package/dist/esm/chunk-FFG32ERA.js.map +0 -7
  461. package/dist/esm/chunk-FHPHEIYJ.js +0 -2
  462. package/dist/esm/chunk-FHPHEIYJ.js.map +0 -7
  463. package/dist/esm/chunk-FJFBM7HW.js +0 -2
  464. package/dist/esm/chunk-FJFBM7HW.js.map +0 -7
  465. package/dist/esm/chunk-HIKMKGPT.js +0 -2
  466. package/dist/esm/chunk-HIKMKGPT.js.map +0 -7
  467. package/dist/esm/chunk-IJRBX6EV.js +0 -2
  468. package/dist/esm/chunk-IJRBX6EV.js.map +0 -7
  469. package/dist/esm/chunk-KMDXIZAG.js +0 -2
  470. package/dist/esm/chunk-KMDXIZAG.js.map +0 -7
  471. package/dist/esm/chunk-LC5AK2ZD.js +0 -2
  472. package/dist/esm/chunk-LC5AK2ZD.js.map +0 -7
  473. package/dist/esm/chunk-LHIS3UKQ.js +0 -2
  474. package/dist/esm/chunk-LHIS3UKQ.js.map +0 -7
  475. package/dist/esm/chunk-NLXJZJNN.js +0 -2
  476. package/dist/esm/chunk-NLXJZJNN.js.map +0 -7
  477. package/dist/esm/chunk-QOHJIF25.js +0 -2
  478. package/dist/esm/chunk-QOHJIF25.js.map +0 -7
  479. package/dist/esm/chunk-R4XJNQX5.js +0 -2
  480. package/dist/esm/chunk-R4XJNQX5.js.map +0 -7
  481. package/dist/esm/chunk-TJL47GIO.js +0 -2
  482. package/dist/esm/chunk-V32EP3S7.js +0 -2
  483. package/dist/esm/chunk-V32EP3S7.js.map +0 -7
  484. package/dist/esm/chunk-WKSXMFFF.js +0 -2
  485. package/dist/esm/chunk-WKSXMFFF.js.map +0 -7
  486. package/dist/esm/chunk-XKSU3NLG.js +0 -2
  487. package/dist/esm/chunk-Y3JYEEFB.js +0 -2
  488. package/dist/esm/chunk-YK3ZUMRQ.js +0 -2
  489. package/dist/esm/chunk-YK3ZUMRQ.js.map +0 -7
  490. package/dist/esm/chunk-YZM54IJE.js +0 -2
  491. package/dist/esm/chunk-YZM54IJE.js.map +0 -7
  492. package/dist/esm/chunk-ZJI2IK7C.js +0 -2
  493. package/dist/esm/chunk-ZJI2IK7C.js.map +0 -7
  494. package/dist/esm/chunk-ZNDCZM5A.js +0 -2
  495. /package/dist/esm/{chunk-T62PRLPN.js.map → chunk-KEGCX5VM.js.map} +0 -0
  496. /package/dist/esm/{chunk-D3U4MWDZ.js.map → chunk-MYYXOFU5.js.map} +0 -0
  497. /package/dist/esm/{chunk-HKPXDQ2B.js.map → chunk-NC3CJUE3.js.map} +0 -0
  498. /package/dist/esm/{chunk-OJQNLROL.js.map → chunk-UY6WJUNA.js.map} +0 -0
  499. /package/dist/esm/{chunk-JBHRV364.js.map → chunk-VUPIJNG2.js.map} +0 -0
  500. /package/dist/esm/{chunk-NNZTSXKH.js.map → chunk-WX7SX5BN.js.map} +0 -0
@@ -22,6 +22,7 @@
22
22
 
23
23
  import * as React from 'react';
24
24
  import classNames from 'classnames';
25
+ import { Slot } from 'radix-ui';
25
26
  import { useComposedRefs } from 'radix-ui/internal';
26
27
  import { PaneResizeContext } from './_internal/shell-resize.js';
27
28
  import { PaneHandle, PanelHandle } from './_internal/shell-handles.js';
@@ -48,7 +49,7 @@ import { useShell, useSidebarMode } from './shell.context.js';
48
49
  import { useResponsivePresentation } from './shell.hooks.js';
49
50
  import { readBreakpoint } from '../hooks/use-breakpoint.js';
50
51
  import { useThemeSize } from '../helpers/theme-size.js';
51
- import { PaneChromeScope, PaneFooter, PaneHeader, Scroll, ShellSizeContext } from './_internal/pane-chrome.js';
52
+ import { PaneChromeScope, PaneFooter, PaneHeader, Scroll, ShellContentContext, ShellSizeContext } from './_internal/pane-chrome.js';
52
53
  import type { PaneSize } from './_internal/pane-chrome.js';
53
54
  import type { Breakpoint, CSSPropertiesWithVars, PaneBaseProps, PaneMode, PaneName, PaneTarget, ResponsivePresentation, SidebarMode } from './shell.types.js';
54
55
 
@@ -365,6 +366,7 @@ const Root = React.forwardRef<HTMLDivElement, ShellRootProps>(({ className, chil
365
366
  return (
366
367
  <ShellStoreContext.Provider value={store}>
367
368
  <ShellSizeContext.Provider value={size}>
369
+ <ShellContentContext.Provider value={false}>
368
370
  <ShellInsetContext.Provider value={insetContext}>
369
371
  {/* The Root is not a widget: it hears Escape bubbling up from the panes,
370
372
  after their own handlers, to close the overlays. */}
@@ -387,6 +389,7 @@ const Root = React.forwardRef<HTMLDivElement, ShellRootProps>(({ className, chil
387
389
  <div className="kui-ShellScrim" aria-hidden onClick={closeOverlays} />
388
390
  </div>
389
391
  </ShellInsetContext.Provider>
392
+ </ShellContentContext.Provider>
390
393
  </ShellSizeContext.Provider>
391
394
  </ShellStoreContext.Provider>
392
395
  );
@@ -679,9 +682,17 @@ interface ShellContentProps extends React.ComponentPropsWithoutRef<'main'> {
679
682
  inset?: boolean;
680
683
  }
681
684
 
682
- const Content = React.forwardRef<HTMLElement, ShellContentProps>(({ className, inset, ...props }, ref) => {
685
+ /**
686
+ * The work area. It scrolls as it is; with a `Shell.Scroll` child it becomes a column and the
687
+ * Scroll scrolls instead, so a `Shell.PaneHeader float` beside it stays pinned over the page.
688
+ */
689
+ const Content = React.forwardRef<HTMLElement, ShellContentProps>(({ className, inset, children, ...props }, ref) => {
683
690
  useInsetRegistration('content', inset);
684
- return <main {...props} ref={ref} className={classNames('kui-ShellContent', className)} data-inset={inset || undefined} />;
691
+ return (
692
+ <main {...props} ref={ref} className={classNames('kui-ShellContent', className)} data-inset={inset || undefined}>
693
+ <ShellContentContext.Provider value={true}>{children}</ShellContentContext.Provider>
694
+ </main>
695
+ );
685
696
  });
686
697
  Content.displayName = 'Shell.Content';
687
698
 
@@ -692,6 +703,12 @@ type TriggerAction = 'toggle' | 'expand' | 'collapse';
692
703
  interface TriggerProps extends React.ComponentPropsWithoutRef<'button'> {
693
704
  target: PaneTarget;
694
705
  action?: TriggerAction;
706
+ /**
707
+ * Renders the single child in place of the trigger's own button, with the trigger's click,
708
+ * `aria-controls`, `aria-expanded` and data attributes merged onto it. Use it to make a
709
+ * `Button` the trigger: `<Shell.Trigger asChild><Button iconOnly aria-label="Toggle sidebar">…</Button></Shell.Trigger>`.
710
+ */
711
+ asChild?: boolean;
695
712
  /**
696
713
  * Whether to show a preview of the target pane on hover while it is closed
697
714
  * and not an overlay. Defaults to false.
@@ -706,9 +723,10 @@ interface TriggerProps extends React.ComponentPropsWithoutRef<'button'> {
706
723
  * A button that drives a pane by name, through the registry. It sets
707
724
  * `aria-controls` and `aria-expanded` (left off while an untouched pane
708
725
  * cannot know its state yet), renders `type="button"`, and runs the
709
- * consumer's `onClick` first: calling `preventDefault()` there cancels it.
726
+ * consumer's `onClick` first: calling `preventDefault()` there cancels it. With `asChild` the
727
+ * child is the button, and its own `type` stands.
710
728
  */
711
- const Trigger = React.forwardRef<HTMLButtonElement, TriggerProps>(({ target, action = 'toggle', peekOnHover, onClick, onMouseEnter, onMouseLeave, children, ...props }, ref) => {
729
+ const Trigger = React.forwardRef<HTMLButtonElement, TriggerProps>(({ target, action = 'toggle', peekOnHover, asChild = false, onClick, onMouseEnter, onMouseLeave, children, ...props }, ref) => {
712
730
  const store = useShellStore('Shell.Trigger');
713
731
  React.useEffect(() => {
714
732
  if (target === 'left') warnOnce('Shell.Trigger target="left" is deprecated and is removed in 1.0. Use target="rail".');
@@ -742,10 +760,13 @@ const Trigger = React.forwardRef<HTMLButtonElement, TriggerProps>(({ target, act
742
760
  if (peekOnHover && store.peek === name) setShellPeek(store, null);
743
761
  };
744
762
 
763
+ const Comp = asChild ? Slot.Root : 'button';
745
764
  return (
746
- <button
765
+ <Comp
747
766
  // A button's default type is `submit`. Stated before the spread, so a consumer's own wins.
748
- type="button"
767
+ // An asChild child states its own (Button already says `button`; a link has none), so the
768
+ // key is left off rather than passed as undefined.
769
+ {...(!asChild && { type: 'button' as const })}
749
770
  aria-controls={entry?.id}
750
771
  aria-expanded={shown}
751
772
  {...props}
@@ -757,7 +778,7 @@ const Trigger = React.forwardRef<HTMLButtonElement, TriggerProps>(({ target, act
757
778
  data-shell-action={action}
758
779
  >
759
780
  {children}
760
- </button>
781
+ </Comp>
761
782
  );
762
783
  });
763
784
  Trigger.displayName = 'Shell.Trigger';
@@ -97,6 +97,23 @@ function wrapTextNodes(node: React.ReactNode): React.ReactNode {
97
97
  return node;
98
98
  }
99
99
 
100
+ // Arrow Up and Down move between the visible buttons of the same sidebar, as a
101
+ // convenience on top of Tab. Sub-menu triggers take part, so the one-item Accordion
102
+ // behind each sub-menu doesn't keep focus on its own trigger.
103
+ function focusAdjacentSidebarButton(event: React.KeyboardEvent<HTMLElement>) {
104
+ if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;
105
+ const scope = event.currentTarget.closest('.kui-SidebarContent, .kui-SidebarSearchPopover');
106
+ const buttons = scope
107
+ ? Array.from(scope.querySelectorAll<HTMLElement>('.kui-SidebarMenuButton')).filter((el) => el.offsetParent !== null)
108
+ : [];
109
+ const index = buttons.indexOf(event.currentTarget);
110
+ const next = buttons[index + (event.key === 'ArrowDown' ? 1 : -1)];
111
+ if (index !== -1 && next) {
112
+ event.preventDefault();
113
+ next.focus();
114
+ }
115
+ }
116
+
100
117
  const SidebarMenuButton = React.forwardRef<HTMLButtonElement, SidebarMenuButtonProps>(
101
118
  ({ asChild = false, isActive = false, shortcut, badge, className, children, onKeyDown, ...props }, forwardedRef) => {
102
119
  const visual = useSidebarVisual();
@@ -105,22 +122,10 @@ const SidebarMenuButton = React.forwardRef<HTMLButtonElement, SidebarMenuButtonP
105
122
 
106
123
  const Comp = asChild ? Slot : 'button';
107
124
 
108
- // Enter and Space are left to the native button or link. Arrow keys move between
109
- // the visible buttons of the same sidebar, as a convenience on top of Tab.
125
+ // Enter and Space are left to the native button or link.
110
126
  const handleKeyDown = React.useCallback(
111
127
  (event: React.KeyboardEvent<HTMLButtonElement>) => {
112
- if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
113
- const scope = event.currentTarget.closest('.kui-SidebarContent, .kui-SidebarSearchPopover');
114
- const buttons = scope
115
- ? Array.from(scope.querySelectorAll<HTMLElement>('.kui-SidebarMenuButton')).filter((el) => el.offsetParent !== null)
116
- : [];
117
- const index = buttons.indexOf(event.currentTarget);
118
- const next = buttons[index + (event.key === 'ArrowDown' ? 1 : -1)];
119
- if (index !== -1 && next) {
120
- event.preventDefault();
121
- next.focus();
122
- }
123
- }
128
+ focusAdjacentSidebarButton(event);
124
129
  onKeyDown?.(event);
125
130
  },
126
131
  [onKeyDown],
@@ -262,7 +267,7 @@ interface SidebarMenuSubTriggerProps extends React.ComponentPropsWithoutRef<type
262
267
  }
263
268
 
264
269
  const SidebarMenuSubTrigger = React.forwardRef<React.ElementRef<typeof Accordion.Trigger>, SidebarMenuSubTriggerProps>(
265
- ({ asChild = false, className, children, ...props }, forwardedRef) => {
270
+ ({ asChild = false, className, children, onKeyDown, ...props }, forwardedRef) => {
266
271
  const mode = React.useContext(SidebarSubMenuModeContext);
267
272
 
268
273
  if (mode === 'dropdown') {
@@ -270,6 +275,7 @@ const SidebarMenuSubTrigger = React.forwardRef<React.ElementRef<typeof Accordion
270
275
  <DropdownMenu.Trigger>
271
276
  <button
272
277
  {...(props as any)}
278
+ onKeyDown={onKeyDown}
273
279
  ref={forwardedRef as any}
274
280
  type="button"
275
281
  aria-haspopup="menu"
@@ -286,6 +292,11 @@ const SidebarMenuSubTrigger = React.forwardRef<React.ElementRef<typeof Accordion
286
292
  <div>
287
293
  <Accordion.Trigger
288
294
  {...props}
295
+ onKeyDown={(event) => {
296
+ // Runs before the Accordion's own arrow handling, which would keep focus here.
297
+ focusAdjacentSidebarButton(event);
298
+ onKeyDown?.(event);
299
+ }}
289
300
  ref={forwardedRef}
290
301
  asChild={asChild}
291
302
  className={classNames('kui-reset', 'kui-BaseMenuItem', 'kui-SidebarMenuButton', 'kui-SidebarMenuSubTrigger', className)}
@@ -357,7 +368,7 @@ const SidebarMenuSubContent = React.forwardRef<React.ElementRef<typeof Accordion
357
368
 
358
369
  return (
359
370
  <Accordion.Content {...props} ref={forwardedRef} className={classNames('kui-SidebarMenuSubContent', className)}>
360
- <div className="kui-SidebarMenuSubList">{children}</div>
371
+ <ul className="kui-SidebarMenuSubList">{children}</ul>
361
372
  </Accordion.Content>
362
373
  );
363
374
  });
@@ -241,6 +241,7 @@
241
241
  .kui-SliderTick {
242
242
  position: absolute;
243
243
  top: 0;
244
+ transform: translateX(-50%);
244
245
  display: flex;
245
246
  flex-direction: column;
246
247
  align-items: center;
@@ -26,18 +26,34 @@ const Slider = React.forwardRef<SliderElement, SliderProps>((ownProps, forwarded
26
26
  props,
27
27
  sliderPropDefs,
28
28
  );
29
- const { ticks, showTickLabels, snapToTicks, unit } = props;
30
-
31
- const min = sliderProps.min ?? 0;
32
- const max = sliderProps.max ?? 100;
33
-
34
- // Current value for accessibility
35
- const currentValue = sliderProps.value ?? sliderProps.defaultValue ?? [min];
36
- const isRange = Array.isArray(currentValue) && currentValue.length > 1;
29
+ const {
30
+ ticks,
31
+ unit,
32
+ value: valueProp,
33
+ defaultValue,
34
+ onValueChange,
35
+ onValueCommit,
36
+ 'aria-label': ariaLabel,
37
+ 'aria-labelledby': ariaLabelledBy,
38
+ ...rootProps
39
+ } = sliderProps;
40
+ const { showTickLabels, snapToTicks } = props;
41
+
42
+ const min = rootProps.min ?? 0;
43
+ const max = rootProps.max ?? 100;
44
+
45
+ // The slider keeps its own copy of the value when uncontrolled, so the handles, their
46
+ // labels and a tick press all read the current value rather than the first one.
47
+ const [uncontrolledValue, setUncontrolledValue] = React.useState<number[]>(
48
+ () => defaultValue ?? [min],
49
+ );
50
+ const isControlled = valueProp !== undefined;
51
+ const currentValue = isControlled ? valueProp : uncontrolledValue;
52
+ const tickIdPrefix = React.useId();
37
53
 
38
54
  // For snapping to ticks, we need to handle this differently
39
55
  // Radix slider doesn't support arbitrary step values, so we'll handle snapping in the onValueChange
40
- const step = sliderProps.step;
56
+ const step = rootProps.step;
41
57
 
42
58
  // Optimized snap-to-ticks with memoized sorted ticks
43
59
  const sortedTicks = React.useMemo(
@@ -108,7 +124,6 @@ const Slider = React.forwardRef<SliderElement, SliderProps>((ownProps, forwarded
108
124
  const announceRef = React.useRef<HTMLDivElement>(null);
109
125
  const announceTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);
110
126
 
111
- const { onValueChange } = sliderProps;
112
127
  // Handle value changes with snapping
113
128
  const handleValueChange = React.useCallback(
114
129
  (newValue: number[]) => {
@@ -131,9 +146,10 @@ const Slider = React.forwardRef<SliderElement, SliderProps>((ownProps, forwarded
131
146
  }, 1000);
132
147
  }
133
148
 
149
+ if (!isControlled) setUncontrolledValue(finalValue);
134
150
  onValueChange?.(finalValue);
135
151
  },
136
- [snapToTicks, ticks, snapToNearestTick, formatValueText, onValueChange],
152
+ [snapToTicks, ticks, snapToNearestTick, formatValueText, onValueChange, isControlled],
137
153
  );
138
154
 
139
155
  // Cleanup timeout on unmount
@@ -152,49 +168,37 @@ const Slider = React.forwardRef<SliderElement, SliderProps>((ownProps, forwarded
152
168
  ref={announceRef}
153
169
  aria-live="polite"
154
170
  aria-atomic="true"
155
- className="sr-only"
156
- style={{
157
- position: 'absolute',
158
- left: '-10000px',
159
- width: '1px',
160
- height: '1px',
161
- overflow: 'hidden',
162
- }}
171
+ className="kui-sr-only"
163
172
  />
164
173
 
165
174
  <SliderPrimitive.Root
166
175
  data-accent-color={color}
167
176
  data-radius={radius}
168
177
  ref={forwardedRef}
169
- {...sliderProps}
178
+ {...rootProps}
179
+ value={currentValue}
170
180
  step={step}
171
181
  onValueChange={handleValueChange}
182
+ onValueCommit={onValueCommit}
172
183
  asChild={false}
173
184
  className={classNames('kui-SliderRoot', className)}
174
- // Essential ARIA attributes for WCAG 2.2 AA compliance
175
- aria-valuemin={min}
176
- aria-valuemax={max}
177
- aria-valuenow={Array.isArray(currentValue) ? currentValue[0] : (currentValue as number)}
178
- aria-valuetext={formatValueText(currentValue as number[])}
179
- aria-label={props['aria-label'] || `${isRange ? 'Range' : 'Value'} slider`}
180
185
  >
181
186
  <SliderPrimitive.Track className="kui-SliderTrack">
182
187
  <SliderPrimitive.Range
183
188
  className="kui-SliderRange"
184
- data-inverted={sliderProps.inverted ? '' : undefined}
189
+ data-inverted={rootProps.inverted ? '' : undefined}
185
190
  />
186
191
  </SliderPrimitive.Track>
187
- {(sliderProps.value ?? sliderProps.defaultValue ?? []).map((value, index) => (
192
+ {currentValue.map((value, index) => (
188
193
  <SliderPrimitive.Thumb
189
194
  key={index}
190
195
  className="kui-SliderThumb"
191
196
  {...(tabIndex !== undefined ? { tabIndex } : undefined)}
192
- aria-label={
193
- isRange
194
- ? `${index === 0 ? 'Minimum' : index === 1 ? 'Maximum' : `Thumb ${index + 1}`} value: ${unit ? `${value} ${unit}` : value}`
195
- : `Slider value: ${unit ? `${value} ${unit}` : value}`
196
- }
197
- aria-valuetext={unit ? `${value} ${unit}` : value.toString()}
197
+ // The caller's name goes to every handle. Without one, Radix names the two
198
+ // handles of a range "Minimum" and "Maximum".
199
+ aria-label={ariaLabel}
200
+ aria-labelledby={ariaLabelledBy}
201
+ aria-valuetext={unit ? `${value} ${unit}` : undefined}
198
202
  />
199
203
  ))}
200
204
  </SliderPrimitive.Root>
@@ -205,20 +209,26 @@ const Slider = React.forwardRef<SliderElement, SliderProps>((ownProps, forwarded
205
209
  <button
206
210
  key={tick.index}
207
211
  className="kui-SliderTick"
208
- style={{
209
- left: `${tick.percentage}%`,
210
- transform: 'translateX(-50%)',
211
- }}
212
+ // Only `left` varies per tick; the centring transform lives in `.kui-SliderTick`.
213
+ style={{ left: `${tick.percentage}%` }}
212
214
  onClick={() => {
213
- const currentValues = sliderProps.value ?? sliderProps.defaultValue ?? [min];
214
- const newValue = Array.isArray(currentValues)
215
- ? currentValues.map(() => tick.value)
216
- : [tick.value];
215
+ // Move only the handle nearest the tick. When handles share a value, a
216
+ // tick above it moves the last of them and a tick below moves the first.
217
+ let nearest = 0;
218
+ currentValue.forEach((v, i) => {
219
+ const distance = Math.abs(v - tick.value);
220
+ const best = Math.abs(currentValue[nearest] - tick.value);
221
+ if (distance < best || (distance === best && tick.value > v)) nearest = i;
222
+ });
223
+ const newValue = currentValue
224
+ .map((v, i) => (i === nearest ? tick.value : v))
225
+ .sort((x, y) => x - y);
217
226
 
218
227
  handleValueChange(newValue);
228
+ onValueCommit?.(newValue);
219
229
  }}
220
230
  aria-label={`Set to ${tick.label || (unit ? `${tick.value} ${unit}` : tick.value)}`}
221
- aria-describedby={tick.label ? undefined : `tick-${tick.index}-value`}
231
+ aria-describedby={tick.label ? undefined : `${tickIdPrefix}-tick-${tick.index}`}
222
232
  type="button"
223
233
  >
224
234
  <div className="kui-SliderTickMark" />
@@ -226,7 +236,7 @@ const Slider = React.forwardRef<SliderElement, SliderProps>((ownProps, forwarded
226
236
  <div className="kui-SliderTickLabel">{tick.label}</div>
227
237
  )}
228
238
  {!tick.label && (
229
- <span id={`tick-${tick.index}-value`} className="sr-only">
239
+ <span id={`${tickIdPrefix}-tick-${tick.index}`} className="kui-sr-only">
230
240
  {unit ? `${tick.value} ${unit}` : tick.value}
231
241
  </span>
232
242
  )}
@@ -8,6 +8,18 @@
8
8
  position: relative;
9
9
  width: var(--space-5);
10
10
  height: var(--space-5);
11
+ /* The rotation runs on the inner wheel, clipped here. Unclipped, a running transform animation
12
+ makes Chrome give its own layer to everything painted after it that it might overlap. The
13
+ leaves stay inside this box at every step; the margin keeps their anti-aliased edges on the
14
+ diagonal steps, which a clip at the box itself shaves. */
15
+ contain: paint;
16
+ overflow-clip-margin: 4px;
17
+ }
18
+
19
+ .kui-SpinnerWheel {
20
+ position: absolute;
21
+ inset: 0;
22
+ /* On the wheel, not the root: opacity on the clipping root costs Chrome a second layer per spinner. */
11
23
  opacity: var(--spinner-opacity);
12
24
  /* Single GPU-composited rotation instead of 8 opacity animations */
13
25
  animation: kui-spinner-rotate var(--spinner-animation-duration) steps(8, end) infinite;
@@ -73,7 +85,13 @@
73
85
 
74
86
  /* A busy indicator keeps moving when motion is reduced, more slowly. */
75
87
  @media (prefers-reduced-motion: reduce) {
76
- .kui-Spinner {
88
+ .kui-SpinnerWheel {
77
89
  animation-duration: calc(var(--spinner-animation-duration) * 3);
78
90
  }
79
91
  }
92
+
93
+ /* Children of a Spinner keep their space but are not shown while it spins. A class, not an inline style. */
94
+ .kui-SpinnerHiddenChildren {
95
+ display: contents;
96
+ visibility: hidden;
97
+ }
@@ -21,16 +21,26 @@ const Spinner = React.forwardRef<SpinnerElement, SpinnerProps>((props, forwarded
21
21
 
22
22
  if (!loading) return children;
23
23
 
24
+ // Decorative unless named: a named spinner is a status message, an unnamed one is hidden.
25
+ const named =
26
+ spinnerProps['aria-label'] !== undefined || spinnerProps['aria-labelledby'] !== undefined;
27
+
24
28
  const spinner = (
25
- <span {...spinnerProps} ref={forwardedRef} className={classNames('kui-Spinner', className)}>
26
- <span className="kui-SpinnerLeaf" />
27
- <span className="kui-SpinnerLeaf" />
28
- <span className="kui-SpinnerLeaf" />
29
- <span className="kui-SpinnerLeaf" />
30
- <span className="kui-SpinnerLeaf" />
31
- <span className="kui-SpinnerLeaf" />
32
- <span className="kui-SpinnerLeaf" />
33
- <span className="kui-SpinnerLeaf" />
29
+ <span
30
+ role={named ? 'status' : undefined}
31
+ aria-hidden={named ? undefined : true}
32
+ {...spinnerProps}
33
+ ref={forwardedRef} className={classNames('kui-Spinner', className)}>
34
+ <span className="kui-SpinnerWheel">
35
+ <span className="kui-SpinnerLeaf" />
36
+ <span className="kui-SpinnerLeaf" />
37
+ <span className="kui-SpinnerLeaf" />
38
+ <span className="kui-SpinnerLeaf" />
39
+ <span className="kui-SpinnerLeaf" />
40
+ <span className="kui-SpinnerLeaf" />
41
+ <span className="kui-SpinnerLeaf" />
42
+ <span className="kui-SpinnerLeaf" />
43
+ </span>
34
44
  </span>
35
45
  );
36
46
 
@@ -38,12 +48,12 @@ const Spinner = React.forwardRef<SpinnerElement, SpinnerProps>((props, forwarded
38
48
 
39
49
  return (
40
50
  <Flex asChild position="relative" align="center" justify="center">
41
- <span>
51
+ <span aria-busy="true">
42
52
  {/**
43
53
  * `display: contents` removes the content from the accessibility tree in some browsers,
44
54
  * so we force remove it with `aria-hidden`
45
55
  */}
46
- <span aria-hidden style={{ display: 'contents', visibility: 'hidden' }} inert={undefined}>
56
+ <span aria-hidden className="kui-SpinnerHiddenChildren" inert={undefined}>
47
57
  {children}
48
58
  </span>
49
59
 
@@ -18,10 +18,16 @@ interface TableRootProps
18
18
  const TableRoot = React.forwardRef<TableRootElement, TableRootProps>((ownProps, forwardedRef) => {
19
19
  const props = useThemeSizeProps(ownProps, tableRootPropDefs.size);
20
20
  const { layout: layoutPropDef, ...rootPropDefs } = tableRootPropDefs;
21
- const { className, children, layout, ...rootProps } = extractProps(
22
- props,
23
- rootPropDefs
24
- );
21
+ const {
22
+ className,
23
+ children,
24
+ layout,
25
+ // The table is what gets named, not the scroll wrapper around it.
26
+ 'aria-label': ariaLabel,
27
+ 'aria-labelledby': ariaLabelledBy,
28
+ 'aria-describedby': ariaDescribedBy,
29
+ ...rootProps
30
+ } = extractProps(props, rootPropDefs);
25
31
  const tableLayoutClassNames = getResponsiveClassNames({
26
32
  value: layout,
27
33
  className: tableRootPropDefs.layout.className,
@@ -30,7 +36,14 @@ const TableRoot = React.forwardRef<TableRootElement, TableRootProps>((ownProps,
30
36
  return (
31
37
  <div ref={forwardedRef} className={classNames('kui-TableRoot', className)} {...rootProps}>
32
38
  <ScrollArea>
33
- <table className={classNames('kui-TableRootTable', tableLayoutClassNames)}>{children}</table>
39
+ <table
40
+ className={classNames('kui-TableRootTable', tableLayoutClassNames)}
41
+ aria-label={ariaLabel}
42
+ aria-labelledby={ariaLabelledBy}
43
+ aria-describedby={ariaDescribedBy}
44
+ >
45
+ {children}
46
+ </table>
34
47
  </ScrollArea>
35
48
  </div>
36
49
  );
@@ -9,3 +9,37 @@
9
9
  outline: var(--focus-ring-width, 2px) solid var(--focus-8);
10
10
  outline-offset: var(--focus-ring-offset, 2px);
11
11
  }
12
+
13
+ /*
14
+ * Vertical: the list is a column beside the panels, its hairline on the inline end, and the
15
+ * active line runs down that edge.
16
+ */
17
+ .kui-TabsRoot:where([data-orientation='vertical']) {
18
+ display: flex;
19
+ }
20
+
21
+ .kui-TabsList:where([data-orientation='vertical']) {
22
+ flex-direction: column;
23
+ flex-shrink: 0;
24
+ overflow-x: hidden;
25
+ overflow-y: auto;
26
+ box-shadow: inset calc(-1 * var(--border-width-standard)) 0 0 0 var(--neutral-a5);
27
+
28
+ &:where(:dir(rtl)) {
29
+ box-shadow: inset var(--border-width-standard) 0 0 0 var(--neutral-a5);
30
+ }
31
+
32
+ :where(&) .kui-TabsTrigger {
33
+ justify-content: flex-start;
34
+ }
35
+
36
+ :where(&) .kui-TabsTrigger:where([data-state='active'])::before {
37
+ top: 0;
38
+ bottom: 0;
39
+ left: auto;
40
+ right: auto;
41
+ inset-inline-end: 0;
42
+ width: var(--focus-ring-width, 2px);
43
+ height: auto;
44
+ }
45
+ }
@@ -86,8 +86,6 @@ const TabsContent = React.forwardRef<TabsContentElement, TabsContentProps>(
86
86
  {...contentProps}
87
87
  ref={forwardedRef}
88
88
  className={classNames('kui-TabsContent', className)}
89
- aria-live="polite"
90
- aria-atomic="true"
91
89
  />
92
90
  );
93
91
  },
@@ -28,8 +28,9 @@
28
28
  font-style: normal;
29
29
  text-align: start;
30
30
 
31
- /* Allows the `resize` property to work on the div */
31
+ /* Allows the `resize` property to work on the div. Vertical by default, as in v2; the `resize` prop overrides it. */
32
32
  overflow: hidden;
33
+ resize: vertical;
33
34
 
34
35
  isolation: isolate;
35
36
 
@@ -52,7 +52,6 @@ const TextArea = React.forwardRef<TextAreaElement, TextAreaProps>((ownProps, for
52
52
  const {
53
53
  error,
54
54
  errorMessage,
55
-
56
55
  required,
57
56
  'aria-describedby': _ariaDescribedby,
58
57
  'aria-labelledby': _ariaLabelledby,
@@ -72,6 +71,7 @@ const TextArea = React.forwardRef<TextAreaElement, TextAreaProps>((ownProps, for
72
71
  className="kui-reset kui-TextAreaInput"
73
72
  ref={forwardedRef}
74
73
  {...nativeTextAreaProps}
74
+ required={required || undefined}
75
75
  {...ariaProps}
76
76
  />
77
77
  {textAreaProps.errorMessage && (
@@ -91,7 +91,7 @@ const TextFieldRoot = React.forwardRef<TextFieldRootElement, TextFieldRootProps>
91
91
  })}
92
92
  onPointerDown={handlePointerDown}
93
93
  >
94
- <input spellCheck="false" {...nativeInputProps} {...ariaProps} ref={composeRefs(inputRef, forwardedRef)} className="kui-reset kui-TextFieldInput" />
94
+ <input {...nativeInputProps} required={required || undefined} {...ariaProps} ref={composeRefs(inputRef, forwardedRef)} className="kui-reset kui-TextFieldInput" />
95
95
  {children}
96
96
  {inputProps.errorMessage && (
97
97
  <div id={errorId} className="kui-TextFieldErrorMessage" role="alert">