Workday Canvas

Menu

Menus display a list of up to 15 options when launched by an action or UI element like an icon or button.

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

Anatomy

Image of a Popup Menu sample showing different possible states.

  1. Container: Rectangular container that houses the icon and text for menu list items.
  2. Text: Text for indicating where the link leads to when the menu is clicked on. Text can overflow to the next line but avoid going over more than two lines of text.
  3. Icons: Icons are optional and can be positioned before or after the text.

Usage Guidance

  • Popup Menus can appear next to, in front of, above, or below the element that launched them, such as Dropdown Buttons, Dropdown Icons, icon only Primary/Secondary/Tertiary Button variants or by right-clicking a contextual item.
  • Popup Menus should overlap and visually look like they are in front of other UI elements. They should always be positioned within the viewable areas of the screen and be 8px away from the element that launched them.
  • Popup Menus should always contain a list of menu selections, which are options users can choose from. The list should be scannable, kept as concise as possible, and written in title case instead of sentences.
  • Consider how important each option is. The list of options should be sorted in a logical order, such as alphabetical, chronological, order of importance, and so on.

When to Use

  • In most cases, as with Overflow Menus, where there aren’t enough space on screen to show all the actions, there could be between 1-7 items to choose from. However, there shouldn’t be more than 15 items listed at once on a single Popup Menu.
  • When users must make a single selection from the list of options.

When to Use Something Else

  • Consider using a Switch if the only options are yes or no.
  • For a list between 2 to 7 predefined options, consider using a Radio input to select one option or Checkboxes to select multiple options. Radio and Checkbox groups display all options upfront and do not require the user to interact with the input to view the list of options.
  • Use a Prompt when the number of list items is large or unknown. Prompts have search capabilities and folders which provide users with the means to browse options. Prompts can be configured to support single or multi-select.

Design Annotations for Accessibility

  • Write an accessible name for icon-only button variants invoking menus.
  • Declare whether any icons used in menu items are decorative, or require additional text alternatives.

Examples

Basic Example

Menu is typically triggered by an action such as pressing a button. The Menu comes with a Target subcomponent and a Popup.

Selected:

import React from 'react';

import {Menu} from '@workday/canvas-kit-react/menu';
import {BodyText} from '@workday/canvas-kit-react/text';

export default () => {
  const [selected, setSelected] = React.useState('');
  return (
    <Menu onSelect={data => setSelected(data.id)}>
      <Menu.Target>Open Menu</Menu.Target>
      <Menu.Popper>
        <Menu.Card>
          <Menu.List>
            <Menu.Item>First Item</Menu.Item>
            <Menu.Item>Second Item</Menu.Item>
            <Menu.Divider />
            <Menu.Item>Third Item (with a really, really, really long label)</Menu.Item>
            <Menu.Item aria-disabled>Fourth Item</Menu.Item>
          </Menu.List>
        </Menu.Card>
      </Menu.Popper>
      <BodyText size="small" marginTop="s">
        Selected: <span data-testid="output">{selected}</span>
      </BodyText>
    </Menu>
  );
};

Menu will automatically focus on the cursor item (first item by default). The Menu uses a menu model which composes a list model and a popup model and sets up accessibility features for you.

Context Menu

Selected:

import React from 'react';

import {Menu} from '@workday/canvas-kit-react/menu';
import {BodyText} from '@workday/canvas-kit-react/text';

export default () => {
  const [selected, setSelected] = React.useState('');
  return (
    <Menu onSelect={data => setSelected(data.id)}>
      <Menu.TargetContext>Right-click to Open Menu</Menu.TargetContext>
      <Menu.Popper>
        <Menu.Card>
          <Menu.List>
            <Menu.Item>First Item</Menu.Item>
            <Menu.Item>Second Item</Menu.Item>
            <Menu.Item>Third Item (with a really, really, really long label)</Menu.Item>
            <Menu.Item>Fourth Item</Menu.Item>
          </Menu.List>
        </Menu.Card>
      </Menu.Popper>
      <BodyText size="small" marginTop="s">
        Selected: <span data-testid="output">{selected}</span>
      </BodyText>
    </Menu>
  );
};

Accessibility Note: This variation relies on the contextmenu browser event, which has varying levels of support across different operating systems. On Windows, this feature is better supported and users can typically trigger context menus using the Shift + F10 keyboard shortcut or the dedicated Context Menu key (if available on their keyboard). However, on macOS, context menu support is limited and may require users to enable specific accessibility settings in their system preferences to function properly. Consider providing alternative access methods for critical functionality.

Icons

Menu supports more complex children, including icons, but the text of the item will no longer be known. In this case, add a data-text attribute to inform the collection system what the text of the item is. The text is used for components that filter based on text. For example, a Select component will jump to an item based on the keys the user types. If the user types “C”, the component will jump to the first item that starts with a “C”. This functionality requires knowledge about the text of the item.

Selected:

import React from 'react';
import {
  setupIcon,
  uploadCloudIcon,
  userIcon,
  taskContactIcon,
} from '@workday/canvas-system-icons-web';
import {Menu} from '@workday/canvas-kit-react/menu';
import {BodyText} from '@workday/canvas-kit-react/text';

export default () => {
  const [selected, setSelected] = React.useState('');
  return (
    <Menu onSelect={data => setSelected(data.id)}>
      <Menu.Target>Open Menu</Menu.Target>
      <Menu.Popper>
        <Menu.Card>
          <Menu.List>
            <Menu.Item data-text="First Item">
              <Menu.Item.Icon icon={uploadCloudIcon} />
              <Menu.Item.Text>First Item</Menu.Item.Text>
            </Menu.Item>
            <Menu.Item data-text="Second Item (with a really really really long label)">
              <Menu.Item.Icon icon={setupIcon} />
              <Menu.Item.Text>Second Item (with a really really really long label)</Menu.Item.Text>
            </Menu.Item>
            <Menu.Item aria-disabled data-text="Third Item">
              <Menu.Item.Icon icon={uploadCloudIcon} />
              <Menu.Item.Text>Third Item</Menu.Item.Text>
              <Menu.Item.Icon icon={taskContactIcon} />
            </Menu.Item>
            <Menu.Item data-text="User">
              <Menu.Item.Icon icon={userIcon} />
              <Menu.Item.Text>User</Menu.Item.Text>
            </Menu.Item>
            <Menu.Divider />
            <Menu.Item data-text="Fifth Item (with divider)">
              <Menu.Item.Icon icon={taskContactIcon} />
              <Menu.Item.Text>Fifth Item (with divider)</Menu.Item.Text>
            </Menu.Item>
          </Menu.List>
        </Menu.Card>
      </Menu.Popper>
      <BodyText size="small" marginTop="s">
        Selected: <span data-testid="output">{selected}</span>
      </BodyText>
    </Menu>
  );
};

