@epilot/zenith-react 0.2.0-next.1 → 0.2.0-next.4

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 (273) hide show
  1. package/README.md +25 -0
  2. package/codemods/README.md +168 -0
  3. package/codemods/migrate/base-elements/accordion.ts +132 -0
  4. package/codemods/migrate/base-elements/alert.ts +81 -0
  5. package/codemods/migrate/base-elements/avatar.ts +116 -0
  6. package/codemods/migrate/base-elements/button.ts +188 -0
  7. package/codemods/migrate/base-elements/checkbox.ts +17 -0
  8. package/codemods/migrate/base-elements/chip.ts +87 -0
  9. package/codemods/migrate/base-elements/chip360.ts +162 -0
  10. package/codemods/migrate/base-elements/circular-progress.ts +73 -0
  11. package/codemods/migrate/base-elements/dialog.ts +323 -0
  12. package/codemods/migrate/base-elements/divider.ts +61 -0
  13. package/codemods/migrate/base-elements/feedback-message.ts +95 -0
  14. package/codemods/migrate/base-elements/icon-button.ts +203 -0
  15. package/codemods/migrate/base-elements/index.ts +55 -0
  16. package/codemods/migrate/base-elements/mui-props.ts +29 -0
  17. package/codemods/migrate/base-elements/notification.ts +98 -0
  18. package/codemods/migrate/base-elements/paper.ts +78 -0
  19. package/codemods/migrate/base-elements/select.ts +328 -0
  20. package/codemods/migrate/base-elements/shared.ts +910 -0
  21. package/codemods/migrate/base-elements/skeleton.ts +83 -0
  22. package/codemods/migrate/base-elements/switch.ts +19 -0
  23. package/codemods/migrate/base-elements/tabs.ts +222 -0
  24. package/codemods/migrate/base-elements/text-field.ts +425 -0
  25. package/codemods/migrate/base-elements/toggle-button.ts +185 -0
  26. package/codemods/migrate/base-elements/tooltip.ts +231 -0
  27. package/codemods/migrate/base-elements/typography.ts +247 -0
  28. package/codemods/migrate/base-elements/unsupported.ts +277 -0
  29. package/codemods/migrate/from-base-elements.ts +20 -0
  30. package/codemods/migrate/from-volt.ts +20 -0
  31. package/codemods/migrate/lib/imports.ts +399 -0
  32. package/codemods/migrate/lib/jsx.ts +313 -0
  33. package/codemods/migrate/lib/run-migration.ts +528 -0
  34. package/codemods/migrate/lib/source.ts +6 -0
  35. package/codemods/migrate/lib/todo.ts +107 -0
  36. package/codemods/migrate/lib/types.ts +114 -0
  37. package/codemods/migrate/volt/class-helpers.ts +37 -0
  38. package/codemods/migrate/volt/index.ts +18 -0
  39. package/codemods/migrate/volt/pagination.ts +26 -0
  40. package/codemods/migrate/volt/same-name.ts +293 -0
  41. package/codemods/migrate/volt/stylesheets.ts +18 -0
  42. package/codemods/migrate/volt/tanstack-types.ts +20 -0
  43. package/codemods/radix-to-base-ui.ts +389 -0
  44. package/dist/_virtual/_zenith-runtime-family_accordion.js +7 -0
  45. package/dist/_virtual/_zenith-runtime-family_accordion.js.map +1 -0
  46. package/dist/_virtual/_zenith-runtime-family_alert-dialog.js +7 -0
  47. package/dist/_virtual/_zenith-runtime-family_alert-dialog.js.map +1 -0
  48. package/dist/_virtual/_zenith-runtime-family_avatar.js +7 -0
  49. package/dist/_virtual/_zenith-runtime-family_avatar.js.map +1 -0
  50. package/dist/_virtual/_zenith-runtime-family_button.js +7 -0
  51. package/dist/_virtual/_zenith-runtime-family_button.js.map +1 -0
  52. package/dist/_virtual/_zenith-runtime-family_checkbox.js +7 -0
  53. package/dist/_virtual/_zenith-runtime-family_checkbox.js.map +1 -0
  54. package/dist/_virtual/_zenith-runtime-family_csp-provider.js +7 -0
  55. package/dist/_virtual/_zenith-runtime-family_csp-provider.js.map +1 -0
  56. package/dist/_virtual/_zenith-runtime-family_dialog.js +7 -0
  57. package/dist/_virtual/_zenith-runtime-family_dialog.js.map +1 -0
  58. package/dist/_virtual/_zenith-runtime-family_direction-provider.js +8 -0
  59. package/dist/_virtual/_zenith-runtime-family_direction-provider.js.map +1 -0
  60. package/dist/_virtual/_zenith-runtime-family_menu.js +7 -0
  61. package/dist/_virtual/_zenith-runtime-family_menu.js.map +1 -0
  62. package/dist/_virtual/_zenith-runtime-family_merge-props.js +11 -0
  63. package/dist/_virtual/_zenith-runtime-family_merge-props.js.map +1 -0
  64. package/dist/_virtual/_zenith-runtime-family_popover.js +7 -0
  65. package/dist/_virtual/_zenith-runtime-family_popover.js.map +1 -0
  66. package/dist/_virtual/_zenith-runtime-family_radio-group.js +7 -0
  67. package/dist/_virtual/_zenith-runtime-family_radio-group.js.map +1 -0
  68. package/dist/_virtual/_zenith-runtime-family_radio.js +7 -0
  69. package/dist/_virtual/_zenith-runtime-family_radio.js.map +1 -0
  70. package/dist/_virtual/_zenith-runtime-family_scroll-area.js +7 -0
  71. package/dist/_virtual/_zenith-runtime-family_scroll-area.js.map +1 -0
  72. package/dist/_virtual/_zenith-runtime-family_select.js +7 -0
  73. package/dist/_virtual/_zenith-runtime-family_select.js.map +1 -0
  74. package/dist/_virtual/_zenith-runtime-family_separator.js +7 -0
  75. package/dist/_virtual/_zenith-runtime-family_separator.js.map +1 -0
  76. package/dist/_virtual/_zenith-runtime-family_switch.js +7 -0
  77. package/dist/_virtual/_zenith-runtime-family_switch.js.map +1 -0
  78. package/dist/_virtual/_zenith-runtime-family_tabs.js +7 -0
  79. package/dist/_virtual/_zenith-runtime-family_tabs.js.map +1 -0
  80. package/dist/_virtual/_zenith-runtime-family_toast.js +7 -0
  81. package/dist/_virtual/_zenith-runtime-family_toast.js.map +1 -0
  82. package/dist/_virtual/_zenith-runtime-family_toggle-group.js +7 -0
  83. package/dist/_virtual/_zenith-runtime-family_toggle-group.js.map +1 -0
  84. package/dist/_virtual/_zenith-runtime-family_toggle.js +7 -0
  85. package/dist/_virtual/_zenith-runtime-family_toggle.js.map +1 -0
  86. package/dist/_virtual/_zenith-runtime-family_tooltip.js +7 -0
  87. package/dist/_virtual/_zenith-runtime-family_tooltip.js.map +1 -0
  88. package/dist/_virtual/_zenith-runtime-family_use-render.js +7 -0
  89. package/dist/_virtual/_zenith-runtime-family_use-render.js.map +1 -0
  90. package/dist/components/accordion/accordion.js +179 -96
  91. package/dist/components/accordion/accordion.js.map +1 -1
  92. package/dist/components/alert-dialog/alert-dialog.js +243 -206
  93. package/dist/components/alert-dialog/alert-dialog.js.map +1 -1
  94. package/dist/components/avatar/avatar.js +94 -82
  95. package/dist/components/avatar/avatar.js.map +1 -1
  96. package/dist/components/badge/badge.js +11 -11
  97. package/dist/components/breadcrumb/breadcrumb.js +69 -70
  98. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  99. package/dist/components/button/button.js +119 -102
  100. package/dist/components/button/button.js.map +1 -1
  101. package/dist/components/checkbox/checkbox.js +68 -51
  102. package/dist/components/checkbox/checkbox.js.map +1 -1
  103. package/dist/components/data-table/data-table-header.js +113 -99
  104. package/dist/components/data-table/data-table-header.js.map +1 -1
  105. package/dist/components/data-table/data-table-row.js +49 -40
  106. package/dist/components/data-table/data-table-row.js.map +1 -1
  107. package/dist/components/date-range-picker/date-range-picker.js +100 -90
  108. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  109. package/dist/components/date-time-picker/date-time-picker-input.js +118 -108
  110. package/dist/components/date-time-picker/date-time-picker-input.js.map +1 -1
  111. package/dist/components/date-time-picker/date-time-picker-panel.js +91 -94
  112. package/dist/components/date-time-picker/date-time-picker-panel.js.map +1 -1
  113. package/dist/components/dialog/dialog.js +238 -228
  114. package/dist/components/dialog/dialog.js.map +1 -1
  115. package/dist/components/drawer/drawer.js +260 -322
  116. package/dist/components/drawer/drawer.js.map +1 -1
  117. package/dist/components/dropdown-menu/dropdown-menu.js +533 -279
  118. package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -1
  119. package/dist/components/field/field-combobox.js +87 -77
  120. package/dist/components/field/field-combobox.js.map +1 -1
  121. package/dist/components/list/list-sortable.js +104 -0
  122. package/dist/components/list/list-sortable.js.map +1 -0
  123. package/dist/components/list/list.js +246 -324
  124. package/dist/components/list/list.js.map +1 -1
  125. package/dist/components/option-card/option-card.js +121 -117
  126. package/dist/components/option-card/option-card.js.map +1 -1
  127. package/dist/components/pill/pill.js +7 -7
  128. package/dist/components/popover/popover.js +223 -127
  129. package/dist/components/popover/popover.js.map +1 -1
  130. package/dist/components/radio/radio-group-base.js +54 -0
  131. package/dist/components/radio/radio-group-base.js.map +1 -0
  132. package/dist/components/radio/radio.js +71 -60
  133. package/dist/components/radio/radio.js.map +1 -1
  134. package/dist/components/scroll-area/scroll-area.js +142 -108
  135. package/dist/components/scroll-area/scroll-area.js.map +1 -1
  136. package/dist/components/scroll-overflow/scroll-overflow.js +156 -127
  137. package/dist/components/scroll-overflow/scroll-overflow.js.map +1 -1
  138. package/dist/components/segmented-control/segmented-control.js +93 -81
  139. package/dist/components/segmented-control/segmented-control.js.map +1 -1
  140. package/dist/components/select/select.js +485 -310
  141. package/dist/components/select/select.js.map +1 -1
  142. package/dist/components/separator/separator.js.map +1 -1
  143. package/dist/components/slot/compose-as-child.js +15 -12
  144. package/dist/components/slot/compose-as-child.js.map +1 -1
  145. package/dist/components/switch/switch.js +75 -68
  146. package/dist/components/switch/switch.js.map +1 -1
  147. package/dist/components/table/table-pagination.js +212 -175
  148. package/dist/components/table/table-pagination.js.map +1 -1
  149. package/dist/components/tabs/tabs.js +193 -190
  150. package/dist/components/tabs/tabs.js.map +1 -1
  151. package/dist/components/toast/toast.js +610 -148
  152. package/dist/components/toast/toast.js.map +1 -1
  153. package/dist/components/toggle/toggle-group.js +143 -32
  154. package/dist/components/toggle/toggle-group.js.map +1 -1
  155. package/dist/components/toggle/toggle.js +83 -53
  156. package/dist/components/toggle/toggle.js.map +1 -1
  157. package/dist/components/tooltip/tooltip.js +298 -138
  158. package/dist/components/tooltip/tooltip.js.map +1 -1
  159. package/dist/index.d.ts +2335 -2129
  160. package/dist/index.js +24 -23
  161. package/dist/list/sortable/index.d.ts +29 -0
  162. package/dist/list/sortable/index.js +5 -0
  163. package/dist/{_virtual → list/sortable}/index.js.map +1 -1
  164. package/dist/packages/tokens/dist/delivery/index.js +10 -10
  165. package/dist/packages/tokens/dist/delivery/index.js.map +1 -1
  166. package/dist/packages/tokens/dist/generated/core.generated.js +6 -15
  167. package/dist/packages/tokens/dist/generated/core.generated.js.map +1 -1
  168. package/dist/packages/tokens/dist/generated/palette.generated.js +4 -5
  169. package/dist/packages/tokens/dist/generated/palette.generated.js.map +1 -1
  170. package/dist/packages/tokens/dist/generated/palette.meta.generated.js +5 -0
  171. package/dist/packages/tokens/dist/generated/palette.meta.generated.js.map +1 -0
  172. package/dist/packages/tokens/dist/install.js +40 -17
  173. package/dist/packages/tokens/dist/install.js.map +1 -1
  174. package/dist/renderer/runtime-contract.generated.js +8 -0
  175. package/dist/renderer/runtime-contract.generated.js.map +1 -0
  176. package/dist/renderer/served.js +34 -0
  177. package/dist/renderer/served.js.map +1 -0
  178. package/dist/tokens/core.meta.generated.js +2 -2
  179. package/dist/tokens/core.meta.generated.js.map +1 -1
  180. package/dist/tokens/index.d.ts +1028 -1028
  181. package/dist/tokens/index.js +863 -863
  182. package/dist/tokens/index.js.map +1 -1
  183. package/dist/tokens/palette.meta.generated.js +5 -0
  184. package/dist/tokens/palette.meta.generated.js.map +1 -0
  185. package/dist/tokens.json +1 -1
  186. package/dist/vendor/.bun/@radix-ui_react-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-dialog/dist/index.js +57 -62
  187. package/dist/vendor/.bun/@radix-ui_react-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-dialog/dist/index.js.map +1 -1
  188. package/dist/vendor/.bun/@radix-ui_react-slot@1.2.3_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js +32 -38
  189. package/dist/vendor/.bun/@radix-ui_react-slot@1.2.3_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js.map +1 -1
  190. package/package.json +29 -21
  191. package/scripts/migration-diagnostics-core.mjs +18 -10
  192. package/scripts/migration-diagnostics.mjs +31 -8
  193. package/dist/_virtual/index.js +0 -6
  194. package/dist/_virtual/index2.js +0 -5
  195. package/dist/_virtual/index2.js.map +0 -1
  196. package/dist/_virtual/use-sync-external-store-shim.development.js +0 -5
  197. package/dist/_virtual/use-sync-external-store-shim.development.js.map +0 -1
  198. package/dist/_virtual/use-sync-external-store-shim.production.js +0 -5
  199. package/dist/_virtual/use-sync-external-store-shim.production.js.map +0 -1
  200. package/dist/tokens/palette.generated.js +0 -5
  201. package/dist/tokens/palette.generated.js.map +0 -1
  202. package/dist/vendor/.bun/@floating-ui_core@1.8.0/vendor/@floating-ui/core/dist/floating-ui.core.js +0 -512
  203. package/dist/vendor/.bun/@floating-ui_core@1.8.0/vendor/@floating-ui/core/dist/floating-ui.core.js.map +0 -1
  204. package/dist/vendor/.bun/@floating-ui_dom@1.8.0/vendor/@floating-ui/dom/dist/floating-ui.dom.js +0 -396
  205. package/dist/vendor/.bun/@floating-ui_dom@1.8.0/vendor/@floating-ui/dom/dist/floating-ui.dom.js.map +0 -1
  206. package/dist/vendor/.bun/@floating-ui_react-dom@2.1.9_6f4b9a1cfb20c0ae/vendor/@floating-ui/react-dom/dist/floating-ui.react-dom.js +0 -233
  207. package/dist/vendor/.bun/@floating-ui_react-dom@2.1.9_6f4b9a1cfb20c0ae/vendor/@floating-ui/react-dom/dist/floating-ui.react-dom.js.map +0 -1
  208. package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.dom.js +0 -137
  209. package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.dom.js.map +0 -1
  210. package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.js +0 -129
  211. package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.js.map +0 -1
  212. package/dist/vendor/.bun/@radix-ui_number@1.1.1/vendor/@radix-ui/number/dist/index.js +0 -7
  213. package/dist/vendor/.bun/@radix-ui_number@1.1.1/vendor/@radix-ui/number/dist/index.js.map +0 -1
  214. package/dist/vendor/.bun/@radix-ui_react-accordion@1.2.12_2b23df507bdda662/vendor/@radix-ui/react-accordion/dist/index.js +0 -240
  215. package/dist/vendor/.bun/@radix-ui_react-accordion@1.2.12_2b23df507bdda662/vendor/@radix-ui/react-accordion/dist/index.js.map +0 -1
  216. package/dist/vendor/.bun/@radix-ui_react-alert-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-alert-dialog/dist/index.js +0 -128
  217. package/dist/vendor/.bun/@radix-ui_react-alert-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-alert-dialog/dist/index.js.map +0 -1
  218. package/dist/vendor/.bun/@radix-ui_react-arrow@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-arrow/dist/index.js +0 -25
  219. package/dist/vendor/.bun/@radix-ui_react-arrow@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-arrow/dist/index.js.map +0 -1
  220. package/dist/vendor/.bun/@radix-ui_react-avatar@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-avatar/dist/index.js +0 -76
  221. package/dist/vendor/.bun/@radix-ui_react-avatar@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-avatar/dist/index.js.map +0 -1
  222. package/dist/vendor/.bun/@radix-ui_react-checkbox@1.3.3_2b23df507bdda662/vendor/@radix-ui/react-checkbox/dist/index.js +0 -252
  223. package/dist/vendor/.bun/@radix-ui_react-checkbox@1.3.3_2b23df507bdda662/vendor/@radix-ui/react-checkbox/dist/index.js.map +0 -1
  224. package/dist/vendor/.bun/@radix-ui_react-collapsible@1.1.12_2b23df507bdda662/vendor/@radix-ui/react-collapsible/dist/index.js +0 -121
  225. package/dist/vendor/.bun/@radix-ui_react-collapsible@1.1.12_2b23df507bdda662/vendor/@radix-ui/react-collapsible/dist/index.js.map +0 -1
  226. package/dist/vendor/.bun/@radix-ui_react-collection@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-collection/dist/index.js +0 -49
  227. package/dist/vendor/.bun/@radix-ui_react-collection@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-collection/dist/index.js.map +0 -1
  228. package/dist/vendor/.bun/@radix-ui_react-direction@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-direction/dist/index.js +0 -11
  229. package/dist/vendor/.bun/@radix-ui_react-direction@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-direction/dist/index.js.map +0 -1
  230. package/dist/vendor/.bun/@radix-ui_react-dropdown-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-dropdown-menu/dist/index.js +0 -228
  231. package/dist/vendor/.bun/@radix-ui_react-dropdown-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-dropdown-menu/dist/index.js.map +0 -1
  232. package/dist/vendor/.bun/@radix-ui_react-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-menu/dist/index.js +0 -653
  233. package/dist/vendor/.bun/@radix-ui_react-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-menu/dist/index.js.map +0 -1
  234. package/dist/vendor/.bun/@radix-ui_react-popover@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-popover/dist/index.js +0 -244
  235. package/dist/vendor/.bun/@radix-ui_react-popover@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-popover/dist/index.js.map +0 -1
  236. package/dist/vendor/.bun/@radix-ui_react-popper@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-popper/dist/index.js +0 -222
  237. package/dist/vendor/.bun/@radix-ui_react-popper@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-popper/dist/index.js.map +0 -1
  238. package/dist/vendor/.bun/@radix-ui_react-radio-group@1.3.8_2b23df507bdda662/vendor/@radix-ui/react-radio-group/dist/index.js +0 -239
  239. package/dist/vendor/.bun/@radix-ui_react-radio-group@1.3.8_2b23df507bdda662/vendor/@radix-ui/react-radio-group/dist/index.js.map +0 -1
  240. package/dist/vendor/.bun/@radix-ui_react-roving-focus@1.1.11_2b23df507bdda662/vendor/@radix-ui/react-roving-focus/dist/index.js +0 -184
  241. package/dist/vendor/.bun/@radix-ui_react-roving-focus@1.1.11_2b23df507bdda662/vendor/@radix-ui/react-roving-focus/dist/index.js.map +0 -1
  242. package/dist/vendor/.bun/@radix-ui_react-scroll-area@1.2.10_2b23df507bdda662/vendor/@radix-ui/react-scroll-area/dist/index.js +0 -535
  243. package/dist/vendor/.bun/@radix-ui_react-scroll-area@1.2.10_2b23df507bdda662/vendor/@radix-ui/react-scroll-area/dist/index.js.map +0 -1
  244. package/dist/vendor/.bun/@radix-ui_react-select@2.2.6_2b23df507bdda662/vendor/@radix-ui/react-select/dist/index.js +0 -863
  245. package/dist/vendor/.bun/@radix-ui_react-select@2.2.6_2b23df507bdda662/vendor/@radix-ui/react-select/dist/index.js.map +0 -1
  246. package/dist/vendor/.bun/@radix-ui_react-slot@1.2.4_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js +0 -63
  247. package/dist/vendor/.bun/@radix-ui_react-slot@1.2.4_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js.map +0 -1
  248. package/dist/vendor/.bun/@radix-ui_react-switch@1.2.6_2b23df507bdda662/vendor/@radix-ui/react-switch/dist/index.js +0 -133
  249. package/dist/vendor/.bun/@radix-ui_react-switch@1.2.6_2b23df507bdda662/vendor/@radix-ui/react-switch/dist/index.js.map +0 -1
  250. package/dist/vendor/.bun/@radix-ui_react-tabs@1.1.13_2b23df507bdda662/vendor/@radix-ui/react-tabs/dist/index.js +0 -164
  251. package/dist/vendor/.bun/@radix-ui_react-tabs@1.1.13_2b23df507bdda662/vendor/@radix-ui/react-tabs/dist/index.js.map +0 -1
  252. package/dist/vendor/.bun/@radix-ui_react-toggle-group@1.1.11_2b23df507bdda662/vendor/@radix-ui/react-toggle-group/dist/index.js +0 -138
  253. package/dist/vendor/.bun/@radix-ui_react-toggle-group@1.1.11_2b23df507bdda662/vendor/@radix-ui/react-toggle-group/dist/index.js.map +0 -1
  254. package/dist/vendor/.bun/@radix-ui_react-toggle@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-toggle/dist/index.js +0 -34
  255. package/dist/vendor/.bun/@radix-ui_react-toggle@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-toggle/dist/index.js.map +0 -1
  256. package/dist/vendor/.bun/@radix-ui_react-tooltip@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-tooltip/dist/index.js +0 -340
  257. package/dist/vendor/.bun/@radix-ui_react-tooltip@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-tooltip/dist/index.js.map +0 -1
  258. package/dist/vendor/.bun/@radix-ui_react-use-is-hydrated@0.1.0_0ac650c021fb1b59/vendor/@radix-ui/react-use-is-hydrated/dist/index.js +0 -16
  259. package/dist/vendor/.bun/@radix-ui_react-use-is-hydrated@0.1.0_0ac650c021fb1b59/vendor/@radix-ui/react-use-is-hydrated/dist/index.js.map +0 -1
  260. package/dist/vendor/.bun/@radix-ui_react-use-previous@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-use-previous/dist/index.js +0 -9
  261. package/dist/vendor/.bun/@radix-ui_react-use-previous@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-use-previous/dist/index.js.map +0 -1
  262. package/dist/vendor/.bun/@radix-ui_react-use-size@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-use-size/dist/index.js +0 -28
  263. package/dist/vendor/.bun/@radix-ui_react-use-size@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-use-size/dist/index.js.map +0 -1
  264. package/dist/vendor/.bun/@radix-ui_react-visually-hidden@1.2.3_2b23df507bdda662/vendor/@radix-ui/react-visually-hidden/dist/index.js +0 -33
  265. package/dist/vendor/.bun/@radix-ui_react-visually-hidden@1.2.3_2b23df507bdda662/vendor/@radix-ui/react-visually-hidden/dist/index.js.map +0 -1
  266. package/dist/vendor/.bun/sonner@2.0.7_6f4b9a1cfb20c0ae/vendor/sonner/dist/index.js +0 -747
  267. package/dist/vendor/.bun/sonner@2.0.7_6f4b9a1cfb20c0ae/vendor/sonner/dist/index.js.map +0 -1
  268. package/dist/vendor/.bun/use-sync-external-store@1.7.0_62547eec5a2188e3/vendor/use-sync-external-store/cjs/use-sync-external-store-shim.development.js +0 -68
  269. package/dist/vendor/.bun/use-sync-external-store@1.7.0_62547eec5a2188e3/vendor/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +0 -1
  270. package/dist/vendor/.bun/use-sync-external-store@1.7.0_62547eec5a2188e3/vendor/use-sync-external-store/cjs/use-sync-external-store-shim.production.js +0 -56
  271. package/dist/vendor/.bun/use-sync-external-store@1.7.0_62547eec5a2188e3/vendor/use-sync-external-store/cjs/use-sync-external-store-shim.production.js.map +0 -1
  272. package/dist/vendor/.bun/use-sync-external-store@1.7.0_62547eec5a2188e3/vendor/use-sync-external-store/shim/index.js +0 -11
  273. package/dist/vendor/.bun/use-sync-external-store@1.7.0_62547eec5a2188e3/vendor/use-sync-external-store/shim/index.js.map +0 -1
