@kushagradhawan/kookie-ui 0.3.21 → 0.3.23

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 (548) hide show
  1. package/components.css +264 -329
  2. package/dist/cjs/components/_internal/base-button.d.ts.map +1 -1
  3. package/dist/cjs/components/_internal/base-button.js +1 -1
  4. package/dist/cjs/components/_internal/base-button.js.map +4 -4
  5. package/dist/cjs/components/_internal/dropdown-menu-drill-down.js +1 -1
  6. package/dist/cjs/components/_internal/dropdown-menu-drill-down.js.map +3 -3
  7. package/dist/cjs/components/_internal/shell-bottom.js +1 -1
  8. package/dist/cjs/components/_internal/shell-bottom.js.map +4 -4
  9. package/dist/cjs/components/_internal/shell-handles.d.ts.map +1 -1
  10. package/dist/cjs/components/_internal/shell-handles.js +1 -1
  11. package/dist/cjs/components/_internal/shell-handles.js.map +3 -3
  12. package/dist/cjs/components/_internal/shell-inspector.js +1 -1
  13. package/dist/cjs/components/_internal/shell-inspector.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.map +1 -1
  17. package/dist/cjs/components/accordion.js +1 -1
  18. package/dist/cjs/components/accordion.js.map +4 -4
  19. package/dist/cjs/components/alert-dialog.d.ts.map +1 -1
  20. package/dist/cjs/components/alert-dialog.js +1 -1
  21. package/dist/cjs/components/alert-dialog.js.map +4 -4
  22. package/dist/cjs/components/avatar.js +1 -1
  23. package/dist/cjs/components/avatar.js.map +4 -4
  24. package/dist/cjs/components/badge.d.ts.map +1 -1
  25. package/dist/cjs/components/badge.js +1 -1
  26. package/dist/cjs/components/badge.js.map +4 -4
  27. package/dist/cjs/components/blockquote.js +1 -1
  28. package/dist/cjs/components/blockquote.js.map +4 -4
  29. package/dist/cjs/components/box.js +1 -1
  30. package/dist/cjs/components/box.js.map +4 -4
  31. package/dist/cjs/components/button.js +1 -1
  32. package/dist/cjs/components/button.js.map +4 -4
  33. package/dist/cjs/components/callout.js +1 -1
  34. package/dist/cjs/components/callout.js.map +4 -4
  35. package/dist/cjs/components/card.js +1 -1
  36. package/dist/cjs/components/card.js.map +4 -4
  37. package/dist/cjs/components/chatbar.js +2 -2
  38. package/dist/cjs/components/chatbar.js.map +4 -4
  39. package/dist/cjs/components/checkbox-cards.js +1 -1
  40. package/dist/cjs/components/checkbox-cards.js.map +4 -4
  41. package/dist/cjs/components/checkbox-group.js +1 -1
  42. package/dist/cjs/components/checkbox-group.js.map +4 -4
  43. package/dist/cjs/components/checkbox.js +1 -1
  44. package/dist/cjs/components/checkbox.js.map +4 -4
  45. package/dist/cjs/components/code.js +1 -1
  46. package/dist/cjs/components/code.js.map +4 -4
  47. package/dist/cjs/components/combobox.js +1 -1
  48. package/dist/cjs/components/combobox.js.map +4 -4
  49. package/dist/cjs/components/container.js +1 -1
  50. package/dist/cjs/components/container.js.map +4 -4
  51. package/dist/cjs/components/context-menu.d.ts.map +1 -1
  52. package/dist/cjs/components/context-menu.js +1 -1
  53. package/dist/cjs/components/context-menu.js.map +4 -4
  54. package/dist/cjs/components/data-list.js +1 -1
  55. package/dist/cjs/components/data-list.js.map +4 -4
  56. package/dist/cjs/components/dialog.d.ts.map +1 -1
  57. package/dist/cjs/components/dialog.js +1 -1
  58. package/dist/cjs/components/dialog.js.map +4 -4
  59. package/dist/cjs/components/dropdown-menu.d.ts.map +1 -1
  60. package/dist/cjs/components/dropdown-menu.js +1 -1
  61. package/dist/cjs/components/dropdown-menu.js.map +4 -4
  62. package/dist/cjs/components/em.js +1 -1
  63. package/dist/cjs/components/em.js.map +4 -4
  64. package/dist/cjs/components/flex.js +1 -1
  65. package/dist/cjs/components/flex.js.map +4 -4
  66. package/dist/cjs/components/grid.js +1 -1
  67. package/dist/cjs/components/grid.js.map +4 -4
  68. package/dist/cjs/components/heading.js +1 -1
  69. package/dist/cjs/components/heading.js.map +4 -4
  70. package/dist/cjs/components/hover-card.js +1 -1
  71. package/dist/cjs/components/hover-card.js.map +4 -4
  72. package/dist/cjs/components/icon-button.js +2 -2
  73. package/dist/cjs/components/icon-button.js.map +4 -4
  74. package/dist/cjs/components/image.js +1 -1
  75. package/dist/cjs/components/image.js.map +4 -4
  76. package/dist/cjs/components/index.js +5 -5
  77. package/dist/cjs/components/index.js.map +4 -4
  78. package/dist/cjs/components/inset.js +1 -1
  79. package/dist/cjs/components/inset.js.map +4 -4
  80. package/dist/cjs/components/kbd.js +1 -1
  81. package/dist/cjs/components/kbd.js.map +4 -4
  82. package/dist/cjs/components/link.js +1 -1
  83. package/dist/cjs/components/link.js.map +4 -4
  84. package/dist/cjs/components/navbar.js +1 -1
  85. package/dist/cjs/components/navbar.js.map +4 -4
  86. package/dist/cjs/components/popover.js +1 -1
  87. package/dist/cjs/components/popover.js.map +4 -4
  88. package/dist/cjs/components/progress.js +1 -1
  89. package/dist/cjs/components/progress.js.map +4 -4
  90. package/dist/cjs/components/quote.js +1 -1
  91. package/dist/cjs/components/quote.js.map +4 -4
  92. package/dist/cjs/components/radio-cards.js +1 -1
  93. package/dist/cjs/components/radio-cards.js.map +4 -4
  94. package/dist/cjs/components/radio-group.js +1 -1
  95. package/dist/cjs/components/radio-group.js.map +4 -4
  96. package/dist/cjs/components/radio.js +1 -1
  97. package/dist/cjs/components/radio.js.map +4 -4
  98. package/dist/cjs/components/schemas/base-button.schema.d.ts +2 -2
  99. package/dist/cjs/components/schemas/button.schema.d.ts +2 -2
  100. package/dist/cjs/components/schemas/icon-button.schema.d.ts +4 -4
  101. package/dist/cjs/components/schemas/shell.schema.d.ts +2 -2
  102. package/dist/cjs/components/schemas/toggle-button.schema.d.ts +6 -6
  103. package/dist/cjs/components/schemas/toggle-icon-button.schema.d.ts +8 -8
  104. package/dist/cjs/components/scroll-area.js +1 -1
  105. package/dist/cjs/components/scroll-area.js.map +4 -4
  106. package/dist/cjs/components/section.js +1 -1
  107. package/dist/cjs/components/section.js.map +4 -4
  108. package/dist/cjs/components/segmented-control.js +1 -1
  109. package/dist/cjs/components/segmented-control.js.map +4 -4
  110. package/dist/cjs/components/select.js +1 -1
  111. package/dist/cjs/components/select.js.map +4 -4
  112. package/dist/cjs/components/separator.js +1 -1
  113. package/dist/cjs/components/separator.js.map +4 -4
  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 +4 -4
  117. package/dist/cjs/components/shell.d.ts.map +1 -1
  118. package/dist/cjs/components/shell.js +1 -1
  119. package/dist/cjs/components/shell.js.map +4 -4
  120. package/dist/cjs/components/sidebar.js +1 -1
  121. package/dist/cjs/components/sidebar.js.map +4 -4
  122. package/dist/cjs/components/skeleton.js +1 -1
  123. package/dist/cjs/components/skeleton.js.map +4 -4
  124. package/dist/cjs/components/slider.js +1 -1
  125. package/dist/cjs/components/slider.js.map +4 -4
  126. package/dist/cjs/components/spinner.js +1 -1
  127. package/dist/cjs/components/spinner.js.map +4 -4
  128. package/dist/cjs/components/strong.js +1 -1
  129. package/dist/cjs/components/strong.js.map +4 -4
  130. package/dist/cjs/components/switch.js +1 -1
  131. package/dist/cjs/components/switch.js.map +4 -4
  132. package/dist/cjs/components/tab-nav.js +1 -1
  133. package/dist/cjs/components/tab-nav.js.map +4 -4
  134. package/dist/cjs/components/table.js +1 -1
  135. package/dist/cjs/components/table.js.map +4 -4
  136. package/dist/cjs/components/tabs.js +1 -1
  137. package/dist/cjs/components/tabs.js.map +4 -4
  138. package/dist/cjs/components/text-area.js +1 -1
  139. package/dist/cjs/components/text-area.js.map +4 -4
  140. package/dist/cjs/components/text-field.js +2 -2
  141. package/dist/cjs/components/text-field.js.map +4 -4
  142. package/dist/cjs/components/text.js +1 -1
  143. package/dist/cjs/components/text.js.map +4 -4
  144. package/dist/cjs/components/theme-panel.js +3 -3
  145. package/dist/cjs/components/theme-panel.js.map +4 -4
  146. package/dist/cjs/components/theme.d.ts.map +1 -1
  147. package/dist/cjs/components/theme.js +1 -1
  148. package/dist/cjs/components/theme.js.map +4 -4
  149. package/dist/cjs/components/toggle-button.js +2 -2
  150. package/dist/cjs/components/toggle-button.js.map +4 -4
  151. package/dist/cjs/components/toggle-icon-button.js +3 -3
  152. package/dist/cjs/components/toggle-icon-button.js.map +4 -4
  153. package/dist/cjs/components/toolbar.js +1 -1
  154. package/dist/cjs/components/toolbar.js.map +4 -4
  155. package/dist/cjs/components/tooltip.js +1 -1
  156. package/dist/cjs/components/tooltip.js.map +4 -4
  157. package/dist/cjs/components/user-card.js +1 -1
  158. package/dist/cjs/components/user-card.js.map +4 -4
  159. package/dist/cjs/helpers/compile-prop-defs.d.ts +49 -0
  160. package/dist/cjs/helpers/compile-prop-defs.d.ts.map +1 -0
  161. package/dist/cjs/helpers/compile-prop-defs.js +2 -0
  162. package/dist/cjs/helpers/compile-prop-defs.js.map +7 -0
  163. package/dist/cjs/helpers/extract-props.d.ts.map +1 -1
  164. package/dist/cjs/helpers/extract-props.js +1 -1
  165. package/dist/cjs/helpers/extract-props.js.map +4 -4
  166. package/dist/cjs/helpers/get-margin-styles.d.ts.map +1 -1
  167. package/dist/cjs/helpers/get-margin-styles.js +1 -1
  168. package/dist/cjs/helpers/get-margin-styles.js.map +3 -3
  169. package/dist/cjs/helpers/get-responsive-styles.d.ts +5 -2
  170. package/dist/cjs/helpers/get-responsive-styles.d.ts.map +1 -1
  171. package/dist/cjs/helpers/get-responsive-styles.js +1 -1
  172. package/dist/cjs/helpers/get-responsive-styles.js.map +3 -3
  173. package/dist/cjs/helpers/index.js +2 -2
  174. package/dist/cjs/helpers/index.js.map +4 -4
  175. package/dist/cjs/helpers/use-deprecation-warning.d.ts +10 -0
  176. package/dist/cjs/helpers/use-deprecation-warning.d.ts.map +1 -0
  177. package/dist/cjs/helpers/use-deprecation-warning.js +2 -0
  178. package/dist/cjs/helpers/use-deprecation-warning.js.map +7 -0
  179. package/dist/cjs/hooks/index.js +2 -2
  180. package/dist/cjs/hooks/index.js.map +3 -3
  181. package/dist/cjs/hooks/use-body-pointer-events-cleanup.d.ts.map +1 -1
  182. package/dist/cjs/hooks/use-body-pointer-events-cleanup.js +1 -1
  183. package/dist/cjs/hooks/use-body-pointer-events-cleanup.js.map +3 -3
  184. package/dist/cjs/hooks/use-breakpoint.d.ts +7 -3
  185. package/dist/cjs/hooks/use-breakpoint.d.ts.map +1 -1
  186. package/dist/cjs/hooks/use-breakpoint.js +1 -1
  187. package/dist/cjs/hooks/use-breakpoint.js.map +3 -3
  188. package/dist/cjs/hooks/use-prop-synced-state.d.ts +14 -0
  189. package/dist/cjs/hooks/use-prop-synced-state.d.ts.map +1 -0
  190. package/dist/cjs/hooks/use-prop-synced-state.js +2 -0
  191. package/dist/cjs/hooks/use-prop-synced-state.js.map +7 -0
  192. package/dist/cjs/index.js +5 -5
  193. package/dist/cjs/index.js.map +4 -4
  194. package/dist/esm/{chunk-RQ2ZPMHJ.js → chunk-22HGLMPQ.js} +2 -2
  195. package/dist/esm/{chunk-WYA4IRU6.js → chunk-25WZA7ZU.js} +2 -2
  196. package/dist/esm/chunk-2UPAYDKR.js +2 -0
  197. package/dist/esm/chunk-2UPAYDKR.js.map +7 -0
  198. package/dist/esm/{chunk-XHQGMOXV.js → chunk-36ZQVP7F.js} +2 -2
  199. package/dist/esm/{chunk-K3R4AH3E.js → chunk-3MWWP4MW.js} +2 -2
  200. package/dist/esm/{chunk-HQ35PM4O.js → chunk-43A5GUSI.js} +2 -2
  201. package/dist/esm/{chunk-Z5DQ6FSA.js → chunk-4AQTUBVP.js} +2 -2
  202. package/dist/esm/{chunk-25U7DENY.js → chunk-4BBOHEF4.js} +2 -2
  203. package/dist/esm/chunk-4CKDU6FY.js +2 -0
  204. package/dist/esm/chunk-4CKDU6FY.js.map +7 -0
  205. package/dist/esm/{chunk-ZSEFZM5H.js → chunk-4IY2PR6N.js} +2 -2
  206. package/dist/esm/{chunk-QLIELX4I.js → chunk-4ME6O27S.js} +2 -2
  207. package/dist/esm/chunk-4XJY6FIK.js +2 -0
  208. package/dist/esm/chunk-4XJY6FIK.js.map +7 -0
  209. package/dist/esm/{chunk-JQOFJNCV.js → chunk-4YFJWXL2.js} +2 -2
  210. package/dist/esm/{chunk-DNI4QRXQ.js → chunk-5IBGFL6O.js} +2 -2
  211. package/dist/esm/chunk-5TXQLK4G.js +2 -0
  212. package/dist/esm/chunk-5TXQLK4G.js.map +7 -0
  213. package/dist/esm/{chunk-IPJUHVM6.js → chunk-666GX7O5.js} +2 -2
  214. package/dist/esm/chunk-6FLLFCBU.js +2 -0
  215. package/dist/esm/chunk-6FLLFCBU.js.map +7 -0
  216. package/dist/esm/{chunk-DJBPM5QK.js → chunk-7FC7HF76.js} +2 -2
  217. package/dist/esm/{chunk-SVLY6B5F.js → chunk-7QDTSBJF.js} +2 -2
  218. package/dist/esm/chunk-AX5S56DS.js +2 -0
  219. package/dist/esm/chunk-AX5S56DS.js.map +7 -0
  220. package/dist/esm/{chunk-DK5MHD6I.js → chunk-B24BDVG2.js} +2 -2
  221. package/dist/esm/{chunk-WZCZHCVE.js → chunk-BJYUPIXO.js} +2 -2
  222. package/dist/esm/{chunk-BJTJUIYJ.js → chunk-CRWYCLTE.js} +2 -2
  223. package/dist/esm/{chunk-OHJVFZMH.js → chunk-CSKZZOI2.js} +2 -2
  224. package/dist/esm/chunk-D5N627TH.js +2 -0
  225. package/dist/esm/chunk-D5N627TH.js.map +7 -0
  226. package/dist/esm/{chunk-ADYTQCZX.js → chunk-D6B7IMZU.js} +2 -2
  227. package/dist/esm/chunk-DL2O3GKG.js +2 -0
  228. package/dist/esm/chunk-DL2O3GKG.js.map +7 -0
  229. package/dist/esm/{chunk-USGTBZ43.js → chunk-E67CIG6A.js} +2 -2
  230. package/dist/esm/{chunk-42HFGCHX.js → chunk-ETMLMDW4.js} +2 -2
  231. package/dist/esm/{chunk-7CBAHIVG.js → chunk-F2HYQ3ZR.js} +2 -2
  232. package/dist/esm/{chunk-YUZPSUJE.js → chunk-F7IYL2VW.js} +2 -2
  233. package/dist/esm/{chunk-FVCWNSRU.js → chunk-FHOCUZDR.js} +2 -2
  234. package/dist/esm/{chunk-7MURQ6CR.js → chunk-FLFAXVFB.js} +2 -2
  235. package/dist/esm/{chunk-APRBRAOT.js → chunk-FOEZLQTW.js} +2 -2
  236. package/dist/esm/{chunk-WNSPLWRV.js → chunk-GJSGKE7B.js} +2 -2
  237. package/dist/esm/{chunk-OGOOZLUD.js → chunk-GLERJXVS.js} +2 -2
  238. package/dist/esm/{chunk-6VGPTAHM.js → chunk-GWXVETMF.js} +2 -2
  239. package/dist/esm/{chunk-ES7MK2MM.js → chunk-GYBLXQ4R.js} +2 -2
  240. package/dist/esm/{chunk-4OBMRJHC.js → chunk-H7ST535H.js} +2 -2
  241. package/dist/esm/{chunk-QLZ5XAW6.js → chunk-HF5WY5YE.js} +2 -2
  242. package/dist/esm/chunk-ICIGZ3N7.js +2 -0
  243. package/dist/esm/chunk-ICIGZ3N7.js.map +7 -0
  244. package/dist/esm/{chunk-RDP4UQ42.js → chunk-IEWCQU2S.js} +2 -2
  245. package/dist/esm/{chunk-XLOHPURR.js → chunk-IHK3H2OM.js} +2 -2
  246. package/dist/esm/{chunk-3F6I7YOR.js → chunk-JDGJSNWT.js} +2 -2
  247. package/dist/esm/chunk-JQQIPEGY.js +2 -0
  248. package/dist/esm/chunk-JQQIPEGY.js.map +7 -0
  249. package/dist/esm/chunk-JR2YOGII.js +2 -0
  250. package/dist/esm/chunk-JR2YOGII.js.map +7 -0
  251. package/dist/esm/chunk-JUY7CBSL.js +2 -0
  252. package/dist/esm/chunk-JUY7CBSL.js.map +7 -0
  253. package/dist/esm/{chunk-VF5TRT3H.js → chunk-KKM6T5P7.js} +2 -2
  254. package/dist/esm/{chunk-ZHYOJNWV.js → chunk-LKAK5GXF.js} +2 -2
  255. package/dist/esm/chunk-LOGJJF4I.js +2 -0
  256. package/dist/esm/chunk-LOGJJF4I.js.map +7 -0
  257. package/dist/esm/{chunk-JCYI4NTV.js → chunk-MBCBP73P.js} +2 -2
  258. package/dist/esm/{chunk-UYNYUR7O.js → chunk-MBE2YSBU.js} +2 -2
  259. package/dist/esm/chunk-MHANZINI.js +2 -0
  260. package/dist/esm/chunk-MHANZINI.js.map +7 -0
  261. package/dist/esm/chunk-MRECKC4D.js +2 -0
  262. package/dist/esm/chunk-MRECKC4D.js.map +7 -0
  263. package/dist/esm/{chunk-H2G446JG.js → chunk-NMKPFUNP.js} +2 -2
  264. package/dist/esm/{chunk-4N5JU7XQ.js → chunk-O3CDWEZA.js} +2 -2
  265. package/dist/esm/{chunk-TEULZKBM.js → chunk-OGXZHAQL.js} +2 -2
  266. package/dist/esm/{chunk-2AEELIG6.js → chunk-OWAUCLRT.js} +2 -2
  267. package/dist/esm/{chunk-7CXVHFMQ.js → chunk-P7HYVJSU.js} +2 -2
  268. package/dist/esm/{chunk-4532RT2B.js → chunk-P7IAHW4V.js} +2 -2
  269. package/dist/esm/{chunk-M3ZYJANH.js → chunk-PQZXQ4ST.js} +2 -2
  270. package/dist/esm/{chunk-SGU4HUHF.js → chunk-PTLFMWCN.js} +2 -2
  271. package/dist/esm/chunk-S2HA3W3V.js +2 -0
  272. package/dist/esm/chunk-S2HA3W3V.js.map +7 -0
  273. package/dist/esm/{chunk-E6IWYD3U.js → chunk-S5C5YRBS.js} +2 -2
  274. package/dist/esm/{chunk-A24PYRVV.js → chunk-SO67YEVQ.js} +2 -2
  275. package/dist/esm/chunk-TLWTUKKL.js +2 -0
  276. package/dist/esm/chunk-TLWTUKKL.js.map +7 -0
  277. package/dist/esm/{chunk-HACQF6F4.js → chunk-TOOSHJOA.js} +2 -2
  278. package/dist/esm/{chunk-QOWA5LK5.js → chunk-U2X2CAW4.js} +2 -2
  279. package/dist/esm/{chunk-U7AASKZI.js → chunk-UVCH7QKO.js} +2 -2
  280. package/dist/esm/{chunk-GWYFT3EI.js → chunk-VLO7NXSP.js} +2 -2
  281. package/dist/esm/{chunk-DXI5P5O4.js → chunk-VX6ARMWP.js} +2 -2
  282. package/dist/esm/chunk-WAURCNAS.js +2 -0
  283. package/dist/esm/chunk-WAURCNAS.js.map +7 -0
  284. package/dist/esm/{chunk-EJWAAFCI.js → chunk-WO43WW3A.js} +2 -2
  285. package/dist/esm/{chunk-GLC4QJBF.js → chunk-WTYNFBFV.js} +2 -2
  286. package/dist/esm/{chunk-6FAICIYS.js → chunk-XMRIRFM7.js} +2 -2
  287. package/dist/esm/chunk-YV2KYHGR.js +2 -0
  288. package/dist/esm/chunk-YV2KYHGR.js.map +7 -0
  289. package/dist/esm/{chunk-UIEUZLZZ.js → chunk-ZY6SQWHT.js} +2 -2
  290. package/dist/esm/components/_internal/base-button.d.ts.map +1 -1
  291. package/dist/esm/components/_internal/base-button.js +1 -1
  292. package/dist/esm/components/_internal/dropdown-menu-drill-down.js +1 -1
  293. package/dist/esm/components/_internal/shell-bottom.js +1 -1
  294. package/dist/esm/components/_internal/shell-handles.d.ts.map +1 -1
  295. package/dist/esm/components/_internal/shell-handles.js +1 -1
  296. package/dist/esm/components/_internal/shell-inspector.js +1 -1
  297. package/dist/esm/components/_internal/shell-sidebar.js +1 -1
  298. package/dist/esm/components/accordion.d.ts.map +1 -1
  299. package/dist/esm/components/accordion.js +1 -1
  300. package/dist/esm/components/alert-dialog.d.ts.map +1 -1
  301. package/dist/esm/components/alert-dialog.js +1 -1
  302. package/dist/esm/components/avatar.js +1 -1
  303. package/dist/esm/components/badge.d.ts.map +1 -1
  304. package/dist/esm/components/badge.js +1 -1
  305. package/dist/esm/components/blockquote.js +1 -1
  306. package/dist/esm/components/box.js +1 -1
  307. package/dist/esm/components/button.js +1 -1
  308. package/dist/esm/components/callout.js +1 -1
  309. package/dist/esm/components/card.js +1 -1
  310. package/dist/esm/components/chatbar.js +1 -1
  311. package/dist/esm/components/checkbox-cards.js +1 -1
  312. package/dist/esm/components/checkbox-group.js +1 -1
  313. package/dist/esm/components/checkbox.js +1 -1
  314. package/dist/esm/components/code.js +1 -1
  315. package/dist/esm/components/combobox.js +1 -1
  316. package/dist/esm/components/container.js +1 -1
  317. package/dist/esm/components/context-menu.d.ts.map +1 -1
  318. package/dist/esm/components/context-menu.js +1 -1
  319. package/dist/esm/components/data-list.js +1 -1
  320. package/dist/esm/components/dialog.d.ts.map +1 -1
  321. package/dist/esm/components/dialog.js +1 -1
  322. package/dist/esm/components/dropdown-menu.d.ts.map +1 -1
  323. package/dist/esm/components/dropdown-menu.js +1 -1
  324. package/dist/esm/components/em.js +1 -1
  325. package/dist/esm/components/flex.js +1 -1
  326. package/dist/esm/components/grid.js +1 -1
  327. package/dist/esm/components/heading.js +1 -1
  328. package/dist/esm/components/hover-card.js +1 -1
  329. package/dist/esm/components/icon-button.js +1 -1
  330. package/dist/esm/components/image.js +1 -1
  331. package/dist/esm/components/index.js +1 -1
  332. package/dist/esm/components/inset.js +1 -1
  333. package/dist/esm/components/kbd.js +1 -1
  334. package/dist/esm/components/link.js +1 -1
  335. package/dist/esm/components/navbar.js +1 -1
  336. package/dist/esm/components/popover.js +1 -1
  337. package/dist/esm/components/progress.js +1 -1
  338. package/dist/esm/components/quote.js +1 -1
  339. package/dist/esm/components/radio-cards.js +1 -1
  340. package/dist/esm/components/radio-group.js +1 -1
  341. package/dist/esm/components/radio.js +1 -1
  342. package/dist/esm/components/schemas/base-button.schema.d.ts +2 -2
  343. package/dist/esm/components/schemas/button.schema.d.ts +2 -2
  344. package/dist/esm/components/schemas/icon-button.schema.d.ts +4 -4
  345. package/dist/esm/components/schemas/shell.schema.d.ts +2 -2
  346. package/dist/esm/components/schemas/toggle-button.schema.d.ts +6 -6
  347. package/dist/esm/components/schemas/toggle-icon-button.schema.d.ts +8 -8
  348. package/dist/esm/components/scroll-area.js +1 -1
  349. package/dist/esm/components/section.js +1 -1
  350. package/dist/esm/components/segmented-control.js +1 -1
  351. package/dist/esm/components/select.js +1 -1
  352. package/dist/esm/components/separator.js +1 -1
  353. package/dist/esm/components/sheet.d.ts.map +1 -1
  354. package/dist/esm/components/sheet.js +1 -1
  355. package/dist/esm/components/shell.d.ts.map +1 -1
  356. package/dist/esm/components/shell.js +1 -1
  357. package/dist/esm/components/sidebar.js +1 -1
  358. package/dist/esm/components/skeleton.js +1 -1
  359. package/dist/esm/components/slider.js +1 -1
  360. package/dist/esm/components/spinner.js +1 -1
  361. package/dist/esm/components/strong.js +1 -1
  362. package/dist/esm/components/switch.js +1 -1
  363. package/dist/esm/components/tab-nav.js +1 -1
  364. package/dist/esm/components/table.js +1 -1
  365. package/dist/esm/components/tabs.js +1 -1
  366. package/dist/esm/components/text-area.js +1 -1
  367. package/dist/esm/components/text-field.js +1 -1
  368. package/dist/esm/components/text.js +1 -1
  369. package/dist/esm/components/theme-panel.js +1 -1
  370. package/dist/esm/components/theme.d.ts.map +1 -1
  371. package/dist/esm/components/theme.js +1 -1
  372. package/dist/esm/components/toggle-button.js +1 -1
  373. package/dist/esm/components/toggle-icon-button.js +1 -1
  374. package/dist/esm/components/toolbar.js +1 -1
  375. package/dist/esm/components/tooltip.js +1 -1
  376. package/dist/esm/components/user-card.js +1 -1
  377. package/dist/esm/helpers/compile-prop-defs.d.ts +49 -0
  378. package/dist/esm/helpers/compile-prop-defs.d.ts.map +1 -0
  379. package/dist/esm/helpers/compile-prop-defs.js +2 -0
  380. package/dist/esm/helpers/compile-prop-defs.js.map +7 -0
  381. package/dist/esm/helpers/extract-props.d.ts.map +1 -1
  382. package/dist/esm/helpers/extract-props.js +1 -1
  383. package/dist/esm/helpers/get-margin-styles.d.ts.map +1 -1
  384. package/dist/esm/helpers/get-margin-styles.js +1 -1
  385. package/dist/esm/helpers/get-responsive-styles.d.ts +5 -2
  386. package/dist/esm/helpers/get-responsive-styles.d.ts.map +1 -1
  387. package/dist/esm/helpers/get-responsive-styles.js +1 -1
  388. package/dist/esm/helpers/index.js +1 -1
  389. package/dist/esm/helpers/use-deprecation-warning.d.ts +10 -0
  390. package/dist/esm/helpers/use-deprecation-warning.d.ts.map +1 -0
  391. package/dist/esm/helpers/use-deprecation-warning.js +2 -0
  392. package/dist/esm/helpers/use-deprecation-warning.js.map +7 -0
  393. package/dist/esm/hooks/index.js +1 -1
  394. package/dist/esm/hooks/use-body-pointer-events-cleanup.d.ts.map +1 -1
  395. package/dist/esm/hooks/use-body-pointer-events-cleanup.js +1 -1
  396. package/dist/esm/hooks/use-breakpoint.d.ts +7 -3
  397. package/dist/esm/hooks/use-breakpoint.d.ts.map +1 -1
  398. package/dist/esm/hooks/use-breakpoint.js +1 -1
  399. package/dist/esm/hooks/use-prop-synced-state.d.ts +14 -0
  400. package/dist/esm/hooks/use-prop-synced-state.d.ts.map +1 -0
  401. package/dist/esm/hooks/use-prop-synced-state.js +2 -0
  402. package/dist/esm/hooks/use-prop-synced-state.js.map +7 -0
  403. package/dist/esm/index.js +1 -1
  404. package/package.json +2 -1
  405. package/schemas/base-button.json +0 -1
  406. package/schemas/button.json +0 -1
  407. package/schemas/icon-button.json +0 -1
  408. package/schemas/index.json +0 -6
  409. package/schemas/toggle-button.json +0 -1
  410. package/schemas/toggle-icon-button.json +0 -1
  411. package/src/components/_internal/base-button.css +2 -2
  412. package/src/components/_internal/base-button.tsx +3 -58
  413. package/src/components/_internal/base-card.css +19 -4
  414. package/src/components/_internal/base-checkbox.css +2 -2
  415. package/src/components/_internal/base-dialog.css +7 -13
  416. package/src/components/_internal/base-menu.css +7 -0
  417. package/src/components/_internal/base-radio.css +2 -2
  418. package/src/components/_internal/base-sidebar.css +7 -0
  419. package/src/components/_internal/base-tab-list.css +2 -2
  420. package/src/components/_internal/shell-handles.tsx +27 -0
  421. package/src/components/accordion.css +6 -6
  422. package/src/components/accordion.tsx +2 -8
  423. package/src/components/alert-dialog.tsx +22 -20
  424. package/src/components/avatar.css +2 -2
  425. package/src/components/badge.css +2 -2
  426. package/src/components/badge.tsx +2 -8
  427. package/src/components/callout.css +2 -2
  428. package/src/components/chatbar.css +1 -1
  429. package/src/components/context-menu.tsx +2 -8
  430. package/src/components/dialog.tsx +46 -72
  431. package/src/components/dropdown-menu.tsx +2 -8
  432. package/src/components/popover.css +7 -0
  433. package/src/components/progress.css +21 -8
  434. package/src/components/segmented-control.css +2 -2
  435. package/src/components/select.css +9 -2
  436. package/src/components/sheet.tsx +31 -28
  437. package/src/components/shell.css +106 -69
  438. package/src/components/shell.tsx +168 -97
  439. package/src/components/slider.css +2 -2
  440. package/src/components/switch.css +2 -2
  441. package/src/components/table.css +7 -0
  442. package/src/components/text-area.css +2 -2
  443. package/src/components/text-field.css +2 -2
  444. package/src/components/theme.tsx +35 -34
  445. package/src/helpers/compile-prop-defs.ts +121 -0
  446. package/src/helpers/extract-props.ts +104 -83
  447. package/src/helpers/get-margin-styles.ts +38 -71
  448. package/src/helpers/get-responsive-styles.ts +37 -38
  449. package/src/helpers/use-deprecation-warning.ts +26 -0
  450. package/src/hooks/use-body-pointer-events-cleanup.ts +36 -6
  451. package/src/hooks/use-breakpoint.ts +94 -53
  452. package/src/hooks/use-prop-synced-state.ts +24 -0
  453. package/src/styles/tokens/blur.css +28 -0
  454. package/src/styles/tokens/color.css +3 -3
  455. package/src/styles/tokens/constants.css +11 -0
  456. package/styles.css +280 -332
  457. package/tokens/base.css +13 -3
  458. package/tokens.css +16 -3
  459. package/dist/esm/chunk-2SS3FA3N.js +0 -2
  460. package/dist/esm/chunk-2SS3FA3N.js.map +0 -7
  461. package/dist/esm/chunk-5U2Q23K3.js +0 -2
  462. package/dist/esm/chunk-5U2Q23K3.js.map +0 -7
  463. package/dist/esm/chunk-6ELPYR73.js +0 -2
  464. package/dist/esm/chunk-6ELPYR73.js.map +0 -7
  465. package/dist/esm/chunk-DZ4H2KTP.js +0 -2
  466. package/dist/esm/chunk-DZ4H2KTP.js.map +0 -7
  467. package/dist/esm/chunk-H4MMVAGQ.js +0 -2
  468. package/dist/esm/chunk-H4MMVAGQ.js.map +0 -7
  469. package/dist/esm/chunk-HURTSXRY.js +0 -2
  470. package/dist/esm/chunk-HURTSXRY.js.map +0 -7
  471. package/dist/esm/chunk-ITRVKLYU.js +0 -2
  472. package/dist/esm/chunk-ITRVKLYU.js.map +0 -7
  473. package/dist/esm/chunk-KCAFSCOV.js +0 -2
  474. package/dist/esm/chunk-KCAFSCOV.js.map +0 -7
  475. package/dist/esm/chunk-KMPBTEZH.js +0 -2
  476. package/dist/esm/chunk-KMPBTEZH.js.map +0 -7
  477. package/dist/esm/chunk-LN5SP46K.js +0 -2
  478. package/dist/esm/chunk-LN5SP46K.js.map +0 -7
  479. package/dist/esm/chunk-Q73Y5O5P.js +0 -2
  480. package/dist/esm/chunk-Q73Y5O5P.js.map +0 -7
  481. package/dist/esm/chunk-RMBS6CAO.js +0 -2
  482. package/dist/esm/chunk-RMBS6CAO.js.map +0 -7
  483. package/dist/esm/chunk-UUX42HBM.js +0 -2
  484. package/dist/esm/chunk-UUX42HBM.js.map +0 -7
  485. package/dist/esm/chunk-X7BD5FLE.js +0 -2
  486. package/dist/esm/chunk-X7BD5FLE.js.map +0 -7
  487. package/dist/esm/chunk-YEA646GM.js +0 -2
  488. package/dist/esm/chunk-YEA646GM.js.map +0 -7
  489. package/dist/esm/chunk-ZMEXIPWM.js +0 -2
  490. package/dist/esm/chunk-ZMEXIPWM.js.map +0 -7
  491. /package/dist/esm/{chunk-RQ2ZPMHJ.js.map → chunk-22HGLMPQ.js.map} +0 -0
  492. /package/dist/esm/{chunk-WYA4IRU6.js.map → chunk-25WZA7ZU.js.map} +0 -0
  493. /package/dist/esm/{chunk-XHQGMOXV.js.map → chunk-36ZQVP7F.js.map} +0 -0
  494. /package/dist/esm/{chunk-K3R4AH3E.js.map → chunk-3MWWP4MW.js.map} +0 -0
  495. /package/dist/esm/{chunk-HQ35PM4O.js.map → chunk-43A5GUSI.js.map} +0 -0
  496. /package/dist/esm/{chunk-Z5DQ6FSA.js.map → chunk-4AQTUBVP.js.map} +0 -0
  497. /package/dist/esm/{chunk-25U7DENY.js.map → chunk-4BBOHEF4.js.map} +0 -0
  498. /package/dist/esm/{chunk-ZSEFZM5H.js.map → chunk-4IY2PR6N.js.map} +0 -0
  499. /package/dist/esm/{chunk-QLIELX4I.js.map → chunk-4ME6O27S.js.map} +0 -0
  500. /package/dist/esm/{chunk-JQOFJNCV.js.map → chunk-4YFJWXL2.js.map} +0 -0
  501. /package/dist/esm/{chunk-DNI4QRXQ.js.map → chunk-5IBGFL6O.js.map} +0 -0
  502. /package/dist/esm/{chunk-IPJUHVM6.js.map → chunk-666GX7O5.js.map} +0 -0
  503. /package/dist/esm/{chunk-DJBPM5QK.js.map → chunk-7FC7HF76.js.map} +0 -0
  504. /package/dist/esm/{chunk-SVLY6B5F.js.map → chunk-7QDTSBJF.js.map} +0 -0
  505. /package/dist/esm/{chunk-DK5MHD6I.js.map → chunk-B24BDVG2.js.map} +0 -0
  506. /package/dist/esm/{chunk-WZCZHCVE.js.map → chunk-BJYUPIXO.js.map} +0 -0
  507. /package/dist/esm/{chunk-BJTJUIYJ.js.map → chunk-CRWYCLTE.js.map} +0 -0
  508. /package/dist/esm/{chunk-OHJVFZMH.js.map → chunk-CSKZZOI2.js.map} +0 -0
  509. /package/dist/esm/{chunk-ADYTQCZX.js.map → chunk-D6B7IMZU.js.map} +0 -0
  510. /package/dist/esm/{chunk-USGTBZ43.js.map → chunk-E67CIG6A.js.map} +0 -0
  511. /package/dist/esm/{chunk-42HFGCHX.js.map → chunk-ETMLMDW4.js.map} +0 -0
  512. /package/dist/esm/{chunk-7CBAHIVG.js.map → chunk-F2HYQ3ZR.js.map} +0 -0
  513. /package/dist/esm/{chunk-YUZPSUJE.js.map → chunk-F7IYL2VW.js.map} +0 -0
  514. /package/dist/esm/{chunk-FVCWNSRU.js.map → chunk-FHOCUZDR.js.map} +0 -0
  515. /package/dist/esm/{chunk-7MURQ6CR.js.map → chunk-FLFAXVFB.js.map} +0 -0
  516. /package/dist/esm/{chunk-APRBRAOT.js.map → chunk-FOEZLQTW.js.map} +0 -0
  517. /package/dist/esm/{chunk-WNSPLWRV.js.map → chunk-GJSGKE7B.js.map} +0 -0
  518. /package/dist/esm/{chunk-OGOOZLUD.js.map → chunk-GLERJXVS.js.map} +0 -0
  519. /package/dist/esm/{chunk-6VGPTAHM.js.map → chunk-GWXVETMF.js.map} +0 -0
  520. /package/dist/esm/{chunk-ES7MK2MM.js.map → chunk-GYBLXQ4R.js.map} +0 -0
  521. /package/dist/esm/{chunk-4OBMRJHC.js.map → chunk-H7ST535H.js.map} +0 -0
  522. /package/dist/esm/{chunk-QLZ5XAW6.js.map → chunk-HF5WY5YE.js.map} +0 -0
  523. /package/dist/esm/{chunk-RDP4UQ42.js.map → chunk-IEWCQU2S.js.map} +0 -0
  524. /package/dist/esm/{chunk-XLOHPURR.js.map → chunk-IHK3H2OM.js.map} +0 -0
  525. /package/dist/esm/{chunk-3F6I7YOR.js.map → chunk-JDGJSNWT.js.map} +0 -0
  526. /package/dist/esm/{chunk-VF5TRT3H.js.map → chunk-KKM6T5P7.js.map} +0 -0
  527. /package/dist/esm/{chunk-ZHYOJNWV.js.map → chunk-LKAK5GXF.js.map} +0 -0
  528. /package/dist/esm/{chunk-JCYI4NTV.js.map → chunk-MBCBP73P.js.map} +0 -0
  529. /package/dist/esm/{chunk-UYNYUR7O.js.map → chunk-MBE2YSBU.js.map} +0 -0
  530. /package/dist/esm/{chunk-H2G446JG.js.map → chunk-NMKPFUNP.js.map} +0 -0
  531. /package/dist/esm/{chunk-4N5JU7XQ.js.map → chunk-O3CDWEZA.js.map} +0 -0
  532. /package/dist/esm/{chunk-TEULZKBM.js.map → chunk-OGXZHAQL.js.map} +0 -0
  533. /package/dist/esm/{chunk-2AEELIG6.js.map → chunk-OWAUCLRT.js.map} +0 -0
  534. /package/dist/esm/{chunk-7CXVHFMQ.js.map → chunk-P7HYVJSU.js.map} +0 -0
  535. /package/dist/esm/{chunk-4532RT2B.js.map → chunk-P7IAHW4V.js.map} +0 -0
  536. /package/dist/esm/{chunk-M3ZYJANH.js.map → chunk-PQZXQ4ST.js.map} +0 -0
  537. /package/dist/esm/{chunk-SGU4HUHF.js.map → chunk-PTLFMWCN.js.map} +0 -0
  538. /package/dist/esm/{chunk-E6IWYD3U.js.map → chunk-S5C5YRBS.js.map} +0 -0
  539. /package/dist/esm/{chunk-A24PYRVV.js.map → chunk-SO67YEVQ.js.map} +0 -0
  540. /package/dist/esm/{chunk-HACQF6F4.js.map → chunk-TOOSHJOA.js.map} +0 -0
  541. /package/dist/esm/{chunk-QOWA5LK5.js.map → chunk-U2X2CAW4.js.map} +0 -0
  542. /package/dist/esm/{chunk-U7AASKZI.js.map → chunk-UVCH7QKO.js.map} +0 -0
  543. /package/dist/esm/{chunk-GWYFT3EI.js.map → chunk-VLO7NXSP.js.map} +0 -0
  544. /package/dist/esm/{chunk-DXI5P5O4.js.map → chunk-VX6ARMWP.js.map} +0 -0
  545. /package/dist/esm/{chunk-EJWAAFCI.js.map → chunk-WO43WW3A.js.map} +0 -0
  546. /package/dist/esm/{chunk-GLC4QJBF.js.map → chunk-WTYNFBFV.js.map} +0 -0
  547. /package/dist/esm/{chunk-6FAICIYS.js.map → chunk-XMRIRFM7.js.map} +0 -0
  548. /package/dist/esm/{chunk-UIEUZLZZ.js.map → chunk-ZY6SQWHT.js.map} +0 -0
