Workday Canvas

Side Panel

Side Panels are containers that anchor to the left or right side of the screen.

v14.2.34
Install
yarn add @workday/canvas-kit-preview-react

Anatomy

Image of a Side Panel in its expanded state with a Collapse Icon Button.

  1. Tooltip (Required if using Expand/Collapse Button): Tooltip used to provide additional visual affordance for the Expand/Collapse Button.
  2. Expand/Collapse Button (Optional): Icon only Tertiary Button variant used to open or close the Side Panel.
  3. Container: Rectangular container that houses the contents of the Side Panel. The container spans the full height of the viewport and are flush to the left or right edge of the screen.

Usage Guidance

  • Side Panels can either push and resize content as it expands within a page or float over page content. See the Expandable pattern (coming soon!) for more detailed information on horizontal animation.
  • When the content of the Side Panel exceeds the height of the viewport, overflow behavior such as a scrollbar is introduced.
  • Consider the behavior of Side Panels at different responsive breakpoints and in different use cases. In use cases where the Side Panel is used to edit content within the page, keeping the Side Panel open and resizing the page content may be ideal. For use cases where a Side Panel is not required to remain open, enabling a Side Panel to automatically collapse when it reaches smaller screen sizes will prevent the panel from taking up too much of the screen until the user wants to take action on it.
  • When using the Expand/Collapse Button within the Side Panel, use a Tooltip to provide additional affordance that the icon is interactive and to improve accessibility for the Side Panel. When the Side Panel is expanded, tooltip text reads “Collapse” and when collapsed, the tooltip reads “Expand.”

When to Use

Although the elements within a Side Panel are highly configurable to support various use cases, they are commonly used in the following ways:

Local Page Navigation

Low-fidelity illustration of a Side Panel fixed to the left of the screen. The Panel contains an Icon Button used to collapse the Panel.

  • Provides users with a way to navigate within an area of your product.
  • Typically tied to the main content region.
  • Often collapsible but not closeable, meaning the Panel remains on the page and cannot be dismissed.

Editing and Displaying Additional Information

Low-fidelity illustration of a Side Panel fixed to the right of the screen. The Panel contains input fields.

  • Ideal for editing specific content within the page or displaying additional information that supports the main content area.
  • Can be temporary, meaning the Panel may disappear when the associated content on the main page is no longer in focus.

Panel Overlays

Low-fidelity illustration of a left Side Panel fixed to the right of the screen on top of an Overlay. The Panel contains a close button.

Low-fidelity illustration of a Side Panel fixed to the right of the screen on top of an Overlay. The Panel contains a close button and input fields.

  • When Panels open over an overlay, the user cannot interact with the main page. The overlay helps users focus attention on the contents of the Panel, making it ideal for higher-level navigation and editing or displaying additional information while minimizing distractions.
  • A Side Panel that opens over an overlay has a close Button but not a collapse. Activating the Button closes the Panel and the Overlay so the user can return focus to the main page.

Do’s and Don’ts

Image demonstrating multiple Side Panels.

Caution

Consider screen real estate when multiple Side Panels are present within a page. When multiple Side Panels are open at the same time, it may be overwhelming to users as their page content shrinks.

Image demonstrating a Side Panel with tooltip.

Do

When using the Expand / Collapse Button with the Side Panel, provide a Tooltip to label the icon only Tertiary Button variant. When the Side Panel is expanded, the Tooltip contains the text "Collapse" and when collapsed, the Tooltip reads "Expand."

Examples

Basic Example

SidePanel is composed of three parts:

  • The panel container
  • An accessible name (either on a visible element or hidden)
  • A toggle button to control the expand / collapse states

Bidirectional support is built into SidePanel. As seen in the example below, CSS Flexbox flips the page layout and the panel’s contents. SidePanel also has logic to flip the position and direction of the ToggleButton as well as the direction of the expand / collapse animation. If you’re using CSS Flexbox for layouts and using the provided components, you shouldn’t have to provide any custom logic or styling for bidirecitonal support.

Tasks Panel

Toggle the content direction