Accessibility Note: Icons in menu items do not inherently provide text alternatives to assistive technologies. However, in most cases, icons are used decoratively alongside text labels, and additional text alternatives are not necessary since the menu item text itself provides the accessible name.

Grouping

Grouping adds hierarchy and categorization to menu items. Group headers do not represent menu items and are not selectable with the keyboard or mouse.

Note: Grouping is not supported in virtual rendering. Menus by default have shouldVirtualize set to false. Setting to true results in unspecified behavior. We use react-virtual which doesn’t support nested virtualization.

Selected:

import React from 'react';

import {Menu} from '@workday/canvas-kit-react/menu';
import {BodyText} from '@workday/canvas-kit-react/text';

export default () => {
  const [selected, setSelected] = React.useState('');
  return (
    <>
      <Menu onSelect={data => setSelected(data.id)}>
        <Menu.Target>Open Menu</Menu.Target>
        <Menu.Popper>
          <Menu.Card>
            <Menu.List>
              <Menu.Group title="First Group">
                <Menu.Item>First Item</Menu.Item>
                <Menu.Item>Second Item</Menu.Item>
              </Menu.Group>
              <Menu.Group title="Second Group">
                <Menu.Item>Third Item (with a really, really, really long label)</Menu.Item>
                <Menu.Item aria-disabled>Fourth Item</Menu.Item>
              </Menu.Group>
            </Menu.List>
          </Menu.Card>
        </Menu.Popper>
        <BodyText size="small" marginTop="s">
          Selected: <span data-testid="output">{selected}</span>
        </BodyText>
      </Menu>
    </>
  );
};

Accessibility Note: Menu groups use role="group" with appropriate labeling to provide semantic structure for assistive technologies. When navigating through grouped menu items, screen readers will announce the group label when users enter a new group, providing important context about the organization of the menu. Group headers are not part of the keyboard navigation sequence, allowing users to efficiently move between actionable menu items. This semantic grouping helps all users, including those using assistive technologies, understand the hierarchy and categorization of menu options.

Nested

Menus support nesting. If you only have a few items and not very many nesting levels, the menu can be defined statically using JSX. A submenu is defined using the <Menu.Submenu> component. The Submenu is implemented as a special Menu subcomponent. The API of the submenu is the same as the Menu except the submenu’s target is also a menu item. The component is named TargetItem to indicate this dual role.

Selected:

import React from 'react';
import {chevronRightSmallIcon} from '@workday/canvas-system-icons-web';

import {Menu} from '@workday/canvas-kit-react/menu';
import {BodyText} from '@workday/canvas-kit-react/text';

export default () => {
  const [selected, setSelected] = React.useState('');
  return (
    <Menu
      id="first-menu"
      onSelect={data => {
        setSelected(data.id);
      }}
    >
      <Menu.Target>Open Menu</Menu.Target>
      <Menu.Popper>
        <Menu.Card>
          <Menu.List>
            <Menu.Item data-id="first-item">First Item</Menu.Item>
            <Menu.Submenu id="second-menu">
              <Menu.Submenu.TargetItem data-id="second-item">Second Item</Menu.Submenu.TargetItem>
              <Menu.Submenu.Popper>
                <Menu.Submenu.Card>
                  <Menu.Submenu.List>
                    <Menu.Submenu.Item data-id="first-sub-item">First Sub Item</Menu.Submenu.Item>
                    <Menu.Submenu.Item data-id="second-sub-item">First Sub Item</Menu.Submenu.Item>
                    <Menu.Submenu.Item data-id="third-sub-item">Third Sub Item</Menu.Submenu.Item>
                    <Menu.Submenu.Item data-id="fourth-sub-item">Fourth Sub Item</Menu.Submenu.Item>
                  </Menu.Submenu.List>
                </Menu.Submenu.Card>
              </Menu.Submenu.Popper>
            </Menu.Submenu>
            <Menu.Divider />
            <Menu.Item data-id="third-item">
              Third Item (with a really, really, really long label)
            </Menu.Item>
            <Menu.Item aria-disabled data-id="fourth-item">
              Fourth Item
            </Menu.Item>
          </Menu.List>
        </Menu.Card>
      </Menu.Popper>
      <BodyText size="small" marginTop="s">
        Selected: <span data-testid="output">{selected}</span>
      </BodyText>
    </Menu>
  );
};

Accessibility Note: When a menu item has an attached submenu, the <Menu.Submenu.TargetItem> includes aria-haspopup="true" and aria-expanded={true | false} properties. These properties will alert screen reader users to the available submenu systems.

Nested Dynamic Items

Menu nesting is simpler with the dynamic API. In this example, a renderItem function is defined to allow recursive nesting of items using a data structure you define. A submenu will inherit the getId and getTextValue functions of the parent menu. While you can pass a specialize getId or getTextValue function to each submenu, it may be simpler to use the same one for the menu and submenus.

Selected:

import React from 'react';

import {Menu} from '@workday/canvas-kit-react/menu';
import {BodyText} from '@workday/canvas-kit-react/text';
import {system} from '@workday/canvas-tokens-web';

type Item = {
  type?: 'item';
  id: string;
  label: string;
};
type SubmenuItem = {
  id: string;
  label: string;
  type: 'submenu';
  children: (Item | SubmenuItem)[];
};