@@ -36,6 +36,7 @@ import { omitPaneProps, extractPaneDomProps, mapResponsiveBooleanToPaneMode } fr
36
36
  import { Sidebar } from './_internal/shell-sidebar.js';
37
37
  import { Bottom } from './_internal/shell-bottom.js';
38
38
  import { Inspector } from './_internal/shell-inspector.js';
39
+ import { _BREAKPOINTS } from './shell.types.js';
39
40
  import type { PresentationValue, ResponsivePresentation, PaneMode, SidebarMode, PaneSizePersistence, Breakpoint, PaneTarget, Responsive, PaneBaseProps, CSSPropertiesWithVars } from './shell.types.js';
40
41
  import { normalizeToPx } from '../helpers/normalize-to-px.js';
41
42
  import { useBreakpoint } from '../hooks/use-breakpoint.js';
@@ -222,114 +223,143 @@ interface ShellRootProps extends React.ComponentPropsWithoutRef<'div'> {
222
223
  height?: 'full' | 'auto' | string | number;
223
224
  }
224
225
 
225
- const Root = React.forwardRef<HTMLDivElement, ShellRootProps>(({ className, children, height = 'full', ...props }, ref) => {
226
- const { breakpoint: currentBreakpoint, ready: currentBreakpointReady } = useBreakpoint();
227
-
228
- // Store hasPanelDefaultOpen for use in passthrough props (computed once during lazy init)
229
- const hasPanelDefaultOpenRef = React.useRef<boolean>(false);
226
+ /**
227
+ * Read the pane modes a set of Shell children asks for.
228
+ *
229
+ * Runs once at mount, for the reducer's initial state, and again whenever a
230
+ * pane family enters after mount. Pure - it only reads the children's props.
231
+ */
232
+ /**
233
+ * Pick the entry of a responsive map that applies at `breakpoint`, falling
234
+ * back down the scale the way useResponsiveValue does. With no breakpoint it
235
+ * takes `initial`, which is what the mount path has always done.
236
+ */
237
+ function pickResponsive<T>(map: Partial<Record<Breakpoint, T>>, breakpoint?: Breakpoint): T | undefined {
238
+ if (breakpoint === undefined) return (map.initial ?? Object.values(map)[0]) as T | undefined;
239
+ if (map[breakpoint] !== undefined) return map[breakpoint];
240
+
241
+ const bpKeys = Object.keys(_BREAKPOINTS) as Array<keyof typeof _BREAKPOINTS>;
242
+ const order: Breakpoint[] = ([...bpKeys].reverse() as Breakpoint[]).concat('initial' as Breakpoint);
243
+ for (let i = order.indexOf(breakpoint) + 1; i < order.length; i++) {
244
+ if (map[order[i]] !== undefined) return map[order[i]];
245
+ }
246
+ return undefined;
247
+ }
230
248
 
231
- // Pane state management via reducer with lazy initialization
232
- // This computation only runs once on mount, not on every render
233
- const [paneState, dispatchPane] = React.useReducer(paneReducer, children, (initialChildren) => {
234
- const childArray = React.Children.toArray(initialChildren) as React.ReactElement[];
249
+ function readPaneStateFromChildren(initialChildren: React.ReactNode, breakpoint?: Breakpoint): PaneState & { hasPanelDefaultOpen: boolean } {
250
+ const childArray = React.Children.toArray(initialChildren) as React.ReactElement[];
235
251
 
236
- // Compute initial defaults from immediate children (one-time, uncontrolled defaults)
237
- const hasPanelDefaultOpen = childArray.some(
238
- (el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Panel' && Boolean((el as any).props?.defaultOpen),
239
- );
240
- // Store for use in passthrough props
241
- hasPanelDefaultOpenRef.current = hasPanelDefaultOpen;
252
+ // Compute initial defaults from immediate children (one-time, uncontrolled defaults)
253
+ const hasPanelDefaultOpen = childArray.some(
254
+ (el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Panel' && Boolean((el as any).props?.defaultOpen),
255
+ );
242
256
 
243
- // Rail defaults to open (true) unless explicitly set to false
244
- // Supports responsive objects: { initial: false, md: true }
245
- const railEl = childArray.find((el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Rail');
246
- const railDefaultOpen = railEl ? (railEl as any).props?.defaultOpen : undefined;
247
- const hasRailDefaultOpen = (() => {
248
- if (!railEl) return false;
249
- if (railDefaultOpen === undefined) return true; // Default to open
250
- if (typeof railDefaultOpen === 'boolean') return railDefaultOpen;
251
- // Responsive object - use 'initial' value, or first defined value, or default true
252
- if (typeof railDefaultOpen === 'object') {
253
- return railDefaultOpen.initial ?? Object.values(railDefaultOpen)[0] ?? true;
254
- }
255
- return true;
256
- })();
257
+ // Rail defaults to open (true) unless explicitly set to false
258
+ // Supports responsive objects: { initial: false, md: true }
259
+ const railEl = childArray.find((el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Rail');
260
+ const railDefaultOpen = railEl ? (railEl as any).props?.defaultOpen : undefined;
261
+ const hasRailDefaultOpen = (() => {
262
+ if (!railEl) return false;
263
+ if (railDefaultOpen === undefined) return true; // Default to open
264
+ if (typeof railDefaultOpen === 'boolean') return railDefaultOpen;
265
+ // Responsive object - use 'initial' value, or first defined value, or default true
266
+ if (typeof railDefaultOpen === 'object') {
267
+ return railDefaultOpen.initial ?? Object.values(railDefaultOpen)[0] ?? true;
268
+ }
269
+ return true;
270
+ })();
257
271
 
258
- const hasInspectorDefaultOpen = childArray.some(
259
- (el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Inspector' && Boolean((el as any).props?.defaultOpen),
260
- );
261
- const hasInspectorOpenControlled = childArray.some(
262
- (el) =>
263
- React.isValidElement(el) &&
264
- (el as any).type?.displayName === 'Shell.Inspector' &&
265
- typeof (el as any).props?.open !== 'undefined' &&
266
- Boolean((el as any).props?.open),
267
- );
272
+ const hasInspectorDefaultOpen = childArray.some(
273
+ (el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Inspector' && Boolean((el as any).props?.defaultOpen),
274
+ );
275
+ const hasInspectorOpenControlled = childArray.some(
276
+ (el) =>
277
+ React.isValidElement(el) &&
278
+ (el as any).type?.displayName === 'Shell.Inspector' &&
279
+ typeof (el as any).props?.open !== 'undefined' &&
280
+ Boolean((el as any).props?.open),
281
+ );
268
282
 
269
- // Detect Panel controlled open state for initial reducer state
270
- const hasPanelOpenControlled = childArray.some((el) => {
271
- if (!React.isValidElement(el) || (el as any).type?.displayName !== 'Shell.Panel') return false;
272
- const openProp = (el as any).props?.open;
273
- if (typeof openProp === 'undefined') return false;
274
- if (typeof openProp === 'boolean') return openProp;
275
- // Responsive object - check 'initial' or first truthy value
276
- if (typeof openProp === 'object' && openProp !== null) {
277
- return openProp.initial ?? Object.values(openProp)[0] ?? false;
278
- }
279
- return false;
280
- });
283
+ // Detect Panel controlled open state for initial reducer state
284
+ const hasPanelOpenControlled = childArray.some((el) => {
285
+ if (!React.isValidElement(el) || (el as any).type?.displayName !== 'Shell.Panel') return false;
286
+ const openProp = (el as any).props?.open;
287
+ if (typeof openProp === 'undefined') return false;
288
+ if (typeof openProp === 'boolean') return openProp;
289
+ // Responsive object - check 'initial' or first truthy value
290
+ if (typeof openProp === 'object' && openProp !== null) {
291
+ return openProp.initial ?? Object.values(openProp)[0] ?? false;
292
+ }
293
+ return false;
294
+ });
281
295
 
282
- // Detect Sidebar initial state from props
283
- const getSidebarInitialState = (): SidebarMode => {
284
- const sidebarEl = childArray.find((el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Sidebar');
285
- if (!sidebarEl) return 'expanded';
286
- const sidebarProps = (sidebarEl as any).props;
287
- // Check controlled state first
288
- if (typeof sidebarProps?.state !== 'undefined') {
289
- if (typeof sidebarProps.state === 'string') return sidebarProps.state as SidebarMode;
290
- // Responsive object - use 'initial' breakpoint or first defined value
291
- if (typeof sidebarProps.state === 'object') {
292
- return (sidebarProps.state.initial ?? Object.values(sidebarProps.state)[0] ?? 'expanded') as SidebarMode;
293
- }
296
+ // Detect Sidebar initial state from props
297
+ const getSidebarInitialState = (): SidebarMode => {
298
+ const sidebarEl = childArray.find((el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Sidebar');
299
+ if (!sidebarEl) return 'expanded';
300
+ const sidebarProps = (sidebarEl as any).props;
301
+ // Check controlled state first
302
+ if (typeof sidebarProps?.state !== 'undefined') {
303
+ if (typeof sidebarProps.state === 'string') return sidebarProps.state as SidebarMode;
304
+ // Responsive object - use 'initial' breakpoint or first defined value
305
+ if (typeof sidebarProps.state === 'object') {
306
+ return (pickResponsive<SidebarMode>(sidebarProps.state, breakpoint) ?? 'expanded') as SidebarMode;
294
307
  }
295
- // Check defaultState
296
- if (typeof sidebarProps?.defaultState !== 'undefined') {
297
- if (typeof sidebarProps.defaultState === 'string') return sidebarProps.defaultState as SidebarMode;
298
- if (typeof sidebarProps.defaultState === 'object') {
299
- return (sidebarProps.defaultState.initial ?? Object.values(sidebarProps.defaultState)[0] ?? 'expanded') as SidebarMode;
300
- }
308
+ }
309
+ // Check defaultState
310
+ if (typeof sidebarProps?.defaultState !== 'undefined') {
311
+ if (typeof sidebarProps.defaultState === 'string') return sidebarProps.defaultState as SidebarMode;
312
+ if (typeof sidebarProps.defaultState === 'object') {
313
+ return (pickResponsive<SidebarMode>(sidebarProps.defaultState, breakpoint) ?? 'expanded') as SidebarMode;
301
314
  }
302
- return 'expanded';
303
- };
315
+ }
316
+ return 'expanded';
317
+ };
304
318
 
305
- // Detect Bottom initial state from props
306
- const getBottomInitialState = (): PaneMode => {
307
- const bottomEl = childArray.find((el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Bottom');
308
- if (!bottomEl) return 'collapsed';
309
- const bottomProps = (bottomEl as any).props;
310
- // Check controlled open first
311
- if (typeof bottomProps?.open !== 'undefined') {
312
- if (typeof bottomProps.open === 'boolean') return bottomProps.open ? 'expanded' : 'collapsed';
313
- // Responsive object - use 'initial' breakpoint or first defined value
314
- if (typeof bottomProps.open === 'object') {
315
- const val = bottomProps.open.initial ?? Object.values(bottomProps.open)[0];
316
- return val ? 'expanded' : 'collapsed';
317
- }
319
+ // Detect Bottom initial state from props
320
+ const getBottomInitialState = (): PaneMode => {
321
+ const bottomEl = childArray.find((el) => React.isValidElement(el) && (el as any).type?.displayName === 'Shell.Bottom');
322
+ if (!bottomEl) return 'collapsed';
323
+ const bottomProps = (bottomEl as any).props;
324
+ // Check controlled open first
325
+ if (typeof bottomProps?.open !== 'undefined') {
326
+ if (typeof bottomProps.open === 'boolean') return bottomProps.open ? 'expanded' : 'collapsed';
327
+ // Responsive object - use 'initial' breakpoint or first defined value
328
+ if (typeof bottomProps.open === 'object') {
329
+ const val = bottomProps.open.initial ?? Object.values(bottomProps.open)[0];
330
+ return val ? 'expanded' : 'collapsed';
318
331
  }
319
- // Check defaultOpen
320
- if (typeof bottomProps?.defaultOpen !== 'undefined') {
321
- return bottomProps.defaultOpen ? 'expanded' : 'collapsed';
322
- }
323
- return 'collapsed';
324
- };
332
+ }
333
+ // Check defaultOpen
334
+ if (typeof bottomProps?.defaultOpen !== 'undefined') {
335
+ return bottomProps.defaultOpen ? 'expanded' : 'collapsed';
336
+ }
337
+ return 'collapsed';
338
+ };
325
339
 
326
- return {
327
- leftMode: hasPanelDefaultOpen || hasPanelOpenControlled || hasRailDefaultOpen ? 'expanded' : ('collapsed' as PaneMode),
328
- panelMode: hasPanelDefaultOpen || hasPanelOpenControlled ? 'expanded' : ('collapsed' as PaneMode),
329
- sidebarMode: getSidebarInitialState(),
330
- inspectorMode: hasInspectorDefaultOpen || hasInspectorOpenControlled ? 'expanded' : ('collapsed' as PaneMode),
331
- bottomMode: getBottomInitialState(),
332
- };
340
+ return {
341
+ hasPanelDefaultOpen,
342
+ leftMode: hasPanelDefaultOpen || hasPanelOpenControlled || hasRailDefaultOpen ? 'expanded' : ('collapsed' as PaneMode),
343
+ panelMode: hasPanelDefaultOpen || hasPanelOpenControlled ? 'expanded' : ('collapsed' as PaneMode),
344
+ sidebarMode: getSidebarInitialState(),
345
+ inspectorMode: hasInspectorDefaultOpen || hasInspectorOpenControlled ? 'expanded' : ('collapsed' as PaneMode),
346
+ bottomMode: getBottomInitialState(),
347
+ };
348
+ }
349
+
350
+ const Root = React.forwardRef<HTMLDivElement, ShellRootProps>(({ className, children, height = 'full', ...props }, ref) => {
351
+ const { breakpoint: currentBreakpoint, ready: currentBreakpointReady } = useBreakpoint();
352
+
353
+ // Store hasPanelDefaultOpen for use in passthrough props (computed once during lazy init)
354
+ const hasPanelDefaultOpenRef = React.useRef<boolean>(false);
355
+
356
+ // Pane state management via reducer with lazy initialization
357
+ // This computation only runs once on mount, not on every render
358
+ const [paneState, dispatchPane] = React.useReducer(paneReducer, children, (initialChildren) => {
359
+ const { hasPanelDefaultOpen, ...modes } = readPaneStateFromChildren(initialChildren);
360
+ // Store for use in passthrough props
361
+ hasPanelDefaultOpenRef.current = hasPanelDefaultOpen;
362
+ return modes;
333
363
  });
334
364
  const setLeftMode = React.useCallback((mode: PaneMode) => dispatchPane({ type: 'SET_LEFT_MODE', mode }), []);
335
365
  const setPanelMode = React.useCallback((mode: PaneMode) => dispatchPane({ type: 'SET_PANEL_MODE', mode }), []);
@@ -381,6 +411,47 @@ const Root = React.forwardRef<HTMLDivElement, ShellRootProps>(({ className, chil
381
411
  return childArray.some((el) => isShellComponentType(el, Sidebar));
382
412
  }, [children]);
383
413
 
414
+ // Re-read the defaults when a pane family enters after mount.
415
+ //
416
+ // The initial modes are computed once, from the children present at mount.
417
+ // That is right until an app swaps families at runtime - a Sidebar giving
418
+ // way to Rail+Panel on one route, and back on the next. The entering pane
419
+ // then renders against the mode left behind by the family that just went:
420
+ // a Rail mounting 'collapsed', at width 0, with its content faded out, put
421
+ // right one layout effect later. The reader sees a flicker in place where
422
+ // the pane should have been there already.
423
+ //
424
+ // Adjusting state during render keeps this out of the paint: React re-runs
425
+ // Root before the children render, so the entering pane never sees the
426
+ // mode of the family it replaced. The ref guard is what makes the update
427
+ // terminate - it fires only on the edge, never on a steady render.
428
+ const enteredFamilyRef = React.useRef({ left: hasLeftChildren, sidebar: hasSidebarChildren });
429
+ if (enteredFamilyRef.current.left !== hasLeftChildren || enteredFamilyRef.current.sidebar !== hasSidebarChildren) {
430
+ const leftEntered = hasLeftChildren && !enteredFamilyRef.current.left;
431
+ const sidebarEntered = hasSidebarChildren && !enteredFamilyRef.current.sidebar;
432
+ enteredFamilyRef.current = { left: hasLeftChildren, sidebar: hasSidebarChildren };
433
+
434
+ if (leftEntered || sidebarEntered) {
435
+ // The live breakpoint, not the mount default: a responsive
436
+ // defaultState like { initial: 'collapsed', md: 'expanded' } must be
437
+ // read for the width the reader is on. Taking `initial` would send a
438
+ // desktop sidebar in collapsed and let its own start-up effect open it
439
+ // again after the paint, which is the blink this whole block exists to
440
+ // remove.
441
+ const { hasPanelDefaultOpen, ...modes } = readPaneStateFromChildren(children, currentBreakpoint as Breakpoint);
442
+ if (leftEntered) {
443
+ hasPanelDefaultOpenRef.current = hasPanelDefaultOpen;
444
+ // Only when the mode actually differs, so a family that enters
445
+ // already in the right mode dispatches nothing.
446
+ if (modes.leftMode !== paneState.leftMode) dispatchPane({ type: 'SET_LEFT_MODE', mode: modes.leftMode });
447
+ if (modes.panelMode !== paneState.panelMode) dispatchPane({ type: 'SET_PANEL_MODE', mode: modes.panelMode });
448
+ }
449
+ if (sidebarEntered && modes.sidebarMode !== paneState.sidebarMode) {
450
+ dispatchPane({ type: 'SET_SIDEBAR_MODE', mode: modes.sidebarMode });
451
+ }
452
+ }
453
+ }
454
+
384
455
  // Keep a ref to sidebar mode so togglePane doesn't depend on it,
385
456
  // preventing ActionsContext churn on every sidebar mode change
386
457
  const sidebarModeRef = React.useRef(paneState.sidebarMode);
@@ -20,7 +20,7 @@
20
20
  */
21
21
  :where([data-panel-background='translucent'], [data-material='translucent']) & {
22
22
  backdrop-filter: var(--backdrop-filter-components);
23
- --backdrop-filter-components: blur(var(--backdrop-blur-components));
23
+ --backdrop-filter-components: var(--backdrop-filter-components-enabled);
24
24
  }
25
25
 
26
26
  /* Prevent backdrop-filter stacking with parent elements */
@@ -37,7 +37,7 @@
37
37
 
38
38
  &:where([data-panel-background='translucent'], [data-material='translucent']) {
39
39
  backdrop-filter: var(--backdrop-filter-components);
40
- --backdrop-filter-components: blur(var(--backdrop-blur-components));
40
+ --backdrop-filter-components: var(--backdrop-filter-components-enabled);
41
41
  }
42
42
 
43
43
  &:where([data-orientation='horizontal']) {
@@ -20,7 +20,7 @@
20
20
  */
21
21
  :where([data-panel-background='translucent'], [data-material='translucent']) & {
22
22
  backdrop-filter: var(--backdrop-filter-components);
23
- --backdrop-filter-components: blur(var(--backdrop-blur-components));
23
+ --backdrop-filter-components: var(--backdrop-filter-components-enabled);
24
24
  }
25
25
 
26
26
  /* Prevent backdrop-filter stacking with parent elements */
@@ -37,7 +37,7 @@
37
37
 
38
38
  &:where([data-panel-background='translucent'], [data-material='translucent']) {
39
39
  backdrop-filter: var(--backdrop-filter-components);
40
- --backdrop-filter-components: blur(var(--backdrop-blur-components));
40
+ --backdrop-filter-components: var(--backdrop-filter-components-enabled);
41
41
  }
42
42
 
43
43
  &::before {
@@ -121,6 +121,13 @@
121
121
  /* surface */
122
122
 
123
123
  .rt-TableRoot:where(.rt-variant-surface) {
124
+ /*
125
+ * This surface blurs its own backdrop, which makes it the backdrop root for
126
+ * everything inside it. A component nested here would re-blur an already
127
+ * blurred, already flat surface for the full cost of another blur pass, so
128
+ * switch the component filter off for the subtree. See tokens/blur.css.
129
+ */
130
+ --backdrop-filter-components-enabled: none;
124
131
  box-sizing: border-box;
125
132
  border: 1px solid var(--gray-a5);
126
133
  border-radius: var(--table-border-radius);
@@ -47,7 +47,7 @@
47
47
  /* Theme-level translucent override */
48
48
  :where([data-panel-background='translucent'], [data-material='translucent']) & {
49
49
  backdrop-filter: var(--backdrop-filter-components);
50
- --backdrop-filter-components: blur(var(--backdrop-blur-components));
50
+ --backdrop-filter-components: var(--backdrop-filter-components-enabled);
51
51
  }
52
52
 
53
53
  /* Prevent backdrop-filter stacking with parents */
@@ -61,7 +61,7 @@
61
61
 
62
62
  &:where([data-panel-background='translucent'], [data-material='translucent']) {
63
63
  backdrop-filter: var(--backdrop-filter-components);
64
- --backdrop-filter-components: blur(var(--backdrop-blur-components));
64
+ --backdrop-filter-components: var(--backdrop-filter-components-enabled);
65
65
  }
66
66
 
67
67
  &:where(:focus-within) {
@@ -12,7 +12,7 @@
12
12
  /* Theme-level translucent override */
13
13
  :where([data-panel-background='translucent'], [data-material='translucent']) & {
14
14
  backdrop-filter: var(--backdrop-filter-components);
15
- --backdrop-filter-components: blur(var(--backdrop-blur-components));
15
+ --backdrop-filter-components: var(--backdrop-filter-components-enabled);
16
16
  }
17
17
 
18
18
  /* Prevent backdrop-filter stacking with parents */
@@ -26,7 +26,7 @@
26
26
 
27
27
  &:where([data-panel-background='translucent'], [data-material='translucent']) {
28
28
  backdrop-filter: var(--backdrop-filter-components);
29
- --backdrop-filter-components: blur(var(--backdrop-blur-components));
29
+ --backdrop-filter-components: var(--backdrop-filter-components-enabled);
30
30
  }
31
31
 
32
32
  @supports selector(:has(*)) {
@@ -3,8 +3,11 @@
3
3
  import * as React from 'react';
4
4
  import classNames from 'classnames';
5
5
  import { Direction, Slot, Tooltip as TooltipPrimitive } from 'radix-ui';
6
+ import { useComposedRefs, useLayoutEffect } from 'radix-ui/internal';
6
7
 
7
8
  import { getMatchingGrayColor } from '../helpers/get-matching-gray-color.js';
9
+ import { usePropSyncedState } from '../hooks/use-prop-synced-state.js';
10
+ import { useDeprecatedPanelBackgroundWarning } from '../helpers/use-deprecation-warning.js';
8
11
  import { themePropDefs } from './theme.props.js';
9
12
 
10
13
  import type { ThemeOwnProps } from './theme.props.js';
@@ -104,42 +107,27 @@ const ThemeRoot = React.forwardRef<ThemeImplElement, ThemeImplPublicProps>(
104
107
  ...rootProps
105
108
  } = props;
106
109
 
107
- // Show deprecation warning for panelBackground when used
108
- React.useEffect(() => {
109
- if (props.panelBackground !== undefined) {
110
- console.warn(
111
- 'Warning: The `panelBackground` prop is deprecated and will be removed in a future version. Use `material` prop instead.',
112
- );
113
- }
114
- }, [props.panelBackground]);
110
+ useDeprecatedPanelBackgroundWarning(props.panelBackground);
115
111
 
116
- const [appearance, setAppearance] = React.useState(appearanceProp);
117
- React.useEffect(() => setAppearance(appearanceProp), [appearanceProp]);
118
-
119
- const [accentColor, setAccentColor] = React.useState(accentColorProp);
120
- React.useEffect(() => setAccentColor(accentColorProp), [accentColorProp]);
121
-
122
- const [grayColor, setGrayColor] = React.useState(grayColorProp);
123
- React.useEffect(() => setGrayColor(grayColorProp), [grayColorProp]);
112
+ // Each of these follows its prop but stays independently settable, so
113
+ // `ThemePanel` can change the theme at runtime. Syncing during render
114
+ // rather than in an effect matters here: an effect would commit the old
115
+ // theme first and re-render every consumer of the context a second time.
116
+ const [appearance, setAppearance] = usePropSyncedState(appearanceProp);
117
+ const [accentColor, setAccentColor] = usePropSyncedState(accentColorProp);
118
+ const [grayColor, setGrayColor] = usePropSyncedState(grayColorProp);
124
119
 
125
120
  // Material takes precedence over panelBackground
126
121
  const effectiveMaterial =
127
122
  materialProp !== themePropDefs.material.default ? materialProp : panelBackgroundProp;
128
- const [material, setMaterial] = React.useState(effectiveMaterial);
129
- React.useEffect(() => setMaterial(effectiveMaterial), [effectiveMaterial]);
123
+ const [material, setMaterial] = usePropSyncedState(effectiveMaterial);
130
124
 
131
125
  // Keep panelBackground in sync with material for backward compatibility
132
- const [panelBackground, setPanelBackground] = React.useState(panelBackgroundProp);
133
- React.useEffect(() => setPanelBackground(material), [material]);
134
-
135
- const [radius, setRadius] = React.useState(radiusProp);
136
- React.useEffect(() => setRadius(radiusProp), [radiusProp]);
137
-
138
- const [scaling, setScaling] = React.useState(scalingProp);
139
- React.useEffect(() => setScaling(scalingProp), [scalingProp]);
126
+ const [panelBackground, setPanelBackground] = usePropSyncedState(material);
140
127
 
141
- const [fontFamily, setFontFamily] = React.useState(fontFamilyProp);
142
- React.useEffect(() => setFontFamily(fontFamilyProp), [fontFamilyProp]);
128
+ const [radius, setRadius] = usePropSyncedState(radiusProp);
129
+ const [scaling, setScaling] = usePropSyncedState(scalingProp);
130
+ const [fontFamily, setFontFamily] = usePropSyncedState(fontFamilyProp);
143
131
 
144
132
  return (
145
133
  <ThemeImpl
@@ -223,10 +211,24 @@ const ThemeImpl = React.forwardRef<ThemeImplElement, ThemeImplProps>((props, for
223
211
  const hasBackground =
224
212
  hasBackgroundProp === undefined ? isRoot || isExplicitAppearance : hasBackgroundProp;
225
213
 
226
- const [clientOS, setClientOS] = React.useState<ReturnType<typeof getClientOS>>(undefined);
227
- React.useEffect(() => {
228
- if (isRoot) setClientOS(getClientOS());
229
- }, [isRoot]);
214
+ // `data-os` can only be resolved on the client. Writing it straight to the
215
+ // DOM keeps it out of the server markup — so hydration still matches — without
216
+ // spending a render pass, and a state update here would re-render the whole
217
+ // application on mount.
218
+ const rootRef = React.useRef<ThemeImplElement>(null);
219
+ const composedRef = useComposedRefs(forwardedRef, rootRef);
220
+ const hasExplicitOS = 'data-os' in themeProps;
221
+
222
+ useLayoutEffect(() => {
223
+ if (!isRoot || hasExplicitOS) return;
224
+ const node = rootRef.current;
225
+ if (!node) return;
226
+
227
+ const os = getClientOS();
228
+ if (!os) return;
229
+ node.setAttribute('data-os', os);
230
+ return () => node.removeAttribute('data-os');
231
+ }, [isRoot, hasExplicitOS]);
230
232
 
231
233
  return (
232
234
  <ThemeContext.Provider
@@ -284,8 +286,7 @@ const ThemeImpl = React.forwardRef<ThemeImplElement, ThemeImplProps>((props, for
284
286
  data-radius={radius}
285
287
  data-scaling={scaling}
286
288
  data-font-family={fontFamily}
287
- data-os={isRoot ? clientOS : undefined}
288
- ref={forwardedRef}
289
+ ref={composedRef}
289
290
  {...themeProps}
290
291
  className={classNames(
291
292
  'radix-themes',
@@ -0,0 +1,121 @@
1
+ import type { PropDef } from '../props/prop-def.js';
2
+
3
+ /**
4
+ * A prop def pre-processed into the exact shape `extractProps` needs at render
5
+ * time. Everything that can be derived from the static prop def — enum
6
+ * membership sets, whether the def is responsive, whether it carries a default
7
+ * — is computed once here instead of on every render.
8
+ */
9
+ interface CompiledPropDef {
10
+ key: string;
11
+ type: PropDef['type'];
12
+ default: unknown;
13
+ hasDefault: boolean;
14
+ responsive: boolean;
15
+ className?: string;
16
+ customProperties?: `--${string}`[];
17
+ parseValue?: (value: string) => string | undefined;
18
+ /** The prop def's own enum values, kept for the responsive class name helpers. */
19
+ values: readonly string[];
20
+ /** O(1) membership for `values`. */
21
+ valueSet: ReadonlySet<string>;
22
+ /**
23
+ * `values` plus the default, used to coerce invalid enum values back to the
24
+ * default. Only present for `type: 'enum'` — `'enum | string'` props accept
25
+ * arbitrary strings and must not be coerced.
26
+ */
27
+ enumValueSet?: ReadonlySet<unknown>;
28
+ }
29
+
30
+ interface CompiledPropDefs {
31
+ /** Defs that contribute a class name and/or custom properties. */
32
+ styling: CompiledPropDef[];
33
+ /**
34
+ * Defs that pass through to the element but still need a default applied or
35
+ * an invalid enum value coerced. Defs that can do neither are omitted
36
+ * entirely — they are already correct as passed.
37
+ */
38
+ passthrough: CompiledPropDef[];
39
+ /** Keys consumed by `styling`, so they can be skipped when copying props. */
40
+ stylingKeys: ReadonlySet<string>;
41
+ }
42
+
43
+ const EMPTY_VALUES: readonly string[] = [];
44
+ const EMPTY_SET: ReadonlySet<string> = new Set();
45
+
46
+ function compile(propDefs: readonly Record<string, PropDef>[]): CompiledPropDefs {
47
+ const merged: Record<string, PropDef> = Object.assign({}, ...propDefs);
48
+ const styling: CompiledPropDef[] = [];
49
+ const passthrough: CompiledPropDef[] = [];
50
+ const stylingKeys = new Set<string>();
51
+
52
+ for (const key in merged) {
53
+ // The PropDef union is narrowed per-field below; reading the optional
54
+ // members off the union directly is what the runtime actually needs.
55
+ const def = merged[key] as PropDef & {
56
+ default?: unknown;
57
+ values?: readonly string[];
58
+ className?: string;
59
+ customProperties?: `--${string}`[];
60
+ parseValue?: (value: string) => string | undefined;
61
+ responsive?: true;
62
+ };
63
+
64
+ const values = def.values ?? EMPTY_VALUES;
65
+ const compiled: CompiledPropDef = {
66
+ key,
67
+ type: def.type,
68
+ default: def.default,
69
+ hasDefault: def.default !== undefined,
70
+ responsive: 'responsive' in def,
71
+ className: def.className,
72
+ customProperties: def.customProperties,
73
+ parseValue: def.parseValue,
74
+ values,
75
+ valueSet: values.length > 0 ? new Set(values) : EMPTY_SET,
76
+ enumValueSet: def.type === 'enum' ? new Set<unknown>([def.default, ...values]) : undefined,
77
+ };
78
+
79
+ if (def.className) {
80
+ styling.push(compiled);
81
+ stylingKeys.add(key);
82
+ } else if (compiled.hasDefault || def.type === 'enum') {
83
+ // Anything else is copied through untouched, so there is nothing to do.
84
+ passthrough.push(compiled);
85
+ }
86
+ }
87
+
88
+ return { styling, passthrough, stylingKeys };
89
+ }
90
+
91
+ interface CacheNode {
92
+ children: WeakMap<object, CacheNode>;
93
+ compiled?: CompiledPropDefs;
94
+ }
95
+
96
+ const cacheRoot: CacheNode = { children: new WeakMap() };
97
+
98
+ /**
99
+ * Compiles a set of prop defs, memoized on the identity of the prop def objects
100
+ * themselves. Components always pass the same module-level constants, so after
101
+ * the first render of a given component this is a couple of WeakMap lookups
102
+ * instead of merging 50-odd prop defs into a fresh object.
103
+ */
104
+ function getCompiledPropDefs(propDefs: readonly Record<string, PropDef>[]): CompiledPropDefs {
105
+ let node = cacheRoot;
106
+
107
+ for (let i = 0; i < propDefs.length; i++) {
108
+ const propDef = propDefs[i];
109
+ let child = node.children.get(propDef);
110
+ if (child === undefined) {
111
+ child = { children: new WeakMap() };
112
+ node.children.set(propDef, child);
113
+ }
114
+ node = child;
115
+ }
116
+
117
+ return (node.compiled ??= compile(propDefs));
118
+ }
119
+
120
+ export { getCompiledPropDefs };
121
+ export type { CompiledPropDef, CompiledPropDefs };