@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
@@ -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';
@@ -21,16 +20,48 @@ import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-p
21
20
 
22
21
  type SelectRootOwnProps = GetPropDefTypes<typeof selectRootPropDefs>;
23
22
 
24
- type SelectContextValue = SelectRootOwnProps;
23
+ // Trigger and Content pass the size prop def as its own record. It is hoisted because
24
+ // extractProps caches its compiled prop defs on the identity of each record it is given:
25
+ // a literal written at the call site would be a new object, and a recompile, every render.
26
+ const selectSizePropDefs = { size: selectRootPropDefs.size };
27
+
28
+ // Keys that open the list from the trigger, as in Radix.
29
+ const OPEN_KEYS = [' ', 'Enter', 'ArrowUp', 'ArrowDown'];
30
+
31
+ interface SelectContextValue extends SelectRootOwnProps {
32
+ /** Whether the list is open. Undefined when Content is rendered outside a Kookie Select.Root. */
33
+ open?: boolean;
34
+ }
25
35
  const SelectContext = React.createContext<SelectContextValue>({});
26
36
 
27
- interface SelectRootProps extends SelectPrimitive.SelectProps, SelectContextValue {}
37
+ interface SelectRootProps extends SelectPrimitive.SelectProps, SelectRootOwnProps {}
28
38
  const SelectRoot: React.FC<SelectRootProps> = (props) => {
29
- const { children, size: sizeProp, ...rootProps } = props;
39
+ const {
40
+ children,
41
+ size: sizeProp,
42
+ open: openProp,
43
+ defaultOpen,
44
+ onOpenChange,
45
+ ...rootProps
46
+ } = props;
30
47
  const size = useThemeSize(sizeProp, selectRootPropDefs.size);
48
+
49
+ // Root owns the open state and hands Radix a controlled `open`, so Content learns of a
50
+ // change in the same render Radix does. Radix's uncontrolled state reports changes from an
51
+ // effect, a render late, which would mount the open list once without its wrappers.
52
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen ?? false);
53
+ const open = openProp ?? uncontrolledOpen;
54
+ const handleOpenChange = React.useCallback(
55
+ (next: boolean) => {
56
+ setUncontrolledOpen(next);
57
+ onOpenChange?.(next);
58
+ },
59
+ [onOpenChange],
60
+ );
61
+
31
62
  return (
32
- <SelectPrimitive.Root {...rootProps}>
33
- <SelectContext.Provider value={React.useMemo(() => ({ size }), [size])}>
63
+ <SelectPrimitive.Root {...rootProps} open={open} onOpenChange={handleOpenChange}>
64
+ <SelectContext.Provider value={React.useMemo(() => ({ size, open }), [size, open])}>
34
65
  {children}
35
66
  </SelectContext.Provider>
36
67
  </SelectPrimitive.Root>
@@ -61,11 +92,10 @@ const SelectTrigger = React.forwardRef<SelectTriggerElement, SelectTriggerProps>
61
92
  // Pass size value from the context to generate styles
62
93
  { size: context?.size, ...props },
63
94
  // Pass size prop def to allow it to be extracted
64
- { size: selectRootPropDefs.size },
95
+ selectSizePropDefs,
65
96
  selectTriggerPropDefs,
66
97
  );
67
98
 
68
-
69
99
  // The props win when set; otherwise a caller's own aria-* (a form library's aria-invalid)
70
100
  // stays, so both paths reach the accessibility tree and the CSS, as on TextField.
71
101
  const {
@@ -85,9 +115,28 @@ const SelectTrigger = React.forwardRef<SelectTriggerElement, SelectTriggerProps>
85
115
  [isInvalid, ariaInvalid, loading, ariaBusy, disabled, ariaDisabled, readOnly, ariaReadOnly],
86
116
  );
87
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
+
88
137
  return (
89
138
  // `disabled` goes to Radix, which merges it with Root's and sets the native attribute.
90
- <SelectPrimitive.Trigger asChild disabled={disabled}>
139
+ <SelectPrimitive.Trigger asChild disabled={disabled} {...blockedHandlers}>
91
140
  <button
92
141
  data-accent-color={color}
93
142
  data-radius={radius}
@@ -143,12 +192,26 @@ const SelectContent = React.forwardRef<SelectContentElement, SelectContentProps>
143
192
  // Pass size value from the context to generate styles
144
193
  { size: context?.size, ...props },
145
194
  // Pass size prop def to allow it to be extracted
146
- { size: selectRootPropDefs.size },
195
+ selectSizePropDefs,
147
196
  selectContentPropDefs,
148
197
  );
149
198
  const themeContext = useThemeContext();
199
+
200
+ // While closed, Radix still renders Content's children, into a detached fragment: the
201
+ // items must exist for the trigger's value label, typeahead and the native form select.
202
+ // Nothing in that fragment is ever shown, so the theme wrapper and the scroll area, with
203
+ // its two resize observers, are left out until the list opens.
204
+ if (context.open === false && !contentProps.forceMount) {
205
+ return (
206
+ <SelectPrimitive.Portal container={container}>
207
+ <SelectPrimitive.Content {...contentProps} asChild={false} ref={forwardedRef}>
208
+ {children}
209
+ </SelectPrimitive.Content>
210
+ </SelectPrimitive.Portal>
211
+ );
212
+ }
213
+
150
214
  const resolvedColor = color || themeContext.accentColor;
