@epilot/zenith-react 0.2.0-next.3 → 0.2.0-next.5

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 (274) hide show
  1. package/README.md +37 -1
  2. package/codemods/README.md +182 -0
  3. package/codemods/format.ts +86 -0
  4. package/codemods/migrate/base-elements/accordion.ts +132 -0
  5. package/codemods/migrate/base-elements/alert.ts +81 -0
  6. package/codemods/migrate/base-elements/avatar.ts +116 -0
  7. package/codemods/migrate/base-elements/button.ts +188 -0
  8. package/codemods/migrate/base-elements/checkbox.ts +17 -0
  9. package/codemods/migrate/base-elements/chip.ts +87 -0
  10. package/codemods/migrate/base-elements/chip360.ts +162 -0
  11. package/codemods/migrate/base-elements/circular-progress.ts +73 -0
  12. package/codemods/migrate/base-elements/dialog.ts +323 -0
  13. package/codemods/migrate/base-elements/divider.ts +61 -0
  14. package/codemods/migrate/base-elements/feedback-message.ts +95 -0
  15. package/codemods/migrate/base-elements/icon-button.ts +203 -0
  16. package/codemods/migrate/base-elements/index.ts +55 -0
  17. package/codemods/migrate/base-elements/mui-props.ts +29 -0
  18. package/codemods/migrate/base-elements/notification.ts +98 -0
  19. package/codemods/migrate/base-elements/paper.ts +78 -0
  20. package/codemods/migrate/base-elements/select.ts +328 -0
  21. package/codemods/migrate/base-elements/shared.ts +910 -0
  22. package/codemods/migrate/base-elements/skeleton.ts +83 -0
  23. package/codemods/migrate/base-elements/switch.ts +19 -0
  24. package/codemods/migrate/base-elements/tabs.ts +222 -0
  25. package/codemods/migrate/base-elements/text-field.ts +425 -0
  26. package/codemods/migrate/base-elements/toggle-button.ts +185 -0
  27. package/codemods/migrate/base-elements/tooltip.ts +231 -0
  28. package/codemods/migrate/base-elements/typography.ts +247 -0
  29. package/codemods/migrate/base-elements/unsupported.ts +277 -0
  30. package/codemods/migrate/from-base-elements.ts +26 -0
  31. package/codemods/migrate/from-volt.ts +26 -0
  32. package/codemods/migrate/lib/imports.ts +399 -0
  33. package/codemods/migrate/lib/jsx.ts +313 -0
  34. package/codemods/migrate/lib/run-migration.ts +528 -0
  35. package/codemods/migrate/lib/source.ts +6 -0
  36. package/codemods/migrate/lib/todo.ts +107 -0
  37. package/codemods/migrate/lib/types.ts +114 -0
  38. package/codemods/migrate/volt/class-helpers.ts +37 -0
  39. package/codemods/migrate/volt/index.ts +18 -0
  40. package/codemods/migrate/volt/pagination.ts +26 -0
  41. package/codemods/migrate/volt/same-name.ts +293 -0
  42. package/codemods/migrate/volt/stylesheets.ts +18 -0
  43. package/codemods/migrate/volt/tanstack-types.ts +20 -0
  44. package/codemods/radix-to-base-ui.ts +677 -0
  45. package/dist/_virtual/_zenith-runtime-family_accordion.js +7 -0
  46. package/dist/_virtual/_zenith-runtime-family_accordion.js.map +1 -0
  47. package/dist/_virtual/_zenith-runtime-family_alert-dialog.js +7 -0
  48. package/dist/_virtual/_zenith-runtime-family_alert-dialog.js.map +1 -0
  49. package/dist/_virtual/_zenith-runtime-family_avatar.js +7 -0
  50. package/dist/_virtual/_zenith-runtime-family_avatar.js.map +1 -0
  51. package/dist/_virtual/_zenith-runtime-family_button.js +7 -0
  52. package/dist/_virtual/_zenith-runtime-family_button.js.map +1 -0
  53. package/dist/_virtual/_zenith-runtime-family_checkbox.js +7 -0
  54. package/dist/_virtual/_zenith-runtime-family_checkbox.js.map +1 -0
  55. package/dist/_virtual/_zenith-runtime-family_csp-provider.js +7 -0
  56. package/dist/_virtual/_zenith-runtime-family_csp-provider.js.map +1 -0
  57. package/dist/_virtual/_zenith-runtime-family_dialog.js +7 -0
  58. package/dist/_virtual/_zenith-runtime-family_dialog.js.map +1 -0
  59. package/dist/_virtual/_zenith-runtime-family_direction-provider.js +8 -0
  60. package/dist/_virtual/_zenith-runtime-family_direction-provider.js.map +1 -0
  61. package/dist/_virtual/_zenith-runtime-family_menu.js +7 -0
  62. package/dist/_virtual/_zenith-runtime-family_menu.js.map +1 -0
  63. package/dist/_virtual/_zenith-runtime-family_merge-props.js +11 -0
  64. package/dist/_virtual/_zenith-runtime-family_merge-props.js.map +1 -0
  65. package/dist/_virtual/_zenith-runtime-family_popover.js +7 -0
  66. package/dist/_virtual/_zenith-runtime-family_popover.js.map +1 -0
  67. package/dist/_virtual/_zenith-runtime-family_radio-group.js +7 -0
  68. package/dist/_virtual/_zenith-runtime-family_radio-group.js.map +1 -0
  69. package/dist/_virtual/_zenith-runtime-family_radio.js +7 -0
  70. package/dist/_virtual/_zenith-runtime-family_radio.js.map +1 -0
  71. package/dist/_virtual/_zenith-runtime-family_scroll-area.js +7 -0
  72. package/dist/_virtual/_zenith-runtime-family_scroll-area.js.map +1 -0
  73. package/dist/_virtual/_zenith-runtime-family_select.js +7 -0
  74. package/dist/_virtual/_zenith-runtime-family_select.js.map +1 -0
  75. package/dist/_virtual/_zenith-runtime-family_separator.js +7 -0
  76. package/dist/_virtual/_zenith-runtime-family_separator.js.map +1 -0
  77. package/dist/_virtual/_zenith-runtime-family_switch.js +7 -0
  78. package/dist/_virtual/_zenith-runtime-family_switch.js.map +1 -0
  79. package/dist/_virtual/_zenith-runtime-family_tabs.js +7 -0
  80. package/dist/_virtual/_zenith-runtime-family_tabs.js.map +1 -0
  81. package/dist/_virtual/_zenith-runtime-family_toast.js +7 -0
  82. package/dist/_virtual/_zenith-runtime-family_toast.js.map +1 -0
  83. package/dist/_virtual/_zenith-runtime-family_toggle-group.js +7 -0
  84. package/dist/_virtual/_zenith-runtime-family_toggle-group.js.map +1 -0
  85. package/dist/_virtual/_zenith-runtime-family_toggle.js +7 -0
  86. package/dist/_virtual/_zenith-runtime-family_toggle.js.map +1 -0
  87. package/dist/_virtual/_zenith-runtime-family_tooltip.js +7 -0
  88. package/dist/_virtual/_zenith-runtime-family_tooltip.js.map +1 -0
  89. package/dist/_virtual/_zenith-runtime-family_use-render.js +7 -0
  90. package/dist/_virtual/_zenith-runtime-family_use-render.js.map +1 -0
  91. package/dist/components/accordion/accordion.js +179 -96
  92. package/dist/components/accordion/accordion.js.map +1 -1
  93. package/dist/components/alert-dialog/alert-dialog.js +243 -206
  94. package/dist/components/alert-dialog/alert-dialog.js.map +1 -1
  95. package/dist/components/avatar/avatar.js +94 -82
  96. package/dist/components/avatar/avatar.js.map +1 -1
  97. package/dist/components/badge/badge.js +11 -11
  98. package/dist/components/breadcrumb/breadcrumb.js +69 -70
  99. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  100. package/dist/components/button/button.js +119 -102
  101. package/dist/components/button/button.js.map +1 -1
  102. package/dist/components/checkbox/checkbox.js +68 -51
  103. package/dist/components/checkbox/checkbox.js.map +1 -1
  104. package/dist/components/date-range-picker/date-range-picker.js +100 -90
  105. package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
  106. package/dist/components/date-time-picker/date-time-picker-input.js +118 -108
  107. package/dist/components/date-time-picker/date-time-picker-input.js.map +1 -1
  108. package/dist/components/date-time-picker/date-time-picker-panel.js +91 -94
  109. package/dist/components/date-time-picker/date-time-picker-panel.js.map +1 -1
  110. package/dist/components/dialog/dialog.js +238 -228
  111. package/dist/components/dialog/dialog.js.map +1 -1
  112. package/dist/components/drawer/drawer.js +259 -321
  113. package/dist/components/drawer/drawer.js.map +1 -1
  114. package/dist/components/dropdown-menu/dropdown-menu.js +533 -279
  115. package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -1
  116. package/dist/components/field/field-combobox.js +205 -186
  117. package/dist/components/field/field-combobox.js.map +1 -1
  118. package/dist/components/field/field-select.js +37 -22
  119. package/dist/components/field/field-select.js.map +1 -1
  120. package/dist/components/list/list-sortable.js +104 -0
  121. package/dist/components/list/list-sortable.js.map +1 -0
  122. package/dist/components/list/list.js +246 -324
  123. package/dist/components/list/list.js.map +1 -1
  124. package/dist/components/option-card/option-card.js +121 -117
  125. package/dist/components/option-card/option-card.js.map +1 -1
  126. package/dist/components/pill/pill.js +7 -7
  127. package/dist/components/popover/popover.js +223 -127
  128. package/dist/components/popover/popover.js.map +1 -1
  129. package/dist/components/radio/radio-group-base.js +54 -0
  130. package/dist/components/radio/radio-group-base.js.map +1 -0
  131. package/dist/components/radio/radio.js +71 -60
  132. package/dist/components/radio/radio.js.map +1 -1
  133. package/dist/components/scroll-area/scroll-area.js +142 -108
  134. package/dist/components/scroll-area/scroll-area.js.map +1 -1
  135. package/dist/components/scroll-overflow/scroll-overflow.js +156 -127
  136. package/dist/components/scroll-overflow/scroll-overflow.js.map +1 -1
  137. package/dist/components/segmented-control/segmented-control.js +93 -81
  138. package/dist/components/segmented-control/segmented-control.js.map +1 -1
  139. package/dist/components/select/select.js +485 -310
  140. package/dist/components/select/select.js.map +1 -1
  141. package/dist/components/separator/separator.js.map +1 -1
  142. package/dist/components/slot/compose-as-child.js +15 -12
  143. package/dist/components/slot/compose-as-child.js.map +1 -1
  144. package/dist/components/switch/switch.js +75 -68
  145. package/dist/components/switch/switch.js.map +1 -1
  146. package/dist/components/table/table-pagination.js +212 -175
  147. package/dist/components/table/table-pagination.js.map +1 -1
  148. package/dist/components/tabs/tabs.js +193 -190
  149. package/dist/components/tabs/tabs.js.map +1 -1
  150. package/dist/components/toast/toast.js +610 -148
  151. package/dist/components/toast/toast.js.map +1 -1
  152. package/dist/components/toggle/toggle-group.js +143 -32
  153. package/dist/components/toggle/toggle-group.js.map +1 -1
  154. package/dist/components/toggle/toggle.js +82 -49
  155. package/dist/components/toggle/toggle.js.map +1 -1
  156. package/dist/components/tooltip/tooltip.js +298 -138
  157. package/dist/components/tooltip/tooltip.js.map +1 -1
  158. package/dist/index.d.ts +2336 -2130
  159. package/dist/index.js +24 -23
  160. package/dist/list/sortable/index.d.ts +29 -0
  161. package/dist/list/sortable/index.js +5 -0
  162. package/dist/{_virtual → list/sortable}/index.js.map +1 -1
  163. package/dist/packages/tokens/dist/delivery/index.js +10 -10
  164. package/dist/packages/tokens/dist/delivery/index.js.map +1 -1
  165. package/dist/packages/tokens/dist/generated/core.generated.js +6 -15
  166. package/dist/packages/tokens/dist/generated/core.generated.js.map +1 -1
  167. package/dist/packages/tokens/dist/generated/palette.generated.js +4 -5
  168. package/dist/packages/tokens/dist/generated/palette.generated.js.map +1 -1
  169. package/dist/packages/tokens/dist/generated/palette.meta.generated.js +5 -0
  170. package/dist/packages/tokens/dist/generated/palette.meta.generated.js.map +1 -0
  171. package/dist/packages/tokens/dist/install.js +40 -17
  172. package/dist/packages/tokens/dist/install.js.map +1 -1
  173. package/dist/renderer/runtime-contract.generated.js +8 -0
  174. package/dist/renderer/runtime-contract.generated.js.map +1 -0
  175. package/dist/renderer/served.js +39 -0
  176. package/dist/renderer/served.js.map +1 -0
  177. package/dist/tokens/core.meta.generated.js +2 -2
  178. package/dist/tokens/core.meta.generated.js.map +1 -1
  179. package/dist/tokens/index.d.ts +1028 -1028
  180. package/dist/tokens/index.js +863 -863
  181. package/dist/tokens/index.js.map +1 -1
  182. package/dist/tokens/palette.meta.generated.js +5 -0
  183. package/dist/tokens/palette.meta.generated.js.map +1 -0
  184. package/dist/tokens.json +1 -1
  185. package/dist/vendor/.bun/@radix-ui_react-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-dialog/dist/index.js +57 -62
  186. package/dist/vendor/.bun/@radix-ui_react-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-dialog/dist/index.js.map +1 -1
  187. package/dist/vendor/.bun/@radix-ui_react-slot@1.2.3_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js +32 -38
  188. package/dist/vendor/.bun/@radix-ui_react-slot@1.2.3_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js.map +1 -1
  189. package/package.json +29 -21
  190. package/scripts/migration-diagnostics-core.mjs +302 -10
  191. package/scripts/migration-diagnostics.mjs +31 -8
  192. package/scripts/migration-sweep.mjs +10 -10
  193. package/testing/setup.cjs +87 -0
  194. package/dist/_virtual/index.js +0 -6
  195. package/dist/_virtual/index2.js +0 -5
  196. package/dist/_virtual/index2.js.map +0 -1
  197. package/dist/_virtual/use-sync-external-store-shim.development.js +0 -5
  198. package/dist/_virtual/use-sync-external-store-shim.development.js.map +0 -1
  199. package/dist/_virtual/use-sync-external-store-shim.production.js +0 -5
  200. package/dist/_virtual/use-sync-external-store-shim.production.js.map +0 -1
  201. package/dist/tokens/palette.generated.js +0 -5
  202. package/dist/tokens/palette.generated.js.map +0 -1
  203. package/dist/vendor/.bun/@floating-ui_core@1.8.0/vendor/@floating-ui/core/dist/floating-ui.core.js +0 -512
  204. package/dist/vendor/.bun/@floating-ui_core@1.8.0/vendor/@floating-ui/core/dist/floating-ui.core.js.map +0 -1
  205. package/dist/vendor/.bun/@floating-ui_dom@1.8.0/vendor/@floating-ui/dom/dist/floating-ui.dom.js +0 -396
  206. package/dist/vendor/.bun/@floating-ui_dom@1.8.0/vendor/@floating-ui/dom/dist/floating-ui.dom.js.map +0 -1
  207. 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
  208. 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
  209. package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.dom.js +0 -137
  210. package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.dom.js.map +0 -1
  211. package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.js +0 -129
  212. package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.js.map +0 -1
  213. package/dist/vendor/.bun/@radix-ui_number@1.1.1/vendor/@radix-ui/number/dist/index.js +0 -7
  214. package/dist/vendor/.bun/@radix-ui_number@1.1.1/vendor/@radix-ui/number/dist/index.js.map +0 -1
  215. package/dist/vendor/.bun/@radix-ui_react-accordion@1.2.12_2b23df507bdda662/vendor/@radix-ui/react-accordion/dist/index.js +0 -240
  216. package/dist/vendor/.bun/@radix-ui_react-accordion@1.2.12_2b23df507bdda662/vendor/@radix-ui/react-accordion/dist/index.js.map +0 -1
  217. package/dist/vendor/.bun/@radix-ui_react-alert-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-alert-dialog/dist/index.js +0 -128
  218. 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
  219. package/dist/vendor/.bun/@radix-ui_react-arrow@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-arrow/dist/index.js +0 -25
  220. package/dist/vendor/.bun/@radix-ui_react-arrow@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-arrow/dist/index.js.map +0 -1
  221. package/dist/vendor/.bun/@radix-ui_react-avatar@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-avatar/dist/index.js +0 -76
  222. package/dist/vendor/.bun/@radix-ui_react-avatar@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-avatar/dist/index.js.map +0 -1
  223. package/dist/vendor/.bun/@radix-ui_react-checkbox@1.3.3_2b23df507bdda662/vendor/@radix-ui/react-checkbox/dist/index.js +0 -252
  224. package/dist/vendor/.bun/@radix-ui_react-checkbox@1.3.3_2b23df507bdda662/vendor/@radix-ui/react-checkbox/dist/index.js.map +0 -1
  225. package/dist/vendor/.bun/@radix-ui_react-collapsible@1.1.12_2b23df507bdda662/vendor/@radix-ui/react-collapsible/dist/index.js +0 -121
  226. package/dist/vendor/.bun/@radix-ui_react-collapsible@1.1.12_2b23df507bdda662/vendor/@radix-ui/react-collapsible/dist/index.js.map +0 -1
  227. package/dist/vendor/.bun/@radix-ui_react-collection@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-collection/dist/index.js +0 -49
  228. package/dist/vendor/.bun/@radix-ui_react-collection@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-collection/dist/index.js.map +0 -1
  229. package/dist/vendor/.bun/@radix-ui_react-direction@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-direction/dist/index.js +0 -11
  230. package/dist/vendor/.bun/@radix-ui_react-direction@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-direction/dist/index.js.map +0 -1
  231. package/dist/vendor/.bun/@radix-ui_react-dropdown-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-dropdown-menu/dist/index.js +0 -228
  232. 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
  233. package/dist/vendor/.bun/@radix-ui_react-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-menu/dist/index.js +0 -653
  234. package/dist/vendor/.bun/@radix-ui_react-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-menu/dist/index.js.map +0 -1
  235. package/dist/vendor/.bun/@radix-ui_react-popover@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-popover/dist/index.js +0 -244
  236. package/dist/vendor/.bun/@radix-ui_react-popover@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-popover/dist/index.js.map +0 -1
  237. package/dist/vendor/.bun/@radix-ui_react-popper@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-popper/dist/index.js +0 -222
  238. package/dist/vendor/.bun/@radix-ui_react-popper@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-popper/dist/index.js.map +0 -1
  239. package/dist/vendor/.bun/@radix-ui_react-radio-group@1.3.8_2b23df507bdda662/vendor/@radix-ui/react-radio-group/dist/index.js +0 -239
  240. 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
  241. package/dist/vendor/.bun/@radix-ui_react-roving-focus@1.1.11_2b23df507bdda662/vendor/@radix-ui/react-roving-focus/dist/index.js +0 -184
  242. 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
  243. package/dist/vendor/.bun/@radix-ui_react-scroll-area@1.2.10_2b23df507bdda662/vendor/@radix-ui/react-scroll-area/dist/index.js +0 -535
  244. 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
  245. package/dist/vendor/.bun/@radix-ui_react-select@2.2.6_2b23df507bdda662/vendor/@radix-ui/react-select/dist/index.js +0 -863
  246. package/dist/vendor/.bun/@radix-ui_react-select@2.2.6_2b23df507bdda662/vendor/@radix-ui/react-select/dist/index.js.map +0 -1
  247. package/dist/vendor/.bun/@radix-ui_react-slot@1.2.4_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js +0 -63
  248. package/dist/vendor/.bun/@radix-ui_react-slot@1.2.4_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js.map +0 -1
  249. package/dist/vendor/.bun/@radix-ui_react-switch@1.2.6_2b23df507bdda662/vendor/@radix-ui/react-switch/dist/index.js +0 -133
  250. package/dist/vendor/.bun/@radix-ui_react-switch@1.2.6_2b23df507bdda662/vendor/@radix-ui/react-switch/dist/index.js.map +0 -1
  251. package/dist/vendor/.bun/@radix-ui_react-tabs@1.1.13_2b23df507bdda662/vendor/@radix-ui/react-tabs/dist/index.js +0 -164
  252. package/dist/vendor/.bun/@radix-ui_react-tabs@1.1.13_2b23df507bdda662/vendor/@radix-ui/react-tabs/dist/index.js.map +0 -1
  253. package/dist/vendor/.bun/@radix-ui_react-toggle-group@1.1.11_2b23df507bdda662/vendor/@radix-ui/react-toggle-group/dist/index.js +0 -138
  254. 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
  255. package/dist/vendor/.bun/@radix-ui_react-toggle@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-toggle/dist/index.js +0 -34
  256. package/dist/vendor/.bun/@radix-ui_react-toggle@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-toggle/dist/index.js.map +0 -1
  257. package/dist/vendor/.bun/@radix-ui_react-tooltip@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-tooltip/dist/index.js +0 -340
  258. package/dist/vendor/.bun/@radix-ui_react-tooltip@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-tooltip/dist/index.js.map +0 -1
  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 +0 -16
  260. 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
  261. package/dist/vendor/.bun/@radix-ui_react-use-previous@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-use-previous/dist/index.js +0 -9
  262. 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
  263. package/dist/vendor/.bun/@radix-ui_react-use-size@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-use-size/dist/index.js +0 -28
  264. 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
  265. package/dist/vendor/.bun/@radix-ui_react-visually-hidden@1.2.3_2b23df507bdda662/vendor/@radix-ui/react-visually-hidden/dist/index.js +0 -33
  266. 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
  267. package/dist/vendor/.bun/sonner@2.0.7_6f4b9a1cfb20c0ae/vendor/sonner/dist/index.js +0 -747
  268. package/dist/vendor/.bun/sonner@2.0.7_6f4b9a1cfb20c0ae/vendor/sonner/dist/index.js.map +0 -1
  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 +0 -68
  270. 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
  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 +0 -56
  272. 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
  273. package/dist/vendor/.bun/use-sync-external-store@1.7.0_62547eec5a2188e3/vendor/use-sync-external-store/shim/index.js +0 -11
  274. package/dist/vendor/.bun/use-sync-external-store@1.7.0_62547eec5a2188e3/vendor/use-sync-external-store/shim/index.js.map +0 -1
