@chassis-ui/react 0.1.3 → 0.2.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 (350) hide show
  1. package/dist/accordion.d.ts +2 -0
  2. package/dist/accordion.js +1 -0
  3. package/dist/autocomplete.d.ts +2 -0
  4. package/dist/autocomplete.js +1 -0
  5. package/dist/avatar.d.ts +2 -0
  6. package/dist/avatar.js +1 -0
  7. package/dist/badge.d.ts +2 -0
  8. package/dist/badge.js +1 -0
  9. package/dist/breadcrumb.d.ts +2 -0
  10. package/dist/breadcrumb.js +1 -0
  11. package/dist/button-group.d.ts +2 -0
  12. package/dist/button-group.js +1 -0
  13. package/dist/button.d.ts +3 -0
  14. package/dist/button.js +1 -0
  15. package/dist/calendar.d.ts +3 -0
  16. package/dist/calendar.js +1 -0
  17. package/dist/card.d.ts +2 -0
  18. package/dist/card.js +1 -0
  19. package/dist/carousel.d.ts +2 -0
  20. package/dist/carousel.js +1 -0
  21. package/dist/checkbox.d.ts +3 -0
  22. package/dist/checkbox.js +1 -0
  23. package/dist/chip-input.d.ts +2 -0
  24. package/dist/chip-input.js +1 -0
  25. package/dist/chip.d.ts +2 -0
  26. package/dist/chip.js +1 -0
  27. package/dist/chunks/Button-Cptd4Yk7.d.ts +65 -0
  28. package/dist/chunks/Button-I0aUy5h-.js +1 -0
  29. package/dist/chunks/Chip-D0Cw0mAr.js +1 -0
  30. package/dist/chunks/CloseButton-DJM7FRKh.js +1 -0
  31. package/dist/chunks/ComboboxItem-C9TpoJOI.d.ts +54 -0
  32. package/dist/chunks/ComboboxListBox-BhO8uRNg.js +1 -0
  33. package/dist/chunks/FormHelp-Be2PQL0y.js +1 -0
  34. package/dist/chunks/FormLabel-CYcQiFUI.js +1 -0
  35. package/dist/chunks/Icon-BIwkD-kx.js +1 -0
  36. package/dist/chunks/Icon-CioraWLF.d.ts +36 -0
  37. package/dist/chunks/Link-B0Y1xgYi.d.ts +69 -0
  38. package/dist/chunks/Link-Cq7FNWpm.js +1 -0
  39. package/dist/chunks/MenuItemDef-D0VDtYIQ.d.ts +82 -0
  40. package/dist/chunks/RangeCalendar-COnSfurr.js +1 -0
  41. package/dist/chunks/accordion-okRicuG5.js +1 -0
  42. package/dist/chunks/autocomplete-B0xTc6kg.js +1 -0
  43. package/dist/chunks/avatar-Bjm0DlPO.js +1 -0
  44. package/dist/chunks/badge-Bj8mf8lu.js +1 -0
  45. package/dist/chunks/breadcrumb-DDxnx_iS.js +1 -0
  46. package/dist/chunks/breakpoints-SLMTNHF9.d.ts +5 -0
  47. package/dist/chunks/breakpoints-o_2Ev7ir.js +1 -0
  48. package/dist/chunks/button-group-CPZYA6aZ.js +1 -0
  49. package/dist/chunks/card-DfF2K_5p.js +1 -0
  50. package/dist/chunks/carousel-DEvwcA7H.js +1 -0
  51. package/dist/chunks/checkbox-BFPS0pD6.js +1 -0
  52. package/dist/chunks/chip-input-CB1lE6vP.js +1 -0
  53. package/dist/chunks/collapse-WifcChO8.js +1 -0
  54. package/dist/chunks/color-input-CyRaLR_G.js +1 -0
  55. package/dist/chunks/combobox-DWEj-Sv7.js +1 -0
  56. package/dist/chunks/datagrid-nbnNThsT.js +2 -0
  57. package/dist/chunks/dateRangePresets-R1FtA1zp.d.ts +41 -0
  58. package/dist/chunks/datepicker-CslLKMm1.js +1 -0
  59. package/dist/chunks/dialogTransition-i9vw0i2Z.js +1 -0
  60. package/dist/chunks/direction-CPhdeL3A.js +1 -0
  61. package/dist/chunks/drawer-zReFjoJG.js +1 -0
  62. package/dist/chunks/file-input-RRqZSzjH.js +1 -0
  63. package/dist/chunks/flex-BTvpgaRv.js +1 -0
  64. package/dist/chunks/floating-input-CIC9Lm2a.js +1 -0
  65. package/dist/chunks/focus-ring-SR_LwaN7.js +1 -0
  66. package/dist/chunks/focusRedirect-BrvK3U_o.js +1 -0
  67. package/dist/chunks/form-GpdAyWWi.js +1 -0
  68. package/dist/chunks/form-field-BjQ9SIjx.js +1 -0
  69. package/dist/chunks/grid-CuFw89yV.js +1 -0
  70. package/dist/chunks/icon-mxYpL5nL.js +1 -0
  71. package/dist/chunks/iconConfig-Bu6Pt9o3.d.ts +69 -0
  72. package/dist/chunks/iconSlot-BmWxJh27.js +1 -0
  73. package/dist/chunks/index--0_IpTDT.d.ts +17 -0
  74. package/dist/chunks/index-6uob77s9.d.ts +80 -0
  75. package/dist/chunks/index-8PhBSbNQ.d.ts +93 -0
  76. package/dist/chunks/index-B0-8n-Gs.d.ts +105 -0
  77. package/dist/chunks/index-B8uaSJA9.d.ts +95 -0
  78. package/dist/chunks/index-BA-raEMm.d.ts +28 -0
  79. package/dist/chunks/index-BDfh8YBc.d.ts +39 -0
  80. package/dist/chunks/index-BKMW0rkw.d.ts +80 -0
  81. package/dist/chunks/index-BO9jLOIb.d.ts +58 -0
  82. package/dist/chunks/index-BO_1MN66.d.ts +87 -0
  83. package/dist/chunks/index-BTDgfLxK.d.ts +94 -0
  84. package/dist/chunks/index-BTTeKpiE.d.ts +363 -0
  85. package/dist/chunks/index-BVGGIaPX.d.ts +110 -0
  86. package/dist/chunks/index-Bi8FFadV.d.ts +98 -0
  87. package/dist/chunks/index-Bkj17NEQ.d.ts +50 -0
  88. package/dist/chunks/index-BlgkO3dn.d.ts +280 -0
  89. package/dist/chunks/index-BxTlIaZu.d.ts +301 -0
  90. package/dist/chunks/index-C61tPIJ-.d.ts +50 -0
  91. package/dist/chunks/index-CCXJXToc.d.ts +52 -0
  92. package/dist/chunks/index-CJzKu7QI.d.ts +40 -0
  93. package/dist/chunks/index-COsIPd8L.d.ts +62 -0
  94. package/dist/chunks/index-COsYSDrz.d.ts +109 -0
  95. package/dist/chunks/index-CRfm7W6C.d.ts +230 -0
  96. package/dist/chunks/index-CVUMS0x7.d.ts +73 -0
  97. package/dist/chunks/index-CaQ1JY5D.d.ts +49 -0
  98. package/dist/chunks/index-Cf2n0l0U.d.ts +138 -0
  99. package/dist/chunks/index-CftERHnE.d.ts +24 -0
  100. package/dist/chunks/index-ClT3E_hv.d.ts +302 -0
  101. package/dist/chunks/index-CsMIgBsd.d.ts +39 -0
  102. package/dist/chunks/index-Ctuk1xBU.d.ts +99 -0
  103. package/dist/chunks/index-D2VVO8rx.d.ts +49 -0
  104. package/dist/chunks/index-D949AidR.d.ts +40 -0
  105. package/dist/chunks/index-D9PZHY_I.d.ts +135 -0
  106. package/dist/chunks/index-DAoPg59I.d.ts +80 -0
  107. package/dist/chunks/index-DB_ToPdz.d.ts +202 -0
  108. package/dist/chunks/index-DEb9zXlC.d.ts +210 -0
  109. package/dist/chunks/index-DHGgezXU.d.ts +58 -0
  110. package/dist/chunks/index-DJJocp_q.d.ts +132 -0
  111. package/dist/chunks/index-DKma0jQw.d.ts +104 -0
  112. package/dist/chunks/index-DPV62IdF.d.ts +118 -0
  113. package/dist/chunks/index-DR8sYtvd.d.ts +296 -0
  114. package/dist/chunks/index-Dcc_W6Kv.d.ts +146 -0
  115. package/dist/chunks/index-Dfg4Ftb8.d.ts +68 -0
  116. package/dist/chunks/index-Dfy1YW5j.d.ts +73 -0
  117. package/dist/chunks/index-Dh5CaHTP.d.ts +44 -0
  118. package/dist/chunks/index-DtbUXxjz.d.ts +53 -0
  119. package/dist/chunks/index-Dum6Y9XR.d.ts +187 -0
  120. package/dist/chunks/index-HrKN6s8z.d.ts +66 -0
  121. package/dist/chunks/index-JllMXhVx.d.ts +176 -0
  122. package/dist/chunks/index-XjLvaH4G.d.ts +67 -0
  123. package/dist/chunks/index-dh3TKanY.d.ts +235 -0
  124. package/dist/chunks/index-nklPDKlC.d.ts +137 -0
  125. package/dist/chunks/index-qgZ5VGmc.d.ts +177 -0
  126. package/dist/chunks/index-tOodmT36.d.ts +129 -0
  127. package/dist/chunks/index-t_x6jj7l.d.ts +96 -0
  128. package/dist/chunks/input-adorn-C_EHML68.js +1 -0
  129. package/dist/chunks/input-group-iI7azfvE.js +1 -0
  130. package/dist/chunks/list-CMr-wB9d.js +1 -0
  131. package/dist/chunks/menu-CXUc-Gva.js +1 -0
  132. package/dist/chunks/modal-ByIj71Mq.js +1 -0
  133. package/dist/chunks/nav-BldxFo_B.js +1 -0
  134. package/dist/chunks/navbar-BwcsQuBk.js +1 -0
  135. package/dist/chunks/notification-DdqigVB1.js +1 -0
  136. package/dist/chunks/otp-input-CXe_wkII.js +1 -0
  137. package/dist/chunks/overlayPlacement-B7843a-Q.d.ts +6 -0
  138. package/dist/chunks/overlayPlacement-BtS90IVf.js +1 -0
  139. package/dist/chunks/pagination-BOpEAYW2.js +1 -0
  140. package/dist/chunks/password-strength-BfLiYiGj.js +1 -0
  141. package/dist/chunks/placeholder-pg95KELl.js +1 -0
  142. package/dist/chunks/polymorphic-CACPOv1_.js +1 -0
  143. package/dist/chunks/polymorphic-CVHbTHSN.d.ts +40 -0
  144. package/dist/chunks/popover-BpSfnZzk.js +1 -0
  145. package/dist/chunks/progress-DlrZ71aV.js +1 -0
  146. package/dist/chunks/radio-BV7Sq6D1.js +1 -0
  147. package/dist/chunks/range-input-BN3430j-.js +1 -0
  148. package/dist/chunks/renderFormCheck-BXBs6_ov.js +1 -0
  149. package/dist/chunks/renderFormCheck-CYWG-Rbt.d.ts +23 -0
  150. package/dist/chunks/renderFormField-fBEny6JV.d.ts +14 -0
  151. package/dist/chunks/renderFormField-wiaxvvLG.js +1 -0
  152. package/dist/chunks/renderMenuItemContent-CmqT3YUQ.js +1 -0
  153. package/dist/chunks/select-CclIIux8.js +1 -0
  154. package/dist/chunks/skeleton-CKq76sE_.js +1 -0
  155. package/dist/chunks/spacingClassName-DVhk8m3P.js +1 -0
  156. package/dist/chunks/spinner-BEq4PAlu.js +1 -0
  157. package/dist/chunks/stack-D3retZ-W.js +1 -0
  158. package/dist/chunks/static-table-D0M4oc_t.js +1 -0
  159. package/dist/chunks/stepper-CTa6e8uv.js +1 -0
  160. package/dist/chunks/switch-BmHpq4tL.js +1 -0
  161. package/dist/chunks/table-Fme9GbAR.js +1 -0
  162. package/dist/chunks/tableClassName-CZA2Bse8.js +1 -0
  163. package/dist/chunks/tabs-BnbMJM_b.js +1 -0
  164. package/dist/chunks/text-input-DD3d08Yf.js +1 -0
  165. package/dist/chunks/textarea-C0qQdCcu.js +1 -0
  166. package/dist/chunks/toast-BQhZ2pv5.js +1 -0
  167. package/dist/chunks/tooltip-DHtVAYUo.js +1 -0
  168. package/dist/chunks/triggerElement-BIqA4KqZ.js +1 -0
  169. package/dist/chunks/types-CS_40Txv.d.ts +34 -0
  170. package/dist/chunks/useButtonSemantics-CILM_lhi.js +1 -0
  171. package/dist/chunks/useDialogElement-BRIU60cT.js +1 -0
  172. package/dist/chunks/useDisabledAnchorGuard-Cz58UCXy.js +1 -0
  173. package/dist/chunks/useFloatingOverlay-CcmDZKMK.js +1 -0
  174. package/dist/chunks/useForkedRef-DVEfT-KI.js +1 -0
  175. package/dist/chunks/useFormField-BOqmBTC4.js +1 -0
  176. package/dist/chunks/useIsomorphicLayoutEffect-BbqRwuqn.js +1 -0
  177. package/dist/chunks/useToastRegionQueue-BH6bWZ73.js +1 -0
  178. package/dist/chunks/validationClassName-gRGs4KBm.js +1 -0
  179. package/dist/close-button.d.ts +2 -0
  180. package/dist/close-button.js +1 -0
  181. package/dist/collapse.d.ts +2 -0
  182. package/dist/collapse.js +1 -0
  183. package/dist/color-input.d.ts +2 -0
  184. package/dist/color-input.js +1 -0
  185. package/dist/combobox.d.ts +3 -0
  186. package/dist/combobox.js +1 -0
  187. package/dist/datagrid.d.ts +2 -0
  188. package/dist/datagrid.js +1 -0
  189. package/dist/datepicker.d.ts +2 -0
  190. package/dist/datepicker.js +1 -0
  191. package/dist/drawer.d.ts +2 -0
  192. package/dist/drawer.js +1 -0
  193. package/dist/file-input.d.ts +2 -0
  194. package/dist/file-input.js +1 -0
  195. package/dist/flex.d.ts +2 -0
  196. package/dist/flex.js +1 -0
  197. package/dist/floating-input.d.ts +2 -0
  198. package/dist/floating-input.js +1 -0
  199. package/dist/form-field.d.ts +2 -0
  200. package/dist/form-field.js +1 -0
  201. package/dist/form.d.ts +2 -0
  202. package/dist/form.js +1 -0
  203. package/dist/grid.d.ts +2 -0
  204. package/dist/grid.js +1 -0
  205. package/dist/icon.d.ts +4 -0
  206. package/dist/icon.js +1 -0
  207. package/dist/index.d.ts +72 -6369
  208. package/dist/index.js +1 -2
  209. package/dist/input-adorn.d.ts +2 -0
  210. package/dist/input-adorn.js +1 -0
  211. package/dist/input-group.d.ts +2 -0
  212. package/dist/input-group.js +1 -0
  213. package/dist/link.d.ts +3 -0
  214. package/dist/link.js +1 -0
  215. package/dist/list.d.ts +2 -0
  216. package/dist/list.js +1 -0
  217. package/dist/menu.d.ts +3 -0
  218. package/dist/menu.js +1 -0
  219. package/dist/modal.d.ts +2 -0
  220. package/dist/modal.js +1 -0
  221. package/dist/nav.d.ts +2 -0
  222. package/dist/nav.js +1 -0
  223. package/dist/navbar.d.ts +2 -0
  224. package/dist/navbar.js +1 -0
  225. package/dist/notification.d.ts +2 -0
  226. package/dist/notification.js +1 -0
  227. package/dist/otp-input.d.ts +2 -0
  228. package/dist/otp-input.js +1 -0
  229. package/dist/pagination.d.ts +2 -0
  230. package/dist/pagination.js +1 -0
  231. package/dist/password-strength.d.ts +2 -0
  232. package/dist/password-strength.js +1 -0
  233. package/dist/placeholder.d.ts +2 -0
  234. package/dist/placeholder.js +1 -0
  235. package/dist/popover.d.ts +2 -0
  236. package/dist/popover.js +1 -0
  237. package/dist/progress.d.ts +2 -0
  238. package/dist/progress.js +1 -0
  239. package/dist/radio.d.ts +2 -0
  240. package/dist/radio.js +1 -0
  241. package/dist/range-input.d.ts +2 -0
  242. package/dist/range-input.js +1 -0
  243. package/dist/select.d.ts +2 -0
  244. package/dist/select.js +1 -0
  245. package/dist/skeleton.d.ts +2 -0
  246. package/dist/skeleton.js +1 -0
  247. package/dist/spinner.d.ts +2 -0
  248. package/dist/spinner.js +1 -0
  249. package/dist/stack.d.ts +2 -0
  250. package/dist/stack.js +1 -0
  251. package/dist/static-table.d.ts +2 -0
  252. package/dist/static-table.js +1 -0
  253. package/dist/stepper.d.ts +2 -0
  254. package/dist/stepper.js +1 -0
  255. package/dist/style.css +1 -1
  256. package/dist/switch.d.ts +2 -0
  257. package/dist/switch.js +1 -0
  258. package/dist/table.d.ts +2 -0
  259. package/dist/table.js +1 -0
  260. package/dist/tabs.d.ts +2 -0
  261. package/dist/tabs.js +1 -0
  262. package/dist/text-input.d.ts +2 -0
  263. package/dist/text-input.js +1 -0
  264. package/dist/textarea.d.ts +2 -0
  265. package/dist/textarea.js +1 -0
  266. package/dist/toast.d.ts +2 -0
  267. package/dist/toast.js +1 -0
  268. package/dist/tooltip.d.ts +2 -0
  269. package/dist/tooltip.js +1 -0
  270. package/package.json +62 -4
  271. package/src/components/accordion/index.ts +4 -0
  272. package/src/components/autocomplete/index.ts +4 -0
  273. package/src/components/avatar/index.ts +4 -0
  274. package/src/components/badge/index.ts +4 -0
  275. package/src/components/breadcrumb/index.ts +4 -0
  276. package/src/components/button/index.ts +4 -0
  277. package/src/components/button-group/index.ts +4 -0
  278. package/src/components/calendar/index.ts +4 -0
  279. package/src/components/card/index.ts +4 -0
  280. package/src/components/carousel/CarouselControlButton.tsx +11 -4
  281. package/src/components/carousel/CarouselControlNext.tsx +6 -0
  282. package/src/components/carousel/CarouselControlPrev.tsx +6 -0
  283. package/src/components/carousel/CarouselPlayPause.tsx +27 -4
  284. package/src/components/carousel/index.ts +4 -0
  285. package/src/components/checkbox/index.ts +4 -0
  286. package/src/components/chip/index.ts +4 -0
  287. package/src/components/chip-input/index.ts +4 -0
  288. package/src/components/close-button/index.ts +4 -0
  289. package/src/components/collapse/index.ts +4 -0
  290. package/src/components/color-input/index.ts +4 -0
  291. package/src/components/combobox/ComboboxListBox.tsx +2 -2
  292. package/src/components/combobox/index.ts +4 -0
  293. package/src/components/datagrid/index.ts +4 -0
  294. package/src/components/datepicker/index.ts +4 -0
  295. package/src/components/drawer/index.ts +8 -0
  296. package/src/components/file-input/index.ts +4 -0
  297. package/src/components/flex/index.ts +4 -0
  298. package/src/components/floating-input/index.ts +4 -0
  299. package/src/components/form/index.ts +4 -0
  300. package/src/components/form-field/index.ts +4 -0
  301. package/src/components/grid/index.ts +4 -0
  302. package/src/components/icon/Icon.tsx +69 -38
  303. package/src/components/icon/IconProvider.tsx +40 -0
  304. package/src/components/icon/index.ts +7 -0
  305. package/src/components/input-adorn/index.ts +4 -0
  306. package/src/components/input-group/index.ts +4 -0
  307. package/src/components/link/index.ts +4 -0
  308. package/src/components/list/index.ts +4 -0
  309. package/src/components/menu/index.ts +4 -0
  310. package/src/components/modal/index.ts +8 -0
  311. package/src/components/nav/index.ts +4 -0
  312. package/src/components/navbar/NavbarToggler.tsx +9 -3
  313. package/src/components/navbar/index.ts +4 -0
  314. package/src/components/notification/Notification.tsx +6 -5
  315. package/src/components/notification/index.ts +8 -0
  316. package/src/components/otp-input/index.ts +4 -0
  317. package/src/components/pagination/Pagination.tsx +16 -3
  318. package/src/components/pagination/index.ts +8 -0
  319. package/src/components/password-strength/index.ts +4 -0
  320. package/src/components/placeholder/index.ts +4 -0
  321. package/src/components/popover/index.ts +4 -0
  322. package/src/components/progress/index.ts +4 -0
  323. package/src/components/radio/index.ts +4 -0
  324. package/src/components/range-input/index.ts +4 -0
  325. package/src/components/select/index.ts +4 -0
  326. package/src/components/skeleton/SkeletonLoader.tsx +13 -6
  327. package/src/components/skeleton/index.ts +4 -0
  328. package/src/components/spinner/index.ts +4 -0
  329. package/src/components/stack/index.ts +4 -0
  330. package/src/components/static-table/StaticTable.tsx +78 -0
  331. package/src/components/static-table/index.ts +8 -0
  332. package/src/components/stepper/index.ts +4 -0
  333. package/src/components/switch/index.ts +4 -0
  334. package/src/components/table/Table.tsx +14 -22
  335. package/src/components/table/index.ts +4 -0
  336. package/src/components/tabs/index.ts +4 -0
  337. package/src/components/text-input/index.ts +4 -0
  338. package/src/components/textarea/index.ts +4 -0
  339. package/src/components/toast/Toast.tsx +2 -1
  340. package/src/components/toast/ToastHeader.tsx +4 -3
  341. package/src/components/toast/index.ts +8 -0
  342. package/src/components/tooltip/index.ts +4 -0
  343. package/src/hooks/useIconConfig.ts +6 -0
  344. package/src/index.ts +24 -4
  345. package/src/utils/iconConfig.ts +88 -0
  346. package/src/utils/iconSlot.tsx +41 -0
  347. package/src/utils/polymorphic.ts +49 -2
  348. package/src/utils/renderMenuItemContent.tsx +4 -9
  349. package/src/utils/slot.tsx +78 -0
  350. package/src/utils/tableClassName.ts +93 -0