// This is a user-defined object. The structure uses `id` for the item identifier which is the
// default key used by the collection system and therefore doesn't require a `getId` function to be
// passed to the model. The `label` isn't the standard text value used by the collection system, so
// a `getTextValue` function is required. The `type` and `children` aren't important at all to the
// menu and are used in the template by the user-defined `renderItem` function.
const items: (SubmenuItem | Item)[] = [
  {id: 'first-item', label: 'First Item'},
  {
    id: 'second-item',
    label: 'Second Item',
    type: 'submenu',
    children: [
      {id: 'first-sub-item', label: 'First Sub Item'},
      {
        id: 'second-sub-item',
        label: 'Second Sub Item',
        type: 'submenu',
        children: [
          {id: 'first-sub-sub-item', label: 'First Sub Sub Item'},
          {
            id: 'second-sub-sub-item',
            type: 'submenu',
            label: 'Second Sub Sub Item',
            children: [
              {id: 'first-sub-sub-sub-item', label: 'First Sub Sub Sub Item'},
              {
                id: 'second-sub-sub-sub-item',
                label: 'Second Sub Sub Sub Item',
              },
              {id: 'third-sub-sub-sub-item', label: 'Third Sub Sub Sub Item'},
              {id: 'fourth-sub-sub-sub-item', label: 'Fourth Sub Sub Sub Item'},
            ],
          },
          {id: 'third-sub-sub-item', label: 'Third Sub Sub Item'},
          {id: 'fourth-sub-sub-item', label: 'Fourth Sub Sub Item'},
        ],
      },
      {id: 'third-sub-item', label: 'Third Sub Item'},
      {id: 'fourth-sub-item', label: 'Fourth Sub Item'},
    ],
  },
  {id: 'third-item', label: 'Third Item'},
  {id: 'fourth-item', label: 'Fourth Item'},
];

export default () => {
  const [selected, setSelected] = React.useState('');

  // defining this inline function allows use to recurse any nesting level defined by the `items`
  // array.
  function renderItem(item: SubmenuItem | Item) {
    if (item.type === 'submenu') {
      return (
        <Menu.Submenu id={item.id} items={item.children}>
          <Menu.Submenu.TargetItem>{item.label}</Menu.Submenu.TargetItem>
          <Menu.Submenu.Popper>
            <Menu.Submenu.Card>
              <Menu.Submenu.List>{renderItem}</Menu.Submenu.List>
            </Menu.Submenu.Card>
          </Menu.Submenu.Popper>
        </Menu.Submenu>
      );
    }
    return <Menu.Item>{item.label}</Menu.Item>;
  }

  return (
    <Menu
      items={items}
      id="first-menu"
      getTextValue={item => item.label}
      onSelect={data => {
        setSelected(data.id);
      }}
    >
      <Menu.Target>Open Menu</Menu.Target>
      <Menu.Popper>
        <Menu.Card>
          <Menu.List>{renderItem}</Menu.List>
        </Menu.Card>
      </Menu.Popper>
      <BodyText size="small" cs={{marginBlockStart: system.space.x4}}>
        Selected: <span data-testid="output">{selected}</span>
      </BodyText>
    </Menu>
  );
};

Accessibility

Our Menu component is based on the Menu Button pattern on the ARIA Authoring Practices Guide from the W3C and relies on the roving tabindex technique for managing focus within the opened menu. This means that the minimum requirements for screen reader support and keyboard navigation are included in the component.

Menu Button Pattern | APG | WAI | W3C

  • The <Menu.Target> sub-component uses aria-haspopup="true" and aria-expanded={true | false} properties. This benefits screen reader users by indicating when a button element has an attached menu.
  • The <Menu.List> sub-component uses role="menu" and <Menu.Item> uses role="menuitem" ARIA roles. These roles allow screen readers to pass through arrow key events to the web application.
  • The <Menu.List> sub-component includes an aria-labelledby ID reference to the <Menu.Target> sub-component. This assigns a label to the menu for context.
  • Enter or Space: When focused on the menu button, opens the menu and moves focus to the first menu item. When focused on a menu item, activates the item and closes the menu
  • Escape: Closes the menu and returns focus to the menu button
  • Up & Down Arrow: Moves focus up and down the menu items
  • Home & End: Moves focus to the first or last menu item
  • Right & Left Arrow: When focused on a menu item with a submenu, opens the submenu and moves focus to the first item in the submenu or closes the submenu and returns focus to the parent menu item

Screen Reader Experience

  • The menu button will be announced with its label text followed by the button role, a notification that it has a popup menu, and the current state of the menu (For example: “Actions, button, menu popup, collapsed”)
  • Opening the Menu: When the menu button is activated, screen readers will announce the menu opening, the number of menu items available, and the currently focused item (For example: “Actions, menu, First Action, menu item, 1 of 4.”)
  • Navigating Menu Items: As focus moves between menu items, screen readers will announce the item name and its position in the list (For example: “Second Action, menu item, 2 of 4.”)
  • Menu Items with Submenus: When focused on a menu item that has a submenu, screen readers will announce that it has a submenu and provide the expanded/collapsed state (For example: “More Actions, menu item, has submenu, collapsed, 3 of 4.”)

Component API

Menu is a combination of a popup and a list. It usually has some type of target element that expands/collapses the menu and a menu role and and several menuitem roles. Focus is managed using roving tabindex for maximum compatibility. A Menu can have two modes: single and multiple. This mode determines both how many items can be selected as well as the default behavior when a menuitem is clicked. For the single mode, selecting a menuitem will select and close the menu. For the multiple mode, clicking a menuitem will toggle selection and will not close the menu.

<Menu>
  <Menu.Target>Open</Menu.Target>
  <Menu.Popper>
    <Menu.Card>
      <Menu.List>
        <Menu.Item data-id="first">First Item</Menu.Item>
        <Menu.Item data-id="second">Second Item</Menu.Item>
      </Menu.List>
    </Menu.Card>
  </Menu.Popper>
</Menu>

Props extend from . If a model is passed, props from MenuModelConfig are ignored.

NameTypeDescriptionDefault
childrenReactNode

