# Migrating to Spectrum 2

An automated upgrade assistant is available by running the following command in the project you want to upgrade:

```bash
npm install @react-spectrum/codemods s1-to-s2
```

To only upgrade specific components, provide a `--components` argument with a comma-separated list of components to upgrade:

```bash
npm install @react-spectrum/codemods s1-to-s2 --components=Button,TextField
```

The following arguments are also available:

* `--path` - Path to apply the upgrade changes to. Defaults to the current directory (`.`)
* `--dry` - Runs the upgrade assistant without making changes to components
* `--ignore-pattern` - Ignore files that match the provided glob expression. Defaults to `'**/node_modules/**'`

For cases that the upgrade assistant doesn't handle automatically or where you'd rather upgrade some components manually, use the guide below.

Note that <PendingBadge/> indicates that future changes will occur before the final release, and the current solution should be considered temporary.

## Components

### All components

* Update imports to use the `@react-spectrum/s2` package instead of `@adobe/react-spectrum` or individual packages like `@react-spectrum/button`
* Update [style props](https://react-spectrum.adobe.com/react-spectrum/styling.html#style-props) to use the style macro instead. See the 'Style props' section below

### Accordion

* Update `Item` to be `Disclosure`. `Disclosure` should now consist of two children: `DisclosureTitle` and `DisclosurePanel`. Note that you can now add interactive elements inside the header and adjacent to the title by using the `DisclosureHeader` component with the `DisclosureTitle` and interactive elements inside.
* Update `Item`'s title prop to be a child of `DisclosureTitle`
* Update children of `Item` to be children of `DisclosurePanel`
* Update `key` to be `id` (and keep `key` if rendered inside `array.map`)
* Remove `disabledKeys` and add `isDisabled` to individual `Disclosure` components
* Add `allowsMultipleExpanded` to allow multiple `Disclosure` components to be expanded at once (previously default behavior)

### ActionBar

* Remove `ActionBarContainer` and move `ActionBar` to `renderActionBar` prop of `TableView` or `CardView`
* Update `Item` to `ActionButton`
* Update root level `onAction` to be called via `onPress` on each `ActionButton`
* Apply `isDisabled` directly on each `ActionButton` or `ToggleButton` instead of root level `disabledKeys`
* Update `key` to be `id` (and keep `key` if rendered inside `array.map`)
* Convert dynamic collections render function to `items.map`
* <PendingBadge/> Comment out `buttonLabelBehavior` (it has not been implemented yet)

### ActionButton

No updates needed.

### ActionMenu

* <PendingBadge/> Comment out `closeOnSelect` (it has not been implemented yet)
* <PendingBadge/> Comment out `trigger` (it has not been implemented yet)
* Update `Item` to be a `MenuItem`

### ActionGroup

* Use `ActionButtonGroup` if you are migrating from an `ActionGroup` that didn't allow for selection. `ActionButtonGroup` takes `ActionButtons` as children.
* Use `ToggleButtonGroup` if you are migrating from an `ActionGroup` that used single or multiple selection. `ToggleButtonGroup` takes `ToggleButtons` as children.
* <PendingBadge/> Comment out `overflowMode` (it has not been implemented yet)
* <PendingBadge/> Comment out `buttonLabelBehavior` (it has not been implemented yet)
* <PendingBadge/> Comment out `summaryIcon` (it has not been implemented yet)
* Update root level `onAction` to called via `onPress` on each `ActionButton`
* Apply `isDisabled` directly on each `ActionButton` or `ToggleButton` instead of root level `disabledKeys`
* Update `key` to be `id` (and keep `key` if rendered inside `array.map`)
* Convert dynamic collections render function to `items.map`

### AlertDialog

No updates needed.

### Avatar

* <PendingBadge/> Comment out `isDisabled` (it has not been implemented yet)
* Update `size` to be a pixel value if it currently matches `'avatar-size-*'`

### Badge

* Change `variant="info"` to `variant="informative"`

### Breadcrumbs

* <PendingBadge/> Comment out `showRoot` (it has not been implemented yet)
* <PendingBadge/> Comment out `isMultiline` (it has not been implemented yet)
* <PendingBadge/> Comment out `autoFocusCurrent` (it has not been implemented yet)
* Remove `size="S"` (Small is no longer a supported size in Spectrum 2)
* Update `Item` to be a `Breadcrumb`

### Button

* Change `variant="cta"` to `variant="accent"`
* Change `variant="overBackground"` to `variant="primary" staticColor="white"`
* Change `style` to `fillStyle`
* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* If `href` is present, the `Button` should be converted to a `LinkButton`
* Remove `elementType` (it is no longer supported in Spectrum 2)

### ButtonGroup

No updates needed.

### Calendar

No updates needed.

### Checkbox

No updates needed.

### CheckboxGroup

* Remove `showErrorIcon` (it has been removed due to accessibility issues)

### ColorArea

* Remove `size` and instead provide a size via the style macro (i.e. `styles={style({size: 20})}`)

### ColorField

* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)