@@ -1,3 +1,7 @@
1
+ 'use client'
2
+
3
+ import '../../utils/suppressFocusRingGlobally'
4
+
1
5
  export { Stepper } from './Stepper'
2
6
  export type { StepperProps, StepperItemDef } from './Stepper'
3
7
  export { StepperItem } from './StepperItem'
@@ -1,2 +1,6 @@
1
+ 'use client'
2
+
3
+ import '../../utils/suppressFocusRingGlobally'
4
+
1
5
  export { Switch } from './Switch'
2
6
  export type { SwitchProps } from './Switch'
@@ -25,6 +25,7 @@ import {
25
25
 
26
26
  import { useForkedRef } from '../../hooks/useForkedRef'
27
27
  import { ContextColor } from '../../types'
28
+ import { tableClassName, tableWrapperClassName } from '../../utils/tableClassName'
28
29
  import './Table.css'
29
30
 
30
31
  // `GridNode<T>` (from `@react-types/shared`) isn't re-exported by either package's public
@@ -179,24 +180,20 @@ const TableInner = <T extends object>(
179
180
  internalRef
180
181
  )
181
182
 
182
- const _className = classNames(
183
- 'table',
183
+ const _className = tableClassName({
184
+ align,
185
+ bordered,
186
+ borderless,
187
+ className,
184
188
  color,
185
- {
186
- [`align-${align}`]: align,
187
- bordered,
188
- borderless,
189
- hoverable: hover,
190
- sm,
191
- stacked: stacked === true,
192
- striped
193
- },
194
- typeof stacked === 'string' ? `max-${stacked}:stacked` : undefined,
195
- className
196
- )
189
+ hover,
190
+ sm,
191
+ stacked,
192
+ striped
193
+ })
197
194
 
198
195
  const tableEl = (
199
- <table {...gridProps} className={_className || undefined} ref={ref}>
196
+ <table {...gridProps} className={_className} ref={ref}>
200
197
  {caption && <caption>{caption}</caption>}
201
198
  <TableRowGroup className={children[0].props.className} type="thead">
202
199
  {state.collection.headerRows.map((headerRow) => (
@@ -228,13 +225,8 @@ const TableInner = <T extends object>(
228
225
  </table>
229
226
  )
230
227
 
231
- if (!responsive && !stacked) return tableEl
232
-
233
- const wrapperClassName = responsive
234
- ? typeof responsive === 'boolean'
235
- ? 'table-responsive'
236
- : `max-${responsive}:table-responsive`
237
- : 'table-responsive'
228
+ const wrapperClassName = tableWrapperClassName({ responsive, stacked })
229
+ if (!wrapperClassName) return tableEl
238
230
 
239
231
  return <div className={wrapperClassName}>{tableEl}</div>
240
232
  }
@@ -1,3 +1,7 @@
1
+ 'use client'
2
+
3
+ import '../../utils/suppressFocusRingGlobally'
4
+
1
5
  export { Table } from './Table'
2
6
  export type { TableProps } from './Table'
3
7
  export { TableBody } from './TableBody'
@@ -1,3 +1,7 @@
1
+ 'use client'
2
+
3
+ import '../../utils/suppressFocusRingGlobally'
4
+
1
5
  export { Tabs } from './Tabs'
2
6
  export type { TabsProps } from './Tabs'
3
7
  export { Tab } from './Tab'
@@ -1,2 +1,6 @@
1
+ 'use client'
2
+
3
+ import '../../utils/suppressFocusRingGlobally'
4
+
1
5
  export { TextInput } from './TextInput'
2
6
  export type { TextInputProps } from './TextInput'
@@ -1,2 +1,6 @@
1
+ 'use client'
2
+
3
+ import '../../utils/suppressFocusRingGlobally'
4
+
1
5
  export { Textarea } from './Textarea'
2
6
  export type { TextareaProps } from './Textarea'
@@ -51,7 +51,8 @@ export interface ToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'
51
51
  */
52
52
  footer?: ReactNode | ((close: () => void) => ReactNode)
53
53
  /**
54
- * Leading icon for the header. A string is rendered as `<ToastIcon name={icon} />`; pass
54
+ * Leading icon for the header. A string is an icon name, rendered like
55
+ * `<ToastIcon name={icon} />` (or by `IconProvider`'s `component`); pass
55
56
  * any other node for a fully custom icon (typically a logo or avatar). Shorthand for
56
57
  * `ToastHeader`'s `icon` prop; hidden from assistive technology by default, since it
57
58
  * duplicates `title` visually.
@@ -8,7 +8,7 @@ import {
8
8
  PolymorphicComponentProps,
9
9
  PolymorphicRef
10
10
  } from '../../utils/polymorphic'
11
- import { ToastIcon } from './ToastIcon'
11
+ import { ResolvedIcon } from '../../utils/iconSlot'
12
12
 
13
13
  type ToastHeaderOwnProps<C extends ElementType> = {
14
14
  /**
@@ -33,7 +33,8 @@ type ToastHeaderOwnProps<C extends ElementType> = {
33
33
  */
34
34
  component?: C
35
35
  /**
36
- * Leading icon. A string is rendered as `<ToastIcon name={icon} />` and hidden from
36
+ * Leading icon. A string is an icon name, rendered like `<ToastIcon name={icon} />` (or by
37
+ * `IconProvider`'s `component`) and hidden from
37
38
  * assistive technology by default, since it duplicates the heading visually. Pass any other
38
39
  * node for a fully custom icon (typically a logo or avatar) — a custom node is left as-is,
39
40
  * since it may carry its own meaningful accessible name (e.g. an avatar's `alt` text).
@@ -82,7 +83,7 @@ function ToastHeaderRender<C extends ElementType = 'div'>(
82
83
  {icon != null &&
83
84
  (typeof icon === 'string' ? (
84
85
  <span aria-hidden="true" className="me-sm">
85
- <ToastIcon name={icon} />
86
+ <ResolvedIcon value={icon} className="toast-icon" />
86
87
  </span>
87
88
  ) : (
88
89
  <span className="me-sm">{icon}</span>
@@ -1,3 +1,7 @@
1
+ 'use client'
2
+
3
+ import '../../utils/suppressFocusRingGlobally'
4
+
1
5
  export { Toast } from './Toast'
2
6
  export type { ToastProps } from './Toast'
3
7
  export { ToastBody } from './ToastBody'
@@ -16,3 +20,7 @@ export { Toaster } from './Toaster'
16
20
  export type { ToasterProps } from './Toaster'
17
21
  export { addToast, closeToast, toastQueue } from './toastQueue'
18
22
  export type { ToastContent } from './toastQueue'
23
+ // Also exported from the package root; repeated here so this folder's subpath entry
24
+ // (`@chassis-ui/react/<folder>`) covers the whole family without reaching back to the root.
25
+ export { useToast } from '../../hooks/useToast'
26
+ export type { UseToastResult } from '../../hooks/useToast'
@@ -1,2 +1,6 @@
1
+ 'use client'
2
+
3
+ import '../../utils/suppressFocusRingGlobally'
4
+
1
5
  export { Tooltip } from './Tooltip'
2
6
  export type { TooltipProps } from './Tooltip'
@@ -0,0 +1,6 @@
1
+ import { useContext } from 'react'
2
+
3
+ import { IconConfig, IconContext } from '../utils/iconConfig'
4
+
5
+ // The nearest `IconProvider`'s settings, merged with every provider above it; empty outside one.
6
+ export const useIconConfig = (): IconConfig => useContext(IconContext)
package/src/index.ts CHANGED
@@ -2,8 +2,9 @@
2
2
 
3
3
  // Side-effect only: installs the single document-level pointerdown listener that works around the
4
4
  // browser's `:focus-visible` first-click heuristic misfire — see the module's own comment. Needs to
5
- // run once wherever this package is used, not per-component, so it's imported here rather than
6
- // from any individual component.
5
+ // run once wherever this package is used, not per-component, so it's imported by entry points
6
+ // (here, and every component folder's `index.ts` barrel, each of which is also a subpath entry)
7
+ // rather than from any individual component.
7
8
  import './utils/suppressFocusRingGlobally'
8
9
 
9
10
  import { Accordion, AccordionBody, AccordionHeader, AccordionItem } from './components/accordion'
@@ -91,7 +92,7 @@ import { Select } from './components/select'
91
92
  import { Switch } from './components/switch'
92
93
  import { TextInput } from './components/text-input'
93
94
  import { Textarea } from './components/textarea'
94
- import { Icon } from './components/icon'
95
+ import { Icon, IconProvider } from './components/icon'
95
96
  import { Placeholder } from './components/placeholder'
96
97
  import { Link } from './components/link'
97
98
  import { List, ListItem } from './components/list'
@@ -104,6 +105,7 @@ import { Progress, ProgressBar } from './components/progress'
104
105
  import { Drawer, DrawerBody, DrawerFooter, DrawerHeader, DrawerTitle } from './components/drawer'
105
106
  import { Skeleton, SkeletonLoader } from './components/skeleton'
106
107
  import { Spinner } from './components/spinner'
108
+ import { StaticTable } from './components/static-table'
107
109
  import { Stepper, StepperItem } from './components/stepper'
108
110
  import { Table, TableBody, TableCell, TableColumn, TableHeader, TableRow } from './components/table'
109
111
  import { Tabs, Tab, TabList, TabPanel } from './components/tabs'
@@ -224,6 +226,7 @@ export {
224
226
  FormHelp,
225
227
  FormLabel,
226
228
  Icon,
229
+ IconProvider,
227
230
  Placeholder,
228
231
  InputGroup,
229
232
  InputGroupAddon,
@@ -265,6 +268,7 @@ export {
265
268
  Skeleton,
266
269
  SkeletonLoader,
267
270
  Spinner,
271
+ StaticTable,
268
272
  Stepper,
269
273
  StepperItem,
270
274
  Switch,
@@ -367,6 +371,15 @@ export type { CloseButtonProps } from './components/close-button'
367
371
  export type { CollapseProps } from './components/collapse'
368
372
  export type { ColorInputProps } from './components/color-input'
369
373
  export type { ComboboxGroupProps, ComboboxItemProps, ComboboxProps } from './components/combobox'
374
+ export type {
375
+ DataGridBodyProps,
376
+ DataGridCellProps,
377
+ DataGridColumnProps,
378
+ DataGridHeaderProps,
379
+ DataGridProps,
380
+ DataGridRowProps,
381
+ DataGridSelectionCellProps
382
+ } from './components/datagrid'
370
383
  export type {
371
384
  DatePickerMultipleProps,
372
385
  DatePickerProps,
@@ -393,7 +406,13 @@ export type {
393
406
  GridProps,
394
407
  RowProps
395
408
  } from './components/grid'
396
- export type { IconProps } from './components/icon'
409
+ export type {
410
+ IconComponentProps,
411
+ IconKey,
412
+ IconProps,
413
+ IconProviderProps,
414
+ IconValue
415
+ } from './components/icon'
397
416
  export type { InputAdornProps } from './components/input-adorn'
398
417
  export type { InputGroupAddonProps, InputGroupProps } from './components/input-group'
399
418
  export type { LinkProps } from './components/link'
@@ -449,6 +468,7 @@ export type { RangeInputProps } from './components/range-input'
449
468
  export type { SelectOptionDef, SelectProps } from './components/select'
450
469
  export type { SkeletonLoaderProps, SkeletonProps } from './components/skeleton'
451
470
  export type { SpinnerProps } from './components/spinner'
471
+ export type { StaticTableProps } from './components/static-table'
452
472
  export type { StackProps } from './components/stack'
453
473
  export type { StepperItemDef, StepperItemProps, StepperProps } from './components/stepper'
454
474
  export type { SwitchProps } from './components/switch'
@@ -0,0 +1,88 @@
1
+ import { ComponentType, createContext, ReactElement } from 'react'
2
+
3
+ /**
4
+ * The icons this library's own components draw, by purpose rather than by icon name — so a
5
+ * consumer can map each one onto any icon set (see `IconProvider`'s `icons`).
6
+ */
7
+ export type IconKey = 'check' | 'previous' | 'next' | 'menu' | 'play' | 'pause'
8
+
9
+ /**
10
+ * An icon given to `IconProvider`'s `icons` or to a component's icon prop: a string is an icon
11
+ * name, rendered by `IconProvider`'s `component` (or the built-in `Icon`); an element is rendered
12
+ * as-is, with the component's own class names merged onto it.
13
+ */
14
+ export type IconValue = string | ReactElement
15
+
16
+ /**
17
+ * Props `IconProvider`'s `component` receives for every icon name it's asked to render.
18
+ */
19
+ export interface IconComponentProps {
20
+ /**
21
+ * The icon name — an `IconValue` string, or `IconProvider`'s default for that icon.
22
+ */
23
+ name: string
24
+ /**
25
+ * The class names the rendering component needs on the icon (e.g. `menu-item-check`,
26
+ * `directional-icon`) for chassis-css to position and flip it.
27
+ */
28
+ className?: string
29
+ [prop: string]: unknown
30
+ }
31
+
32
+ export interface IconConfig {
33
+ /**
34
+ * Class names added to every `Icon`, alongside its own `icon` class.
35
+ */
36
+ className?: string
37
+ /**
38
+ * Replaces the built-in `Icon` for every icon this library's components render by name — the
39
+ * strings in `icons` and their defaults, and a string `icon` on `Toast`/`Notification`. A
40
+ * component reference can't be passed from a React Server Component, so set this in a
41
+ * `'use client'` module.
42
+ */
43
+ component?: ComponentType<IconComponentProps>
44
+ /**
45
+ * Render `Icon` as an icon-font glyph instead of an SVG sprite reference, unless an `Icon` sets
46
+ * `font` itself. Needs the icon font's stylesheet loaded.
47
+ */
48
+ font?: boolean
49
+ /**
50
+ * Class-name prefix of the icon font's glyphs: an icon named `check-solid` renders as
51
+ * `{fontPrefix}check-solid`.
52
+ *
53
+ * @default 'cx-'
54
+ */
55
+ fontPrefix?: string
56
+ /**
57
+ * The icon to render for each of the library's own icons, by purpose. Unset ones keep their
58
+ * defaults (`check-solid`, `chevron-left-outline`, `chevron-right-outline`, `bars-outline`,
59
+ * `play-solid`, `pause-solid`).
60
+ */
61
+ icons?: Partial<Record<IconKey, IconValue>>
62
+ /**
63
+ * URL of the SVG sprite `Icon` references, e.g. `/static/icons/chassis-icons.svg`. Leave empty
64
+ * (the default) when the sprite is embedded in the page, so icons render as `href="#name"`.
65
+ * Browsers don't load an external sprite from another origin.
66
+ *
67
+ * @default ''
68
+ */
69
+ sprite?: string
70
+ }
71
+
72
+ // The chassis-icons names this library used before its icons became configurable. Both
73
+ // previous/next consumers (Pagination, Carousel) now share the outline chevrons — Pagination used
74
+ // the solid ones.
75
+ export const DEFAULT_ICONS: Record<IconKey, string> = {
76
+ check: 'check-solid',
77
+ previous: 'chevron-left-outline',
78
+ next: 'chevron-right-outline',
79
+ menu: 'bars-outline',
80
+ play: 'play-solid',
81
+ pause: 'pause-solid'
82
+ }
83
+
84
+ export const DEFAULT_FONT_PREFIX = 'cx-'
85
+
86
+ // Lives in `utils/` rather than `components/icon/` because it's read outside that folder too —
87
+ // by `IconSlot` (`./iconSlot.tsx`), which every icon-drawing component renders through.
88
+ export const IconContext = createContext<IconConfig>({})
@@ -0,0 +1,41 @@
1
+ import React, { cloneElement, ReactElement } from 'react'
2
+ import { mergeProps } from 'react-aria'
3
+
4
+ import { Icon } from '../components/icon/Icon'
5
+ import { useIconConfig } from '../hooks/useIconConfig'
6
+ import { DEFAULT_ICONS, IconKey, IconValue } from './iconConfig'
7
+
8
+ // Every icon this library's own components draw goes through here, never through `<Icon>`
9
+ // directly, so a consumer can swap in their own icons (`IconProvider`'s `icons`/`component`, or a
10
+ // component's own icon prop). The rendering component passes the class names chassis-css hooks
11
+ // onto (`menu-item-check` positions the check, `navbar-toggler-icon` sizes and colors it,
12
+ // `carousel-icon-play`/`-pause` are toggled by state, `directional-icon` flips in RTL); those are
13
+ // merged onto whatever icon ends up rendered, so a custom icon lands in the same place a built-in
14
+ // one would. `aria-hidden` defaults on: each of these icons sits beside its own visible or
15
+ // visually-hidden label.
16
+ //
17
+ // A custom *element* deliberately doesn't get the `icon` class itself: chassis-css's `.icon` sets
18
+ // `fill`, which would paint over an outline icon set's `fill="none"` (Lucide, Heroicons outline,
19
+ // ...). It keeps its own size and color — `currentColor` icons still follow the control's text.
20
+ type IconRenderProps = { className?: string } & Record<string, unknown>
21
+
22
+ export function ResolvedIcon({ value, ...props }: IconRenderProps & { value: IconValue }) {
23
+ const { component: Component } = useIconConfig()
24
+ const iconProps = { 'aria-hidden': true, ...props }
25
+
26
+ if (typeof value !== 'string') {
27
+ const element = value as ReactElement<Record<string, unknown>>
28
+ return cloneElement(element, mergeProps(iconProps, element.props))
29
+ }
30
+ if (Component) return <Component name={value} {...iconProps} />
31
+ return <Icon name={value} {...iconProps} />
32
+ }
33
+
34
+ export function IconSlot({
35
+ icon,
36
+ override,
37
+ ...props
38
+ }: IconRenderProps & { icon: IconKey; override?: IconValue }) {
39
+ const { icons } = useIconConfig()
40
+ return <ResolvedIcon value={override ?? icons?.[icon] ?? DEFAULT_ICONS[icon]} {...props} />
41
+ }
@@ -1,12 +1,16 @@
1
1
  import {
2
2
  ComponentPropsWithoutRef,
3
3
  ComponentPropsWithRef,
4
+ createElement,
4
5
  ElementType,
5
6
  ForwardRefRenderFunction,
6
7
  forwardRef,
7
8
  Ref
8
9
  } from 'react'
9
10
 
11
+ import { devWarning } from './devWarning'
12
+ import { getSlotChild, Slot, SlotProvider } from './slot'
13
+
10
14
  // Ref type inferred from a polymorphic component's currently-selected `component` element type.
11
15
  export type PolymorphicRef<C extends ElementType> = ComponentPropsWithRef<C>['ref']
12
16
 
@@ -26,6 +30,21 @@ export type PolymorphicRef<C extends ElementType> = ComponentPropsWithRef<C>['re
26
30
  export type PolymorphicRefWithFallback<C extends ElementType, Fallback extends HTMLElement> =
27
31
  PolymorphicRef<C> | Ref<Fallback>
28
32
 
33
+ /**
34
+ * The `asChild` prop every polymorphic component accepts alongside `component` — see
35
+ * `createPolymorphicComponent` below for how it's implemented once for all of them.
36
+ */
37
+ export interface AsChildProps {
38
+ /**
39
+ * Render the single child element in place of this component's own element, with this
40
+ * component's classes, props and ref merged onto it: `<Button asChild><Link href="/login">Log
41
+ * in</Link></Button>`. The alternative to `component` for React Server Components — an element
42
+ * can be passed from the server to this package's client components, a component reference
43
+ * (`component={Link}`) can't.
44
+ */
45
+ asChild?: boolean
46
+ }
47
+
29
48
  /**
30
49
  * Props for a polymorphic component: `OwnProps` (which must declare `component?: C`) plus
31
50
  * whatever props `C` itself accepts, minus any name already claimed by `OwnProps` so the two
@@ -33,7 +52,8 @@ export type PolymorphicRefWithFallback<C extends ElementType, Fallback extends H
33
52
  * type-checking/autocomplete for that component's own props at the call site.
34
53
  */
35
54
  export type PolymorphicComponentProps<C extends ElementType, OwnProps extends object> = OwnProps &
36
- Omit<ComponentPropsWithoutRef<C>, keyof OwnProps>
55
+ AsChildProps &
56
+ Omit<ComponentPropsWithoutRef<C>, keyof OwnProps | keyof AsChildProps>
37
57
 
38
58
  /**
39
59
  * Wraps a polymorphic component's render function in `forwardRef` and stamps `displayName` — the
@@ -41,13 +61,40 @@ export type PolymorphicComponentProps<C extends ElementType, OwnProps extends ob
41
61
  * fully generic component type (e.g. `ButtonComponent`) that `forwardRef`'s own return type can't
42
62
  * express, since `forwardRef` only accepts a non-generic render function — the caller still casts
43
63
  * the render function to a concrete `Element`-typed instance before passing it in here.
64
+ *
65
+ * Also implements `asChild` for every polymorphic component at once (#23): the render function
66
+ * gets `component={Slot}` and the child element's own children, so it computes its classes,
67
+ * props and ref exactly as it would for any component reference (`component={Link}`) — `Slot`
68
+ * then clones the caller's child element with all of that merged on (see `./slot`). No render
69
+ * function needs to know `asChild` exists.
44
70
  */
45
71
  export function createPolymorphicComponent<T>(
46
72
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
73
  render: ForwardRefRenderFunction<Element, any>,
48
74
  displayName: string
49
75
  ): T {
50
- const Component = forwardRef(render) as unknown as T & { displayName?: string }
76
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
+ const Component = forwardRef<Element, any>(({ asChild, ...props }, ref) => {
78
+ const child = asChild ? getSlotChild(props.children, displayName) : null
79
+ if (!child) return render(props, ref)
80
+
81
+ devWarning(
82
+ props.component !== undefined,
83
+ `${displayName}: both \`asChild\` and \`component\` were passed; \`asChild\` wins and ` +
84
+ `\`component\` is ignored.`
85
+ )
86
+
87
+ return createElement(
88
+ SlotProvider,
89
+ { value: child },
90
+ render(
91
+ { ...props, component: Slot, children: (child.props as PropsWithChildren).children },
92
+ ref
93
+ )
94
+ )
95
+ }) as unknown as T & { displayName?: string }
51
96
  Component.displayName = displayName
52
97
  return Component
53
98
  }
99
+
100
+ type PropsWithChildren = { children?: unknown }
@@ -1,6 +1,6 @@
1
1
  import React, { ReactNode } from 'react'
2
2
 
3
- import { Icon } from '../components/icon/Icon'
3
+ import { IconSlot } from './iconSlot'
4
4
 
5
5
  export interface MenuItemContentDef {
6
6
  /**
@@ -16,13 +16,9 @@ export interface MenuItemContentDef {
16
16
  */
17
17
  description?: ReactNode
18
18
  /**
19
- * Renders a `.menu-item-check` at the trailing edge when true.
19
+ * Renders a `.menu-item-check` at the trailing edge when true — `IconProvider`'s `check` icon.
20
20
  */
21
21
  selected?: boolean
22
- /**
23
- * Icon name for the selected-state check. Defaults to chassis-css's own doc example.
24
- */
25
- checkIcon?: string
26
22
  }
27
23
 
28
24
  // Chassis-css defines identical markup for rich item content in both Menu and Combobox items
@@ -36,8 +32,7 @@ export const renderMenuItemContent = ({
36
32
  icon,
37
33
  label,
38
34
  description,
39
- selected,
40
- checkIcon = 'check-solid'
35
+ selected
41
36
  }: MenuItemContentDef): ReactNode => {
42
37
  if (icon == null && description == null && !selected) return label
43
38
 
@@ -56,7 +51,7 @@ export const renderMenuItemContent = ({
56
51
  ) : (
57
52
  label
58
53
  )}
59
- {selected && <Icon name={checkIcon} className="menu-item-check" />}
54
+ {selected && <IconSlot icon="check" className="menu-item-check" />}
60
55
  </>
61
56
  )
62
57
  }
@@ -0,0 +1,78 @@
1
+ import React, {
2
+ cloneElement,
3
+ createContext,
4
+ forwardRef,
5
+ Fragment,
6
+ isValidElement,
7
+ ReactElement,
8
+ ReactNode,
9
+ Ref,
10
+ useContext,
11
+ version
12
+ } from 'react'
13
+ import { mergeProps } from 'react-aria'
14
+
15
+ import { useForkedRef } from '../hooks/useForkedRef'
16
+ import { devWarning } from './devWarning'
17
+
18
+ // Backs the `asChild` prop every polymorphic component accepts (see `createPolymorphicComponent`).
19
+ // The component renders `Slot` as its `component`, exactly like any other component reference;
20
+ // `Slot` then renders the caller's child element in its place, with the props the component
21
+ // computed (className, handlers, ARIA attributes, ref) merged onto it.
22
+ //
23
+ // The child element travels through context rather than a prop because a render function spreads
24
+ // its `rest` props onto `component` in its own way (some filter them, some don't forward every
25
+ // one) — context reaches `Slot` no matter how the render function wires it up. `Slot` resets the
26
+ // context for its own subtree, so a polymorphic component nested *inside* the child doesn't pick
27
+ // up the outer one's element.
28
+ type SlotElement = ReactElement<Record<string, unknown>>
29
+
30
+ const SlotContext = createContext<SlotElement | null>(null)
31
+
32
+ export const SlotProvider = SlotContext.Provider
33
+
34
+ // React 19 moved `ref` onto `props` (and warns on reading `element.ref`); React 18 only has
35
+ // `element.ref`. The package supports both (`peerDependencies.react: >=18`).
36
+ const REACT_19 = parseInt(version, 10) >= 19
37
+
38
+ function getElementRef(element: SlotElement): Ref<unknown> | undefined {
39
+ return REACT_19
40
+ ? (element.props as { ref?: Ref<unknown> }).ref
41
+ : (element as unknown as { ref?: Ref<unknown> }).ref
42
+ }
43
+
44
+ // `Record` rather than a declared prop list: `Slot` forwards whatever the render function hands it.
45
+ type SlotProps = Record<string, unknown>
46
+
47
+ export const Slot = forwardRef<unknown, SlotProps>(function Slot({ children, ...slotProps }, ref) {
48
+ const element = useContext(SlotContext)
49
+ const forkedRef = useForkedRef(ref, element ? getElementRef(element) : undefined)
50
+ if (!element) return null
51
+
52
+ return (
53
+ <SlotContext.Provider value={null}>
54
+ {cloneElement(
55
+ element,
56
+ // react-aria's `mergeProps`: the child's own props win over the component's, except that
57
+ // classNames concatenate, event handlers chain (the component's first), and ids merge.
58
+ { ...mergeProps(slotProps, element.props), ref: forkedRef } as Record<string, unknown>,
59
+ children as ReactNode
60
+ )}
61
+ </SlotContext.Provider>
62
+ )
63
+ })
64
+
65
+ // The single element `asChild` renders in place of the component's own element, or `null` (with
66
+ // a dev warning) when `children` isn't exactly one — the component then falls back to rendering
67
+ // its default element, so a misuse degrades to a working, if unstyled-as-intended, UI.
68
+ export function getSlotChild(children: ReactNode, displayName: string): SlotElement | null {
69
+ if (isValidElement<Record<string, unknown>>(children) && children.type !== Fragment) {
70
+ return children
71
+ }
72
+ devWarning(
73
+ true,
74
+ `${displayName}: \`asChild\` expects exactly one React element as its child (not text, a ` +
75
+ `fragment, or several elements); rendering the default element instead.`
76
+ )
77
+ return null
78
+ }