The contents of the Menu. Can be Menu children or any valid elements.

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

Menu.Target is similar to all types. The component only provides behavior and no styling. The as prop is used to determine which component is rendered. This component should forward the ref and apply any additional props directly to an element. The default as is a {@link SecondaryButton }. Any Canvas Kit component should work with an as.

An example changing to a {@link PrimaryButton }

<Menu.Target as={PrimaryButton}>Primary Button Text</Menu.Target>

This element will apply aria-haspopup and aria-expanded to inform screen readers there's a popup associated with the element.

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

NameTypeDescriptionDefault
childrenReactNode
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.

refReact.Ref<R = >

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuTarget

(
  unknown {    "kind": "unknown",    "value": "unknown",    "text": "useMenuTargetBase"   },
  
)

The menu card is a non-semantic element used to give the dropdown menu its distinct visual cue that the dropdown menu is floating above other content. A menu card usually contains a menu list, but can also contain other elements like a header or footer.

Menu.Card supports all props from thelayout component.

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

NameTypeDescriptionDefault
childrenReactNode

Children of the Card. Should contain a <Card.Body> and an optional <Card.Heading>

variant 'borderless' 'filled'

The variant of the Card. Can be default, borderless or filled.

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

div
refReact.Ref<R = div>

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuCard

(
  model: ,
  elemProps: {},
  ref: React.Ref
) => {}

The menu list follows the Collections API. A list can either contain static items or a render prop and items to the model.

const MyComponent = () => {
  const model = useMenuModel({
    items: [
      { id: 'first',  text: 'First Item' },
      { id: 'second', text: 'Second Item' },
    ]
  })

  return (
    <Menu model={model}>
      <Menu.List>
        {(item) => <Menu.Item data-id={item.id}>{item.text}</Menu.Item>}
      </Menu.List>
    </Menu>
  )
}

Menu.List supports all props from thelayout component.

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

NameTypeDescriptionDefault
children
  undefined
  null
  string
  number
  false
  true
  ReactElement
  
  
  (item: T) => ReactNode

The label text of the MenuList.

marginY
  undefined
  number
  string & {}
  'zero'
  's'
  'm'
  'l'
  'xxxs'
  'xxs'
  'xs'
  'xl'
  'xxl'
  'xxxl'

Set the margin top and bottom of the list box. You must use this prop and not style any other way. The Menu uses virtualization and needs margins to be set on the correct element. This ensure proper rendering.

marginTop
  undefined
  number
  string & {}
  'zero'
  's'
  'm'
  'l'
  'xxxs'
  'xxs'
  'xs'
  'xl'
  'xxl'
  'xxxl'

Set the margin top of the list box. You must use this prop and not style any other way. The Menu uses virtualization and needs margins to be set on the correct element. This ensure proper rendering. If a marginTop is not provided, the value falls back to marginY.

marginBottom
  undefined
  number
  string & {}
  'zero'
  's'
  'm'
  'l'
  'xxxs'
  'xxs'
  'xs'
  'xl'
  'xxl'
  'xxxl'

Set the margin bottom of the list box. You must use this prop and not style any other way. The Menu uses virtualization and needs margins to be set on the correct element. This ensure proper rendering. If a marginBottom is not provided, the value falls back to marginY.

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

If this is set it will cause a wrapping of a list that will turn it into a grid

0
idstring

IDREF of the list. Children ids can be derived from this id

navigation

Controls the state changes when the user sends navigation events to the model. For example, when the user hits the "right" arrow, a behavior hook will determine directionality (left-to-right or right-to-left) and call the correct navigation method. In our example, a left-to-right language would send a getNext. The navigation manager may return the next item in the list. Different managers can be created for slightly different use cases. The default navigation manager will accept orientation and directionality to determine mapping.

An example override might be a tab list with an overflow menu that is meant to be transparent to screen reader users. This would require the overflow menu to accept both up/down keys as well as left/right keys to give a more consistent experience to all users.

shouldVirtualizetrue
selection
pageSizenumber

Controls how much a pageUp/pageDown navigation request will jump. If not provided, the size of the list and number of items rendered will determine this value.

getId(item: ) => string

Optional function to return an id of an item. If not provided, the default function will return the id property from the object of each item. If you did not provide items, do not override this function. If you don't provided items and instead provide static items via JSX, the list will create an internal array of items where id is the only property and the default getId will return the desired result.

getTextValue(item: ) => string

Optional function to return the text representation of an item. If not provided, the default function will return the text property of the object of each item or an empty string if there is no text property. If you did not provide items, do not override this function.

defaultItemHeightnumber

Best guess to the default item height for virtualization. Getting this number correct avoids a rerender while the list is initializing.

50
nonInteractiveIdsstring[]

Array of all ids which are currently disabled. This is used for navigation to skip over items which are not focusable.

orientation

The orientation of a list of items. Values are either vertical or horizontal. This value will effect which ids activate progression through a list. For example, horizontal will activate with left and right arrows while vertical will activate with up and down arrows.

'vertical'
items[]

Optional array of items. If provided, use a render prop for list children instead of static children. If the shape of each item object does not have an id property or uses a different property to uniquely identify each item, a getId must also be supplied.

initialCursorId string string[]

Initial cursor position. If not provided, the cursor will point to the first item in the list

