@womp/kookie-ui 0.23.0 → 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 (463) hide show
  1. package/components.css +190 -185
  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/index.d.ts +1 -1
  72. package/dist/cjs/components/index.d.ts.map +1 -1
  73. package/dist/cjs/components/index.js +2 -10
  74. package/dist/cjs/components/index.js.map +4 -4
  75. package/dist/cjs/components/message-scroller.d.ts.map +1 -1
  76. package/dist/cjs/components/message-scroller.js +1 -1
  77. package/dist/cjs/components/message-scroller.js.map +4 -4
  78. package/dist/cjs/components/navbar.d.ts.map +1 -1
  79. package/dist/cjs/components/navbar.js +1 -1
  80. package/dist/cjs/components/navbar.js.map +3 -3
  81. package/dist/cjs/components/notice.d.ts +4 -1
  82. package/dist/cjs/components/notice.d.ts.map +1 -1
  83. package/dist/cjs/components/notice.js +1 -1
  84. package/dist/cjs/components/notice.js.map +4 -4
  85. package/dist/cjs/components/progress.d.ts.map +1 -1
  86. package/dist/cjs/components/progress.js +1 -1
  87. package/dist/cjs/components/progress.js.map +3 -3
  88. package/dist/cjs/components/schemas/button.schema.d.ts +2 -2
  89. package/dist/cjs/components/schemas/toggle.schema.d.ts +1 -1
  90. package/dist/cjs/components/scroll-area.d.ts +3 -1
  91. package/dist/cjs/components/scroll-area.d.ts.map +1 -1
  92. package/dist/cjs/components/scroll-area.js +1 -1
  93. package/dist/cjs/components/scroll-area.js.map +4 -4
  94. package/dist/cjs/components/segmented-control.d.ts +3 -1
  95. package/dist/cjs/components/segmented-control.d.ts.map +1 -1
  96. package/dist/cjs/components/segmented-control.js +1 -1
  97. package/dist/cjs/components/segmented-control.js.map +3 -3
  98. package/dist/cjs/components/select.d.ts.map +1 -1
  99. package/dist/cjs/components/select.js +1 -1
  100. package/dist/cjs/components/select.js.map +3 -3
  101. package/dist/cjs/components/separator.d.ts.map +1 -1
  102. package/dist/cjs/components/separator.js +1 -1
  103. package/dist/cjs/components/separator.js.map +3 -3
  104. package/dist/cjs/components/sheet.d.ts +1 -0
  105. package/dist/cjs/components/sheet.d.ts.map +1 -1
  106. package/dist/cjs/components/sheet.js +1 -1
  107. package/dist/cjs/components/sheet.js.map +3 -3
  108. package/dist/cjs/components/shell.d.ts +12 -1
  109. package/dist/cjs/components/shell.d.ts.map +1 -1
  110. package/dist/cjs/components/shell.js +1 -1
  111. package/dist/cjs/components/shell.js.map +4 -4
  112. package/dist/cjs/components/sidebar.d.ts.map +1 -1
  113. package/dist/cjs/components/sidebar.js +1 -1
  114. package/dist/cjs/components/sidebar.js.map +4 -4
  115. package/dist/cjs/components/slider.d.ts.map +1 -1
  116. package/dist/cjs/components/slider.js +1 -1
  117. package/dist/cjs/components/slider.js.map +3 -3
  118. package/dist/cjs/components/spinner.d.ts.map +1 -1
  119. package/dist/cjs/components/spinner.js +1 -1
  120. package/dist/cjs/components/spinner.js.map +3 -3
  121. package/dist/cjs/components/table.d.ts.map +1 -1
  122. package/dist/cjs/components/table.js +1 -1
  123. package/dist/cjs/components/table.js.map +4 -4
  124. package/dist/cjs/components/tabs.d.ts.map +1 -1
  125. package/dist/cjs/components/tabs.js +1 -1
  126. package/dist/cjs/components/tabs.js.map +2 -2
  127. package/dist/cjs/components/text-area.js +1 -1
  128. package/dist/cjs/components/text-area.js.map +2 -2
  129. package/dist/cjs/components/text-field.js +2 -2
  130. package/dist/cjs/components/text-field.js.map +2 -2
  131. package/dist/cjs/components/toggle.d.ts +3 -2
  132. package/dist/cjs/components/toggle.d.ts.map +1 -1
  133. package/dist/cjs/components/toggle.js +1 -9
  134. package/dist/cjs/components/toggle.js.map +4 -4
  135. package/dist/cjs/components/toolbar.d.ts +80 -8
  136. package/dist/cjs/components/toolbar.d.ts.map +1 -1
  137. package/dist/cjs/components/toolbar.js +1 -1
  138. package/dist/cjs/components/toolbar.js.map +4 -4
  139. package/dist/cjs/components/virtual-menu.d.ts +3 -5
  140. package/dist/cjs/components/virtual-menu.d.ts.map +1 -1
  141. package/dist/cjs/components/virtual-menu.js +1 -1
  142. package/dist/cjs/components/virtual-menu.js.map +3 -3
  143. package/dist/cjs/helpers/extract-margin-props.d.ts +7 -7
  144. package/dist/cjs/hooks/use-scroll-edges.d.ts +4 -2
  145. package/dist/cjs/hooks/use-scroll-edges.d.ts.map +1 -1
  146. package/dist/cjs/hooks/use-scroll-edges.js +1 -1
  147. package/dist/cjs/hooks/use-scroll-edges.js.map +3 -3
  148. package/dist/cjs/index.js +5 -5
  149. package/dist/cjs/index.js.map +4 -4
  150. package/dist/cjs/props/index.js +1 -1
  151. package/dist/cjs/props/index.js.map +2 -2
  152. package/dist/esm/chunk-3VTS4C63.js +2 -0
  153. package/dist/esm/chunk-3VTS4C63.js.map +7 -0
  154. package/dist/esm/chunk-3WE4E2WQ.js +2 -0
  155. package/dist/esm/chunk-3WE4E2WQ.js.map +7 -0
  156. package/dist/esm/chunk-3XUY5WFA.js +2 -0
  157. package/dist/esm/chunk-3XUY5WFA.js.map +7 -0
  158. package/dist/esm/chunk-3XZOE2IQ.js +2 -0
  159. package/dist/esm/chunk-3XZOE2IQ.js.map +7 -0
  160. package/dist/esm/chunk-432YLNB3.js +2 -0
  161. package/dist/esm/chunk-432YLNB3.js.map +7 -0
  162. package/dist/esm/chunk-4QKZYCCH.js +2 -0
  163. package/dist/esm/chunk-4QKZYCCH.js.map +7 -0
  164. package/dist/esm/chunk-4R5EMVB3.js +2 -0
  165. package/dist/esm/chunk-4R5EMVB3.js.map +7 -0
  166. package/dist/esm/chunk-4ZOVV3TY.js +2 -0
  167. package/dist/esm/chunk-4ZOVV3TY.js.map +7 -0
  168. package/dist/esm/{chunk-IX5HIHVI.js → chunk-62ZGP4ET.js} +2 -2
  169. package/dist/esm/{chunk-IX5HIHVI.js.map → chunk-62ZGP4ET.js.map} +3 -3
  170. package/dist/esm/chunk-BGAJ2MDF.js +2 -0
  171. package/dist/esm/chunk-BGAJ2MDF.js.map +7 -0
  172. package/dist/esm/chunk-CHPT42BY.js +2 -0
  173. package/dist/esm/{chunk-Y3JYEEFB.js.map → chunk-CHPT42BY.js.map} +2 -2
  174. package/dist/esm/{chunk-KS4U4VPH.js → chunk-CMHUK7OG.js} +2 -2
  175. package/dist/esm/{chunk-KS4U4VPH.js.map → chunk-CMHUK7OG.js.map} +2 -2
  176. package/dist/esm/chunk-CN6F4REJ.js +2 -0
  177. package/dist/esm/chunk-CN6F4REJ.js.map +7 -0
  178. package/dist/esm/chunk-DUTZUWZP.js +2 -0
  179. package/dist/esm/chunk-DUTZUWZP.js.map +7 -0
  180. package/dist/esm/chunk-FDJV5RXX.js +2 -0
  181. package/dist/esm/chunk-FDJV5RXX.js.map +7 -0
  182. package/dist/esm/chunk-G2JD52O5.js +2 -0
  183. package/dist/esm/{chunk-23KT3D2Z.js.map → chunk-G2JD52O5.js.map} +3 -3
  184. package/dist/esm/{chunk-6DDOR73D.js → chunk-G4ETY2NP.js} +2 -2
  185. package/dist/esm/chunk-GPOCLDBR.js +2 -0
  186. package/dist/esm/chunk-GPOCLDBR.js.map +7 -0
  187. package/dist/esm/chunk-GYP66ZK2.js +2 -0
  188. package/dist/esm/chunk-GYP66ZK2.js.map +7 -0
  189. package/dist/esm/chunk-H5BYPX6V.js +2 -0
  190. package/dist/esm/chunk-H5BYPX6V.js.map +7 -0
  191. package/dist/esm/chunk-H5G7UECV.js +2 -0
  192. package/dist/esm/chunk-H5G7UECV.js.map +7 -0
  193. package/dist/esm/chunk-I4FLQELQ.js +2 -0
  194. package/dist/esm/chunk-I4FLQELQ.js.map +7 -0
  195. package/dist/esm/chunk-JYQGCXXI.js +2 -0
  196. package/dist/esm/chunk-JYQGCXXI.js.map +7 -0
  197. package/dist/esm/chunk-KA5UE2VN.js +2 -0
  198. package/dist/esm/chunk-KA5UE2VN.js.map +7 -0
  199. package/dist/esm/{chunk-QGCXTULQ.js → chunk-KEGCX5VM.js} +2 -2
  200. package/dist/esm/chunk-KVHKPUZ2.js +2 -0
  201. package/dist/esm/chunk-KVHKPUZ2.js.map +7 -0
  202. package/dist/esm/{chunk-FFG32ERA.js → chunk-N3WBEQWL.js} +3 -3
  203. package/dist/esm/chunk-N3WBEQWL.js.map +7 -0
  204. package/dist/esm/{chunk-HKPXDQ2B.js → chunk-NC3CJUE3.js} +2 -2
  205. package/dist/esm/chunk-P2MV6HLA.js +2 -0
  206. package/dist/esm/{chunk-7SS4UUJH.js.map → chunk-P2MV6HLA.js.map} +3 -3
  207. package/dist/esm/chunk-PALE5UWK.js +2 -0
  208. package/dist/esm/{chunk-DSPYHO3L.js.map → chunk-PALE5UWK.js.map} +2 -2
  209. package/dist/esm/chunk-PDMCLVYT.js +2 -0
  210. package/dist/esm/chunk-PDMCLVYT.js.map +7 -0
  211. package/dist/esm/chunk-PM6QY3JO.js +2 -0
  212. package/dist/esm/{chunk-ZEX2DECM.js.map → chunk-PM6QY3JO.js.map} +3 -3
  213. package/dist/esm/chunk-RKZVXVBN.js +2 -0
  214. package/dist/esm/chunk-RKZVXVBN.js.map +7 -0
  215. package/dist/esm/chunk-TXQZ5HLV.js +2 -0
  216. package/dist/esm/chunk-TXQZ5HLV.js.map +7 -0
  217. package/dist/esm/chunk-UKASIY6M.js +2 -0
  218. package/dist/esm/chunk-UKASIY6M.js.map +7 -0
  219. package/dist/esm/{chunk-OJQNLROL.js → chunk-UY6WJUNA.js} +2 -2
  220. package/dist/esm/chunk-V5O3TF57.js +2 -0
  221. package/dist/esm/{chunk-3KQE2PSJ.js.map → chunk-V5O3TF57.js.map} +3 -3
  222. package/dist/esm/chunk-VUNCI6A6.js +2 -0
  223. package/dist/esm/chunk-VUNCI6A6.js.map +7 -0
  224. package/dist/esm/{chunk-JBHRV364.js → chunk-VUPIJNG2.js} +2 -2
  225. package/dist/esm/chunk-W6BN5QLH.js +2 -0
  226. package/dist/esm/{chunk-ZNDCZM5A.js.map → chunk-W6BN5QLH.js.map} +2 -2
  227. package/dist/esm/chunk-WG5ORTIW.js +2 -0
  228. package/dist/esm/chunk-WG5ORTIW.js.map +7 -0
  229. package/dist/esm/chunk-WMVR2XBR.js +2 -0
  230. package/dist/esm/{chunk-XKSU3NLG.js.map → chunk-WMVR2XBR.js.map} +2 -2
  231. package/dist/esm/{chunk-NNZTSXKH.js → chunk-WX7SX5BN.js} +2 -2
  232. package/dist/esm/chunk-XOACTIBL.js +2 -0
  233. package/dist/esm/chunk-XOACTIBL.js.map +7 -0
  234. package/dist/esm/components/_internal/base-button.d.ts +11 -1
  235. package/dist/esm/components/_internal/base-button.d.ts.map +1 -1
  236. package/dist/esm/components/_internal/base-button.js +1 -1
  237. package/dist/esm/components/_internal/menu-context.d.ts +2 -0
  238. package/dist/esm/components/_internal/menu-context.d.ts.map +1 -1
  239. package/dist/esm/components/_internal/menu-context.js +1 -1
  240. package/dist/esm/components/_internal/pane-chrome.d.ts +17 -2
  241. package/dist/esm/components/_internal/pane-chrome.d.ts.map +1 -1
  242. package/dist/esm/components/_internal/pane-chrome.js +1 -1
  243. package/dist/esm/components/_internal/shell-bottom.js +1 -1
  244. package/dist/esm/components/_internal/shell-inspector.js +1 -1
  245. package/dist/esm/components/_internal/shell-sidebar.js +1 -1
  246. package/dist/esm/components/accordion.d.ts +2 -2
  247. package/dist/esm/components/accordion.d.ts.map +1 -1
  248. package/dist/esm/components/accordion.js +1 -1
  249. package/dist/esm/components/alert-dialog.d.ts.map +1 -1
  250. package/dist/esm/components/alert-dialog.js +1 -1
  251. package/dist/esm/components/avatar.d.ts +1 -1
  252. package/dist/esm/components/avatar.d.ts.map +1 -1
  253. package/dist/esm/components/avatar.js +1 -1
  254. package/dist/esm/components/avatar.props.d.ts +8 -0
  255. package/dist/esm/components/avatar.props.d.ts.map +1 -1
  256. package/dist/esm/components/avatar.props.js +1 -1
  257. package/dist/esm/components/blockquote.d.ts +1 -1
  258. package/dist/esm/components/blockquote.d.ts.map +1 -1
  259. package/dist/esm/components/blockquote.js +1 -1
  260. package/dist/esm/components/button.js +1 -1
  261. package/dist/esm/components/chatbar.d.ts.map +1 -1
  262. package/dist/esm/components/chatbar.js +1 -1
  263. package/dist/esm/components/checkbox-group.d.ts.map +1 -1
  264. package/dist/esm/components/checkbox-group.js +1 -1
  265. package/dist/esm/components/checkbox-group.primitive.d.ts +12 -5
  266. package/dist/esm/components/checkbox-group.primitive.d.ts.map +1 -1
  267. package/dist/esm/components/checkbox-group.primitive.js +1 -1
  268. package/dist/esm/components/checkbox.js +1 -1
  269. package/dist/esm/components/chip.d.ts.map +1 -1
  270. package/dist/esm/components/chip.js +1 -1
  271. package/dist/esm/components/code.d.ts.map +1 -1
  272. package/dist/esm/components/code.js +1 -1
  273. package/dist/esm/components/combobox.js +1 -1
  274. package/dist/esm/components/context-menu.d.ts.map +1 -1
  275. package/dist/esm/components/context-menu.js +1 -1
  276. package/dist/esm/components/dialog.d.ts +1 -1
  277. package/dist/esm/components/dialog.d.ts.map +1 -1
  278. package/dist/esm/components/dialog.js +1 -1
  279. package/dist/esm/components/dropdown-menu.d.ts.map +1 -1
  280. package/dist/esm/components/dropdown-menu.js +1 -1
  281. package/dist/esm/components/icons.d.ts +3 -1
  282. package/dist/esm/components/icons.d.ts.map +1 -1
  283. package/dist/esm/components/icons.js +1 -1
  284. package/dist/esm/components/index.d.ts +1 -1
  285. package/dist/esm/components/index.d.ts.map +1 -1
  286. package/dist/esm/components/index.js +1 -1
  287. package/dist/esm/components/message-scroller.d.ts.map +1 -1
  288. package/dist/esm/components/message-scroller.js +1 -1
  289. package/dist/esm/components/navbar.d.ts.map +1 -1
  290. package/dist/esm/components/navbar.js +1 -1
  291. package/dist/esm/components/notice.d.ts +4 -1
  292. package/dist/esm/components/notice.d.ts.map +1 -1
  293. package/dist/esm/components/notice.js +1 -1
  294. package/dist/esm/components/progress.d.ts.map +1 -1
  295. package/dist/esm/components/progress.js +1 -1
  296. package/dist/esm/components/schemas/button.schema.d.ts +2 -2
  297. package/dist/esm/components/schemas/toggle.schema.d.ts +1 -1
  298. package/dist/esm/components/scroll-area.d.ts +3 -1
  299. package/dist/esm/components/scroll-area.d.ts.map +1 -1
  300. package/dist/esm/components/scroll-area.js +1 -1
  301. package/dist/esm/components/segmented-control.d.ts +3 -1
  302. package/dist/esm/components/segmented-control.d.ts.map +1 -1
  303. package/dist/esm/components/segmented-control.js +1 -1
  304. package/dist/esm/components/select.d.ts.map +1 -1
  305. package/dist/esm/components/select.js +1 -1
  306. package/dist/esm/components/separator.d.ts.map +1 -1
  307. package/dist/esm/components/separator.js +1 -1
  308. package/dist/esm/components/sheet.d.ts +1 -0
  309. package/dist/esm/components/sheet.d.ts.map +1 -1
  310. package/dist/esm/components/sheet.js +1 -1
  311. package/dist/esm/components/shell.d.ts +12 -1
  312. package/dist/esm/components/shell.d.ts.map +1 -1
  313. package/dist/esm/components/shell.js +1 -1
  314. package/dist/esm/components/sidebar.d.ts.map +1 -1
  315. package/dist/esm/components/sidebar.js +1 -1
  316. package/dist/esm/components/slider.d.ts.map +1 -1
  317. package/dist/esm/components/slider.js +1 -1
  318. package/dist/esm/components/spinner.d.ts.map +1 -1
  319. package/dist/esm/components/spinner.js +1 -1
  320. package/dist/esm/components/table.d.ts.map +1 -1
  321. package/dist/esm/components/table.js +1 -1
  322. package/dist/esm/components/tabs.d.ts.map +1 -1
  323. package/dist/esm/components/tabs.js +1 -1
  324. package/dist/esm/components/text-area.js +1 -1
  325. package/dist/esm/components/text-field.js +1 -1
  326. package/dist/esm/components/toggle.d.ts +3 -2
  327. package/dist/esm/components/toggle.d.ts.map +1 -1
  328. package/dist/esm/components/toggle.js +1 -1
  329. package/dist/esm/components/toolbar.d.ts +80 -8
  330. package/dist/esm/components/toolbar.d.ts.map +1 -1
  331. package/dist/esm/components/toolbar.js +1 -1
  332. package/dist/esm/components/virtual-menu.d.ts +3 -5
  333. package/dist/esm/components/virtual-menu.d.ts.map +1 -1
  334. package/dist/esm/components/virtual-menu.js +1 -1
  335. package/dist/esm/helpers/extract-margin-props.d.ts +7 -7
  336. package/dist/esm/hooks/index.js +1 -1
  337. package/dist/esm/hooks/use-scroll-edges.d.ts +4 -2
  338. package/dist/esm/hooks/use-scroll-edges.d.ts.map +1 -1
  339. package/dist/esm/hooks/use-scroll-edges.js +1 -1
  340. package/dist/esm/index.js +1 -1
  341. package/dist/esm/props/index.js +1 -1
  342. package/package.json +1 -1
  343. package/src/components/_internal/base-button.tsx +51 -12
  344. package/src/components/_internal/base-sidebar-menu.css +8 -0
  345. package/src/components/_internal/menu-context.tsx +11 -0
  346. package/src/components/_internal/pane-chrome.tsx +45 -8
  347. package/src/components/accordion.css +35 -3
  348. package/src/components/accordion.tsx +12 -16
  349. package/src/components/alert-dialog.tsx +59 -161
  350. package/src/components/avatar.props.tsx +6 -0
  351. package/src/components/avatar.tsx +57 -71
  352. package/src/components/blockquote.tsx +8 -9
  353. package/src/components/chatbar.tsx +27 -20
  354. package/src/components/checkbox-group.primitive.tsx +40 -51
  355. package/src/components/checkbox-group.tsx +1 -9
  356. package/src/components/chip.css +18 -20
  357. package/src/components/chip.tsx +3 -4
  358. package/src/components/code.tsx +3 -2
  359. package/src/components/context-menu.tsx +23 -5
  360. package/src/components/dialog.tsx +59 -160
  361. package/src/components/dropdown-menu.tsx +8 -5
  362. package/src/components/icons.tsx +11 -1
  363. package/src/components/index.tsx +7 -0
  364. package/src/components/message-scroller.tsx +48 -26
  365. package/src/components/navbar.tsx +34 -69
  366. package/src/components/notice.tsx +6 -3
  367. package/src/components/progress.tsx +6 -3
  368. package/src/components/scroll-area.css +28 -2
  369. package/src/components/scroll-area.tsx +49 -3
  370. package/src/components/segmented-control.css +8 -130
  371. package/src/components/segmented-control.tsx +36 -5
  372. package/src/components/select.tsx +23 -3
  373. package/src/components/separator.tsx +13 -1
  374. package/src/components/sheet.css +7 -6
  375. package/src/components/sheet.tsx +76 -143
  376. package/src/components/shell.css +14 -0
  377. package/src/components/shell.tsx +29 -8
  378. package/src/components/sidebar.tsx +27 -16
  379. package/src/components/slider.tsx +51 -32
  380. package/src/components/spinner.tsx +10 -2
  381. package/src/components/table.tsx +18 -5
  382. package/src/components/tabs.css +34 -0
  383. package/src/components/tabs.tsx +0 -2
  384. package/src/components/text-area.css +2 -1
  385. package/src/components/text-area.tsx +1 -1
  386. package/src/components/text-field.tsx +1 -1
  387. package/src/components/toggle.tsx +21 -39
  388. package/src/components/toolbar.css +34 -0
  389. package/src/components/toolbar.tsx +432 -23
  390. package/src/components/virtual-menu.tsx +110 -37
  391. package/src/hooks/use-scroll-edges.ts +11 -2
  392. package/src/styles/utilities/truncate.css +10 -0
  393. package/styles.css +195 -185
  394. package/utilities.css +5 -0
  395. package/dist/esm/chunk-23KT3D2Z.js +0 -2
  396. package/dist/esm/chunk-3JA7SJDT.js +0 -2
  397. package/dist/esm/chunk-3JA7SJDT.js.map +0 -7
  398. package/dist/esm/chunk-3KQE2PSJ.js +0 -2
  399. package/dist/esm/chunk-5BWLY27A.js +0 -2
  400. package/dist/esm/chunk-5BWLY27A.js.map +0 -7
  401. package/dist/esm/chunk-6CK7UTNH.js +0 -2
  402. package/dist/esm/chunk-6CK7UTNH.js.map +0 -7
  403. package/dist/esm/chunk-6RK26HIY.js +0 -2
  404. package/dist/esm/chunk-6RK26HIY.js.map +0 -7
  405. package/dist/esm/chunk-7ESWH773.js +0 -2
  406. package/dist/esm/chunk-7ESWH773.js.map +0 -7
  407. package/dist/esm/chunk-7SS4UUJH.js +0 -2
  408. package/dist/esm/chunk-AB3QCCUM.js +0 -2
  409. package/dist/esm/chunk-AB3QCCUM.js.map +0 -7
  410. package/dist/esm/chunk-BEP4AH5V.js +0 -2
  411. package/dist/esm/chunk-BEP4AH5V.js.map +0 -7
  412. package/dist/esm/chunk-BOL3VVSN.js +0 -2
  413. package/dist/esm/chunk-BOL3VVSN.js.map +0 -7
  414. package/dist/esm/chunk-DBROSD2J.js +0 -2
  415. package/dist/esm/chunk-DBROSD2J.js.map +0 -7
  416. package/dist/esm/chunk-DSPYHO3L.js +0 -2
  417. package/dist/esm/chunk-E2D2VWUI.js +0 -2
  418. package/dist/esm/chunk-E2D2VWUI.js.map +0 -7
  419. package/dist/esm/chunk-EMNSA65L.js +0 -2
  420. package/dist/esm/chunk-EMNSA65L.js.map +0 -7
  421. package/dist/esm/chunk-FFG32ERA.js.map +0 -7
  422. package/dist/esm/chunk-FHPHEIYJ.js +0 -2
  423. package/dist/esm/chunk-FHPHEIYJ.js.map +0 -7
  424. package/dist/esm/chunk-FJFBM7HW.js +0 -2
  425. package/dist/esm/chunk-FJFBM7HW.js.map +0 -7
  426. package/dist/esm/chunk-FYT7TYGS.js +0 -2
  427. package/dist/esm/chunk-FYT7TYGS.js.map +0 -7
  428. package/dist/esm/chunk-GLV7VGBH.js +0 -2
  429. package/dist/esm/chunk-GLV7VGBH.js.map +0 -7
  430. package/dist/esm/chunk-HIKMKGPT.js +0 -2
  431. package/dist/esm/chunk-HIKMKGPT.js.map +0 -7
  432. package/dist/esm/chunk-L2R62BOB.js +0 -2
  433. package/dist/esm/chunk-L2R62BOB.js.map +0 -7
  434. package/dist/esm/chunk-LHIS3UKQ.js +0 -2
  435. package/dist/esm/chunk-LHIS3UKQ.js.map +0 -7
  436. package/dist/esm/chunk-NQDMTOGB.js +0 -2
  437. package/dist/esm/chunk-NQDMTOGB.js.map +0 -7
  438. package/dist/esm/chunk-Q6MFPATL.js +0 -2
  439. package/dist/esm/chunk-Q6MFPATL.js.map +0 -7
  440. package/dist/esm/chunk-QOHJIF25.js +0 -2
  441. package/dist/esm/chunk-QOHJIF25.js.map +0 -7
  442. package/dist/esm/chunk-R4XJNQX5.js +0 -2
  443. package/dist/esm/chunk-R4XJNQX5.js.map +0 -7
  444. package/dist/esm/chunk-UE3HATOA.js +0 -2
  445. package/dist/esm/chunk-UE3HATOA.js.map +0 -7
  446. package/dist/esm/chunk-V32EP3S7.js +0 -2
  447. package/dist/esm/chunk-V32EP3S7.js.map +0 -7
  448. package/dist/esm/chunk-XKSU3NLG.js +0 -2
  449. package/dist/esm/chunk-XRCMPBAY.js +0 -2
  450. package/dist/esm/chunk-XRCMPBAY.js.map +0 -7
  451. package/dist/esm/chunk-Y3JYEEFB.js +0 -2
  452. package/dist/esm/chunk-YZM54IJE.js +0 -2
  453. package/dist/esm/chunk-YZM54IJE.js.map +0 -7
  454. package/dist/esm/chunk-ZEX2DECM.js +0 -2
  455. package/dist/esm/chunk-ZJI2IK7C.js +0 -2
  456. package/dist/esm/chunk-ZJI2IK7C.js.map +0 -7
  457. package/dist/esm/chunk-ZNDCZM5A.js +0 -2
  458. /package/dist/esm/{chunk-6DDOR73D.js.map → chunk-G4ETY2NP.js.map} +0 -0
  459. /package/dist/esm/{chunk-QGCXTULQ.js.map → chunk-KEGCX5VM.js.map} +0 -0
  460. /package/dist/esm/{chunk-HKPXDQ2B.js.map → chunk-NC3CJUE3.js.map} +0 -0
  461. /package/dist/esm/{chunk-OJQNLROL.js.map → chunk-UY6WJUNA.js.map} +0 -0
  462. /package/dist/esm/{chunk-JBHRV364.js.map → chunk-VUPIJNG2.js.map} +0 -0
  463. /package/dist/esm/{chunk-NNZTSXKH.js.map → chunk-WX7SX5BN.js.map} +0 -0