package/README.md CHANGED
@@ -39,6 +39,14 @@ Application styles that need a design token import a named binding from
39
39
  `@epilot/zenith-react/tokens`. Do not add the token CSS as a second stylesheet,
40
40
  and do not write generated `--zenith-<hash>-*` names by hand.
41
41
 
42
+ Drag-and-drop reordering for `List` is a separate entry, so apps that render a plain
43
+ `List` do not bundle dnd-kit:
44
+
45
+ ```tsx
46
+ import { ListItem } from "@epilot/zenith-react"
47
+ import { SortableList } from "@epilot/zenith-react/list/sortable"
48
+ ```
49
+
42
50
  Zenith ships no `.css` files, and its `exports` map has no stylesheet entry:
43
51
  there is nothing to import. Porting from Volt, drop its `style.css`,
44
52
  `preflight.css` and `font.css` imports and add no replacement — the token CSS
@@ -124,6 +132,23 @@ Replace `https://main.d8s2wyuq7fsgk.amplifyapp.com` with your custom domain if
124
132
  configured. All queries and tools are strictly read-only and require no
125
133
  credentials.
126
134
 
135
+ ## Agents
136
+
137
+ A Zenith skill teaches a coding agent to use the MCP above. It has `compose`,
138
+ `review`, `tokens`, `migrate` and `setup` modes. In Claude Code, one plugin
139
+ install adds the skill and the MCP connection:
140
+
141
+ ```sh
142
+ claude plugin marketplace add https://gitlab.com/e-pilot/product/frontend/zenith.git
143
+ claude plugin install zenith@zenith
144
+ ```
145
+
146
+ Then run `/zenith:compose <screen>` or `/zenith:review`. For Codex, Cursor,
147
+ Copilot and OpenCode, install the skill with
148
+ `npx skills add https://gitlab.com/e-pilot/product/frontend/zenith --skill zenith`
149
+ and add the MCP endpoint to the agent's configuration. The "Coding agents"
150
+ page in the documentation's setup section has the steps for each agent.
151
+
127
152
  ## Which version you get