initialSelectedIds
initialUnselectedIdsstring[]
UNSTABLE_parentModel {
    state: {
      selectedIds:  'all' string[];
      unselectedIds: string[];
      cursorId:  string string[];
      columnCount: number;
      pageSizeRef: <number>;
      cursorIndexRef: {
        current: number;
      };
      UNSTABLE_virtual: <, Element>;
      UNSTABLE_defaultItemHeight: number;
      containerRef: <>;
      id: string;
      orientation:  'horizontal' 'vertical';
      indexRef: <number>;
      nonInteractiveIds: string[];
      isVirtualized: boolean;
      items: <any>[];
    };
    events: {
      select: (data: {
        id: string;
      }) => void;
      selectAll: () => void;
      unselectAll: () => void;
      setSelectedIds: (ids:  'all' string[]) => void;
      remove: (data: {
        id: string;
        nextId: string;
        event:  Event SyntheticEvent;
      }) => void;
      goTo: (data: {
        id: string;
      }) => void;
      goToNext: () => void;
      goToPrevious: () => void;
      goToPreviousRow: () => void;
      goToNextRow: () => void;
      goToFirst: () => void;
      goToLast: () => void;
      goToFirstOfRow: () => void;
      goToLastOfRow: () => void;
      goToNextPage: () => void;
      goToPreviousPage: () => void;
      registerItem: (data: {
        id: string;
        textValue: string;
      }) => void;
      unregisterItem: (data: {
        id: string;
      }) => void;
      updateItemHeight: (data: {
        value: number;
      }) => void;
    };
    selection: ;
    navigation: ;
    getId: (item: ) => string;
    getTextValue: (item: ) => string;
  } undefined
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.

div
refReact.Ref<R = div>

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuList

(
  (
    model: ,
    elemProps: {},
    ref: React.Ref
  ) => {
    role: 'menu';
    aria-labelledby: string;
    aria-orientation:  'horizontal' 'vertical';
  },
  ,
  
)

A Menu.Item has an optional data-id prop that identifies the item in the Menu.List and will be passed to the optional onSelect callback of the Menu model. A Menu.Item can contain any HTML. If more complex HTML is provided, add data-text to the Menu.Item component if using the static API. If you're using the dynamic API, pass getTextValue to the model.

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

NameTypeDescriptionDefault
indexnumber

Optionally pass index to menu item. This should be done if Menu.Item components were created via a Array::map function. This index will ensure keyboard navigation works even if items are inserted out of order.

childrenReactNode

The label text of the MenuItem.

data-idstring

The name of the menu item. This name will be used in the onSelect callback in the model. If this property is not provided, it will default to a string representation of the the zero-based index of the Tab when it was initialized.

aria-disabledboolean

aria-disabled is used for keyboard and screen reader users to discover disabled content with the keyboard or screen reader caret tool. For more information, see https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_disabled_controls

isDisabledboolean

If true, set the StyledMenuItem to the disabled state so it is not clickable.

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuItem

(
  (
    model: ,
    elemProps: {},
    ref: React.Ref
  ) => {
    role: 'menuitem';
    onMouseDown: (event: ) => void;
    onClick:  ((event: SyntheticEvent) => void) undefined;
  },
  ,
  ,
  ,
  ,
  
)

Basic type information:

MenuItemIcon

Basic type information:

MenuItemText

This component references the component.

A Menu.Option is similar to the Menu.Item, but has a role=option and works with aria-activedescendant and is selectable with a selected checkmark. It adds the aria-selected="true/false" attribute. Menu.Option requires much more accessibility behavior composed into the Menu.Target and Menu.List component. The Combobox and Select components make use of the Menu.Option. See those components for a better idea of how behavior is composed.

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

NameTypeDescriptionDefault
indexnumber

Optionally pass index to menu item. This should be done if Menu.Item components were created via a Array::map function. This index will ensure keyboard navigation works even if items are inserted out of order.

childrenReactNode

The label text of the MenuItem.

data-idstring

The name of the menu item. This name will be used in the onSelect callback in the model. If this property is not provided, it will default to a string representation of the the zero-based index of the Tab when it was initialized.

aria-disabledboolean

aria-disabled is used for keyboard and screen reader users to discover disabled content with the keyboard or screen reader caret tool. For more information, see https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_disabled_controls

isDisabledboolean

If true, set the StyledMenuItem to the disabled state so it is not clickable.

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

li
refReact.Ref<R = li>

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuOption

(
  (
    model: ,
    elemProps: {
      data-id: string;
    },
    ref: React.Ref
  ) => {
    role: 'option';
    aria-selected: boolean;
    onMouseDown: (event: <>) => void;
  },
  ,
  
)

Basic type information:

MenuOptionText

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

NameTypeDescriptionDefault
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>
)
childrenReact.ReactNode
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.

hr
refReact.Ref<R = hr>

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

A Menu.TargetContext is the same as a , except it adds a context event handler instead of a click handler to trigger context menus.

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

NameTypeDescriptionDefault
childrenReactNode
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.

refReact.Ref<R = >

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuTargetContext

(
  unknown {    "kind": "unknown",    "value": "unknown",    "text": "useMenuTargetBase"   },
  
)

The "Popper" of a menu. The popper will appear around the . It renders a div element that is portalled to the document.body which is controlled by the {@link PopupStack }. The PopupStack is not part of React. This means no extra props given to this component will be forwarded to the div element, but the ref will be forwarded.

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

NameTypeDescriptionDefault
anchorElement <Element> Element null

The reference element used to position the Popper. Popper content will try to follow the anchorElement if it moves and will reposition itself if there is no longer room in the window.

children ((props: {
    placement: ;
  }) => ReactNode)
ReactNode

The content of the Popper. If a function is provided, it will be treated as a Render Prop and pass the placement chosen by PopperJS. This placement value is useful if your popup needs to animate and that animation depends on the direction of the content in relation to the anchorElement.

getAnchorClientRect() => 

When provided, this optional callback will be used to determine positioning for the Popper element instead of calling getBoundingClientRect on the anchorElement prop. Use this when you need complete control over positioning. When this prop is specified, it is safe to pass null into the anchorElement prop. If null is passed into the anchorElement prop, an owner will not be provided for the PopupStack.

openboolean

Determines if Popper content should be rendered. The content only exists in the DOM when open is true

true
placement

The placement of the Popper contents relative to the anchorElement. Accepts auto, top, right, bottom, or left. Each placement can also be modified using any of the following variations: -start or -end.

fallbackPlacements[]

Define fallback placements by providing a list of in array (in order of preference). The default preference is following the order of top, right, bottom, and left. Once the initial and opposite placements are not available, the fallback placements will be in use. Use an empty array to disable the fallback placements.

onPlacementChange(placement: ) => void

A callback function that will be called whenever PopperJS chooses a placement that is different from the provided placement preference. If a placement preference doesn't fit, PopperJS will choose a new one and call this callback.