import * as React from 'react';
import {SecondaryButton} from '@workday/canvas-kit-react/button';
import {SidePanel, useSidePanel} from '@workday/canvas-kit-preview-react/side-panel';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Heading, Text} from '@workday/canvas-kit-react/text';
import {CanvasProvider} from '@workday/canvas-kit-react/common';
import {AccentIcon} from '@workday/canvas-kit-react/icon';
import {rocketIcon} from '@workday/canvas-accent-icons-web';
import {useDirection} from './useDirection';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
import {system, base} from '@workday/canvas-tokens-web';

const stylesOverride = {
  viewPortContainer: createStyles({
    height: px2rem(320),
  }),
  panel: createStyles({
    alignItems: 'center',
    paddingY: system.space.x4,
    paddingX: system.space.x4,
  }),
  accentIcon: createStyles({
    marginInlineEnd: system.space.x4,
  }),
  mainContent: createStyles({
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'column',
    flex: 1,
    flexBasis: 'auto',
  }),
};

export default () => {
  const {direction, toggleDirection} = useDirection();
  const {expanded, panelProps, labelProps, controlProps} = useSidePanel();

  return (
    <CanvasProvider dir={direction}>
      <Flex cs={stylesOverride.viewPortContainer}>
        <SidePanel {...panelProps}>
          <SidePanel.ToggleButton {...controlProps} />
          <Flex cs={stylesOverride.panel}>
            {expanded && (
              <Flex cs={stylesOverride.accentIcon}>
                <AccentIcon icon={rocketIcon} />
              </Flex>
            )}
            <Heading size="small" {...labelProps} hidden={!expanded ? true : undefined}>
              Tasks Panel
            </Heading>
          </Flex>
        </SidePanel>
        <Flex as="main" cs={stylesOverride.mainContent}>
          <Text as="p" typeLevel="body.large">
            Toggle the content direction
          </Text>
          <SecondaryButton onClick={toggleDirection}>
            Set to {direction === 'ltr' ? 'Right-to-Left' : 'Left-to-Right'}
          </SecondaryButton>
        </Flex>
      </Flex>
    </CanvasProvider>
  );
};

Hidden Name

SidePanel must always have an accessible label for both the HTML <section> container and the ToggleButton. The labelProps component must always be present in the DOM in order for the panelProps and controlProps component labels to be assigned properly. A hidden attribute can be applied to the labelProps component. In the example below, we are demonstrating the AccessibleHide component that relies on CSS properties to visually hide text for screen readers only.

Hidden Title

Side Panel with a hidden title text.

import * as React from 'react';
import {SidePanel, useSidePanel} from '@workday/canvas-kit-preview-react/side-panel';
import {Flex} from '@workday/canvas-kit-react/layout';
import {AccessibleHide} from '@workday/canvas-kit-react/common';
import {Text} from '@workday/canvas-kit-react/text';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';

const stylesOverride = {
  viewport: createStyles({
    height: px2rem(320),
  }),
  main: createStyles({
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'column',
    flex: 1,
    flexBasis: 'auto',
  }),
};

export default () => {
  const {panelProps, labelProps, controlProps} = useSidePanel();

  return (
    <Flex cs={stylesOverride.viewport}>
      <SidePanel
        {...panelProps}
        onExpandedChange={expanded => {
          console.log(`expanded prop is: ${expanded ? 'true' : 'false'}`);
        }}
        onStateTransition={state => {
          console.log(`Side Panel is ${state}`);
        }}
      >
        <SidePanel.ToggleButton {...controlProps} />
        <AccessibleHide {...labelProps}>Hidden Title</AccessibleHide>
      </SidePanel>
      <Flex as="main" cs={stylesOverride.main}>
        <Text as="p" typeLevel="body.large">
          Side Panel with a hidden title text.
        </Text>
      </Flex>
    </Flex>
  );
};

Alternate Variant

SidePanel has one variant, alternate, which you can supply as a top-level prop. Default depth of alternate variant is 5, if alternate SidePanel has an overlay behavior the depth 6 should be used (this case is covered in the Examples section).

Alternate Panel

Toggle the content direction

import * as React from 'react';
import {SecondaryButton} from '@workday/canvas-kit-react/button';
import {SidePanel, useSidePanel} from '@workday/canvas-kit-preview-react/side-panel';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Heading, Text} from '@workday/canvas-kit-react/text';
import {CanvasProvider} from '@workday/canvas-kit-react/common';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';