### ColorSlider

* Remove `showValueLabel` (it has been removed due to accessibility issues)

### ColorSwatch

No updates needed.

### ColorWheel

* Remove `size` and instead provide a size via the style macro (i.e. `styles={style({size: 20})}`)

### ComboBox

* Change `menuWidth` value from a `DimensionValue` to a pixel value
* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)
* Update `Item` to be a `ComboBoxItem`

### DateField

* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)

### DatePicker

* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)

### DateRangePicker

* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)

### Dialog

* Update children to move render props from being the second child of `DialogTrigger` to being a child of `Dialog`
* Remove `onDismiss` and use `onOpenChange` on the `DialogTrigger`, or `onDismiss` on the `DialogContainer` instead
* `Dialog` is now meant specifically for rendering modal dialogs only and follows the same preset layout as before
* If you are trying to create a dialog with a custom layout use `CustomDialog`
* If you are trying to create a fullscreen dialog use `FullscreenDialog`
* If you are trying to create a popover dialog use `Popover`
* Supports `isKeyboardDismissDisabled` in place of `DialogTrigger`
* Supports `isDismissible` in place of `DialogTrigger`. Note the fixed spelling from previous `isDismissible` prop.
* Supports `role: "dialog" | "alertdialog"`

### DialogContainer

* Remove `type`, this is dependent on the dialog level child that you use (e.g. `Dialog`, `FullscreenDialog`, `Popover`)
* Remove `isDismissable`, prop now exists on the dialog level component as `isDismissible`
* Remove `isKeyboardDismissDisabled`, prop now exists on the dialog level component

### DialogTrigger

* <PendingBadge/> Comment out `type="tray"` (`Tray` has not been implemented yet)
* <PendingBadge/> Comment out `mobileType` (`Tray` and other types have not been implemented yet for `Popover`)
* Remove `targetRef` (it is no longer supported in Spectrum 2)
* Update `children` to remove render props usage, and note that the `close` function was moved from `DialogTrigger` to `Dialog`
* Remove `containerPadding`, prop now exists on the `Popover` component
* Remove `crossOffset`, prop now exists on the `Popover` component
* Remove `hideArrow`, prop now exists on the `Popover` component
* Remove `isDismissable`, prop now exists on the dialog level component as `isDismissible`
* Remove `isKeyboardDismissDisabled`, prop now exists on the dialog level component
* Remove `offset`, prop now exists on the `Popover` component
* Remove `placement`, prop now exists on the `Popover` component
* Remove `shouldFlip`, prop now exists on the `Popover` component
* Remove `type`, this is dependent on the dialog level child that you use (e.g. `Dialog`, `FullscreenDialog`, `Popover`)

### Divider

* Remove Divider component if within a Dialog (Updated design for Dialog in Spectrum 2)

### Flex

* Update `Flex` to be a `div` and apply flex styles using the style macro (i.e. `<div className={style({display: 'flex'})} />`)

### Form

* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Remove `isReadOnly` (it is no longer supported in Spectrum 2)
* Remove `validationState` (it is no longer supported in Spectrum 2)
* Remove `validationBehavior` (it is no longer supported in Spectrum 2)

### Grid

* Update `Grid` to be a `div` and apply grid styles using the style macro (i.e. `<div className={style({display: 'grid'})} />`)

### IllustratedMessage

* Update illustrations to be from `@react-spectrum/s2/illustrations`. See Illustrations

### InlineAlert

* Change `variant="info"` to `variant="informative"`

### Item

* If within `Menu`: Update `Item` to be a `MenuItem`
* If within `ActionMenu`: Update `Item` to be a `MenuItem`
* If within `TagGroup`: Update `Item` to be a `Tag`
* If within `Breadcrumbs`: Update `Item` to be a `Breadcrumb`
* If within `Picker`: Update `Item` to be a `PickerItem`
* If within `ComboBox`: Update `Item` to be a `ComboBoxItem`
* If within `ListBox`: Update `Item` to be a `ListBoxItem`
* If within `TabList`: Update `Item` to be a `Tab`
* If within `TabPanels`: Update `Item` to be a `TabPanel` and remove surrounding `TabPanels`
* Update `key` to be `id` (and keep `key` if rendered inside `array.map`)

### Link

* Change `variant="overBackground"` to `staticColor="white"`
* If `a` was used inside `Link` (legacy API), remove the `a` and apply props (i.e `href`) directly to `Link`

### ListBox

* Update `Item` to be a `ListBoxItem`

### Menu

* Update `Item` to be a `MenuItem`

### MenuTrigger

* <PendingBadge/> Comment out `closeOnSelect` (it has not been implemented yet)

### NumberField

* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)

### Picker

* Change `menuWidth` value from a `DimensionValue` to a pixel value
* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)
* Update `Item` to be a `PickerItem`
* Change `isLoading` to `loadingState` and provide the appropriate loading state.
* Update `defaultSelectedKey` and `selectedKey` to be `defaultValue` and `value` respectively. See the [Picker](Picker.html#value) documentation for more details.

### ProgressBar

* Change `variant="overBackground"` to `staticColor="white"`
* <PendingBadge/> Comment out `labelPosition` (it has not been implemented yet)
* <PendingBadge/> Comment out `showValueLabel` (it has not been implemented yet)

### ProgressCircle

* Change `variant="overBackground"` to `staticColor="white"`

### Radio

No updates needed.

### RadioGroup

* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)
* Remove `showErrorIcon` (it has been removed due to accessibility issues)

### RangeCalendar

No updates needed.

### RangeSlider

* Remove `showValueLabel` (it has been removed due to accessibility issues)
* <PendingBadge/> Comment out `getValueLabel` (it has not been implemented yet)
* <PendingBadge/> Comment out `orientation` (it has not been implemented yet)

### SearchField

* <PendingBadge/> Comment out icon (it has not been implemented yet)
* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)

### Section

* If within `Menu`: Update `Section` to be a `MenuSection`
* If within `Picker`: Update `Section` to be a `PickerSection`

### Slider

* Remove `isFilled` (Slider is always filled in Spectrum 2)
* Remove `trackGradient` (Not supported in S2 design)
* Remove `showValueLabel` (it has been removed due to accessibility issues)
* <PendingBadge/> Comment out `getValueLabel` (it has not been implemented yet)
* <PendingBadge/> Comment out `orientation` (it has not been implemented yet)

### StatusLight

* Remove `isDisabled` (it is no longer supported in Spectrum 2)
* Change `variant="info"` to `variant="informative"`

### SubmenuTrigger

No updates needed.

### Switch

No updates needed.

### TableView