popperOptions<PopperOptions>

The additional options passed to the Popper's popper.js instance.

portalboolean

If false, render the Popper within the DOM hierarchy of its parent. A non-portal Popper will constrained by the parent container overflows. If you set this to false, you may experience issues where you content gets cut off by scrollbars or overflow: hidden

true
popperInstanceRefRef<>

Reference to the PopperJS instance. Useful for making direct method calls on the popper instance like update.

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.

div
refReact.Ref<R = div>

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

usePopupPopper

Adds the necessary props to a {@link Popper } component. Used by the subcomponent.

(
  model: ,
  elemProps: {},
  ref: React.Ref
) => {
  open: boolean;
  anchorElement: <>;
  ref: (instance:  null) => void;
  onPlacementChange: (placement: ) => void;
}

Submenu should be put in place of a Menu.Item. It will render a menu item that is the target for the submenu card.

<Menu.Item>First Item</Menu.Item>
<Menu.Submenu>
  <Menu.Submenu.TargetItem>Second Item</Menu.Submenu.TargetItem>
  <Menu.Submenu.Popper>
    <Menu.Submenu.Card>
      <Menu.Submenu.List>
        <Menu.Submenu.Item data-id="first">First Sub Item</Menu.Submenu.Item>
        <Menu.Submenu.Item data-id="second">Second Sub Item</Menu.Submenu.Item>
      </Menu.Submenu.List>
    </Menu.Submenu.Card>
  </Menu.Submenu.Popper>
</Menu.Submenu>
</Menu.Item>Third Item</Menu.Item>
NameTypeDescriptionDefault
childrenReactNode

The contents of the Menu. Can be Menu children or any valid elements.

mode 'multiple' 'single'

Determines the default selection manager used as well as if the menu closes when an item is selected

shouldVirtualizefalse
returnFocusRef <any> undefined

Optional reference to an element that should receive focus when a popup is hidden. If left blank, focus will return to the targetRef

initialFocusRef <any> undefined

Optional reference to an element that should receive focus when a popup is shown. If left blank, focus will be moved to the first focusable element inside the popup.

idstring

ID reference of the list. Children ids can be derived from this id

initialVisibility

The initial visibility of the disclosed content

'hidden'
initialSelectedIds
initialUnselectedIdsstring[]
selection
initialCursorId string string[]

Initial cursor position. If not provided, the cursor will point to the first item in the list

columnCountnumber

If this is set it will cause a wrapping of a list that will turn it into a grid

0
navigation

Controls the state changes when the user sends navigation events to the model. For example, when the user hits the "right" arrow, a behavior hook will determine directionality (left-to-right or right-to-left) and call the correct navigation method. In our example, a left-to-right language would send a getNext. The navigation manager may return the next item in the list. Different managers can be created for slightly different use cases. The default navigation manager will accept orientation and directionality to determine mapping.

An example override might be a tab list with an overflow menu that is meant to be transparent to screen reader users. This would require the overflow menu to accept both up/down keys as well as left/right keys to give a more consistent experience to all users.

pageSizenumber

Controls how much a pageUp/pageDown navigation request will jump. If not provided, the size of the list and number of items rendered will determine this value.

getId(item: ) => string

Optional function to return an id of an item. If not provided, the default function will return the id property from the object of each item. If you did not provide items, do not override this function. If you don't provided items and instead provide static items via JSX, the list will create an internal array of items where id is the only property and the default getId will return the desired result.

getTextValue(item: ) => string

Optional function to return the text representation of an item. If not provided, the default function will return the text property of the object of each item or an empty string if there is no text property. If you did not provide items, do not override this function.

nonInteractiveIdsstring[]

Array of all ids which are currently disabled. This is used for navigation to skip over items which are not focusable.

orientation

The orientation of a list of items. Values are either vertical or horizontal. This value will effect which ids activate progression through a list. For example, horizontal will activate with left and right arrows while vertical will activate with up and down arrows.

'vertical'
defaultItemHeightnumber

Best guess to the default item height for virtualization. Getting this number correct avoids a rerender while the list is initializing.

50
items[]

Optional array of items. If provided, use a render prop for list children instead of static children. If the shape of each item object does not have an id property or uses a different property to uniquely identify each item, a getId must also be supplied.

UNSTABLE_parentModel {
    state: {
      selectedIds:  'all' string[];
      unselectedIds: string[];
      cursorId:  string string[];
      columnCount: number;
      pageSizeRef: <number>;
      cursorIndexRef: {
        current: number;
      };
      UNSTABLE_virtual: <, Element>;
      UNSTABLE_defaultItemHeight: number;
      containerRef: <>;
      id: string;
      orientation:  'horizontal' 'vertical';
      indexRef: <number>;
      nonInteractiveIds: string[];
      isVirtualized: boolean;
      items: <any>[];
    };
    events: {
      select: (data: {
        id: string;
      }) => void;
      selectAll: () => void;
      unselectAll: () => void;
      setSelectedIds: (ids:  'all' string[]) => void;
      remove: (data: {
        id: string;
        nextId: string;
        event:  Event SyntheticEvent;
      }) => void;
      goTo: (data: {
        id: string;
      }) => void;
      goToNext: () => void;
      goToPrevious: () => void;
      goToPreviousRow: () => void;
      goToNextRow: () => void;
      goToFirst: () => void;
      goToLast: () => void;
      goToFirstOfRow: () => void;
      goToLastOfRow: () => void;
      goToNextPage: () => void;
      goToPreviousPage: () => void;
      registerItem: (data: {
        id: string;
        textValue: string;
      }) => void;
      unregisterItem: (data: {
        id: string;
      }) => void;
      updateItemHeight: (data: {
        value: number;
      }) => void;
    };
    selection: ;
    navigation: ;
    getId: (item: ) => string;
    getTextValue: (item: ) => string;
  } undefined
model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

Menu.Submenu.Card

The menu card is a non-semantic element used to give the dropdown menu its distinct visual cue that the dropdown menu is floating above other content. A menu card usually contains a menu list, but can also contain other elements like a header or footer.