128
153
 
129
154
  `npm install @epilot/zenith-react` resolves the `latest` dist-tag, which points
@@ -138,10 +163,21 @@ npm install @epilot/zenith-react@next
138
163
  These are opt-in twice over — you name the tag, and a range like `^0.1.0` never
139
164
  resolves a prerelease. Pin an exact version if you adopt one.
140
165
 
166
+ ## Upgrading to 0.2.0
167
+
168
+ 0.2.0 moves every family from Radix to Base UI and serves the primitives from
169
+ the runtime. The "Upgrade to 0.2.0" page in the documentation's setup section
170
+ has the steps in order: the host serves the new runtime first (with `react` and
171
+ `react-dom` external), bump the packages, run the `radix-to-base-ui` codemod
172
+ (its output comes through your Prettier), run the migration sweep, add the test
173
+ setup, check the attribute renames, and keep the two rules for pages that still
174
+ mix Volt 1.x and Zenith.
175
+
141
176
  ## Reference
142
177
 
143
178
  The package is ESM-only and tree-shakeable. Resolved literal token values are in
144
- `@epilot/zenith-react/tokens.json`, and an optional Jest helper in
179
+ `@epilot/zenith-react/tokens.json`. For tests, `@epilot/zenith-react/testing/setup.cjs`
180
+ (a `PointerEvent` for jsdom 26 and older, Vitest and Jest) and an optional Jest helper in
145
181
  `@epilot/zenith-react/testing/jest-preset.cjs`.