151
- const setThumbViewport = useThumbSync<HTMLDivElement>();
152
215
  return (
153
216
  <SelectPrimitive.Portal container={container}>
154
217
  <Theme asChild>
@@ -161,31 +224,12 @@ const SelectContent = React.forwardRef<SelectContentElement, SelectContentProps>
161
224
  className={classNames(
162
225
  'kui-PopperContent',
163
226
  'kui-BaseMenuContent',
164
- 'kui-variant-soft',
227
+ 'kui-variant-soft',
165
228
  'kui-SelectContent',
166
229
  className,
167
230
  )}
168
231
  >
169
- <ScrollAreaPrimitive.Root type="auto" className="kui-ScrollAreaRoot">
170
- <SelectPrimitive.Viewport
171
- asChild
172
- className={classNames('kui-BaseMenuViewport', 'kui-SelectViewport')}
173
- >
174
- <ScrollAreaPrimitive.Viewport
175
- ref={setThumbViewport}
176
- className="kui-ScrollAreaViewport"
177
- style={{ overflowY: undefined }}
178
- >
179
- {children}
180
- </ScrollAreaPrimitive.Viewport>
181
- </SelectPrimitive.Viewport>
182
- <ScrollAreaPrimitive.Scrollbar
183
- className="kui-ScrollAreaScrollbar"
184
- orientation="vertical"
185
- >
186
- <ScrollAreaPrimitive.Thumb className="kui-ScrollAreaThumb" />
187
- </ScrollAreaPrimitive.Scrollbar>
188
- </ScrollAreaPrimitive.Root>
232
+ <SelectScrollArea>{children}</SelectScrollArea>
189
233
  </SelectPrimitive.Content>
190
234
  </Theme>
191
235
  </SelectPrimitive.Portal>
@@ -194,6 +238,30 @@ const SelectContent = React.forwardRef<SelectContentElement, SelectContentProps>
194
238
  );
195
239
  SelectContent.displayName = 'Select.Content';
196
240
 
241
+ /** The open list's scroll area. Its own component so the thumb sync hook runs only while open. */
242
+ function SelectScrollArea({ children }: { children: React.ReactNode }) {
243
+ const setThumbViewport = useThumbSync<HTMLDivElement>();
244
+ return (
245
+ <ScrollAreaPrimitive.Root type="auto" className="kui-ScrollAreaRoot">
246
+ <SelectPrimitive.Viewport
247
+ asChild
248
+ className={classNames('kui-BaseMenuViewport', 'kui-SelectViewport')}
249
+ >
250
+ <ScrollAreaPrimitive.Viewport
251
+ ref={setThumbViewport}
252
+ className="kui-ScrollAreaViewport"
253
+ style={{ overflowY: undefined }}
254
+ >
255
+ {children}
256
+ </ScrollAreaPrimitive.Viewport>
257
+ </SelectPrimitive.Viewport>
258
+ <ScrollAreaPrimitive.Scrollbar className="kui-ScrollAreaScrollbar" orientation="vertical">
259
+ <ScrollAreaPrimitive.Thumb className="kui-ScrollAreaThumb" />
260
+ </ScrollAreaPrimitive.Scrollbar>
261
+ </ScrollAreaPrimitive.Root>
262
+ );
263
+ }
264
+
197
265
  type SelectItemElement = React.ElementRef<typeof SelectPrimitive.Item>;
198
266
  interface SelectItemProps
199
267
  extends ComponentPropsWithout<typeof SelectPrimitive.Item, RemovedProps> {}
@@ -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 };
@@ -88,6 +88,18 @@
88
88
  isolation: isolate;
89
89
  }
90
90
 
91
+ /*
92
+ * Chromium (the only engine with -webkit-app-region) gives a scroller whose overscroll-behavior is
93
+ * not auto two composited layers even when its content fits: about 3 MB for a 1280x800 pane. There
94
+ * the Root's own overscroll-behavior already stops the chain, so the content does not need one.
95
+ * WebKit ignores an ancestor that is not user-scrollable, so it keeps `contain` above.
96
+ */
97
+ @supports (-webkit-app-region: drag) {
98
+ .kui-ShellContent {
99
+ overscroll-behavior: auto;
100
+ }
101
+ }
102
+
91
103
  /* ── Panes ─────────────────────────────────────────────────────────────────── */
92
104
 
93
105
  /*
@@ -212,6 +224,16 @@
212
224
  min-height: 0;
213
225
  }
214
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
+
215
237
  /* ── Floating header and footer ───────────────────────────────────────────── */
216
238
 
217
239
  /*
@@ -326,6 +348,10 @@
326
348
  --scroll-fade-end: var(--kui-pane-inset-end);
327
349
  --scrollarea-scrollbar-vertical-margin-bottom: calc(var(--space-2) + var(--kui-pane-inset-end));
328
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
+ }
329
355
  .kui-ShellScroll > .kui-ScrollAreaViewport > * {
330
356
  padding-top: var(--kui-pane-inset-start, 0px);
331
357
  padding-bottom: var(--kui-pane-inset-end, 0px);