// local helper hook for setting content direction;
import {useDirection} from './useDirection';

const stylesOverride = {
  viewport: createStyles({
    height: px2rem(320),
    backgroundColor: system.color.bg.alt.default,
  }),
  panel: createStyles({
    alignItems: 'center',
    paddingY: system.space.x4,
    paddingX: system.space.x4,
  }),
  main: createStyles({
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'column',
    flex: 1,
    flexBasis: 'auto',
  }),
};

export default () => {
  const {direction, toggleDirection} = useDirection();
  const {expanded, panelProps, labelProps, controlProps} = useSidePanel();

  return (
    <CanvasProvider dir={direction}>
      <Flex cs={stylesOverride.viewport}>
        <SidePanel {...panelProps} variant="alternate">
          <SidePanel.ToggleButton {...controlProps} />
          <Flex cs={stylesOverride.panel}>
            <Heading size="small" hidden={!expanded ? true : undefined} {...labelProps}>
              Alternate Panel
            </Heading>
          </Flex>
        </SidePanel>
        <Flex as="main" cs={stylesOverride.main}>
          <Text as="p" typeLevel="body.large">
            Toggle the content direction
          </Text>
          <SecondaryButton onClick={toggleDirection}>
            Set to {direction === 'ltr' ? 'Right-to-Left' : 'Left-to-Right'}
          </SecondaryButton>
        </Flex>
      </Flex>
    </CanvasProvider>
  );
};

External Control

Sometimes you’ll want to control SidePanel’s’ expand / collapse behavior from outside the component. In that case, you can use the controlProps supplied by the useSidePanel hook.

Notes about accessibility

The controlProps object delivers ARIA attributes to a component under the following assumptions:

  1. The control is an icon button that does not already have an accessible name
  2. The control appears at (or near) the top of the expandable content in the SidePanel

Spreading the controlProps onto an external control can introduce serious accessibility issues:

  • aria-labelledby HTML id reference may become invalid when the SidePanel is collapsed, or when the labelProps component isn’t present in the DOM.
  • aria-labelledby will change the name of controlProps component to the title of the SidePanel. (This may be undesirable. For example, the “Show Side Panel” button will be overwritten with the “Tasks Panel” heading.)
  • aria-expanded won’t make sense to screen reader users when the expanded SidePanel content isn’t logically following the control.
  • aria-controls is unsupported by screen readers and will not allow users to navigate to the controlled content.

In the following example, the controlProps click handler function is passed down to the SecondaryButton and a toggle state was added to the button using the aria-pressed property.

Control the panel externally

import * as React from 'react';
import {
  SidePanel,
  useSidePanel,
  SidePanelTransitionStates,
} from '@workday/canvas-kit-preview-react/side-panel';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Heading, Text} from '@workday/canvas-kit-react/text';
import {SecondaryButton} from '@workday/canvas-kit-react/button';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';

const stylesOverride = {
  viewport: createStyles({
    height: px2rem(320),
  }),
  panel: createStyles({
    alignItems: 'center',
    paddingY: system.space.x4,
    paddingX: system.space.x4,
  }),
  panelHeading: createStyles({
    color: system.color.fg.muted.stronger,
  }),
  main: createStyles({
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'column',
    flex: 1,
    flexBasis: 'auto',
  }),
};

/*
 * NOTE TO DEV:
 * Spreading the `controlProps` onto an external control creates serious accessibility issues.
 * - `aria-labelledby` id reference is invalid when the SidePanel is collapsed
 * - `aria-labelledby` will change the name of "Toggle Side Panel" button to "Tasks Panel"
 * - `aria-expanded` won't make sense to screen reader users when the expanded SidePanel content isn't following the control
 * - `aria-controls` is unsupported by screen readers and will not allow users to navigate to the controlled content
 *
 * SOLUTION:
 * - Pass the `controlProps` click handler function down to the external control component.
 * - Add a toggle state to Button components with `aria-pressed` for screen readers,
 * - OR use a similar toggle input like Checkbox or Switch.
 */