* For `Column` and `Row`: Update `key` to be `id` (and keep `key` if rendered inside `array.map`)
* For dynamic tables, pass a `columns` prop into `Row`
* For `Row`: Update dynamic render function to pass in `column` instead of `columnKey`
* Move `loadingState` and `onLoadMore` from `TableBody` to `TableView`
* <PendingBadge/> Comment out `UNSTABLE_allowsExpandableRows` (it has not been implemented yet)
* <PendingBadge/> Comment out `UNSTABLE_onExpandedChange` (it has not been implemented yet)
* <PendingBadge/> Comment out `UNSTABLE_expandedKeys` (it has not been implemented yet)
* <PendingBadge/> Comment out `UNSTABLE_defaultExpandedKeys` (it has not been implemented yet)

### Tabs

* Inside `TabList`: Update `Item` to be `Tab`
* Update `items` on `Tabs` to be on `TabList`
* Inside `TabPanels`: Update `Item` to be a `TabPanel` and remove the surrounding `TabPanels`
* Remove `isEmphasized` (it is no longer supported in Spectrum 2)
* Remove `isQuiet` (it is no longer supported in Spectrum 2)

### TagGroup

* Rename `actionLabel` to `groupActionLabel`
* Rename `onAction` to `onGroupAction`
* Change `validationState="invalid"` to `isInvalid`
* Update `Item` to be `Tag`

### TextArea

* <PendingBadge/> Comment out `icon` (it has not been implemented yet)
* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)

### TextField

* <PendingBadge/> Comment out `icon` (it has not been implemented yet)
* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)

### TimeField

* Remove `isQuiet` (it is no longer supported in Spectrum 2)
* Change `validationState="invalid"` to `isInvalid`
* Remove `validationState="valid"` (it is no longer supported in Spectrum 2)

### ToggleButton

No updates needed.

### Tooltip

* Remove `variant` (it is no longer supported in Spectrum 2)
* Remove `placement` and add to the parent `TooltipTrigger` instead
* Remove `showIcon` (it is no longer supported in Spectrum 2)
* Remove `isOpen` and add to the parent `TooltipTrigger` instead

### TooltipTrigger

* Update placement prop to have one value (i.e. Update `placement="bottom left"` to be `placement="bottom"`)

### TreeView

If migrating from TreeView version 3.0.0-beta.3 or before, please do the following. Otherwise, no updates needed.

* Update content within `TreeViewItem` to be wrapped in `TreeViewContentItem`

### View

* Update `View` to be a `div` and apply styles using the style macro

### Well

Update `Well` to be a `div` and apply styles using the style macro:

```tsx
<div className={style({
  display: 'block',
  textAlign: 'start',
  padding: 16,
  minWidth: 160,
  marginTop: 4,
  borderWidth: 1,
  borderRadius: 'sm',
  borderStyle: 'solid',
  borderColor: 'transparent-black-75',
  font: 'body-sm'
})} />
```

## Style props