Menu.Card supports all props from thelayout component.

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

NameTypeDescriptionDefault
childrenReactNode

Children of the Card. Should contain a <Card.Body> and an optional <Card.Heading>

variant 'borderless' 'filled'

The variant of the Card. Can be default, borderless or filled.

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

div
refReact.Ref<R = div>

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuCard

(
  model: ,
  elemProps: {},
  ref: React.Ref
) => {}

Menu.Submenu.List

The menu list follows the Collections API. A list can either contain static items or a render prop and items. It is recommended that the items comes from a nested JavaScript object.

Menu.List supports all props from thelayout component.

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

NameTypeDescriptionDefault
children
  undefined
  null
  string
  number
  false
  true
  ReactElement
  
  
  (item: T) => ReactNode

The label text of the MenuList.

marginY
  undefined
  number
  string & {}
  'zero'
  's'
  'm'
  'l'
  'xxxs'
  'xxs'
  'xs'
  'xl'
  'xxl'
  'xxxl'

Set the margin top and bottom of the list box. You must use this prop and not style any other way. The Menu uses virtualization and needs margins to be set on the correct element. This ensure proper rendering.

marginTop
  undefined
  number
  string & {}
  'zero'
  's'
  'm'
  'l'
  'xxxs'
  'xxs'
  'xs'
  'xl'
  'xxl'
  'xxxl'

Set the margin top of the list box. You must use this prop and not style any other way. The Menu uses virtualization and needs margins to be set on the correct element. This ensure proper rendering. If a marginTop is not provided, the value falls back to marginY.

marginBottom
  undefined
  number
  string & {}
  'zero'
  's'
  'm'
  'l'
  'xxxs'
  'xxs'
  'xs'
  'xl'
  'xxl'
  'xxxl'

Set the margin bottom of the list box. You must use this prop and not style any other way. The Menu uses virtualization and needs margins to be set on the correct element. This ensure proper rendering. If a marginBottom is not provided, the value falls back to marginY.

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

If this is set it will cause a wrapping of a list that will turn it into a grid

0
idstring

IDREF of the list. Children ids can be derived from this id

navigation

Controls the state changes when the user sends navigation events to the model. For example, when the user hits the "right" arrow, a behavior hook will determine directionality (left-to-right or right-to-left) and call the correct navigation method. In our example, a left-to-right language would send a getNext. The navigation manager may return the next item in the list. Different managers can be created for slightly different use cases. The default navigation manager will accept orientation and directionality to determine mapping.

An example override might be a tab list with an overflow menu that is meant to be transparent to screen reader users. This would require the overflow menu to accept both up/down keys as well as left/right keys to give a more consistent experience to all users.

shouldVirtualizetrue
selection
pageSizenumber

Controls how much a pageUp/pageDown navigation request will jump. If not provided, the size of the list and number of items rendered will determine this value.

getId(item: ) => string

Optional function to return an id of an item. If not provided, the default function will return the id property from the object of each item. If you did not provide items, do not override this function. If you don't provided items and instead provide static items via JSX, the list will create an internal array of items where id is the only property and the default getId will return the desired result.

getTextValue(item: ) => string

Optional function to return the text representation of an item. If not provided, the default function will return the text property of the object of each item or an empty string if there is no text property. If you did not provide items, do not override this function.

defaultItemHeightnumber

Best guess to the default item height for virtualization. Getting this number correct avoids a rerender while the list is initializing.

50
nonInteractiveIdsstring[]

Array of all ids which are currently disabled. This is used for navigation to skip over items which are not focusable.

orientation

The orientation of a list of items. Values are either vertical or horizontal. This value will effect which ids activate progression through a list. For example, horizontal will activate with left and right arrows while vertical will activate with up and down arrows.

'vertical'
items[]

Optional array of items. If provided, use a render prop for list children instead of static children. If the shape of each item object does not have an id property or uses a different property to uniquely identify each item, a getId must also be supplied.

initialCursorId string string[]

Initial cursor position. If not provided, the cursor will point to the first item in the list

initialSelectedIds
initialUnselectedIdsstring[]
UNSTABLE_parentModel {
    state: {
      selectedIds:  'all' string[];
      unselectedIds: string[];
      cursorId:  string string[];
      columnCount: number;
      pageSizeRef: <number>;
      cursorIndexRef: {
        current: number;
      };
      UNSTABLE_virtual: <, Element>;
      UNSTABLE_defaultItemHeight: number;
      containerRef: <>;
      id: string;
      orientation:  'horizontal' 'vertical';
      indexRef: <number>;
      nonInteractiveIds: string[];
      isVirtualized: boolean;
      items: <any>[];
    };
    events: {
      select: (data: {
        id: string;
      }) => void;
      selectAll: () => void;
      unselectAll: () => void;
      setSelectedIds: (ids:  'all' string[]) => void;
      remove: (data: {
        id: string;
        nextId: string;
        event:  Event SyntheticEvent;
      }) => void;
      goTo: (data: {
        id: string;
      }) => void;
      goToNext: () => void;
      goToPrevious: () => void;
      goToPreviousRow: () => void;
      goToNextRow: () => void;
      goToFirst: () => void;
      goToLast: () => void;
      goToFirstOfRow: () => void;
      goToLastOfRow: () => void;
      goToNextPage: () => void;
      goToPreviousPage: () => void;
      registerItem: (data: {
        id: string;
        textValue: string;
      }) => void;
      unregisterItem: (data: {
        id: string;
      }) => void;
      updateItemHeight: (data: {
        value: number;
      }) => void;
    };
    selection: ;
    navigation: ;
    getId: (item: ) => string;
    getTextValue: (item: ) => string;
  } undefined
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.

div
refReact.Ref<R = div>

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuList

(
  (
    model: ,
    elemProps: {},
    ref: React.Ref
  ) => {
    role: 'menu';
    aria-labelledby: string;
    aria-orientation:  'horizontal' 'vertical';
  },
  ,
  
)

Menu.Submenu.Item

If the static API is used, a data-id prop should be used to identify the item. If you're using the dynamic API, pass a getId and getTextValue to the parent Menu the model.

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

NameTypeDescriptionDefault
indexnumber

Optionally pass index to menu item. This should be done if Menu.Item components were created via a Array::map function. This index will ensure keyboard navigation works even if items are inserted out of order.

childrenReactNode

The label text of the MenuItem.

data-idstring

The name of the menu item. This name will be used in the onSelect callback in the model. If this property is not provided, it will default to a string representation of the the zero-based index of the Tab when it was initialized.

aria-disabledboolean

aria-disabled is used for keyboard and screen reader users to discover disabled content with the keyboard or screen reader caret tool. For more information, see https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_disabled_controls

isDisabledboolean

If true, set the StyledMenuItem to the disabled state so it is not clickable.

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuItem

(
  (
    model: ,
    elemProps: {},
    ref: React.Ref
  ) => {
    role: 'menuitem';
    onMouseDown: (event: ) => void;
    onClick:  ((event: SyntheticEvent) => void) undefined;
  },
  ,
  ,
  ,
  ,
  
)

Basic type information:

MenuItemIcon

Basic type information:

MenuItemText

Menu.Submenu.TargetItem

The Submenu.TargetItem is similar to the Menu.Item, but represents both the target for the submenu and the item in the menu list. This should only be used once per <Menu.Submenu> component.

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

NameTypeDescriptionDefault
model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useSubmenuTargetItem

(
  ,
  ,
  ,
  (
    model: ,
    elemProps: {},
    ref: React.Ref
  ) => {
    ref: (instance:  null) => void;
  },
  ,
  (
    model: ,
    elemProps: {},
    ref: React.Ref
  ) => {
    id: string;
    role: 'menuitem';
    aria-haspopup: 'true';
    aria-expanded: boolean;
    onMouseDown: (event: ) => void;
    onMouseEnter: (event: ) => void;
    onMouseLeave: () => void;
    onClick: (event: ) => void;
    data-has-children: true;
    onKeyDown: (event: ) => void;
  }
)

Menu.Submenu.Group

This component references the component.

Menu.Submenu.Option

A Menu.Option is similar to the Menu.Item, but has a role=option and works with aria-activedescendant and is selectable with a selected checkmark. It adds the aria-selected="true/false" attribute. Menu.Option requires much more accessibility behavior composed into the Menu.Target and Menu.List component. The Combobox and Select components make use of the Menu.Option. See those components for a better idea of how behavior is composed.

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

NameTypeDescriptionDefault
indexnumber

Optionally pass index to menu item. This should be done if Menu.Item components were created via a Array::map function. This index will ensure keyboard navigation works even if items are inserted out of order.

childrenReactNode

The label text of the MenuItem.

data-idstring

The name of the menu item. This name will be used in the onSelect callback in the model. If this property is not provided, it will default to a string representation of the the zero-based index of the Tab when it was initialized.

aria-disabledboolean

aria-disabled is used for keyboard and screen reader users to discover disabled content with the keyboard or screen reader caret tool. For more information, see https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_disabled_controls

isDisabledboolean

If true, set the StyledMenuItem to the disabled state so it is not clickable.

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

li
refReact.Ref<R = li>

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuOption

(
  (
    model: ,
    elemProps: {
      data-id: string;
    },
    ref: React.Ref
  ) => {
    role: 'option';
    aria-selected: boolean;
    onMouseDown: (event: <>) => void;
  },
  ,
  
)

Basic type information:

MenuOptionText

Menu.Submenu.Divider

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

NameTypeDescriptionDefault
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>
)
childrenReact.ReactNode
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.

hr
refReact.Ref<R = hr>

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

Menu.Submenu.Popper

The "Popper" of a menu. The popper will appear around the . It renders a div element that is portalled to the document.body which is controlled by the {@link PopupStack }. The PopupStack is not part of React. This means no extra props given to this component will be forwarded to the div element, but the ref will be forwarded.

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

NameTypeDescriptionDefault
anchorElement <Element> Element null

The reference element used to position the Popper. Popper content will try to follow the anchorElement if it moves and will reposition itself if there is no longer room in the window.

children ((props: {
    placement: ;
  }) => ReactNode)
ReactNode

The content of the Popper. If a function is provided, it will be treated as a Render Prop and pass the placement chosen by PopperJS. This placement value is useful if your popup needs to animate and that animation depends on the direction of the content in relation to the anchorElement.

getAnchorClientRect() => 

When provided, this optional callback will be used to determine positioning for the Popper element instead of calling getBoundingClientRect on the anchorElement prop. Use this when you need complete control over positioning. When this prop is specified, it is safe to pass null into the anchorElement prop. If null is passed into the anchorElement prop, an owner will not be provided for the PopupStack.

openboolean

Determines if Popper content should be rendered. The content only exists in the DOM when open is true

true
placement

The placement of the Popper contents relative to the anchorElement. Accepts auto, top, right, bottom, or left. Each placement can also be modified using any of the following variations: -start or -end.

fallbackPlacements[]

Define fallback placements by providing a list of in array (in order of preference). The default preference is following the order of top, right, bottom, and left. Once the initial and opposite placements are not available, the fallback placements will be in use. Use an empty array to disable the fallback placements.

onPlacementChange(placement: ) => void

A callback function that will be called whenever PopperJS chooses a placement that is different from the provided placement preference. If a placement preference doesn't fit, PopperJS will choose a new one and call this callback.

popperOptions<PopperOptions>

The additional options passed to the Popper's popper.js instance.

portalboolean

If false, render the Popper within the DOM hierarchy of its parent. A non-portal Popper will constrained by the parent container overflows. If you set this to false, you may experience issues where you content gets cut off by scrollbars or overflow: hidden

true
popperInstanceRefRef<>

Reference to the PopperJS instance. Useful for making direct method calls on the popper instance like update.

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.

div
refReact.Ref<R = div>

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

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useMenuPopper

useMenuModel

useMenuModel (config: ):

Specifications

Content Guidelines

  • When writing Menu list items, refer to the Menus section of the Content Style Guide.

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: