# Canvas Kit 4.0 Upgrade Guide

Below are the breaking changes made in Canvas Kit v4. Please reach out if you have any questions
about the update.

CSS users rejoice! :tada: No breaking changes in this release. The following changes all relate to
our React infrastructure and components.

- [Infrastructure Upgrades](#infrastructure-upgrades)
- [Theming Changes](#theming-changes)
- [Breaking Component Changes](#breaking-component-changes)
  - [General](#general)
  - [Core](#core)
  - [Avatar](#avatar)
  - [Button](#button)
  - [IconButtonToggleGroup](#iconbuttontogglegroup)
  - [InputProvider](#inputprovider)
  - [Modal](#modal)
  - [DrawerHeader](#drawerheader)
  - [SearchBar](#searchbar)
  - [Menu](#menu)
  - [Popup](#popup)
  - [SidePanel](#sidepanel)
  - [Skeleton](#skeleton)
  - [Popper](#popper)
  - [Tooltip](#tooltip)

## Infrastructure Upgrades

Breaking:

- React & ReactDOM upgraded to 16.12 (https://github.com/Workday/canvas-kit/pull/533)
  - We are now fully adopting hooks, so version 16.7 and below are no longer supported

Non-breaking:

- Typescript upgraded to v3.8 (https://github.com/Workday/canvas-kit/pull/533)
  - [downlevel-dts](https://github.com/sandersn/downlevel-dts) was used to resolve breaking changes
    in `typescript@3.7`, so older versions of typescript are still supported. However, it is
    recommended to use v3.8.
- Many of our dependencies have been updated to address a low level vulnerability. This shouldn't
  affect your day to day usage of Canvas Kit.

## Theming Changes

We have promoted all of the theming functionality out of Canvas Kit Labs.
[It now lives in `@workday/canvas-kit-react-common`](https://github.com/Workday/canvas-kit/tree/v4.0.0/modules/common/react/lib/theming).
This includes the `CanvasProvider` component. We've also made some stability improvements (see
below).

PRs:

- https://github.com/Workday/canvas-kit/pull/558
- https://github.com/Workday/canvas-kit/pull/594
- https://github.com/Workday/canvas-kit/pull/593

#### Changes

- We now call `createCanvasTheme` as part of our internal `useTheme` hook to ensure we are always
  accessing defined theme fields. It is no longer required to wrap your partial theme with
  `createCanvasTheme` before passing it into `CanvasProvider`/`ThemeProvider`. `CanvasProvider` now
  accepts a theme of the type `PartialEmotionCanvasTheme`.
- Because of this change, if you're using the Canvas theme passed from emotion within your
  components, you now need to wrap the theme (e.g. `useTheme(theme)`) to ensure all fields are
  defined.
- In order to better support non-Canvas themes, the `CanvasTheme` object now needs to be namespaced
  under `canvas`:

```tsx
{
  theme: {
    canvas: {
      palette: {
        // ...
      },
      breakpoints: {
        // ...
      },
      direction: ContentDirection.LTR
    }
  }
}
```

- This means several type references have changed:

  - `CanvasTheme` > `EmotionCanvasTheme`
  - `PartialCanvasTheme` > `PartialEmotionCanvasTheme`

## Breaking Component Changes

### General

- We've moved away from using `SyntheticEvent` typing in favor of using more accurate types
  (https://github.com/Workday/canvas-kit/pull/499)
- Popper dependency has been upgraded to v2 and now all popups use React Portals (potential z-index
  breaking change)
- Several ARIA label props have been renamed for clarity
  (https://github.com/Workday/canvas-kit/pull/551). These changes are broken down by component
  below.
- Our `focusRing` utility has been updated with a new API to support theming and improve legibility.
  (https://github.com/Workday/canvas-kit/pull/558 & https://github.com/Workday/canvas-kit/pull/726).
  Example:
  ```tsx
  focusRing(2, 2, true, false, buttonColors.focusRingInner, buttonColors.focusRingOuter);
  ```
  becomes
  ```tsx
  focusRing({
    separation: 2,
    innerColor: buttonColors.focusRingInner,
    outerColor: buttonColors.focusRingOuter,
  });
  ```

### Core

We've made minor changes to our link variant text styles based on feedback from accessibility. As
part of this change, we've also added a new `Hyperlink` component to
`@workday/canvas-kit-react-button` to make applying these styles easier.

We've updated to `@workday/canvas-colors-web@2.0.0`, which comes with a few breaking changes:

- `canvas.colors.primary` & `colors.primary` were previously deprecated and are no longer available
  under this namespace. All of these semantic colors are still accessible via the semantic colors
  exports (`buttonColors`, `inputColors`, etc.)
- `canvas.colors.gradients` & `colors.gradients` exports have been moved to `canvas.gradients` or
  `gradients`.
- `canvas.inputColors.warning` & `inputColors.warning` exports have been changed to
  `*inputColors.alert` to match other conventions
- Narrow incorrect `CanvasColor` type from `string | undefined` to a list of all canvas colors

PRs:

- https://github.com/Workday/canvas-kit/pull/541
- https://github.com/Workday/canvas-kit/pull/706

### Avatar

- `AvatarButton` has been removed. By default `Avatar` will now be a button. If you need the old
  plain div version you can pass the prop `as="div"`.
- The component is now a functional component instead of a class. If you are using ref on the class
  version it will not be pointing to the same thing. `buttonRef` has changed to `ref` since it could
  now reference a button or a div
- Visual change: Avatar images appear once they are load. While loading or if they fail to load the
  default icon will be shown. So you may want to check which variant you are using even in the image
  case.

PR:

- https://github.com/Workday/canvas-kit/pull/614

### Button

We've refactored our Button components to simplify logic and add support for theming.

PRs:

- https://github.com/Workday/canvas-kit/pull/471
- https://github.com/Workday/canvas-kit/pull/509
- https://github.com/Workday/canvas-kit/pull/527
- https://github.com/Workday/canvas-kit/pull/540
- https://github.com/Workday/canvas-kit/pull/541

#### Changes

- Some of the button variants have been split into different components to prevent invalid API
  combinations. `DeleteButton`, `HighlightButton`, and `OutlineButton` are now separate components
  with their own interface. Here are some of the invalid prop combinations that are no longer
  possible:

  - Delete button with a data label or icon
  - Dropdown button with a data label or icon
  - Highlight button with a data label
  - Highlight button without an icon
  - Dropdown with variants other than primary and secondary
  - Small buttons with an icon or data label
  - Small Highlight button
  - Small Dropdown button
  - etc.

  - **Required changes:**
    - `<Button variant={Button.Variant.Delete}>` > `<DeleteButton>`
    - `<Button variant={Button.Variant.Highlight}>` > `<HighlightButton>`
    - `<Button variant={Button.Variant.OutlineSecondary}>` > `<OutlineButton>`
    - `<Button variant={Button.Variant.OutlinePrimary}>` >
      `<OutlineButton variant={OutlineButton.Variant.Primary}>`
    - `<Button variant={Button.Variant.OutlineInverse}>` >
      `<OutlineButton variant={OutlineButton.Variant.Inverse}>`
    - All invalid prop combinations (noted above) will need to be remedied

- The majority of the button variant types have changed. `BaseButtonProps` is no longer available as
  each button variant has their own interface.
- React >= 16.8 required for hooks
- Spacing within buttons has been corrected to match the specs. This may cause horizontal flow
  changes
- `TextButton` now only allows `TextButtonSize.Small` and `TextButtonSize.Medium`. **Required
  changes:**
  - `TextButtonSize.Medium` > `"small"` or `TextButtonSize.Small`
  - `TextButtonSize.Large` > `"medium"` or `TextButtonSize.Medium`
- All caps variants for TextButton have been turned into a prop
  - **Required changes:**
  - `<TextButton variant={TextButton.Variant.AllCaps}>` > `<TextButton allCaps={true}>`
  - `<TextButton variant={TextButton.Variant.InverseAllCaps}>` >
    `<TextButton variant={TextButton.Variant.Inverse} allCaps={true}>`
- All caps large/medium text buttons now correctly use 16px font (up from 14)
- Text button has some minor visual changes for various interaction states

#### Quality of Life changes:

With the new components for variants and the simpler types for sizes, the code for complex buttons
is much more concise.

Before:

```tsx
<Button variant={Button.Variant.OutlineSecondary} size={Button.Size.Large}>
  Label
</Button>
```

After:

```tsx
<OutlineButton size="large">Label</OutlineButton>
```

---

### IconButtonToggleGroup

This component has been renamed to `SegmentedControl` and has been converted into it's own component
(`@workday/canvas-kit-react-segmented-control`). `IconButtonToggleGroup` is no longer exported from
`@workday/canvas-kit-react-button`.

PRs:

- https://github.com/Workday/canvas-kit/pull/505
- https://github.com/Workday/canvas-kit/pull/524

Before:

```tsx
import {IconButtonToggleGroup} from '@workday/canvas-kit-react-button';

<IconButtonToggleGroup>
  <IconButton icon={listViewIcon} title="List View" aria-label="List View" />
  <IconButton icon={worksheetsIcon} title="Worksheets" aria-label="Worksheets" />
</IconButtonToggleGroup>;
```

After:

```tsx
import {SegmentedControl} from '@workday/canvas-kit-react-segmented-control';

<SegmentedControl>
  <IconButton icon={listViewIcon} title="List View" aria-label="List View" />
  <IconButton icon={worksheetsIcon} title="Worksheets" aria-label="Worksheets" />
</SegmentedControl>;
```

---

### InputProvider

Our `InputProvider` did not work with React Portals (since the popups get placed outside of the
`InputProvider` container `div`. `InputProvider` provider has been updated to use `document.body`
(configurable with the `containerElement` prop).

PR: https://github.com/Workday/canvas-kit/pull/546

---

### Modal

Modal now uses React Portals which could cause a visual breaking change related to z-indexing.
Modals now use a popup stack manager that controls z-indexing. Adding your own zIndex will no longer
have any effect. Modals accurately handle escape key, so `closeOnEscape` has been removed. If you
used this feature, you may want to look into the PopupStack.

PRs:

- https://github.com/Workday/canvas-kit/pull/419
- https://github.com/Workday/canvas-kit/pull/670

---

### DrawerHeader

The following props where renamed for appropriate aria naming and clarity

- `closeIconLabel` -> `closeIconAriaLabel`

PRs:

- https://github.com/Workday/canvas-kit/pull/551

---

### SearchBar

The following props where renamed for appropriate aria naming and clarity

- `submitLabel` -> `submitAriaLabel`
- `openButtonLabel` -> `openButtonAriaLabel`
- `closeButtonLabel` -> `closeButtonAriaLabel`

PRs:

- https://github.com/Workday/canvas-kit/pull/551

---

### Menu

The following props where renamed for appropriate aria naming and clarity

- `labeledBy` -> `'aria-labelledby'`

PRs:

- https://github.com/Workday/canvas-kit/pull/551

---

### Popup

The following props where renamed for appropriate aria naming and clarity

- `closeLabel` -> `closeButtonAriaLabel`

PRs:

- https://github.com/Workday/canvas-kit/pull/551

---

### SidePanel

The following props where renamed for appropriate aria naming and clarity

- `closeNavigationLabel` -> `closeNavigationAriaLabel`
- `openNavigationLabel` -> `openNavigationAriaLabel`

PRs:

- https://github.com/Workday/canvas-kit/pull/551

---

### Skeleton

The following props where renamed for appropriate aria naming and clarity

- `loadingLabel` -> `'aria-label`

PRs:

- https://github.com/Workday/canvas-kit/pull/551

---

### Popper

`Popper` was changed to a Functional Component with a forwarded ref. If you passed a `ref` object to
`Popper` before, it will now point to the element rather than the `Popper` instance. Popper was
moved to the `@workday/canvas-kit-react-popup` module. This change aligns with the concept that
Popup is a type of UI behavior. Popups can be built on top of the popup system in the Popup module.

PRs:

- https://github.com/Workday/canvas-kit/pull/528
- https://github.com/Workday/canvas-kit/pull/670

---

### Tooltip

Tooltip now uses React Portals and has been completely updated to make attaching tooltips much
easier.

PR:

- https://github.com/Workday/canvas-kit/pull/528

The original `Tooltip` did little more than add a `role="tooltip"` to a styled component. The
original tooltip is now exported as `TooltipContainer` to make it easier to migrate without
rewriting all tooltips. The new experience is much better and will remove the need for wrapping
components, but if you'd like to keep using the old tooltip as is, your imports will have to be
updated to use the old API: **Before:**

```ts
import {Tooltip} from '@workday/canvas-kit-react-tooltip';
```

**After:**

```ts
import {TooltipContainer as Tooltip} from '@workday/canvas-kit-react-tooltip';
```

Also with this change, the tooltip no longer gets the role `tooltip` and must be added manually.

---

**More to come! Check out [our 4.0 tracking issue](https://github.com/Workday/canvas-kit/issues/483)
for all planned changes.**