export default () => {
  const {expanded, panelProps, labelProps, controlProps} = useSidePanel({initialExpanded: false});
  const [panelState, setPanelState] = React.useState<SidePanelTransitionStates>(
    expanded ? 'expanded' : 'collapsed'
  );

  return (
    <Flex cs={stylesOverride.viewport}>
      <SidePanel
        {...panelProps}
        onExpandedChange={expanded => {
          console.log(`expanded prop is: ${expanded ? 'true' : 'false'}`);
        }}
        onStateTransition={setPanelState}
      >
        {panelState === 'expanded' && (
          <Flex cs={stylesOverride.panel}>
            <Heading size="small" cs={stylesOverride.panelHeading} {...labelProps}>
              Tasks Panel
            </Heading>
          </Flex>
        )}
      </SidePanel>
      <Flex as="main" cs={stylesOverride.main}>
        <Text as="p" typeLevel="body.large">
          Control the panel externally
        </Text>
        <SecondaryButton onClick={controlProps.onClick} aria-pressed={expanded}>
          Show Side Panel
        </SecondaryButton>
      </Flex>
    </Flex>
  );
};

Right Origin

By default, SidePanel uses a left origin. This sets the ToggleButton’s position and direction as well as the direction of the animation. But you can set SidePanel’s origin to "right" to flip these. As with the left-origin panel, all right-origin styles have bidirecitonal support.

Toggle the content direction

Tasks Panel

import * as React from 'react';
import {SecondaryButton} from '@workday/canvas-kit-react/button';
import {SidePanel, useSidePanel} from '@workday/canvas-kit-preview-react/side-panel';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Heading, Text} from '@workday/canvas-kit-react/text';
import {CanvasProvider} from '@workday/canvas-kit-react/common';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';

// local helper hook for setting content direction;
import {useDirection} from './useDirection';

const stylesOverride = {
  viewport: createStyles({
    height: px2rem(320),
  }),
  panelContainer: createStyles({
    marginLeft: 'auto',
  }),
  panel: createStyles({
    alignItems: 'center',
    justifyContent: 'flex-end',
    paddingY: system.space.x4,
    paddingX: system.space.x4,
  }),
  main: createStyles({
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'column',
    flex: 1,
    flexBasis: 'auto',
  }),
};

const RightPanel = () => {
  const {expanded, panelProps, labelProps, controlProps} = useSidePanel();

  return (
    <SidePanel {...panelProps} origin="right" className={stylesOverride.panelContainer}>
      <SidePanel.ToggleButton {...controlProps} />
      <Flex cs={stylesOverride.panel}>
        <Heading size="small" hidden={!expanded ? true : undefined} {...labelProps}>
          Tasks Panel
        </Heading>
      </Flex>
    </SidePanel>
  );
};

export default () => {
  const {direction, toggleDirection} = useDirection();

  return (
    <CanvasProvider dir={direction}>
      <Flex cs={stylesOverride.viewport}>
        <Flex as="main" cs={stylesOverride.main}>
          <Text as="p" typeLevel="body.large">
            Toggle the content direction
          </Text>
          <SecondaryButton onClick={toggleDirection}>
            Set to {direction === 'ltr' ? 'Right-to-Left' : 'Left-to-Right'}
          </SecondaryButton>
        </Flex>

        <RightPanel />
      </Flex>
    </CanvasProvider>
  );
};

Always Open

If you do not need SidePanel’s’ expand / collapse behavior, you can simply omit the controlProps and ToggleButton.

Tasks Panel

This is the main content section.

import * as React from 'react';
import {AccentIcon} from '@workday/canvas-kit-react/icon';
import {rocketIcon} from '@workday/canvas-accent-icons-web';
import {SidePanel, useSidePanel} from '@workday/canvas-kit-preview-react/side-panel';
import {Flex} from '@workday/canvas-kit-react/layout';
import {Heading, Text} from '@workday/canvas-kit-react/text';
import {system} from '@workday/canvas-tokens-web';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';