@@ -1,10 +1,9 @@
1
1
  'use client';
2
2
 
3
- import { warnDeprecated } from '../helpers/warn-deprecated.js';
4
3
  import * as React from 'react';
5
4
  import classNames from 'classnames';
6
5
  import { ToggleGroup as ToggleGroupPrimitive } from 'radix-ui';
7
- import { useControllableState } from 'radix-ui/internal';
6
+ import { useComposedRefs, useControllableState } from 'radix-ui/internal';
8
7
 
9
8
  import { segmentedControlRootPropDefs } from './segmented-control.props.js';
10
9
  import { extractProps } from '../helpers/extract-props.js';
@@ -23,6 +22,8 @@ interface SegmentedControlRootProps
23
22
  onValueChange?(value: string): void;
24
23
  }
25
24
 
25
+ const useIsomorphicLayoutEffect = typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;
26
+
26
27
  const SegmentedControlRoot = React.forwardRef<HTMLDivElement, SegmentedControlRootProps>(
27
28
  (ownProps, forwardedRef) => {
28
29
  const props = useThemeSizeProps(ownProps, segmentedControlRootPropDefs.size);
@@ -33,6 +34,7 @@ const SegmentedControlRoot = React.forwardRef<HTMLDivElement, SegmentedControlRo
33
34
  value: valueProp,
34
35
  defaultValue: defaultValueProp,
35
36
  onValueChange: onValueChangeProp,
37
+ style,
36
38
  ...rootProps
37
39
  } = extractProps(props, segmentedControlRootPropDefs);
38
40
 
@@ -42,11 +44,39 @@ const SegmentedControlRoot = React.forwardRef<HTMLDivElement, SegmentedControlRo
42
44
  defaultProp: defaultValueProp ?? '',
43
45
  });
44
46
 
47
+ // The indicator is sized and placed from the item count and the selected index, written
48
+ // as custom properties. They are read from the children on render, so the server markup
49
+ // is right, then corrected from the DOM, which also sees items inside fragments or
50
+ // wrapper components.
51
+ const rootRef = React.useRef<HTMLDivElement>(null);
52
+ const composedRef = useComposedRefs(forwardedRef, rootRef);
53
+ const items = React.Children.toArray(children).filter(React.isValidElement);
54
+ const renderedCount = items.length;
55
+ const renderedIndex = Math.max(
56
+ 0,
57
+ items.findIndex((child) => (child.props as { value?: unknown }).value === value),
58
+ );
59
+ useIsomorphicLayoutEffect(() => {
60
+ const root = rootRef.current;
61
+ if (!root) return;
62
+ const domItems = Array.from(root.querySelectorAll(':scope > .kui-SegmentedControlItem'));
63
+ const index = domItems.findIndex((item) => item.getAttribute('data-state') === 'on');
64
+ root.style.setProperty('--segmented-control-count', String(domItems.length || 1));
65
+ root.style.setProperty('--segmented-control-index', String(Math.max(0, index)));
66
+ });
67
+
45
68
  return (
46
69
  <ToggleGroupPrimitive.Root
47
70
  data-disabled={props.disabled || undefined}
48
71
  data-radius={radius}
49
- ref={forwardedRef}
72
+ ref={composedRef}
73
+ style={
74
+ {
75
+ '--segmented-control-count': renderedCount || 1,
76
+ '--segmented-control-index': renderedIndex,
77
+ ...style,
78
+ } as React.CSSProperties
79
+ }
50
80
  className={classNames('kui-SegmentedControlRoot', className)}
51
81
  onValueChange={(value) => {
52
82
  if (value) {
@@ -70,6 +100,8 @@ SegmentedControlRoot.displayName = 'SegmentedControl.Root';
70
100
 
71
101
  interface SegmentedControlItemOwnProps {
72
102
  value: string;
103
+ /** When true, this segment can't be selected. */
104
+ disabled?: boolean;
73
105
  /** When true, applies fixed square width for icon-only segments */
74
106
  iconOnly?: boolean;
75
107
  }
@@ -77,7 +109,7 @@ interface SegmentedControlItemOwnProps {
77
109
  interface SegmentedControlItemProps
78
110
  extends ComponentPropsWithout<
79
111
  typeof ToggleGroupPrimitive.Item,
80
- RemovedProps | 'disabled' | 'type' | 'value'
112
+ RemovedProps | 'type' | 'value'
81
113
  >,
82
114
  SegmentedControlItemOwnProps {}
83
115
 
@@ -88,7 +120,6 @@ const SegmentedControlItem = React.forwardRef<HTMLButtonElement, SegmentedContro
88
120
  className={classNames('kui-reset', 'kui-SegmentedControlItem', className)}
89
121
  data-icon-only={iconOnly || undefined}
90
122
  {...props}
91
- disabled={false}
92
123
  asChild={false}
93
124
  >
94
125
  <span className="kui-SegmentedControlItemSeparator" />
@@ -1,6 +1,5 @@
1
1
  'use client';
2
2
 
3
- import { warnDeprecated } from '../helpers/warn-deprecated.js';
4
3
  import * as React from 'react';
5
4
  import classNames from 'classnames';
6
5
  import { Select as SelectPrimitive, ScrollArea as ScrollAreaPrimitive } from 'radix-ui';
@@ -26,6 +25,9 @@ type SelectRootOwnProps = GetPropDefTypes<typeof selectRootPropDefs>;
26
25
  // a literal written at the call site would be a new object, and a recompile, every render.
27
26
  const selectSizePropDefs = { size: selectRootPropDefs.size };
28
27
 
28
+ // Keys that open the list from the trigger, as in Radix.
29
+ const OPEN_KEYS = [' ', 'Enter', 'ArrowUp', 'ArrowDown'];
30
+
29
31
  interface SelectContextValue extends SelectRootOwnProps {
30
32
  /** Whether the list is open. Undefined when Content is rendered outside a Kookie Select.Root. */
31
33
  open?: boolean;
@@ -94,7 +96,6 @@ const SelectTrigger = React.forwardRef<SelectTriggerElement, SelectTriggerProps>
94
96
  selectTriggerPropDefs,
95
97
  );
96
98
 
97
-
98
99
  // The props win when set; otherwise a caller's own aria-* (a form library's aria-invalid)
99
100
  // stays, so both paths reach the accessibility tree and the CSS, as on TextField.
100
101
  const {
@@ -114,9 +115,28 @@ const SelectTrigger = React.forwardRef<SelectTriggerElement, SelectTriggerProps>
114
115
  [isInvalid, ariaInvalid, loading, ariaBusy, disabled, ariaDisabled, readOnly, ariaReadOnly],
115
116
  );
116
117
 
118
+ // Read-only and loading triggers stay focusable but do not open or take typeahead,
119
+ // as on Combobox. Radix skips its own handler when the event is default-prevented.
120
+ const isBlocked = Boolean(readOnly || loading);
121
+ const blockedHandlers = isBlocked
122
+ ? {
123
+ onPointerDown: (event: React.PointerEvent<HTMLButtonElement>) => event.preventDefault(),
124
+ onClick: (event: React.MouseEvent<HTMLButtonElement>) => {
125
+ event.preventDefault();
126
+ event.currentTarget.focus();
127
+ },
128
+ onKeyDown: (event: React.KeyboardEvent<HTMLButtonElement>) => {
129
+ const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
130
+ if (OPEN_KEYS.includes(event.key) || (!isModifierKey && event.key.length === 1)) {
131
+ event.preventDefault();
132
+ }
133
+ },
134
+ }
135
+ : undefined;
136
+
117
137
  return (
118
138
  // `disabled` goes to Radix, which merges it with Root's and sets the native attribute.
119
- <SelectPrimitive.Trigger asChild disabled={disabled}>
139
+ <SelectPrimitive.Trigger asChild disabled={disabled} {...blockedHandlers}>
120
140
  <button
121
141
  data-accent-color={color}
122
142
  data-radius={radius}
@@ -12,7 +12,19 @@ type SeparatorOwnProps = GetPropDefTypes<typeof separatorPropDefs>;
12
12
  interface SeparatorProps extends ComponentPropsWithout<'span', RemovedProps>, SeparatorOwnProps {}
13
13
  const Separator = React.forwardRef<SeparatorElement, SeparatorProps>((props, forwardedRef) => {
14
14
  const { className, color, decorative, ...separatorProps } = extractProps(props, separatorPropDefs);
15
- return <span data-accent-color={color} role={decorative ? undefined : 'separator'} {...separatorProps} ref={forwardedRef} className={classNames('kui-Separator', className)} />;
15
+ // A responsive orientation announces the one it starts with.
16
+ const orientation =
17
+ typeof props.orientation === 'object' ? props.orientation.initial : props.orientation;
18
+ return (
19
+ <span
20
+ data-accent-color={color}
21
+ role={decorative ? undefined : 'separator'}
22
+ aria-orientation={!decorative && orientation === 'vertical' ? 'vertical' : undefined}
23
+ {...separatorProps}
24
+ ref={forwardedRef}
25
+ className={classNames('kui-Separator', className)}
26
+ />
27
+ );
16
28
  });
17
29
  Separator.displayName = 'Separator';
18
30
 
@@ -7,7 +7,6 @@
7
7
  height: 100vh;
8
8
  max-height: 100vh;
9
9
  margin: 0 !important;
10
- border-radius: 0 !important;
11
10
  will-change: transform;
12
11
  }
13
12
 
@@ -19,8 +18,10 @@
19
18
  }
20
19
  }
21
20
 
22
- /* Logical side anchoring (RTL-aware via logical inset) */
23
- :where(.kui-SheetContent[data-side='start']) {
21
+ /* Logical side anchoring (RTL-aware via logical inset). The two corners on the panel's own
22
+ edge are square; the two facing the page keep the size's overlay corner. The class sits
23
+ outside :where() so these corners outrank the size radius in base-dialog.css. */
24
+ .kui-SheetContent:where([data-side='start']) {
24
25
  inset-block: 0 !important;
25
26
  inset-inline-start: 0 !important;
26
27
  margin: 0 !important;
@@ -29,7 +30,7 @@
29
30
  /* iOS safe area for home indicator */
30
31
  padding-bottom: env(safe-area-inset-bottom, 0px);
31
32
  }
32
- :where(.kui-SheetContent[data-side='end']) {
33
+ .kui-SheetContent:where([data-side='end']) {
33
34
  inset-block: 0 !important;
34
35
  inset-inline-end: 0 !important;
35
36
  margin: 0 !important;
@@ -38,7 +39,7 @@
38
39
  /* iOS safe area for home indicator */
39
40
  padding-bottom: env(safe-area-inset-bottom, 0px);
40
41
  }
41
- :where(.kui-SheetContent[data-side='top']) {
42
+ .kui-SheetContent:where([data-side='top']) {
42
43
  inset-block-start: 0 !important;
43
44
  inset-inline: 0 !important;
44
45
  width: auto;
@@ -48,7 +49,7 @@
48
49
  border-start-start-radius: 0;
49
50
  border-start-end-radius: 0;
50
51
  }
51
- :where(.kui-SheetContent[data-side='bottom']) {
52
+ .kui-SheetContent:where([data-side='bottom']) {
52
53
  inset-block-end: 0 !important;
53
54
  inset-inline: 0 !important;
54
55
  width: auto;
@@ -15,6 +15,7 @@
15
15
  * - Sizing: reuses Dialog content prop defs (width/min/max/height/size). Size follows the
16
16
  * Theme size; start/end sheets cap at the size's overlay width unless maxWidth is set.
17
17
  * - A11y: provide an accessible name via `Sheet.Title` or `aria-label` on `Sheet.Content`.
18
+ * Radix owns the focus trap, initial focus and the return of focus to the trigger.
18
19
  *
19
20
  * Example
20
21
  * <Sheet.Root>
@@ -71,15 +72,12 @@ Root.displayName = 'Sheet.Root';
71
72
  /** Element type for `Sheet.Trigger`. */
72
73
  type SheetTriggerElement = React.ElementRef<typeof DialogPrimitive.Trigger>;
73
74
  /** Props for `Sheet.Trigger` (expects a single element child). */
74
- interface SheetTriggerProps
75
- extends ComponentPropsWithout<typeof DialogPrimitive.Trigger, RemovedProps> {}
76
- const Trigger = React.forwardRef<SheetTriggerElement, SheetTriggerProps>(
77
- ({ children, ...props }, ref) => (
78
- <DialogPrimitive.Trigger {...props} ref={ref} asChild>
79
- {requireReactElement(children)}
80
- </DialogPrimitive.Trigger>
81
- ),
82
- );
75
+ interface SheetTriggerProps extends ComponentPropsWithout<typeof DialogPrimitive.Trigger, RemovedProps> {}
76
+ const Trigger = React.forwardRef<SheetTriggerElement, SheetTriggerProps>(({ children, ...props }, ref) => (
77
+ <DialogPrimitive.Trigger {...props} ref={ref} asChild>
78
+ {requireReactElement(children)}
79
+ </DialogPrimitive.Trigger>
80
+ ));
83
81
  Trigger.displayName = 'Sheet.Trigger';
84
82
 
85
83
  // Content
@@ -88,16 +86,14 @@ Trigger.displayName = 'Sheet.Trigger';
88
86
  // Built once at module scope: `extractProps` memoises on the identity of the
89
87
  // prop def objects it is handed, so rebuilding these per render would recompile
90
88
  // them every time a sheet renders.
91
- const {
92
- align: _alignPropDef,
93
- ...dialogPropDefsForSheet
94
- } = dialogContentPropDefs;
89
+ const { align: _alignPropDef, ...dialogPropDefsForSheet } = dialogContentPropDefs;
95
90
  const sheetPropDefs = dialogPropDefsForSheet;
96
91
 
92
+ /** Counts the Sheet.Title elements mounted inside a Sheet.Content, for the dev-only name check. */
93
+ const SheetTitleCountContext = React.createContext<React.MutableRefObject<number> | null>(null);
94
+
97
95
  type SheetContentElement = React.ElementRef<typeof DialogPrimitive.Content>;
98
- interface SheetContentProps
99
- extends ComponentPropsWithout<typeof DialogPrimitive.Content, RemovedProps>,
100
- DialogContentOwnProps {
96
+ interface SheetContentProps extends ComponentPropsWithout<typeof DialogPrimitive.Content, RemovedProps>, DialogContentOwnProps {
101
97
  /** Side where the Sheet should appear. `left`/`right` alias to `start`/`end`. */
102
98
  side?: SheetSide;
103
99
  /** Optional DOM container to portal into. Defaults to `document.body`. */
@@ -109,166 +105,103 @@ interface SheetContentProps
109
105
  * forwards dialog sizing props. Provide an accessible name via `Sheet.Title`
110
106
  * or `aria-label`.
111
107
  */
112
- const Content = React.forwardRef<SheetContentElement, SheetContentProps>(
113
- (allProps, forwardedRef) => {
114
- const {
115
- side = 'start',
116
- forceMount,
117
- container,
118
- className,
119
- ...ownProps
120
- } = allProps;
121
- const restProps = useThemeSizeProps(ownProps, sheetPropDefs.size);
122
- const normalizedSideMap: Record<SheetSide, 'start' | 'end' | 'top' | 'bottom'> = {
123
- left: 'start',
124
- right: 'end',
125
- start: 'start',
126
- end: 'end',
127
- top: 'top',
128
- bottom: 'bottom',
129
- };
130
- const normalizedSide = normalizedSideMap[side];
131
- // Size/width/height class names come from the dialog defs — see `sheetPropDefs`.
132
- const { className: extractedClassName, ...contentProps } = extractProps(
133
- restProps,
134
- sheetPropDefs,
135
- );
136
-
137
- // Dev-only a11y guard: ensure label is provided via Title or aria-label
138
- if (process.env.NODE_ENV !== 'production') {
139
- const children = (contentProps as any).children as React.ReactNode;
140
- const hasAriaLabel = typeof (contentProps as any)['aria-label'] === 'string';
141
- let hasTitle = false;
142
- if (children) {
143
- for (const child of React.Children.toArray(children)) {
144
- if (React.isValidElement(child) && child.type === Title) {
145
- hasTitle = true;
146
- break;
147
- }
148
- }
108
+ const Content = React.forwardRef<SheetContentElement, SheetContentProps>((allProps, forwardedRef) => {
109
+ const { side = 'start', forceMount, container, className, ...ownProps } = allProps;
110
+ const restProps = useThemeSizeProps(ownProps, sheetPropDefs.size);
111
+ const normalizedSideMap: Record<SheetSide, 'start' | 'end' | 'top' | 'bottom'> = {
112
+ left: 'start',
113
+ right: 'end',
114
+ start: 'start',
115
+ end: 'end',
116
+ top: 'top',
117
+ bottom: 'bottom',
118
+ };
119
+ const normalizedSide = normalizedSideMap[side];
120
+ // Size/width/height class names come from the dialog defs — see `sheetPropDefs`.
121
+ const { className: extractedClassName, ...contentProps } = extractProps(restProps, sheetPropDefs);
122
+
123
+ // Dev-only a11y guard: the panel needs a name. A Sheet.Title anywhere inside counts it
124
+ // in a layout effect, which runs before this ref is attached, so nesting doesn't matter.
125
+ const titleCountRef = React.useRef(0);
126
+ const combinedRef = React.useCallback(
127
+ (node: HTMLDivElement | null) => {
128
+ if (typeof forwardedRef === 'function') {
129
+ forwardedRef(node);
130
+ } else if (forwardedRef) {
131
+ forwardedRef.current = node;
149
132
  }
150
- if (!hasTitle && !hasAriaLabel) {
151
- console.warn(
152
- 'Sheet.Content: Missing accessible name. Include Sheet.Title as a child or provide aria-label.',
153
- );
154
- }
155
- }
156
-
157
- // Focus management and stuck pointer-events cleanup like Dialog
158
- const contentRef = React.useRef<HTMLDivElement>(null);
159
- const combinedRef = React.useMemo(
160
- () => (node: HTMLDivElement | null) => {
161
- contentRef.current = node;
162
- if (typeof forwardedRef === 'function') {
163
- forwardedRef(node);
164
- } else if (forwardedRef) {
165
- (forwardedRef as React.MutableRefObject<HTMLDivElement | null>).current = node;
166
- }
167
- },
168
- [forwardedRef],
169
- );
170
-
171
- useBodyPointerEventsCleanup();
172
-
173
- React.useEffect(() => {
174
- if (typeof window === 'undefined') return;
175
- const content = contentRef.current;
176
- if (!content) return;
177
-
178
- const focusableElements = content.querySelectorAll(
179
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
180
- );
181
-
182
- if (focusableElements.length === 0) return;
183
-
184
- const firstElement = focusableElements[0] as HTMLElement;
185
- const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;
186
-
187
- const handleKeyDown = (event: KeyboardEvent) => {
188
- if (event.key === 'Tab') {
189
- if (event.shiftKey) {
190
- if (document.activeElement === firstElement) {
191
- event.preventDefault();
192
- lastElement.focus();
193
- }
194
- } else if (document.activeElement === lastElement) {
195
- event.preventDefault();
196
- firstElement.focus();
197
- }
133
+ if (process.env.NODE_ENV !== 'production' && node) {
134
+ const hasName = titleCountRef.current > 0 || Boolean(node.getAttribute('aria-label')) || Boolean(node.getAttribute('aria-labelledby'));
135
+ if (!hasName) {
136
+ console.warn('Sheet.Content: Missing accessible name. Include Sheet.Title inside it or provide aria-label.');
198
137
  }
199
- };
200
-
201
- content.addEventListener('keydown', handleKeyDown);
202
- firstElement.focus();
138
+ }
139
+ },
140
+ [forwardedRef],
141
+ );
203
142
 
204
- return () => {
205
- content.removeEventListener('keydown', handleKeyDown);
206
- };
207
- }, []);
143
+ useBodyPointerEventsCleanup();
208
144
 
209
- return (
210
- <DialogPrimitive.Portal container={container} forceMount={forceMount}>
145
+ return (
146
+ <DialogPrimitive.Portal container={container} forceMount={forceMount}>
147
+ <SheetTitleCountContext.Provider value={titleCountRef}>
211
148
  <Theme asChild>
212
149
  <DialogPrimitive.Overlay className="kui-BaseDialogOverlay kui-DialogOverlay kui-SheetOverlay">
213
150
  <DialogPrimitive.Content
214
151
  {...contentProps}
215
152
  ref={combinedRef}
216
- className={classNames(
217
- 'kui-BaseDialogContent',
218
- 'kui-SheetContent',
219
- className,
220
- extractedClassName,
221
- )}
153
+ className={classNames('kui-BaseDialogContent', 'kui-SheetContent', className, extractedClassName)}
222
154
  data-side={normalizedSide}
223
- tabIndex={-1}
224
- role="dialog"
225
155
  aria-modal="true"
226
156
  />
227
157
  </DialogPrimitive.Overlay>
228
158
  </Theme>
229
- </DialogPrimitive.Portal>
230
- );
231
- },
232
- );
159
+ </SheetTitleCountContext.Provider>
160
+ </DialogPrimitive.Portal>
161
+ );
162
+ });
233
163
  Content.displayName = 'Sheet.Content';
234
164
 
235
165
  // Title - renders as Heading with sensible defaults
236
166
  type SheetTitleElement = React.ElementRef<typeof Heading>;
237
167
  type SheetTitleProps = HeadingProps;
238
168
  /** Accessible title for the Sheet. Renders as Heading with sensible defaults. */
239
- const Title = React.forwardRef<SheetTitleElement, SheetTitleProps>(
240
- ({ size = '4', weight = 'medium', ...props }, ref) => (
169
+ const Title = React.forwardRef<SheetTitleElement, SheetTitleProps>(({ size = '4', weight = 'medium', ...props }, ref) => {
170
+ const titleCountRef = React.useContext(SheetTitleCountContext);
171
+ React.useLayoutEffect(() => {
172
+ if (!titleCountRef) return;
173
+ titleCountRef.current += 1;
174
+ return () => {
175
+ titleCountRef.current -= 1;
176
+ };
177
+ }, [titleCountRef]);
178
+ return (
241
179
  <DialogPrimitive.Title asChild>
242
180
  <Heading ref={ref} size={size} weight={weight} {...props} />
243
181
  </DialogPrimitive.Title>
244
- ),
245
- );
182
+ );
183
+ });
246
184
  Title.displayName = 'Sheet.Title';
247
185
 
248
186
  // Description - renders as Text with sensible defaults
249
187
  type SheetDescriptionElement = React.ElementRef<typeof Text>;
250
188
  type SheetDescriptionProps = React.ComponentPropsWithoutRef<typeof Text>;
251
189
  /** Supplementary description text for Sheet content. Renders as Text with sensible defaults. */
252
- const Description = React.forwardRef<SheetDescriptionElement, SheetDescriptionProps>(
253
- ({ size = '2', emphasis = 'medium', ...rest }, ref) => (
254
- <DialogPrimitive.Description asChild>
255
- <Text ref={ref} size={size} emphasis={emphasis} {...rest} />
256
- </DialogPrimitive.Description>
257
- ),
258
- );
190
+ const Description = React.forwardRef<SheetDescriptionElement, SheetDescriptionProps>(({ size = '2', emphasis = 'medium', ...rest }, ref) => (
191
+ <DialogPrimitive.Description asChild>
192
+ <Text ref={ref} size={size} emphasis={emphasis} {...rest} />
193
+ </DialogPrimitive.Description>
194
+ ));
259
195
  Description.displayName = 'Sheet.Description';
260
196
 
261
197
  type SheetCloseElement = React.ElementRef<typeof DialogPrimitive.Close>;
262
- interface SheetCloseProps
263
- extends ComponentPropsWithout<typeof DialogPrimitive.Close, RemovedProps> {}
198
+ interface SheetCloseProps extends ComponentPropsWithout<typeof DialogPrimitive.Close, RemovedProps> {}
264
199
  /** Close button for the Sheet. Expects a single element child rendered via `asChild`. */
265
- const Close = React.forwardRef<SheetCloseElement, SheetCloseProps>(
266
- ({ children, ...props }, ref) => (
267
- <DialogPrimitive.Close {...props} ref={ref} asChild>
268
- {requireReactElement(children)}
269
- </DialogPrimitive.Close>
270
- ),
271
- );
200
+ const Close = React.forwardRef<SheetCloseElement, SheetCloseProps>(({ children, ...props }, ref) => (
201
+ <DialogPrimitive.Close {...props} ref={ref} asChild>
202
+ {requireReactElement(children)}
203
+ </DialogPrimitive.Close>
204
+ ));
272
205
  Close.displayName = 'Sheet.Close';
273
206
 
274
207
  export { Root, Trigger, Content, Title, Description, Close };
@@ -224,6 +224,16 @@
224
224
  min-height: 0;
225
225
  }
226
226
 
227
+ /*
228
+ * In the content it is the page's scroller. The content becomes a column that does not scroll
229
+ * itself, so a floating header beside the Scroll stays pinned while the page scrolls under it.
230
+ */
231
+ .kui-ShellContent:has(> .kui-ShellScroll) {
232
+ display: flex;
233
+ flex-direction: column;
234
+ overflow: hidden;
235
+ }
236
+
227
237
  /* ── Floating header and footer ───────────────────────────────────────────── */
228
238
 
229
239
  /*
@@ -338,6 +348,10 @@
338
348
  --scroll-fade-end: var(--kui-pane-inset-end);
339
349
  --scrollarea-scrollbar-vertical-margin-bottom: calc(var(--space-2) + var(--kui-pane-inset-end));
340
350
  }
351
+ /* A link target or a focused control scrolls into view clear of the floating rows, not under them. */
352
+ .kui-ShellScroll > .kui-ScrollAreaViewport {
353
+ scroll-padding-block: var(--kui-pane-inset-start, 0px) var(--kui-pane-inset-end, 0px);
354
+ }
341
355
  .kui-ShellScroll > .kui-ScrollAreaViewport > * {
342
356
  padding-top: var(--kui-pane-inset-start, 0px);
343
357
  padding-bottom: var(--kui-pane-inset-end, 0px);
@@ -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';