@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.
- package/README.md +37 -1
- package/codemods/README.md +182 -0
- package/codemods/format.ts +86 -0
- package/codemods/migrate/base-elements/accordion.ts +132 -0
- package/codemods/migrate/base-elements/alert.ts +81 -0
- package/codemods/migrate/base-elements/avatar.ts +116 -0
- package/codemods/migrate/base-elements/button.ts +188 -0
- package/codemods/migrate/base-elements/checkbox.ts +17 -0
- package/codemods/migrate/base-elements/chip.ts +87 -0
- package/codemods/migrate/base-elements/chip360.ts +162 -0
- package/codemods/migrate/base-elements/circular-progress.ts +73 -0
- package/codemods/migrate/base-elements/dialog.ts +323 -0
- package/codemods/migrate/base-elements/divider.ts +61 -0
- package/codemods/migrate/base-elements/feedback-message.ts +95 -0
- package/codemods/migrate/base-elements/icon-button.ts +203 -0
- package/codemods/migrate/base-elements/index.ts +55 -0
- package/codemods/migrate/base-elements/mui-props.ts +29 -0
- package/codemods/migrate/base-elements/notification.ts +98 -0
- package/codemods/migrate/base-elements/paper.ts +78 -0
- package/codemods/migrate/base-elements/select.ts +328 -0
- package/codemods/migrate/base-elements/shared.ts +910 -0
- package/codemods/migrate/base-elements/skeleton.ts +83 -0
- package/codemods/migrate/base-elements/switch.ts +19 -0
- package/codemods/migrate/base-elements/tabs.ts +222 -0
- package/codemods/migrate/base-elements/text-field.ts +425 -0
- package/codemods/migrate/base-elements/toggle-button.ts +185 -0
- package/codemods/migrate/base-elements/tooltip.ts +231 -0
- package/codemods/migrate/base-elements/typography.ts +247 -0
- package/codemods/migrate/base-elements/unsupported.ts +277 -0
- package/codemods/migrate/from-base-elements.ts +26 -0
- package/codemods/migrate/from-volt.ts +26 -0
- package/codemods/migrate/lib/imports.ts +399 -0
- package/codemods/migrate/lib/jsx.ts +313 -0
- package/codemods/migrate/lib/run-migration.ts +528 -0
- package/codemods/migrate/lib/source.ts +6 -0
- package/codemods/migrate/lib/todo.ts +107 -0
- package/codemods/migrate/lib/types.ts +114 -0
- package/codemods/migrate/volt/class-helpers.ts +37 -0
- package/codemods/migrate/volt/index.ts +18 -0
- package/codemods/migrate/volt/pagination.ts +26 -0
- package/codemods/migrate/volt/same-name.ts +293 -0
- package/codemods/migrate/volt/stylesheets.ts +18 -0
- package/codemods/migrate/volt/tanstack-types.ts +20 -0
- package/codemods/radix-to-base-ui.ts +677 -0
- package/dist/_virtual/_zenith-runtime-family_accordion.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_accordion.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_alert-dialog.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_alert-dialog.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_avatar.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_avatar.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_button.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_button.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_checkbox.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_checkbox.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_csp-provider.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_csp-provider.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_dialog.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_dialog.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_direction-provider.js +8 -0
- package/dist/_virtual/_zenith-runtime-family_direction-provider.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_menu.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_menu.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_merge-props.js +11 -0
- package/dist/_virtual/_zenith-runtime-family_merge-props.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_popover.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_popover.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_radio-group.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_radio-group.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_radio.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_radio.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_scroll-area.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_scroll-area.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_select.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_select.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_separator.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_separator.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_switch.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_switch.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_tabs.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_tabs.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_toast.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_toast.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_toggle-group.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_toggle-group.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_toggle.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_toggle.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_tooltip.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_tooltip.js.map +1 -0
- package/dist/_virtual/_zenith-runtime-family_use-render.js +7 -0
- package/dist/_virtual/_zenith-runtime-family_use-render.js.map +1 -0
- package/dist/components/accordion/accordion.js +179 -96
- package/dist/components/accordion/accordion.js.map +1 -1
- package/dist/components/alert-dialog/alert-dialog.js +243 -206
- package/dist/components/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/components/avatar/avatar.js +94 -82
- package/dist/components/avatar/avatar.js.map +1 -1
- package/dist/components/badge/badge.js +11 -11
- package/dist/components/breadcrumb/breadcrumb.js +69 -70
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/button/button.js +119 -102
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/checkbox/checkbox.js +68 -51
- package/dist/components/checkbox/checkbox.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.js +100 -90
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker-input.js +118 -108
- package/dist/components/date-time-picker/date-time-picker-input.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker-panel.js +91 -94
- package/dist/components/date-time-picker/date-time-picker-panel.js.map +1 -1
- package/dist/components/dialog/dialog.js +238 -228
- package/dist/components/dialog/dialog.js.map +1 -1
- package/dist/components/drawer/drawer.js +259 -321
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/dropdown-menu/dropdown-menu.js +533 -279
- package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -1
- package/dist/components/field/field-combobox.js +205 -186
- package/dist/components/field/field-combobox.js.map +1 -1
- package/dist/components/field/field-select.js +37 -22
- package/dist/components/field/field-select.js.map +1 -1
- package/dist/components/list/list-sortable.js +104 -0
- package/dist/components/list/list-sortable.js.map +1 -0
- package/dist/components/list/list.js +246 -324
- package/dist/components/list/list.js.map +1 -1
- package/dist/components/option-card/option-card.js +121 -117
- package/dist/components/option-card/option-card.js.map +1 -1
- package/dist/components/pill/pill.js +7 -7
- package/dist/components/popover/popover.js +223 -127
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/radio/radio-group-base.js +54 -0
- package/dist/components/radio/radio-group-base.js.map +1 -0
- package/dist/components/radio/radio.js +71 -60
- package/dist/components/radio/radio.js.map +1 -1
- package/dist/components/scroll-area/scroll-area.js +142 -108
- package/dist/components/scroll-area/scroll-area.js.map +1 -1
- package/dist/components/scroll-overflow/scroll-overflow.js +156 -127
- package/dist/components/scroll-overflow/scroll-overflow.js.map +1 -1
- package/dist/components/segmented-control/segmented-control.js +93 -81
- package/dist/components/segmented-control/segmented-control.js.map +1 -1
- package/dist/components/select/select.js +485 -310
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/separator/separator.js.map +1 -1
- package/dist/components/slot/compose-as-child.js +15 -12
- package/dist/components/slot/compose-as-child.js.map +1 -1
- package/dist/components/switch/switch.js +75 -68
- package/dist/components/switch/switch.js.map +1 -1
- package/dist/components/table/table-pagination.js +212 -175
- package/dist/components/table/table-pagination.js.map +1 -1
- package/dist/components/tabs/tabs.js +193 -190
- package/dist/components/tabs/tabs.js.map +1 -1
- package/dist/components/toast/toast.js +610 -148
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toggle/toggle-group.js +143 -32
- package/dist/components/toggle/toggle-group.js.map +1 -1
- package/dist/components/toggle/toggle.js +82 -49
- package/dist/components/toggle/toggle.js.map +1 -1
- package/dist/components/tooltip/tooltip.js +298 -138
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/index.d.ts +2336 -2130
- package/dist/index.js +24 -23
- package/dist/list/sortable/index.d.ts +29 -0
- package/dist/list/sortable/index.js +5 -0
- package/dist/{_virtual → list/sortable}/index.js.map +1 -1
- package/dist/packages/tokens/dist/delivery/index.js +10 -10
- package/dist/packages/tokens/dist/delivery/index.js.map +1 -1
- package/dist/packages/tokens/dist/generated/core.generated.js +6 -15
- package/dist/packages/tokens/dist/generated/core.generated.js.map +1 -1
- package/dist/packages/tokens/dist/generated/palette.generated.js +4 -5
- package/dist/packages/tokens/dist/generated/palette.generated.js.map +1 -1
- package/dist/packages/tokens/dist/generated/palette.meta.generated.js +5 -0
- package/dist/packages/tokens/dist/generated/palette.meta.generated.js.map +1 -0
- package/dist/packages/tokens/dist/install.js +40 -17
- package/dist/packages/tokens/dist/install.js.map +1 -1
- package/dist/renderer/runtime-contract.generated.js +8 -0
- package/dist/renderer/runtime-contract.generated.js.map +1 -0
- package/dist/renderer/served.js +39 -0
- package/dist/renderer/served.js.map +1 -0
- package/dist/tokens/core.meta.generated.js +2 -2
- package/dist/tokens/core.meta.generated.js.map +1 -1
- package/dist/tokens/index.d.ts +1028 -1028
- package/dist/tokens/index.js +863 -863
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/palette.meta.generated.js +5 -0
- package/dist/tokens/palette.meta.generated.js.map +1 -0
- package/dist/tokens.json +1 -1
- package/dist/vendor/.bun/@radix-ui_react-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-dialog/dist/index.js +57 -62
- package/dist/vendor/.bun/@radix-ui_react-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-dialog/dist/index.js.map +1 -1
- package/dist/vendor/.bun/@radix-ui_react-slot@1.2.3_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js +32 -38
- package/dist/vendor/.bun/@radix-ui_react-slot@1.2.3_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js.map +1 -1
- package/package.json +29 -21
- package/scripts/migration-diagnostics-core.mjs +302 -10
- package/scripts/migration-diagnostics.mjs +31 -8
- package/scripts/migration-sweep.mjs +10 -10
- package/testing/setup.cjs +87 -0
- package/dist/_virtual/index.js +0 -6
- package/dist/_virtual/index2.js +0 -5
- package/dist/_virtual/index2.js.map +0 -1
- package/dist/_virtual/use-sync-external-store-shim.development.js +0 -5
- package/dist/_virtual/use-sync-external-store-shim.development.js.map +0 -1
- package/dist/_virtual/use-sync-external-store-shim.production.js +0 -5
- package/dist/_virtual/use-sync-external-store-shim.production.js.map +0 -1
- package/dist/tokens/palette.generated.js +0 -5
- package/dist/tokens/palette.generated.js.map +0 -1
- package/dist/vendor/.bun/@floating-ui_core@1.8.0/vendor/@floating-ui/core/dist/floating-ui.core.js +0 -512
- package/dist/vendor/.bun/@floating-ui_core@1.8.0/vendor/@floating-ui/core/dist/floating-ui.core.js.map +0 -1
- package/dist/vendor/.bun/@floating-ui_dom@1.8.0/vendor/@floating-ui/dom/dist/floating-ui.dom.js +0 -396
- package/dist/vendor/.bun/@floating-ui_dom@1.8.0/vendor/@floating-ui/dom/dist/floating-ui.dom.js.map +0 -1
- 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
- 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
- package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.dom.js +0 -137
- package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.dom.js.map +0 -1
- package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.js +0 -129
- package/dist/vendor/.bun/@floating-ui_utils@0.2.12/vendor/@floating-ui/utils/dist/floating-ui.utils.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_number@1.1.1/vendor/@radix-ui/number/dist/index.js +0 -7
- package/dist/vendor/.bun/@radix-ui_number@1.1.1/vendor/@radix-ui/number/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-accordion@1.2.12_2b23df507bdda662/vendor/@radix-ui/react-accordion/dist/index.js +0 -240
- package/dist/vendor/.bun/@radix-ui_react-accordion@1.2.12_2b23df507bdda662/vendor/@radix-ui/react-accordion/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-alert-dialog@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-alert-dialog/dist/index.js +0 -128
- 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
- package/dist/vendor/.bun/@radix-ui_react-arrow@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-arrow/dist/index.js +0 -25
- package/dist/vendor/.bun/@radix-ui_react-arrow@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-arrow/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-avatar@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-avatar/dist/index.js +0 -76
- package/dist/vendor/.bun/@radix-ui_react-avatar@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-avatar/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-checkbox@1.3.3_2b23df507bdda662/vendor/@radix-ui/react-checkbox/dist/index.js +0 -252
- package/dist/vendor/.bun/@radix-ui_react-checkbox@1.3.3_2b23df507bdda662/vendor/@radix-ui/react-checkbox/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-collapsible@1.1.12_2b23df507bdda662/vendor/@radix-ui/react-collapsible/dist/index.js +0 -121
- package/dist/vendor/.bun/@radix-ui_react-collapsible@1.1.12_2b23df507bdda662/vendor/@radix-ui/react-collapsible/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-collection@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-collection/dist/index.js +0 -49
- package/dist/vendor/.bun/@radix-ui_react-collection@1.1.7_2b23df507bdda662/vendor/@radix-ui/react-collection/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-direction@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-direction/dist/index.js +0 -11
- package/dist/vendor/.bun/@radix-ui_react-direction@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-direction/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-dropdown-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-dropdown-menu/dist/index.js +0 -228
- 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
- package/dist/vendor/.bun/@radix-ui_react-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-menu/dist/index.js +0 -653
- package/dist/vendor/.bun/@radix-ui_react-menu@2.1.16_2b23df507bdda662/vendor/@radix-ui/react-menu/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-popover@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-popover/dist/index.js +0 -244
- package/dist/vendor/.bun/@radix-ui_react-popover@1.1.15_2b23df507bdda662/vendor/@radix-ui/react-popover/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-popper@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-popper/dist/index.js +0 -222
- package/dist/vendor/.bun/@radix-ui_react-popper@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-popper/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-radio-group@1.3.8_2b23df507bdda662/vendor/@radix-ui/react-radio-group/dist/index.js +0 -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
- package/dist/vendor/.bun/@radix-ui_react-roving-focus@1.1.11_2b23df507bdda662/vendor/@radix-ui/react-roving-focus/dist/index.js +0 -184
- 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
- package/dist/vendor/.bun/@radix-ui_react-scroll-area@1.2.10_2b23df507bdda662/vendor/@radix-ui/react-scroll-area/dist/index.js +0 -535
- 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
- package/dist/vendor/.bun/@radix-ui_react-select@2.2.6_2b23df507bdda662/vendor/@radix-ui/react-select/dist/index.js +0 -863
- package/dist/vendor/.bun/@radix-ui_react-select@2.2.6_2b23df507bdda662/vendor/@radix-ui/react-select/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-slot@1.2.4_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js +0 -63
- package/dist/vendor/.bun/@radix-ui_react-slot@1.2.4_0ac650c021fb1b59/vendor/@radix-ui/react-slot/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-switch@1.2.6_2b23df507bdda662/vendor/@radix-ui/react-switch/dist/index.js +0 -133
- package/dist/vendor/.bun/@radix-ui_react-switch@1.2.6_2b23df507bdda662/vendor/@radix-ui/react-switch/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-tabs@1.1.13_2b23df507bdda662/vendor/@radix-ui/react-tabs/dist/index.js +0 -164
- package/dist/vendor/.bun/@radix-ui_react-tabs@1.1.13_2b23df507bdda662/vendor/@radix-ui/react-tabs/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-toggle-group@1.1.11_2b23df507bdda662/vendor/@radix-ui/react-toggle-group/dist/index.js +0 -138
- 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
- package/dist/vendor/.bun/@radix-ui_react-toggle@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-toggle/dist/index.js +0 -34
- package/dist/vendor/.bun/@radix-ui_react-toggle@1.1.10_2b23df507bdda662/vendor/@radix-ui/react-toggle/dist/index.js.map +0 -1
- package/dist/vendor/.bun/@radix-ui_react-tooltip@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-tooltip/dist/index.js +0 -340
- package/dist/vendor/.bun/@radix-ui_react-tooltip@1.2.8_2b23df507bdda662/vendor/@radix-ui/react-tooltip/dist/index.js.map +0 -1
- 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
- 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
- package/dist/vendor/.bun/@radix-ui_react-use-previous@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-use-previous/dist/index.js +0 -9
- 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
- package/dist/vendor/.bun/@radix-ui_react-use-size@1.1.1_0ac650c021fb1b59/vendor/@radix-ui/react-use-size/dist/index.js +0 -28
- 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
- package/dist/vendor/.bun/@radix-ui_react-visually-hidden@1.2.3_2b23df507bdda662/vendor/@radix-ui/react-visually-hidden/dist/index.js +0 -33
- 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
- package/dist/vendor/.bun/sonner@2.0.7_6f4b9a1cfb20c0ae/vendor/sonner/dist/index.js +0 -747
- package/dist/vendor/.bun/sonner@2.0.7_6f4b9a1cfb20c0ae/vendor/sonner/dist/index.js.map +0 -1
- 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
- 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
- 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
- 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
- package/dist/vendor/.bun/use-sync-external-store@1.7.0_62547eec5a2188e3/vendor/use-sync-external-store/shim/index.js +0 -11
- 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
|
+
}
|