For Developers

Canvas Kit v4 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



  • Typescript upgraded to v3.8 (
    • 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. This includes the CanvasProvider component. We've also made some stability improvements (see below).



  • 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:
theme: {
canvas: {
palette: {
// ...
breakpoints: {
// ...
direction: ContentDirection.LTR
  • This means several type references have changed:

    • CanvasTheme > EmotionCanvasTheme
    • PartialCanvasTheme > PartialEmotionCanvasTheme

Breaking Component Changes



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



  • 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.



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



  • 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.


<Button variant={Button.Variant.OutlineSecondary} size={Button.Size.Large}>


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


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.



import {IconButtonToggleGroup} from '@workday/canvas-kit-react-button';
<IconButton icon={listViewIcon} title="List View" aria-label="List View" />
<IconButton icon={worksheetsIcon} title="Worksheets" aria-label="Worksheets" />


import {SegmentedControl} from '@workday/canvas-kit-react-segmented-control';
<IconButton icon={listViewIcon} title="List View" aria-label="List View" />
<IconButton icon={worksheetsIcon} title="Worksheets" aria-label="Worksheets" />


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).


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.



The following props where renamed for appropriate aria naming and clarity

  • closeIconLabel -> closeIconAriaLabel


The following props where renamed for appropriate aria naming and clarity

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


The following props where renamed for appropriate aria naming and clarity

  • labeledBy -> 'aria-labelledby'


The following props where renamed for appropriate aria naming and clarity

  • closeLabel -> closeButtonAriaLabel



The following props where renamed for appropriate aria naming and clarity

  • closeNavigationLabel -> closeNavigationAriaLabel
  • openNavigationLabel -> openNavigationAriaLabel



The following props where renamed for appropriate aria naming and clarity

  • loadingLabel -> 'aria-label



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.



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


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:

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


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 for all planned changes.

Can't Find What You Need?

Check out our FAQ section which may help you find the information you're looking for.

FAQ Section