@@ -0,0 +1,399 @@
1
+ /**
2
+ * Import bookkeeping: resolve what a file imports from a module, rename a local binding
3
+ * throughout the file, and rebuild the legacy import as a Zenith import plus whatever stays.
4
+ */
5
+ import type {
6
+ ASTPath,
7
+ Collection,
8
+ Identifier,
9
+ ImportDeclaration,
10
+ ImportSpecifier,
11
+ JSCodeshift,
12
+ } from "jscodeshift"
13
+
14
+ export type ImportedName = {
15
+ imported: string
16
+ local: string
17
+ /** `import type { X }` or `import { type X }`. */
18
+ typeOnly: boolean
19
+ specifier: ImportSpecifier
20
+ declaration: ASTPath<ImportDeclaration>
21
+ }
22
+
23
+ /** Every named import from `moduleSpecifier`, aliases resolved. */
24
+ export function importedNames(
25
+ j: JSCodeshift,
26
+ root: Collection,
27
+ moduleSpecifier: string
28
+ ): ImportedName[] {
29
+ const names: ImportedName[] = []
30
+ root
31
+ .find(j.ImportDeclaration, { source: { value: moduleSpecifier } })
32
+ .forEach((declaration) => {
33
+ const declarationTypeOnly = declaration.node.importKind === "type"
34
+ for (const s of declaration.node.specifiers ?? []) {
35
+ if (s.type !== "ImportSpecifier") continue
36
+ names.push({
37
+ imported: String(s.imported.name),
38
+ local: String(s.local?.name ?? s.imported.name),
39
+ typeOnly:
40
+ declarationTypeOnly ||
41
+ (s as { importKind?: string }).importKind === "type",
42
+ specifier: s,
43
+ declaration,
44
+ })
45
+ }
46
+ })
47
+ return names
48
+ }
49
+
50
+ /** Imported name → local binding. */
51
+ export function localNames(names: ImportedName[]): Record<string, string> {
52
+ const map: Record<string, string> = {}
53
+ for (const n of names) map[n.imported] = n.local
54
+ return map
55
+ }
56
+
57
+ /** Whether `name` is bound anywhere at the top level of the file (import, declaration). */
58
+ export function isTopLevelBound(
59
+ j: JSCodeshift,
60
+ root: Collection,
61
+ name: string
62
+ ): boolean {
63
+ const program = root.find(j.Program).paths()[0]
64
+ if (!program) return false
65
+ const scope = program.scope
66
+ if (scope.declares(name)) return true
67
+ // Imports are bindings too; ast-types' scope tracks them, but be explicit for type-only ones.
68
+ return (
69
+ root
70
+ .find(j.ImportSpecifier)
71
+ .filter(
72
+ (p) => String(p.node.local?.name ?? p.node.imported.name) === name
73
+ )
74
+ .size() > 0
75
+ )
76
+ }
77
+
78
+ /** Every reference path to the local binding `name`: identifiers and JSX tags. */
79
+ function referencePaths(
80
+ j: JSCodeshift,
81
+ root: Collection,
82
+ name: string
83
+ ): ASTPath[] {
84
+ const paths: ASTPath[] = []
85
+ root.find(j.JSXIdentifier, { name }).forEach((p) => {
86
+ const parent = p.parent.node
87
+ if (parent.type === "JSXAttribute") return
88
+ if (parent.type === "JSXMemberExpression" && parent.property === p.node)
89
+ return
90
+ paths.push(p as ASTPath)
91
+ })
92
+ valueUses(j, root, name).forEach((p) => paths.push(p as ASTPath))
93
+ return paths
94
+ }
95
+
96
+ /**
97
+ * Whether any reference to `from` sits in a scope where `name` is bound (a prop, a parameter, a
98
+ * local): renaming `from` to `name` there would capture that binding instead of the import.
99
+ */
100
+ export function referenceSeesBinding(
101
+ j: JSCodeshift,
102
+ root: Collection,
103
+ from: string,
104
+ name: string
105
+ ): boolean {
106
+ return referencePaths(j, root, from).some((p) => {
107
+ const scope = (p as { scope?: { lookup(n: string): unknown } }).scope
108
+ return !!scope?.lookup(name)
109
+ })
110
+ }
111
+
112
+ /** Whether `name` is bound in any scope of the file (top level, a function, a catch clause). */
113
+ export function isBoundAnywhere(
114
+ j: JSCodeshift,
115
+ root: Collection,
116
+ name: string
117
+ ): boolean {
118
+ if (isTopLevelBound(j, root, name)) return true
119
+ const scopes = [
120
+ ...root.find(j.Function).paths(),
121
+ ...root.find(j.CatchClause).paths(),
122
+ ] as { scope?: { declares(n: string): boolean } }[]
123
+ return scopes.some((p) => !!p.scope?.declares(name))
124
+ }
125
+
126
+ /**
127
+ * Renames every reference to the local binding `from` to `to`: JSX tags, identifiers, type
128
+ * references, `typeof` queries. Property keys, member-expression properties and JSX attribute
129
+ * names are not references and stay as they are. Import specifiers are rebuilt by the caller.
130
+ */
131
+ export function renameBinding(
132
+ j: JSCodeshift,
133
+ root: Collection,
134
+ from: string,
135
+ to: string
136
+ ): void {
137
+ if (from === to) return
138
+ root.find(j.JSXIdentifier, { name: from }).forEach((path) => {
139
+ const parent = path.parent.node
140
+ if (parent.type === "JSXAttribute") return
141
+ if (parent.type === "JSXMemberExpression" && parent.property === path.node)
142
+ return
143
+ path.node.name = to
144
+ })
145
+ root.find(j.Identifier, { name: from }).forEach((path) => {
146
+ const parent = path.parent.node
147
+ const node = path.node
148
+ switch (parent.type) {
149
+ case "ImportSpecifier":
150
+ case "ImportDefaultSpecifier":
151
+ case "ImportNamespaceSpecifier":
152
+ case "ExportSpecifier":
153
+ return
154
+ case "MemberExpression":
155
+ case "OptionalMemberExpression":
156
+ if (parent.property === node && !parent.computed) return
157
+ break
158
+ case "Property":
159
+ case "ObjectProperty": {
160
+ if (parent.key === node && !parent.computed) {
161
+ if (parent.shorthand && parent.value === node) {
162
+ // `{ Spinner }` is a reference to the binding AND a key: keep the key, rename the value.
163
+ parent.shorthand = false
164
+ parent.value = j.identifier(to)
165
+ }
166
+ return
167
+ }
168
+ break
169
+ }
170
+ case "MethodDefinition":
171
+ case "ClassMethod":
172
+ case "ClassProperty":
173
+ case "TSPropertySignature":
174
+ case "TSMethodSignature":
175
+ case "ObjectMethod":
176
+ if (parent.key === node && !parent.computed) return
177
+ break
178
+ case "LabeledStatement":
179
+ case "BreakStatement":
180
+ case "ContinueStatement":
181
+ return
182
+ default:
183
+ break
184
+ }
185
+ node.name = to
186
+ })
187
+ }
188
+
189
+ /**
190
+ * References to the local binding `name` as a value, outside JSX tags and import specifiers:
191
+ * property keys, member-expression properties and type positions are not references.
192
+ */
193
+ export function valueUses(
194
+ j: JSCodeshift,
195
+ root: Collection,
196
+ name: string
197
+ ): Collection<Identifier> {
198
+ return root.find(j.Identifier, { name }).filter((path) => {
199
+ const parent = path.parent.node
200
+ const node = path.node
201
+ // ast-types derives JSXIdentifier from Identifier: tags and attribute names are not values.
202
+ if (node.type !== "Identifier") return false
203
+ switch (parent.type) {
204
+ case "ImportSpecifier":
205
+ case "ImportDefaultSpecifier":
206
+ case "ImportNamespaceSpecifier":
207
+ case "TSTypeReference":
208
+ case "TSTypeQuery":
209
+ case "TSQualifiedName":
210
+ case "TSExpressionWithTypeArguments":
211
+ case "LabeledStatement":
212
+ case "BreakStatement":
213
+ case "ContinueStatement":
214
+ return false
215
+ case "ExportSpecifier":
216
+ return parent.local === node
217
+ case "MemberExpression":
218
+ case "OptionalMemberExpression":
219
+ return !(parent.property === node && !parent.computed)
220
+ case "Property":
221
+ case "ObjectProperty":
222
+ if (parent.key === node && !parent.computed) return !!parent.shorthand
223
+ return true
224
+ case "MethodDefinition":
225
+ case "ClassMethod":
226
+ case "ClassProperty":
227
+ case "TSPropertySignature":
228
+ case "TSMethodSignature":
229
+ case "ObjectMethod":
230
+ return !(parent.key === node && !parent.computed)
231
+ default:
232
+ return true
233
+ }
234
+ })
235
+ }
236
+
237
+ export type Moved = {
238
+ imported: string
239
+ local: string
240
+ typeOnly: boolean
241
+ }
242
+
243
+ /**
244
+ * Adds `moved` to the file's import of `zenith` (any module: Zenith, or an upstream library),
245
+ * merging into the first existing one (or creating one `before` the given declaration). Type-only names go to an `import type` declaration when the
246
+ * value import does not exist yet; otherwise they are inline `type` specifiers.
247
+ */
248
+ export function addToZenithImport(
249
+ j: JSCodeshift,
250
+ root: Collection,
251
+ zenith: string,
252
+ moved: Moved[],
253
+ before: ASTPath<ImportDeclaration>,
254
+ quote: "single" | "double"
255
+ ): ImportDeclaration[] {
256
+ // Two legacy names moved onto the same Zenith binding are one specifier.
257
+ const seen = new Set<string>()
258
+ moved = moved.filter((m) => {
259
+ const key = `${m.imported}\0${m.local}`
260
+ if (seen.has(key)) return false
261
+ seen.add(key)
262
+ return true
263
+ })
264
+ if (moved.length === 0) return []
265
+ const existing = root
266
+ .find(j.ImportDeclaration, { source: { value: zenith } })
267
+ .filter((p) => p.node.importKind !== "type")
268
+ .paths()[0]
269
+ const existingType = root
270
+ .find(j.ImportDeclaration, { source: { value: zenith } })
271
+ .filter((p) => p.node.importKind === "type")
272
+ .paths()[0]
273
+
274
+ const q = quote === "single" ? "'" : '"'
275
+ const moduleLiteral = () => {
276
+ const node = j.literal(zenith) as { extra?: unknown }
277
+ node.extra = { raw: `${q}${zenith}${q}`, rawValue: zenith }
278
+ return node as ReturnType<typeof j.literal>
279
+ }
280
+ const specifier = (m: Moved, inlineType: boolean) => {
281
+ const s = j.importSpecifier(
282
+ j.identifier(m.imported),
283
+ m.local === m.imported ? null : j.identifier(m.local)
284
+ )
285
+ if (inlineType) (s as { importKind?: string }).importKind = "type"
286
+ return s
287
+ }
288
+ const has = (decl: ImportDeclaration, m: Moved) =>
289
+ (decl.specifiers ?? []).some(
290
+ (s) =>
291
+ s.type === "ImportSpecifier" &&
292
+ String(s.imported.name) === m.imported &&
293
+ String(s.local?.name ?? s.imported.name) === m.local
294
+ )
295
+
296
+ const values = moved.filter((m) => !m.typeOnly)
297
+ const types = moved.filter((m) => m.typeOnly)
298
+
299
+ const insertAfter: ImportDeclaration[] = []
300
+ if (existing) {
301
+ for (const m of values)
302
+ if (!has(existing.node, m))
303
+ existing.node.specifiers!.push(specifier(m, false))
304
+ for (const m of types)
305
+ if (
306
+ !has(existing.node, m) &&
307
+ !(existingType && has(existingType.node, m))
308
+ )
309
+ existing.node.specifiers!.push(specifier(m, true))
310
+ } else {
311
+ if (values.length) {
312
+ const decl = j.importDeclaration(
313
+ values.map((m) => specifier(m, false)),
314
+ moduleLiteral()
315
+ )
316
+ insertAfter.push(decl)
317
+ }
318
+ if (types.length) {
319
+ if (existingType) {
320
+ for (const m of types)
321
+ if (!has(existingType.node, m))
322
+ existingType.node.specifiers!.push(specifier(m, false))
323
+ } else if (values.length) {
324
+ for (const m of types)
325
+ insertAfter[0].specifiers!.push(specifier(m, true))
326
+ } else {
327
+ const decl = j.importDeclaration(
328
+ types.map((m) => specifier(m, false)),
329
+ moduleLiteral()
330
+ )
331
+ decl.importKind = "type"
332
+ insertAfter.push(decl)
333
+ }
334
+ }
335
+ }
336
+ for (const decl of insertAfter) before.insertBefore(decl)
337
+ return insertAfter
338
+ }
339
+
340
+ type CommentLike = {
341
+ type?: string
342
+ value?: string
343
+ leading?: boolean
344
+ trailing?: boolean
345
+ loc?: unknown
346
+ }
347
+
348
+ /**
349
+ * Moves `comments` (the leading ones) from `from` to the front of `to`. A file-leading
350
+ * `/* eslint-disable *\/` above the first import belongs to the file: when that import gets a
351
+ * new import inserted above it, or goes away, the comment moves to the Program node, which recast
352
+ * prints at the top with no extra blank line (on the inserted import it would get one).
353
+ */
354
+ export function hoistLeadingComments(
355
+ from: { comments?: CommentLike[] | null },
356
+ to: { comments?: CommentLike[] | null },
357
+ comments: CommentLike[] = from.comments ?? []
358
+ ): void {
359
+ const leading = comments.filter((c) => c.leading !== false)
360
+ if (leading.length === 0) return
361
+ from.comments = (from.comments ?? []).filter((c) => !leading.includes(c))
362
+ if (from.comments.length === 0) from.comments = null
363
+ // Copies without source positions: recast would otherwise keep the moved comment's original
364
+ // whitespace and print a blank line where it used to be.
365
+ const copies = leading.map((c) => ({
366
+ type: c.type,
367
+ value: c.value,
368
+ leading: true,
369
+ trailing: false,
370
+ }))
371
+ to.comments = [...copies, ...(to.comments ?? [])]
372
+ }
373
+
374
+ /**
375
+ * Where a first statement's leading comments go when something is inserted above it: the
376
+ * Program node (printed at the top), unless the file opens with a directive such as
377
+ * `"use client"`, which must stay first; then `undefined`, and the caller puts the comments on
378
+ * the inserted statement. Undefined as well when `path` is not the first statement.
379
+ */
380
+ export function programIfFirstStatement(
381
+ path: ASTPath
382
+ ): { comments?: CommentLike[] | null } | undefined {
383
+ const parent = path.parent?.node as
384
+ { type?: string; body?: unknown[]; directives?: unknown[] } | undefined
385
+ if (parent?.type !== "Program") return undefined
386
+ if (parent.body?.[0] !== path.node) return undefined
387
+ return parent.directives?.length ? undefined : (parent as never)
388
+ }
389
+
390
+ /** Whether `path` is the first statement of a Program that opens with a directive. */
391
+ export function isFirstStatementAfterDirective(path: ASTPath): boolean {
392
+ const parent = path.parent?.node as
393
+ { type?: string; body?: unknown[]; directives?: unknown[] } | undefined
394
+ return (
395
+ parent?.type === "Program" &&
396
+ parent.body?.[0] === path.node &&
397
+ !!parent.directives?.length
398
+ )
399
+ }
@@ -0,0 +1,313 @@
1
+ /**
2
+ * JSX helpers for rule modules: read, rename, drop and map props; wrap children in a part; rename
3
+ * a tag; merge into an inline `style`. Every helper is a local, syntactic edit on one element.
4
+ */
5
+ import type {
6
+ ASTPath,
7
+ ConditionalExpression,
8
+ JSCodeshift,
9
+ JSXAttribute,
10
+ JSXElement,
11
+ JSXSpreadAttribute,
12
+ ObjectExpression,
13
+ } from "jscodeshift"
14
+
15
+ export type Literal = string | number | boolean
16
+
17
+ export type JsxHelpers = ReturnType<typeof makeJsxHelpers>
18
+
19
+ type Attr = JSXAttribute | JSXSpreadAttribute
20
+
21
+ export function makeJsxHelpers(j: JSCodeshift) {
22
+ const attrsOf = (el: JSXElement): JSXAttribute[] =>
23
+ (el.openingElement.attributes ?? []).filter(
24
+ (a): a is JSXAttribute => a.type === "JSXAttribute"
25
+ )
26
+ const attrName = (a: JSXAttribute) =>
27
+ a.name.type === "JSXIdentifier"
28
+ ? a.name.name
29
+ : `${a.name.namespace.name}:${a.name.name.name}`
30
+ const attr = (el: JSXElement, name: string) =>
31
+ attrsOf(el).find((a) => attrName(a) === name)
32
+ const setAttrs = (el: JSXElement, attrs: Attr[]) => {
33
+ el.openingElement.attributes = attrs
34
+ }
35
+
36
+ /** The literal value of an attribute, when it has one. `<X flag />` is `true`. */
37
+ const literal = (a: JSXAttribute | undefined): Literal | undefined => {
38
+ if (!a) return undefined
39
+ const v = a.value
40
+ if (v == null) return true
41
+ if (v.type === "StringLiteral" || v.type === "Literal") {
42
+ return typeof v.value === "string" ? v.value : undefined
43
+ }
44
+ if (v.type === "JSXExpressionContainer") {
45
+ const e = v.expression
46
+ if (e.type === "StringLiteral") return e.value
47
+ if (e.type === "NumericLiteral") return e.value
48
+ if (e.type === "BooleanLiteral") return e.value
49
+ if (e.type === "Literal") {
50
+ const lv = (e as { value: unknown }).value
51
+ if (
52
+ typeof lv === "string" ||
53
+ typeof lv === "number" ||
54
+ typeof lv === "boolean"
55
+ )
56
+ return lv
57
+ }
58
+ if (e.type === "TemplateLiteral" && e.expressions.length === 0) {
59
+ return e.quasis[0]?.value.cooked ?? undefined
60
+ }
61
+ }
62
+ return undefined
63
+ }
64
+
65
+ /**
66
+ * A string literal that prints with the given quote whatever `toSource` options say: recast
67
+ * honours `extra.raw` on an ESTree `Literal`. JSX attributes are conventionally double-quoted.
68
+ */
69
+ const str = (value: string, quote: '"' | "'" = '"') => {
70
+ const node = j.literal(value) as { extra?: unknown }
71
+ node.extra = { raw: `${quote}${value}${quote}`, rawValue: value }
72
+ return node as ReturnType<typeof j.literal>
73
+ }
74
+
75
+ const valueNode = (value: Literal | null | ASTPath["node"]) => {
76
+ if (value === null) return null
77
+ if (typeof value === "string") return str(value)
78
+ if (typeof value === "number")
79
+ return j.jsxExpressionContainer(j.numericLiteral(value))
80
+ if (typeof value === "boolean")
81
+ return j.jsxExpressionContainer(j.booleanLiteral(value))
82
+ return j.jsxExpressionContainer(value as never)
83
+ }
84
+
85
+ type Expr = ConditionalExpression["consequent"]
86
+ const branchQuote = (node: { extra?: { raw?: string } }): '"' | "'" =>
87
+ node.extra?.raw?.startsWith("'") ? "'" : '"'
88
+ /** A branch: a string literal through the map (`null` → `undefined`), or a nested ternary. */
89
+ const mapBranch = (
90
+ node: Expr,
91
+ map: Record<string, string | null>
92
+ ): Expr | "dynamic" | "unknown" => {
93
+ if (node.type === "ConditionalExpression") return mapConditional(node, map)
94
+ const value =
95
+ node.type === "StringLiteral"
96
+ ? node.value
97
+ : node.type === "Literal" && typeof node.value === "string"
98
+ ? node.value
99
+ : undefined
100
+ if (value === undefined) return "dynamic"
101
+ if (!(value in map)) return "unknown"
102
+ const target = map[value]
103
+ if (target === null) return j.identifier("undefined")
104
+ return str(target, branchQuote(node as never)) as Expr
105
+ }
106
+ const mapConditional = (
107
+ node: ConditionalExpression,
108
+ map: Record<string, string | null>
109
+ ): ConditionalExpression | "dynamic" | "unknown" => {
110
+ const consequent = mapBranch(node.consequent, map)
111
+ if (consequent === "dynamic" || consequent === "unknown") return consequent
112
+ const alternate = mapBranch(node.alternate, map)
113
+ if (alternate === "dynamic" || alternate === "unknown") return alternate
114
+ return j.conditionalExpression(node.test, consequent, alternate)
115
+ }
116
+
117
+ const helpers = {
118
+ attrs: attrsOf,
119
+ attr,
120
+ attrName,
121
+ literal,
122
+ str,
123
+ /** The tag name of an element when it is a plain identifier (`<Button>`, not `<Ui.Button>`). */
124
+ tagName(el: JSXElement): string | undefined {
125
+ const n = el.openingElement.name
126
+ return n.type === "JSXIdentifier" ? n.name : undefined
127
+ },
128
+ hasSpread(el: JSXElement): boolean {
129
+ return (el.openingElement.attributes ?? []).some(
130
+ (a) => a.type === "JSXSpreadAttribute"
131
+ )
132
+ },
133
+ /** Removes the attribute and returns it, or `undefined` when absent. */
134
+ removeAttr(el: JSXElement, name: string): JSXAttribute | undefined {
135
+ const found = attr(el, name)
136
+ if (!found) return undefined
137
+ setAttrs(
138
+ el,
139
+ (el.openingElement.attributes ?? []).filter((a) => a !== found)
140
+ )
141
+ return found
142
+ },
143
+ renameAttr(el: JSXElement, from: string, to: string): boolean {
144
+ const found = attr(el, from)
145
+ if (!found) return false
146
+ found.name = j.jsxIdentifier(to)
147
+ return true
148
+ },
149
+ /**
150
+ * Sets (or replaces) an attribute. A string becomes `name="…"`, a number or boolean an
151
+ * expression, `null` a bare boolean attribute, and any other node an expression container.
152
+ */
153
+ setAttr(
154
+ el: JSXElement,
155
+ name: string,
156
+ value: Literal | null | ASTPath["node"]
157
+ ): void {
158
+ const next = j.jsxAttribute(j.jsxIdentifier(name), valueNode(value))
159
+ const existing = attr(el, name)
160
+ if (existing) {
161
+ setAttrs(
162
+ el,
163
+ (el.openingElement.attributes ?? []).map((a) =>
164
+ a === existing ? next : a
165
+ )
166
+ )
167
+ } else {
168
+ setAttrs(el, [...(el.openingElement.attributes ?? []), next])
169
+ }
170
+ },
171
+ /**
172
+ * Maps a string-literal attribute through `map` (`null` drops the attribute), or a ternary
173
+ * whose branches are all literals in the map (nested ternaries too; `null` becomes
174
+ * `undefined` there). Returns
175
+ * `absent` when the element has no such attribute, `dynamic` when its value is not a literal,
176
+ * `unknown` when the literal is not in the map (the attribute is left as it was), and `mapped`.
177
+ */
178
+ mapAttrValue(
179
+ el: JSXElement,
180
+ name: string,
181
+ map: Record<string, string | null>
182
+ ): "mapped" | "dynamic" | "absent" | "unknown" {
183
+ const found = attr(el, name)
184
+ if (!found) return "absent"
185
+ const value = literal(found)
186
+ if (typeof value === "string") {
187
+ if (!(value in map)) return "unknown"
188
+ const target = map[value]
189
+ if (target === null) helpers.removeAttr(el, name)
190
+ else found.value = str(target)
191
+ return "mapped"
192
+ }
193
+ // `cond ? "a" : "b"` (nested too): every branch is a literal in the map, or nothing moves.
194
+ if (
195
+ found.value?.type === "JSXExpressionContainer" &&
196
+ found.value.expression.type === "ConditionalExpression"
197
+ ) {
198
+ const mapped = mapConditional(found.value.expression, map)
199
+ if (mapped === "dynamic" || mapped === "unknown") return mapped
200
+ found.value = j.jsxExpressionContainer(mapped)
201
+ return "mapped"
202
+ }
203
+ return "dynamic"
204
+ },
205
+ /**
206
+ * An attribute parsed from source text, printed verbatim (recast keeps a parsed node's own
207
+ * formatting): `parseAttr('style={{ width: 200 }}')` stays on one line where a built
208
+ * object literal would be reflowed.
209
+ */
210
+ parseAttr(text: string): JSXAttribute {
211
+ const el = j(`<x ${text} />`).find(j.JSXAttribute).paths()[0]
212
+ if (!el) throw new Error(`parseAttr: no attribute in ${text}`)
213
+ return el.node
214
+ },
215
+ /** Source text of an attribute, for TODO messages (`size={progress}`). */
216
+ print(a: JSXAttribute): string {
217
+ return j(a).toSource()
218
+ },
219
+ /** `<El>children</El>` → `<El><Part>children</Part></El>`; returns the new part. */
220
+ wrapChildren(el: JSXElement, partTag: string): JSXElement {
221
+ const part = j.jsxElement(
222
+ j.jsxOpeningElement(j.jsxIdentifier(partTag)),
223
+ j.jsxClosingElement(j.jsxIdentifier(partTag)),
224
+ el.children ?? []
225
+ )
226
+ el.children = [part]
227
+ return part
228
+ },
229
+ /** Replaces `path`'s element with `<Wrapper>…</Wrapper>` around it; returns the wrapper. */
230
+ wrap(path: ASTPath<JSXElement>, wrapperTag: string): JSXElement {
231
+ const wrapper = j.jsxElement(
232
+ j.jsxOpeningElement(j.jsxIdentifier(wrapperTag)),
233
+ j.jsxClosingElement(j.jsxIdentifier(wrapperTag)),
234
+ [path.node]
235
+ )
236
+ path.replace(wrapper)
237
+ return wrapper
238
+ },
239
+ /** Renames the opening and closing tag. */
240
+ rename(el: JSXElement, tag: string): void {
241
+ el.openingElement.name = j.jsxIdentifier(tag)
242
+ if (el.closingElement) el.closingElement.name = j.jsxIdentifier(tag)
243
+ },
244
+ /** Replaces the element's children. */
245
+ setChildren(el: JSXElement, children: JSXElement["children"]): void {
246
+ if (!children || children.length === 0) {
247
+ el.children = []
248
+ el.openingElement.selfClosing = true
249
+ el.closingElement = null
250
+ return
251
+ }
252
+ el.children = children
253
+ el.openingElement.selfClosing = false
254
+ if (!el.closingElement)
255
+ el.closingElement = j.jsxClosingElement(el.openingElement.name)
256
+ },
257
+ /** A child node for a `label`-style prop value: text for a string, `{expr}` otherwise. */
258
+ childFromValue(
259
+ a: JSXAttribute
260
+ ): NonNullable<JSXElement["children"]>[number] {
261
+ const value = literal(a)
262
+ if (typeof value === "string") return j.jsxText(value)
263
+ if (a.value?.type === "JSXExpressionContainer") {
264
+ const e = a.value.expression
265
+ if (e.type === "JSXElement" || e.type === "JSXFragment") return e
266
+ return j.jsxExpressionContainer(e as never)
267
+ }
268
+ return j.jsxExpressionContainer(j.booleanLiteral(true))
269
+ },
270
+ /**
271
+ * The object literal of `style={{…}}`, created when absent. `undefined` when `style` is
272
+ * present but not an object literal (the caller reports a TODO).
273
+ */
274
+ styleObject(el: JSXElement): ObjectExpression | undefined {
275
+ const existing = attr(el, "style")
276
+ if (!existing) {
277
+ const object = j.objectExpression([])
278
+ helpers.setAttr(el, "style", object)
279
+ return object
280
+ }
281
+ const v = existing.value
282
+ if (
283
+ v?.type === "JSXExpressionContainer" &&
284
+ v.expression.type === "ObjectExpression"
285
+ )
286
+ return v.expression
287
+ return undefined
288
+ },
289
+ /** Adds `key: value` to an object literal, replacing an existing non-computed key. */
290
+ setObjectKey(
291
+ object: ObjectExpression,
292
+ key: string,
293
+ value: ASTPath["node"]
294
+ ): void {
295
+ object.properties = object.properties.filter((p) => {
296
+ if (p.type !== "ObjectProperty" && p.type !== "Property") return true
297
+ if (p.computed) return true
298
+ const k = p.key
299
+ const name =
300
+ k.type === "Identifier"
301
+ ? k.name
302
+ : k.type === "StringLiteral"
303
+ ? k.value
304
+ : undefined
305
+ return name !== key
306
+ })
307
+ object.properties.push(
308
+ j.objectProperty(j.identifier(key), value as never)
309
+ )
310
+ },
311
+ }
312
+ return helpers
313
+ }