const stylesOverride = {
  accentIcon: createStyles({
    marginRight: system.space.x4,
  }),
  pageContainer: createStyles({
    gap: system.space.x4,
    height: px2rem(320),
  }),
  panelContainer: createStyles({
    alignItems: 'center',
    paddingY: system.space.x4,
    paddingX: system.space.x4,
  }),
  panelHeading: createStyles({
    color: system.color.fg.default,
  }),
  mainContent: createStyles({
    alignItems: 'center',
    justifyContent: 'center',
    flexBasis: 'auto',
    flex: 1,
  }),
};

export default () => {
  const {panelProps, labelProps} = useSidePanel();

  return (
    <Flex cs={stylesOverride.pageContainer}>
      <SidePanel {...panelProps}>
        <Flex cs={stylesOverride.panelContainer}>
          <AccentIcon icon={rocketIcon} cs={stylesOverride.accentIcon} />
          <Heading size="small" cs={stylesOverride.panelHeading} {...labelProps}>
            Tasks Panel
          </Heading>
        </Flex>
      </SidePanel>
      <Flex as="main" cs={stylesOverride.mainContent}>
        <Text as="p" typeLevel="body.large">
          This is the main content section.
        </Text>
      </Flex>
    </Flex>
  );
};

The majority of SidePanel’s logic and funcitonality lives in this container component. Most of this functionality has been described in the examples above, but there a couple specific callbacks worth mentioning here.

onExpandedChange

The onExpandedChange callback is called when the boolean expanded state is updated. This is a handy way to hook into these updates to trigger side-effects. Below is an example:

Hidden Title

Side panel is expanded.

import * as React from 'react';
import {Flex} from '@workday/canvas-kit-react/layout';
import {SidePanel, useSidePanel} from '@workday/canvas-kit-preview-react/side-panel';
import {Text} from '@workday/canvas-kit-react/text';
import {AccessibleHide} from '@workday/canvas-kit-react/common';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';

const stylesOverride = {
  viewport: createStyles({
    height: px2rem(320),
  }),
  main: createStyles({
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'column',
    flex: 1,
    flexBasis: 'auto',
  }),
};

export default () => {
  const {expanded, panelProps, labelProps, controlProps} = useSidePanel();

  const handleExpandedChange = (expanded: boolean) => {
    console.log(`Side panel is ${expanded ? 'expanded' : 'collapsed'}`);
  };

  return (
    <Flex cs={stylesOverride.viewport}>
      <SidePanel {...panelProps} onExpandedChange={handleExpandedChange}>
        <SidePanel.ToggleButton {...controlProps} />
        <AccessibleHide {...labelProps}>Hidden Title</AccessibleHide>
      </SidePanel>
      <Flex as="main" cs={stylesOverride.main}>
        <Text as="p" typeLevel="body.large">
          Side panel is {expanded ? 'expanded' : 'collapsed'}.
        </Text>
      </Flex>
    </Flex>
  );
};

onStateTransition

While onExpandedChange works well for discrete boolean state changes, there may be occasions where you also need transition states. In these situations, onStateTransition is a better fit. This callback it called on all state transitions and returns the current transtion state. This can be one of four SidePanelTransitionStates, expanding, expanded, collapsing, and collapsed. Below is an example:

Hidden Title

Side panel is expanded.

import * as React from 'react';
import {Flex} from '@workday/canvas-kit-react/layout';
import {
  SidePanel,
  useSidePanel,
  SidePanelTransitionStates,
} from '@workday/canvas-kit-preview-react/side-panel';
import {AccessibleHide} from '@workday/canvas-kit-react/common';
import {Text} from '@workday/canvas-kit-react/text';
import {createStyles, px2rem} from '@workday/canvas-kit-styling';

const stylesOverride = {
  viewport: createStyles({
    height: px2rem(320),
  }),
  main: createStyles({
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'column',
    flex: 1,
    flexBasis: 'auto',
  }),
};

export default () => {
  const {panelProps, labelProps, controlProps} = useSidePanel();
  const [transitionState, setTransitionState] =
    React.useState<SidePanelTransitionStates>('expanded');

  const handleStateTransition = (transition: SidePanelTransitionStates) => {
    setTransitionState(transition);
  };

  return (
    <Flex cs={stylesOverride.viewport}>
      <SidePanel {...panelProps} onStateTransition={handleStateTransition}>
        <SidePanel.ToggleButton {...controlProps} />
        <AccessibleHide {...labelProps}>Hidden Title</AccessibleHide>
      </SidePanel>
      <Flex as="main" cs={stylesOverride.main}>
        <Text as="p" typeLevel="body.large">
          Side panel is {transitionState}.
        </Text>
      </Flex>
    </Flex>
  );
};