React Spectrum v3 supported a limited set of [style props](https://react-spectrum.adobe.com/react-spectrum/styling.html#style-props) for layout and positioning using Spectrum-defined values. Usage of these should be updated to instead use the style macro.

### Border width

Affected style props: `borderWidth`, `borderStartWidth`, `borderEndWidth`, `borderTopWidth`, `borderBottomWidth`, `borderXWidth`, `borderYWidth`.

Border widths should be updated to use pixel values. Use the following mappings:

| Spectrum 1 | Spectrum 2 |
| ------ | ------ |
| `'none'` | `0` |
| `'thin'` | `1` |
| `'thick'` | `2` |
| `'thicker'` | `4` |
| `'thickest'` | `'[8px]'` |

### Border radius

Affected style props: `borderRadius`, `borderTopStartRadius`, `borderTopEndRadius`, `borderBottomStartRadius`, `borderBottomEndRadius`.

Border radius values should be updated to use pixel values. Use the following mappings:

| Spectrum 1 | Spectrum 2 |
| ------ | ------ |
| `'xsmall'` | `'[1px]'` |
| `'small'` | `'sm'` |
| `'regular'` | `'default'` |
| `'medium'` | `'lg'` |
| `'large'` | `'xl'` |

### Dimension values

Affected style props: `width`, `minWidth`, `maxWidth`, `height`, `minHeight`, `maxHeight`, `margin`, `marginStart`, `marginEnd`, `marginTop`, `marginBottom`, `marginX`, `marginY`, `top`, `bottom`, `left`, `right`, `start`, `end`, `flexBasis`, `gap`, `columnGap`, `rowGap`, `padding`, `paddingX`, `paddingY`, `paddingStart`, `paddingEnd`, `paddingTop`, `paddingBottom`.

Dimension values should be converted to pixel values. Use the following mappings:

| Spectrum 1 | Spectrum 2 |
| ------ | ------ |
| `'size-0'` | `0` |
| `'size-10'` | `1` |
| `'size-25'` | `2` |
| `'size-40'` | `3` |
| `'size-50'` | `4` |
| `'size-65'` | `5` |
| `'size-75'` | `6` |
| `'size-85'` | `7` |
| `'size-100'` | `8` |
| `'size-115'` | `9` |
| `'size-125'` | `10` |
| `'size-130'` | `11` |
| `'size-150'` | `12` |
| `'size-160'` | `13` |
| `'size-175'` | `14` |
| `'size-200'` | `16` |
| `'size-225'` | `18` |
| `'size-250'` | `20` |
| `'size-275'` | `22` |
| `'size-300'` | `24` |
| `'size-325'` | `26` |
| `'size-350'` | `28` |
| `'size-400'` | `32` |
| `'size-450'` | `36` |
| `'size-500'` | `40` |
| `'size-550'` | `44` |
| `'size-600'` | `48` |
| `'size-675'` | `54` |
| `'size-700'` | `56` |
| `'size-800'` | `64` |
| `'size-900'` | `72` |
| `'size-1000'` | `80` |
| `'size-1200'` | `96` |
| `'size-1250'` | `100` |
| `'size-1600'` | `128` |
| `'size-1700'` | `136` |
| `'size-2000'` | `160` |
| `'size-2400'` | `192` |
| `'size-3000'` | `240` |
| `'size-3400'` | `272` |
| `'size-3600'` | `288` |
| `'size-4600'` | `368` |
| `'size-5000'` | `400` |
| `'size-6000'` | `480` |
| `'static-size-0'` | `0` |
| `'static-size-10'` | `1` |
| `'static-size-25'` | `2` |
| `'static-size-40'` | `3` |
| `'static-size-50'` | `4` |
| `'static-size-65'` | `5` |
| `'static-size-100'` | `8` |
| `'static-size-115'` | `9` |
| `'static-size-125'` | `10` |
| `'static-size-130'` | `11` |
| `'static-size-150'` | `12` |
| `'static-size-160'` | `13` |
| `'static-size-175'` | `14` |
| `'static-size-200'` | `16` |
| `'static-size-225'` | `18` |
| `'static-size-250'` | `20` |
| `'static-size-300'` | `24` |
| `'static-size-400'` | `32` |
| `'static-size-450'` | `36` |
| `'static-size-500'` | `40` |
| `'static-size-550'` | `44` |
| `'static-size-600'` | `48` |
| `'static-size-700'` | `56` |
| `'static-size-800'` | `64` |
| `'static-size-900'` | `72` |
| `'static-size-1000'` | `80` |
| `'static-size-1200'` | `96` |
| `'static-size-1700'` | `136` |
| `'static-size-2400'` | `192` |
| `'static-size-2600'` | `208` |
| `'static-size-3400'` | `272` |
| `'static-size-3600'` | `288` |
| `'static-size-4600'` | `368` |
| `'static-size-5000'` | `400` |
| `'static-size-6000'` | `480` |
| `'single-line-height'` | `32` |
| `'single-line-width'` | `192` |

### Break points

Break points previously used in style props can be used in the style macro with updated keys. Use the following mappings:

| Spectrum 1 | Spectrum 2 |
| ------ | ------ |
| `base` | `default` |
| `S` | `sm` |
| `M` | `md` |
| `L` | `lg` |