146
182
 
147
183
  Component reference, guidelines and examples are on the documentation site — the
@@ -0,0 +1,182 @@
1
+ # Consumer codemods
2
+
3
+ `radix-to-base-ui.ts` moves consumer code across the Base UI port (DECISIONS.md D12: only overlay
4
+ dismissal interceptors left the surface). It is one transform for every family; consumers run it
5
+ once on code that imports `@epilot/zenith-react`:
6
+
7
+ ```sh
8
+ bunx jscodeshift@17.3.0 --parser=tsx -t node_modules/@epilot/zenith-react/codemods/radix-to-base-ui.ts src/
9
+ ```
10
+
11
+ Every transform here prints each file it rewrites through your project's Prettier (resolved
12
+ next to the file, with the config that applies to it), so the result passes your format check as
13
+ it is; `.prettierignore` is not consulted. Without Prettier in the project the output keeps
14
+ recast's formatting, the run says so once on stderr, and you run your formatter on the changed
15
+ files.
16
+
17
+ What it rewrites:
18
+
19
+ | Content part | Root whose `onOpenChange` takes the handlers | Props moved |
20
+ | ------------------------ | -------------------------------------------- | -------------------------------------------------------------------------------- |
21
+ | `DialogContent` | `Dialog` | `onEscapeKeyDown`, `onPointerDownOutside`, `onInteractOutside`, `onFocusOutside` |
22
+ | `AlertDialogContent` | `AlertDialog` | `onEscapeKeyDown`, `onFocusOutside` |
23
+ | `DrawerContent` | `Drawer` | all four |
24
+ | `PopoverContent` | `Popover` | all four |
25
+ | `FieldComboboxContent` | `FieldCombobox` | all four |
26
+ | `DropdownMenuContent` | `DropdownMenu` | all four |
27
+ | `DropdownMenuSubContent` | `DropdownMenuSub` | all four |
28
+ | `SelectContent` | `Select` | `onEscapeKeyDown`, `onPointerDownOutside` |
29
+ | `TooltipContent` | `Tooltip` | `onEscapeKeyDown`, `onPointerDownOutside` |
30
+
31
+ Each handler becomes a check on Base UI's `eventDetails.reason` (`escape-key`, `outside-press`,
32
+ `focus-out`), and one that calls `preventDefault()` keeps the overlay open through
33
+ `eventDetails.cancel()`, as it did under Radix. A handler is called with the event only when it
34
+ takes one: an inline function by its parameters, a reference by its declaration (a `const` or
35
+ `function`, `useCallback`, a type annotation, a destructured prop whose type is written in the
36
+ file, or one of those behind a relative import), so `const close = () => …` becomes `close?.()`
37
+ and typechecks. A reference the file cannot explain (a package import, a member expression, a
38
+ conditional) gets the event. A DropdownMenu item whose `onSelect` calls
39
+ `preventDefault()` to keep the menu open is reported: the menu closes regardless under Base UI. Props
40
+ a wrapper can still translate, such as `forceMount`, stay on the surface and need no rule.
41
+
42
+ Each port added its own `<family>-base-ui.ts`; the Radix teardown (#97) folded them into this one
43
+ before any release shipped them, with every family's fixtures.
44
+
45
+ Rules for a transform:
46
+
47
+ - Only touch named imports from `@epilot/zenith-react` (aliases resolved); leave Volt imports alone.
48
+ - Each rule is a local, syntactic rewrite with no hand edits afterwards. Anything else gets a
49
+ `/* TODO(zenith-base-ui): … */` comment and an `api.report` line, so the run's output is the
50
+ list of places a human has to look.
51
+ - Fixtures: `__testfixtures__/radix-to-base-ui-<family>-<case>.input.tsx` and `.output.tsx`, the
52
+ output being exactly what `--dry --print` emits (no report lines, no absolute paths), formatted
53
+ by the repository's own Prettier config as the transform prints it. Cover, per
54
+ family: the plain case, aliased imports, an inline handler, a handler reference, a
55
+ zero-parameter reference (a `const`, a `function` and an import from `handlers.ts`), and one
56
+ unsupported shape that gets the TODO.
57
+ - `./run-fixtures.sh radix-to-base-ui` diffs every fixture of the transform. `fixtures.test.ts`
58
+ also reruns the transform over each expected output and requires a no-op, and typechecks the
59
+ outputs against the public types; the `-unsupported` fixtures keep the prop the transform cannot
60
+ rewrite and are the only outputs not typechecked.
61
+
62
+ ## Migrating to Zenith
63
+
64
+ Two entry transforms in `migrate/` move consumer code onto `@epilot/zenith-react` from the
65
+ predecessor libraries. Run one, work the report, then run `radix-to-base-ui.ts` (it is not
66
+ chained: the predecessor APIs are the Radix-era ones). Both print through your project's
67
+ Prettier, as above:
68
+
69
+ ```sh
70
+ bunx jscodeshift@17.3.0 --parser=tsx -t node_modules/@epilot/zenith-react/codemods/migrate/from-volt.ts src/
71
+ bunx jscodeshift@17.3.0 --parser=tsx -t node_modules/@epilot/zenith-react/codemods/migrate/from-base-elements.ts src/
72
+ ```
73
+
74
+ The run's output is the TODO list. Every place a human has to look is one line,
75
+ ` REP <file> <line> <Component>: <fix>`, and the same text sits in the code as a
76
+ `TODO(zenith-migrate): <Component>: <fix>` comment. The fix is concrete ("dropped `value={p}`:
77
+ Spinner is indeterminate…"), so the reader needs no mapping document; look a component up only
78
+ when its line says so. `rg 'TODO\(zenith-migrate\)'` lists what is left.
79
+
80
+ ### What each transform does
81
+
82
+ `from-volt` (Volt 1.7): every name Zenith kept (279, the whole barrel minus the list below)
83
+ moves onto the Zenith import unchanged; the `style.css`, `preflight.css` and `font.css` imports
84
+ are deleted; `ColumnFiltersState`, `ColumnOrderState`, `ColumnPinningState`, `FilterFn` and
85
+ `PaginationState` come from `@tanstack/react-table`; `cn`, `CloseIcon`, the `*Variants` helpers
86
+ and `useClientPagination` stay on the Volt import with the replacement in their TODO
87
+ (`mergeClasses` + `makeZenithStyles`; `calculatePagination`/`clampPage`). Then run the
88
+ `radix-to-base-ui` transform: the Volt API is Radix-era.
89
+
90
+ `from-base-elements` (3.10, MUI v4): syntactic renames with prop maps for `CircularProgress` →
91
+ `Spinner`, `Divider` → `Separator`, `Skeleton`, `Avatar`/`AvatarGroup`, `Paper` → `Surface`,
92
+ `Chip`/`Chip360` → `Pill`, structural rewrites for the button, form, dialog, typography,
93
+ navigation and feedback families (the table below), and a one-line hint for everything else
94
+ (`unsupported.ts`: Grid, Box, the spacing components, Icon, theme and `makeStyles`, MUI's count
95
+ Badge, masked fields, LinearProgress, Drawer360, react-beautiful-dnd, transitions, and the
96
+ same-name-different-API families such as Table and List). MUI theming props (`color="primary"`
97
+ on a spinner, `classes`) are dropped and, where they change behaviour, reported. A legacy
98
+ binding that is also used as a value (`styled(Paper)`, `component={Paper}`) stays on the legacy
99
+ import with one TODO per use; only its JSX elements move. Re-exports, `import()`, `require` and
100
+ `jest.mock`/`vi.mock` of the legacy package are reported, never rewritten.
101
+
102
+ Dry run first and read the report (`--dry` writes nothing; add `--print` to see the output).
103
+ Line numbers in the report are the input file's; after a write run, find each place by its
104
+ `TODO(zenith-migrate)` comment instead. The `tsx` parser rejects the `<T>x` cast in `.ts`
105
+ files: rewrite those as `x as T` before running.
106
+
107
+ ```sh
108
+ bunx jscodeshift@17.3.0 --parser=tsx --extensions=tsx,ts,jsx,js --dry \
109
+ -t node_modules/@epilot/zenith-react/codemods/migrate/from-base-elements.ts src/ | grep ' REP '
110
+ ```
111
+
112
+ ### base-elements structural rules
113
+
114
+ One module per family in `migrate/base-elements/` (shared helpers in `shared.ts`). Simple
115
+ shapes are rewritten onto the Zenith parts; anything else still compiles and gets a TODO.
116
+
117
+ | base-elements | Zenith | Rewritten | Reported |
118
+ | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
119
+ | `Button` | `Button` | variant × color (contained → primary, outlined → secondary, text → tertiary or ghost), size, `startIcon`/`endIcon` as children, `href`/`component` → `asChild`, `fullWidth` → `width: 100%`, `type="button"` when MUI rendered a native button | a dynamic variant or size, MUI-only props |
120
+ | `IconButton`, `ElevatedIconButton`, `TooltipIconButton` | `Button size="icon…"` | small → `icon-xs`, medium → `icon`, large → `icon-lg`; ghost, primary or secondary; TooltipIconButton → Tooltip parts with its title as `aria-label` | no accessible name, `edge` |
121
+ | `Dialog`, `DialogTitle`, `DialogContent`, `DialogActions`, `DialogContentText` | `Dialog` > `DialogContent` (the panel) > `DialogHeader`/`DialogTitle`, `DialogFooter`, `DialogDescription` | `onClose` → `onOpenChange`, `maxWidth` → panel `size` (nearest with `fullWidth`, else at most `lg`), `disableBackdropClick`/`disableEscapeKeyDown` → `preventDefault()` handlers, `showCloseButton={false}`; MUI's `DialogContent` is the body and becomes a `<div>` | the body's scrolling, an `onClose` that reads `(event, reason)`, ids Radix owns, `aria-labelledby` pointing elsewhere |
122
+ | `TextField` | `Field` + `FieldLabel` + `FieldInput`/`FieldTextarea` + `FieldDescription`/`FieldError` | input props, `inputProps`, `inputRef`, `multiline`/`rows`, `error` + `helperText`, `InputProps` adornments → `FieldInputGroup` + `FieldGroupAddon` | a label without an `id` to tie it to, `select`, a dynamic `multiline`, `margin` |
123
+ | `Typography`, `H1`–`H6`, `DisplayText`, `LargeText`, `BodyText`, `SmallText` | `Text` | variant by the epilot theme's sizes (h1–h4 → title3 … caption → body1), `textSecondary` → helper2/helper1, `gutterBottom`/`noWrap`/`align`/`customColor` → inline style | a lost heading level, block → inline next to siblings, colours Text has no variant for |
124
+ | `Tooltip` | `Tooltip` > `TooltipTrigger asChild` + `TooltipContent` | `placement` → `side`/`align` (MUI's bottom default written out), `enterDelay` → `delayDuration` | the TooltipProvider Radix needs (once per file), a title that can be empty, MUI timing props |
125
+ | `Switch`, `Checkbox` | `Switch`, `Checkbox` | `onChange(event, checked)` → `onCheckedChange(checked)`, `indeterminate` → `checked="indeterminate"`, `label` → a wrapping `Label` | handler references, spread props (`{...field}`) |
126
+ | `TabContext`, `Tabs`, `TabList`, `PrimaryTabs`, `Tab`, `TabPanel` | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` | the list's `onChange` → the root's `onValueChange`, `label` → children | numeric or missing tab values |
127
+ | `Select` + `MenuItem` | `Select` > `SelectTrigger` > `SelectValue`, `SelectContent` > `SelectItem` | static or `.map` items, `event.target.value` handlers, `placeholder`, `label` → `Field` + `FieldLabel` | other children, empty or null values, `renderValue`, `multiple`, a `MenuItem` outside a Select |
128
+ | `Alert`, `Notification` (and Info/Error/Success), `FeedbackMessage` | `Callout` + `CalloutTitle`/`CalloutDescription`/`CalloutAction` | `severity`/`stateVariant` → `variant`, `onClose` → `dismissible onDismiss`, `visible` → a render condition | a dynamic severity, the feedback icon action |
129
+ | `Accordion`, `AccordionSummary`, `AccordionDetails` | `Accordion type="single" collapsible` > `AccordionItem` > `AccordionTrigger` + `AccordionContent` | `defaultExpanded`/`expanded`/`onChange` → `defaultValue`/`value`/`onValueChange` | `AccordionActions`, handler references |
130
+ | `ToggleButtonGroup`, `ToggleButton` | `SegmentedControl` (exclusive) or `ToggleGroup type="multiple"` | `onChange` → `onValueChange` | a dynamic `exclusive`, a `ToggleButton` on its own |
131
+
132
+ An inline MUI handler `(event, value) => …` becomes `(value) => …` when it reads only the value
133
+ or `event.target.<prop>`; a handler reference keeps MUI's signature, so it is dropped and
134
+ reported. Where Zenith's parts need Zenith's root (Dialog, Tabs, Accordion, ToggleButtonGroup),
135
+ a family member used as a value (`styled(Dialog)`) keeps the whole family on base-elements: a
136
+ Zenith part inside an MUI root breaks at runtime.
137
+
138
+ ### Rule contract
139
+
140
+ One module per legacy component, listed in its source's registry (`migrate/volt/index.ts`,
141
+ `migrate/base-elements/index.ts`). The contract is `migrate/lib/types.ts`:
142
+
143
+ ```ts
144
+ export const handles = ["CircularProgress", "CircularProgressProps"] as const
145
+ export function migrate(ctx: MigrateContext) {
146
+ ctx.move("CircularProgress", "Spinner") // onto the Zenith import; un-aliased bindings are renamed
147
+ ctx.move("CircularProgressProps", "SpinnerProps")
148
+ ctx.elements("CircularProgress").forEach((path) => {
149
+ ctx.jsx.removeAttr(path.node, "color")
150
+ const value = ctx.jsx.attr(path.node, "value")
151
+ if (value) {
152
+ ctx.jsx.removeAttr(path.node, "value")
153
+ ctx.todo(
154
+ path,
155
+ "CircularProgress",
156
+ `dropped ${ctx.jsx.print(value)}: Spinner is indeterminate`
157
+ )
158
+ }
159
+ })
160
+ }
161
+ ```
162
+
163
+ - `ctx.move(name, target?)` puts the legacy export on the Zenith import (merged into an existing
164
+ one); `ctx.keep(name, fix)` leaves it on the legacy import with one TODO at the import. A name
165
+ the rule neither moves nor keeps is kept with a generic TODO. A rule never edits imports itself.
166
+ - `ctx.todo(path, component, fix)` adds the comment (a `{/* */}` sibling inside JSX children)
167
+ and the report line. `ctx.ensureZenith(name)` imports a Zenith export for a per-element rewrite
168
+ (`ctx.jsx.rename(el, ctx.ensureZenith("Spinner"))`) when only some elements can move.
169
+ - `ctx.jsx` has the prop helpers: `attr`, `literal`, `removeAttr`, `renameAttr`, `setAttr`,
170
+ `mapAttrValue`, `wrapChildren`, `wrap`, `rename`, `styleObject`, `print`.
171
+ - A moved element must compile against Zenith's types: drop what has no equivalent and name it
172
+ in the TODO, or keep the whole name on the legacy import. Theming-only props (`color="primary"`)
173
+ are dropped silently; anything that changes behaviour or layout is reported.
174
+ - A rule that owns a bare module specifier (a stylesheet import) lists it in `handlesModules`.
175
+ - Fixtures: `__testfixtures__/from-<source>-<component>-<case>.{input,output}.tsx`, with `plain`,
176
+ `aliased`, `partial` (names left on the legacy import) and one `todo` shape. `fixtures.test.ts`
177
+ runs every transform on its fixtures, asserts one report per TODO and a no-op rerun, and
178
+ typechecks the outputs against Zenith's public types (`tsconfig.fixtures.json`, with
179
+ `legacy-modules.d.ts` stubbing the predecessors) the way a consumer ends up with them: a
180
+ `from-*` output is first run through the `radix-to-base-ui` transform, since its Zenith
181
+ API is the Radix-era one. `./run-fixtures.sh <transform>` is the
182
+ per-transform CLI over the same test.
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Prints a transform's output the way the project's formatter would, so the written file passes
3
+ * the project's Prettier check (#114). Prettier is resolved from the file's own location, so it is
4
+ * the project's copy under npm, bun and pnpm alike, and runs with the config that applies to the
5
+ * file. A project without Prettier gets recast's output as it is and one note on stderr to run
6
+ * its formatter on the changed files.
7
+ */
8
+ import { createRequire } from "node:module"
9
+ import { dirname, isAbsolute, relative, resolve, sep } from "node:path"
10
+
11
+ type Prettier = {
12
+ resolveConfig: (
13
+ file: string,
14
+ options?: { editorconfig?: boolean }
15
+ ) => Promise<Record<string, unknown> | null>
16
+ format: (
17
+ source: string,
18
+ options?: Record<string, unknown>
19
+ ) => Promise<string> | string
20
+ }
21
+
22
+ const loaded = new Map<string, Promise<Prettier | undefined>>()
23
+ let noted = false
24
+
25
+ export async function formatOutput(
26
+ output: string,
27
+ filePath: string
28
+ ): Promise<string> {
29
+ const file = resolve(filePath)
30
+ const prettier = await loadPrettier(file)
31
+ if (!prettier) {
32
+ if (!noted) {
33
+ noted = true
34
+ process.stderr.write(
35
+ `zenith codemods: no Prettier found from ${dirname(file)}; run your formatter on the changed files\n`
36
+ )
37
+ }
38
+ return output
39
+ }
40
+ try {
41
+ const config =
42
+ (await prettier.resolveConfig(file, { editorconfig: true })) ?? {}
43
+ return await prettier.format(output, { ...config, filepath: file })
44
+ } catch (error) {
45
+ process.stderr.write(
46
+ `zenith codemods: Prettier could not format ${file}: ${String(error)}\n`
47
+ )
48
+ return output
49
+ }
50
+ }
51
+
52
+ /** One resolution per directory: the same Prettier serves every file beside it. */
53
+ function loadPrettier(file: string): Promise<Prettier | undefined> {
54
+ const dir = dirname(file)
55
+ let pending = loaded.get(dir)
56
+ if (!pending) {
57
+ pending = resolvePrettier(file)
58
+ loaded.set(dir, pending)
59
+ }
60
+ return pending
61
+ }
62
+
63
+ async function resolvePrettier(file: string): Promise<Prettier | undefined> {
64
+ try {
65
+ const id = createRequire(file).resolve("prettier")
66
+ if (!installedAbove(id, file)) return undefined
67
+ const loadedModule = (await import(id)) as { default?: Prettier } & Prettier
68
+ const prettier = loadedModule.default ?? loadedModule
69
+ return typeof prettier.format === "function" ? prettier : undefined
70
+ } catch {
71
+ return undefined
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Only the project's own copy formats: one in a `node_modules` above the file. Bun resolves a
77
+ * missing package from its global cache, which would format a project that never uses Prettier
78
+ * with Prettier's defaults.
79
+ */
80
+ function installedAbove(resolved: string, file: string): boolean {
81
+ const index = resolved.indexOf(`${sep}node_modules${sep}`)
82
+ if (index < 0) return false
83
+ const project = resolved.slice(0, index)
84
+ const below = relative(project, file)
85
+ return below !== "" && !below.startsWith("..") && !isAbsolute(below)
86
+ }
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Accordion / AccordionSummary / AccordionDetails → Accordion / AccordionItem /
3
+ * AccordionTrigger / AccordionContent.
4
+ *
5
+ * An MUI Accordion is one collapsible item; Zenith's Accordion is the group. Each MUI Accordion
6
+ * becomes `<Accordion type="single" collapsible>` around one `<AccordionItem value="item">`:
7
+ *
8
+ * - `defaultExpanded` → `defaultValue="item"`; `expanded={open}` → `value={open ? "item" : ""}`;
9
+ * `onChange={(event, expanded) => …}` → `onValueChange={(expanded) => …}` with each read of
10
+ * `expanded` as `expanded === "item"`. `disabled` goes to the item.
11
+ * - `expandIcon` is dropped (the trigger draws its own chevron), as are MUI's paper and
12
+ * transition props. AccordionActions has no part: it stays, reported.
13
+ */
14
+ import type { ASTPath, JSXElement } from "jscodeshift"
15
+ import type { MigrateContext } from "../lib/types"
16
+ import {
17
+ attrExpression,
18
+ attrValue,
19
+ isTrue,
20
+ nestChildren,
21
+ printAttr,
22
+ renamedAttr,
23
+ stringIn,
24
+ takeAttrs,
25
+ valueHandler,
26
+ familyStays,
27
+ } from "./shared"
28
+
29
+ export const handles = [
30
+ "Accordion",
31
+ "AccordionProps",
32
+ "AccordionSummary",
33
+ "AccordionSummaryProps",
34
+ "AccordionDetails",
35
+ "AccordionDetailsProps",
36
+ "AccordionActions",
37
+ "AccordionActionsProps",
38
+ ] as const
39
+
40
+ const ITEM = "item"
41
+ const SILENT = [
42
+ "TransitionComponent",
43
+ "TransitionProps",
44
+ "square",
45
+ "elevation",
46
+ "variant",
47
+ "classes",
48
+ ]
49
+
50
+ export function migrate(ctx: MigrateContext): void {
51
+ if (
52
+ familyStays(
53
+ ctx,
54
+ ["Accordion", "AccordionSummary", "AccordionDetails", "AccordionActions"],
55
+ 'migrate this accordion by hand: Accordion type="single" collapsible > AccordionItem > AccordionTrigger + AccordionContent'
56
+ )
57
+ )
58
+ return
59
+ ctx.move("Accordion")
60
+ ctx.move("AccordionProps")
61
+ ctx.move("AccordionSummary", "AccordionTrigger")
62
+ ctx.move("AccordionSummaryProps", "AccordionTriggerProps")
63
+ ctx.move("AccordionDetails", "AccordionContent")
64
+ ctx.move("AccordionDetailsProps", "AccordionContentProps")
65
+ const actions = "no part for actions: put them at the end of AccordionContent"
66
+ ctx.keep("AccordionActions", actions)
67
+ ctx.keep("AccordionActionsProps", actions)
68
+
69
+ ctx.elements("Accordion").forEach((path) => migrateAccordion(ctx, path))
70
+ ctx.elements("AccordionSummary").forEach((path) => {
71
+ takeAttrs(ctx, path.node, [
72
+ "expandIcon",
73
+ "IconButtonProps",
74
+ "aria-controls",
75
+ "id",
76
+ ])
77
+ })
78
+ }
79
+
80
+ function migrateAccordion(
81
+ ctx: MigrateContext,
82
+ path: ASTPath<JSXElement>
83
+ ): void {
84
+ const { j, jsx } = ctx
85
+ const el = path.node
86
+ const reported: string[] = []
87
+ const item = () => stringIn(ctx, ITEM)
88
+
89
+ const expanded = jsx.removeAttr(el, "expanded")
90
+ const defaultExpanded = jsx.removeAttr(el, "defaultExpanded")
91
+ const onChange = jsx.removeAttr(el, "onChange")
92
+ const disabled = jsx.removeAttr(el, "disabled")
93
+ takeAttrs(ctx, el, SILENT)
94
+
95
+ const openWhen = (a: NonNullable<typeof expanded>) =>
96
+ isTrue(ctx, a)
97
+ ? ITEM
98
+ : j.conditionalExpression(
99
+ attrValue(j, a) as never,
100
+ item() as never,
101
+ stringIn(ctx, "") as never
102
+ )
103
+ const attrs = [
104
+ j.jsxAttribute(j.jsxIdentifier("type"), jsx.str("single")),
105
+ j.jsxAttribute(j.jsxIdentifier("collapsible")),
106
+ ]
107
+ el.openingElement.attributes = [
108
+ ...attrs,
109
+ ...(el.openingElement.attributes ?? []),
110
+ ]
111
+ if (expanded) jsx.setAttr(el, "value", openWhen(expanded))
112
+ else if (defaultExpanded && jsx.literal(defaultExpanded) !== false)
113
+ jsx.setAttr(el, "defaultValue", openWhen(defaultExpanded))
114
+
115
+ if (onChange) {
116
+ const handler = valueHandler(j, attrExpression(onChange), {
117
+ valueName: "value",
118
+ mapValue: (value) =>
119
+ j.binaryExpression("===", value as never, item() as never),
120
+ })
121
+ if (handler) jsx.setAttr(el, "onValueChange", handler)
122
+ else
123
+ reported.push(
124
+ `dropped ${printAttr(ctx, onChange)} (onValueChange(value) passes "item" when it opens and "" when it closes)`
125
+ )
126
+ }
127
+
128
+ const itemAttrs = [j.jsxAttribute(j.jsxIdentifier("value"), jsx.str(ITEM))]
129
+ if (disabled) itemAttrs.push(renamedAttr(j, disabled, "disabled"))
130
+ nestChildren(j, el, ctx.ensureZenith("AccordionItem"), itemAttrs)
131
+ if (reported.length) ctx.todo(path, "Accordion", reported.join("; "))
132
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Alert → Callout.
3
+ *
4
+ * - `severity` → `variant` (error → destructive); MUI's default is success, Callout's info, so an
5
+ * absent severity is written as `variant="success"`.
6
+ * - Children → `CalloutDescription`; `action` → a trailing `CalloutAction`; `onClose` →
7
+ * `dismissible onDismiss`.
8
+ * - `icon={false}` → `hideIcon`, another icon → `customIcon`.
9
+ * - MUI's `variant`, `color`, `elevation` and base-elements' `isSmall` are theming: dropped.
10
+ */
11
+ import type { ASTPath, JSXElement } from "jscodeshift"
12
+ import type { MigrateContext } from "../lib/types"
13
+ import {
14
+ SEVERITY,
15
+ fillCallout,
16
+ mapAttr,
17
+ printAttr,
18
+ printAttrs,
19
+ renamedAttr,
20
+ takeAttrs,
21
+ moveElements,
22
+ } from "./shared"
23
+
24
+ export const handles = ["Alert", "AlertProps"] as const
25
+
26
+ export function migrate(ctx: MigrateContext): void {
27
+ moveElements(ctx, "Alert", "Callout", (path) => migrateAlert(ctx, path))
28
+ ctx.move("AlertProps", "CalloutProps")
29
+ }
30
+
31
+ function migrateAlert(ctx: MigrateContext, path: ASTPath<JSXElement>): void {
32
+ const { j, jsx } = ctx
33
+ const el = path.node
34
+ const reported: string[] = []
35
+
36
+ if (!jsx.attr(el, "severity")) jsx.setAttr(el, "variant", "success")
37
+ else if (
38
+ !mapAttr(ctx, el, "severity", SEVERITY, {
39
+ rename: "variant",
40
+ fallback: "info",
41
+ })
42
+ )
43
+ reported.push(
44
+ `dropped ${printAttr(ctx, takeAttrs(ctx, el, ["severity"])[0])} (variant: success | info | warning | destructive)`
45
+ )
46
+
47
+ const icon = jsx.removeAttr(el, "icon")
48
+ if (icon && jsx.literal(icon) === false) jsx.setAttr(el, "hideIcon", null)
49
+ else if (icon)
50
+ el.openingElement.attributes = [
51
+ ...(el.openingElement.attributes ?? []),
52
+ renamedAttr(j, icon, "customIcon"),
53
+ ]
54
+ takeAttrs(ctx, el, ["color", "isSmall", "elevation", "square"])
55
+ const variant = jsx.attr(el, "variant")
56
+ if (
57
+ variant &&
58
+ !["success", "info", "warning", "destructive"].includes(
59
+ String(jsx.literal(variant))
60
+ )
61
+ )
62
+ takeAttrs(ctx, el, ["variant"])
63
+ const unsupported = takeAttrs(ctx, el, [
64
+ "iconMapping",
65
+ "closeText",
66
+ "classes",
67
+ ])
68
+ if (unsupported.length)
69
+ reported.push(
70
+ `dropped ${printAttrs(ctx, unsupported)} (no Callout equivalent)`
71
+ )
72
+
73
+ reported.push(
74
+ ...fillCallout(ctx, el, {
75
+ description: el.children ?? [],
76
+ onClose: jsx.removeAttr(el, "onClose"),
77
+ action: jsx.removeAttr(el, "action"),
78
+ })
79
+ )
80
+ if (reported.length) ctx.todo(path, "Alert", reported.join("; "))
81
+ }
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Avatar and AvatarGroup keep their names. MUI's initials are children; Zenith's are `initials`.
3
+ * Custom colours become the `color` family or a TODO; shapes other than round are reported.
4
+ */
5
+ import type { MigrateContext } from "../lib/types"
6
+ import { dropWithHint } from "./mui-props"
7
+
8
+ export const handles = [
9
+ "Avatar",
10
+ "AvatarProps",
11
+ "AvatarGroup",
12
+ "AvatarGroupProps",
13
+ ] as const
14
+
15
+ const COLORS =
16
+ "gray | blue | sky | cyan | teal | mint | green | lime | yellow | orange | bronze | red | pink | purple | indigo"
17
+
18
+ export function migrate(ctx: MigrateContext): void {
19
+ const { jsx } = ctx
20
+ const avatars = ctx.elements("Avatar")
21
+ const groups = ctx.elements("AvatarGroup")
22
+ ctx.moveElements("Avatar")
23
+ ctx.moveElements("AvatarGroup")
24
+ ctx.move("AvatarProps")
25
+ ctx.move("AvatarGroupProps")
26
+
27
+ avatars.forEach((path) => {
28
+ const el = path.node
29
+ const children = (el.children ?? []).filter(
30
+ (c) => !(c.type === "JSXText" && c.value.trim() === "")
31
+ )
32
+ if (children.length === 1) {
33
+ const [child] = children
34
+ if (child.type === "JSXText") {
35
+ jsx.setAttr(el, "initials", child.value.trim())
36
+ jsx.setChildren(el, [])
37
+ } else if (
38
+ child.type === "JSXExpressionContainer" &&
39
+ child.expression.type !== "JSXEmptyExpression"
40
+ ) {
41
+ const literal =
42
+ child.expression.type === "StringLiteral"
43
+ ? child.expression.value
44
+ : undefined
45
+ jsx.setAttr(el, "initials", literal ?? (child.expression as never))
46
+ jsx.setChildren(el, [])
47
+ } else {
48
+ const printed = ctx.j(child as never).toSource()
49
+ jsx.setChildren(el, [])
50
+ ctx.todo(
51
+ path,
52
+ "Avatar",
53
+ `dropped child ${printed}: Avatar shows src= or initials= only; an icon avatar is a styled span`
54
+ )
55
+ }
56
+ } else if (children.length > 1) {
57
+ jsx.setChildren(el, [])
58
+ ctx.todo(
59
+ path,
60
+ "Avatar",
61
+ "dropped children: Avatar shows src= or initials= only (one text child becomes initials=)"
62
+ )
63
+ }
64
+
65
+ const variant = jsx.mapAttrValue(el, "variant", {
66
+ circle: null,
67
+ circular: null,
68
+ })
69
+ if (variant === "unknown" || variant === "dynamic") {
70
+ const printed = jsx.print(jsx.attr(el, "variant")!)
71
+ jsx.removeAttr(el, "variant")
72
+ ctx.todo(
73
+ path,
74
+ "Avatar",
75
+ `dropped ${printed}: Avatar is round; a square one is a styled span`
76
+ )
77
+ }
78
+
79
+ for (const name of ["backgroundColor", "borderColor"]) {
80
+ const attr = jsx.attr(el, name)
81
+ if (!attr) continue
82
+ jsx.removeAttr(el, name)
83
+ ctx.todo(
84
+ path,
85
+ "Avatar",
86
+ `dropped ${jsx.print(attr)}: pick color= (${COLORS}), or leave it unset to hash alt/initials`
87
+ )
88
+ }
89
+ for (const name of ["sizes", "srcSet", "imgProps"]) {
90
+ const attr = jsx.attr(el, name)
91
+ if (!attr) continue
92
+ jsx.removeAttr(el, name)
93
+ ctx.todo(
94
+ path,
95
+ "Avatar",
96
+ `dropped ${jsx.print(attr)}: Avatar takes src and alt only`
97
+ )
98
+ }
99
+ dropWithHint(ctx, path, "Avatar")
100
+ })
101
+
102
+ groups.forEach((path) => {
103
+ const el = path.node
104
+ jsx.removeAttr(el, "spacing")
105
+ const variant = jsx.attr(el, "variant")
106
+ if (variant) {
107
+ jsx.removeAttr(el, "variant")
108
+ ctx.todo(
109
+ path,
110
+ "AvatarGroup",
111
+ `dropped ${jsx.print(variant)}: avatars are round`
112
+ )
113
+ }
114
+ dropWithHint(ctx, path, "AvatarGroup")
115
+ })
116
+ }