Component API

SidePanel

Props

Props extend from section. Changing the as prop will change the element interface.

NameTypeDescriptionDefault
collapsedWidth number string

The width of the component (in px if it's a number) when it is collapsed.

64
expandedboolean

If true, sets the expanded state of the side panel

true
expandedWidth number string

The width of the component (in px if it's a number) when it is expanded.

320
origin 'left' 'right'

Which side the side panel is meant to originate from.

'left'
onExpandedChange(expanded: boolean) => void

The function called when the side panel's expanded state changes. States like 'collapsing' and 'expanding' are tracked in another callback: onStateTransition

onStateTransition(state: ) => void

The function called when the side panel is transitioning between states. Use this to track when the side panel is animating between 'collapsed', 'collapsing', 'expanded', and 'expanding' states. This can be particularly helpful if child components need to react specifically to these states.

variant

The style variant of the side panel. 'standard' is with a soap100 background, no depth. 'alternate' is a frenchVanilla100 background with a level 6 depth.

'standard'
touchedboolean

This is set by the useSidePanel hook and prevents unintended keyframe animations

childrenReactNode
onAnimationEnd<>
asReact.ElementType

Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using React.forwardRefand spread extra props to a root element.

Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care.

section
refReact.Ref<R = section>

Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If as is set to an element, it will be that element. If as is a component, the reference will be to that component (or element if the component uses React.forwardRef).

SidePanel.ToggleButton

SidePanel.ToggleButton is a control that is meant to toggle between expanded = true and expanded = false states. It must be used within the SidePanel component as a child. Use in conjunction with useSidePanel's controlProps, otherwise it does not come with explicit onClick handlers.

For accessibility purposes, it must be the first focusable element. We recommend that you keep it as the first child of SidePanel

Layout Component

SidePanel.ToggleButton supports all props from thelayout component.

Props

Props extend from button. Changing the as prop will change the element interface.

NameTypeDescriptionDefault
tooltipTextExpandstring

The tooltip text to expand the side panel

'Expand'
tooltipTextCollapsestring

The tooltip text to collapse the side panel

'Collapse'
variant'inverse'

Variant has an option for inverse which will inverse the styling

iconPosition 'start' 'end'

Button icon positions can either be start or end. If no value is provided, it defaults to start.

'start'
shouldMirrorIconboolean

If set to true, transform the icon's x-axis to mirror the graphic. Use this if you want to always mirror the icon regardless of the content direction. If the icon should mirror only when in an right-to-left language, use shouldMirrorIconInRTL instead.

false
shouldMirrorIconInRTLboolean

If set to true, transform the icon's x-axis to mirror the graphic when the content direction is rtl. Icons don't have enough context to know if they should be mirrored in all cases. Setting this to true indicates the icon should be mirrored in right-to-left languages.

false
size

There are four button sizes: extraSmall, small, medium, and large. If no size is provided, it will default to medium.

colors

Override default colors of a button. The default will depend on the button type

icon

The icon of the Button. Note: Not displayed at small size

fillstring

The fill color of the SystemIcon. This overrides color.

backgroundstring

The background color of the SystemIcon.

colorstring

The color of the SystemIcon. This defines accent and fill. color may be overwritten by accent and fill.

shouldMirrorboolean

If set to true, transform the SVG's x-axis to mirror the graphic. Use this if you want to always mirror the icon regardless of the content direction. If the SVG should mirror only when in an right-to-left language, use shouldMirrorInRTL instead.

false
shouldMirrorInRTLboolean

If set to true, transform the SVG's x-axis to mirror the graphic when the content direction is rtl. Icons don't have enough context to know if they should be mirrored in all cases. Setting this to true indicates the icon should be mirrored in right-to-left languages.

false
cs

The cs prop takes in a single value or an array of values. You can pass the CSS class name returned by , or the result of and . If you're extending a component already using cs, you can merge that prop in as well. Any style that is passed to the cs prop will override style props. If you wish to have styles that are overridden by the css prop, or styles added via the styled API, use wherever elemProps is used. If your component needs to also handle style props, use {@link mergeStyles } instead.

import {handleCsProp} from '@workday/canvas-kit-styling';
import {mergeStyles} from '@workday/canvas-kit-react/layout';

// ...

// `handleCsProp` handles compat mode with Emotion's runtime APIs. `mergeStyles` has the same
// function signature, but adds support for style props.

return (
 <Element
   {...handleCsProp(elemProps, [
     myStyles,
     myModifiers({ size: 'medium' }),
     myVars({ backgroundColor: 'red' })
   ])}
 >
   {children}
 </Element>
)
childrenReactNode
accentstring

The accent color of the SystemIcon. This overrides color.

accentHoverstring

The accent color of the SystemIcon on hover. This overrides colorHover.

backgroundHoverstring

The background color of the SystemIcon on hover.

colorHoverstring

The hover color of the SystemIcon. This defines accentHover and fillHover. colorHover may be overwritten by accentHover and fillHover.

fillHoverstring

The fill color of the SystemIcon on hover. This overrides colorHover.

fillIconboolean

Whether the icon should received filled (colored background layer) or regular styles. Corresponds to toggled in ToolbarIconButton

growboolean

True if the component should grow to its container's width. False otherwise.

asReact.ElementType

Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using React.forwardRefand spread extra props to a root element.

Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care.

button
refReact.Ref<R = button>

Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If as is set to an element, it will be that element. If as is a component, the reference will be to that component (or element if the component uses React.forwardRef).

Hooks

useSidePanel

useSidePanel

This hook manages the state and aria- attributes for the SidePanel. It takes an optional configuration object:

import {useSidePanel} from '@workday/canvas-kit-preview-react/side-panel';

const {expanded, setExpanded, panelProps, labelProps, controlProps} = useSidePanel({
  initialExpanded: false,
  panelId: 'custom-panel-id',
  labelId: 'custom-label-id',
});
(config: ) => {
  expanded: boolean;
  setExpanded: (newExpandedState: boolean) => void;
  panelProps: ;
  labelProps: ;
  controlProps: ;
}

Specifications

Accessibility Guidelines

How Side Panels Impact the Accessible Experience

One of the most important aspects of Side Panel is understanding when the Side Panel’s content begins and ends in the context of the holistic design. Side Panel uses a “landmark region” to help establish such boundaries of the Side Panel’s content for non-visual screen reader users. Including semantic heading text at the top of the Side Panel is recommended to help reinforce the beginning of Side Panel content, and convey the intended purpose of the section. Finally, users must be able to understand whether the Side Panel content is expanded or collapsed on the screen.

Keyboard Interaction

Each interactive component inside Side Panel must have a focus indicator that is highly visible against the background and against the non-focused state. Refer to Accessible Colors for more information.

Side Panel must support the following keyboard interactions:

  • Tab: focus the Side Panel toggle button, and any other interactive components inside Side Panel
  • Enter or Space: activates Side Panel toggle button

Screen Reader Interaction

Side Panel must communicate the following to users:

  • The Side Panel is a landmark region, named by the Side Panel’s heading text
  • The “expanded” or “collapsed” state of the Side Panel

Design Annotations Needed

  • Specify when the Side Panel is used for navigation
  • Specify heading level at the top of SIde Panel

Implementation Markup Needed

  • Use semantic heading text at the top of Side Panel to describe the purpose of the content included inside of Side Panel.
  • [Included in component] Use a semantic <section> element and an aria-labelledby reference to create a landmark region for screen readers.
  • When Side Panel is used for navigation purposes, use the as prop to change the rendered element from the default <section> to a <nav> element.
  • [Included in component] An accessible Tooltip component is included on the Side Panel toggle button describing what the icon button will do when activated.
  • [Included in component] The toggle button must have an accessible name using either an aria-labelledby reference or an aria-label string.
  • [Included in component] The toggle button must convey the Side Panel state using the aria-expanded property.

Can't Find What You Need?

Check out our FAQ section which may help you find the information you're looking for. For further information, contact the #ask-canvas-design or #ask-canvas-kitchannels on Slack.

On this Page: