Pill

Pills are static or interactive elements that allow users to input, filter, or label information.

yarn add @workday/canvas-kit-preview-react
Install
yarn add @workday/canvas-kit-preview-react

Anatomy

Image of Pill component with annotation markers.

  1. Container: Background and stroke element containing all other elements within this component
  2. Pill Label: Describes the Pill meaning or input.
  3. Icon (Optional): Displayed before the Pill label to provide an additional supporting visual. Icons displayed after the label are reserved for Removable Pills to further convey the action. For Removable Pills, the icon becomes the click or touch target.
  4. Counter: Number appearing after the label used to show the count of something.
  5. Counter Container: Contrasting background that houses the Counter.
  6. Avatar (Optional): Circular graphic or photo that appears to the left of the Pill label.

Usage Guidance

Pills are used to visually label objects on a page for quick recognition. They’re offered as both static, read-only and interactive elements. They allow users to input a section, filter a list or table, or label information to help with scanning and organization.

Pills with Icon or Avatar

  • There are considerations specifically for leading and trailing icons.
  • All leading elements (icons or avatars) are intended to be descriptive, helping support the label. Do not rely on the leading element to indicate the interaction behavior.
  • All trailing elements are reserved for removable Pills and Pills with count. The X icon indicates the expected interaction, and appears after the label to assure the user is aware what is being removed. The count appears after indicating the action is directly related to the count of that label.

Pills that are Removable

  • Pills that are removable display the X icon following after the label.
  • Removable pills have a smaller, more specific focus state and click target to be more intentional about its action and to avoid unintended removal of a Pill.
  • Pills are aligned either left or right and the flow of the removal will move existing Pills towards that alignment. If a Pill is removed, there should be a way for the user to add the Pill again.

Pills Used as a Filter

  • Filters appearing as a Pill allow for the user to scan and organize their filters more easily.
  • Pills fit the type of filter into a small space and allows users to quickly see if the filter is applied and/or remove it.
  • Pills add progressive disclosure to your filters by increasing learnability and reducing filter errors.

Responsive Treatment

Pills should fill their container, inline. For smaller screens and smaller containers wrap Pills so they stack to multiple lines when necessary.

When To Use

  • To show and label selected inputs that can be added and removed.
  • Pills are meant for displaying in a small space as a group. Use them to communicate labels, selections, and categories.
  • Pills can increase the amount of visual noise on a page so use them in moderation.
  • Pills can be used to input complex information in a compact Form Field. Input Pills allow users to verify input by converting content or text into a Pill. They can produce suggested responses, such as in a Workday Prompt.

When To Use Something Else

  • For static labels that communicate a status use the Status Indicator component.
  • For actions that affect anything else use a Button. Buttons are expected to appear consistently and with familiar calls to action, Pills should appear dynamically as a group of multiple interactive elements.
  • For labels that don’t appear in multiples and in a group, consider using simple body text or a header.
  • If you have more content than a simple label to display, consider using simple body text or a header.

Examples

Pills are used to visually label objects on a page for quick recognition. They’re offered as both static (read-only) and interactive elements. They allow users to filter a list or table, or label information to help with scanning and organization.

Basic Pills

By default a Pill is considered interactive, therefore it's default variant is default.All leading elements (icons or avatars) are intended to be descriptive, helping support the label. Do not rely on the leading element to indicate the interaction behavior.

Icon

You can render an icon inside the Pill with Pill.Icon. It will render a plusIcon by default, but it can be customized by providing an icon to the icon prop. Because it uses SystemIcon under the hood, you also have to all SystemIconProps.

Avatar

You can render an avatar image inside the Pill with Pill.Avatar. It should appear before the Pill text. Because it uses Avatar under the hood, you also have access to all AvatarProps.

Count

The count appears after the label. It is usually associated with the label. If you have a category, the count will dirrectly correlate to that category.

Read Only

If the Pill has variant='readOnly', it will look like a read-only Pill. This is a non-interactive element that is used to display information.

NOTE: maxWidth measures the width of the Pill.Label (or text) and not the width of the entire Pill. By default, this maxWidth is set to 200px and the text will be truncated with an ellipsis and render an OverflowTooltip on hover and focus. This max width can be changed by providing a maxWidth prop on the Pill.

Read-onlyRead-only but with super long text in case you want to read a paragraph in a Pill which we don't recommend

Removable Pills

Removable Pills display an X icon after the label. They have a smaller, more specific focus state and click target to be more intentional about their actions and to avoid unintended removal.

You can define a removable Pill by providing a variant='removable' prop.

<Pill variant="removable">
Pink Shirts
<Pill.IconButton onClick={() => console.warn('clicked')} />
</Pill>

In this case, we use a Pill.IconButton because the X becomes the focusable and clickable element.

The default icon for Pill.IconButton is xSmallIcon but this can also be overwritten by passing an icon prop to Pill.IconButton

Pink Shirts
Avatar
Carolyn Grimaldi
This is a category that should not exist because it is too long

List of Pills

Pills can often represent multiple pieces of information such as a filtered list of categories or skills.

In order to achieve this, use our Flex component to wrap each Pill and space them out accordingly.

Shoes
Pants
Dress Shoes
Color
Accessories
Luxury
Casual
Hats
Beanies
Glasses
Jewelry

Component API

Pill

By default, a Pill renders an interactive element that accepts subcomponents. By "interactive" we mean that the Pill container is a focusable element (a <button>). All leading elements (icons or avatars) are intended to be descriptive, helping support the label. They should not receive focus.

Pill is the container component. It also provides a React context model for its subcomponents. Based on the variant prop this component will render different styled Pills.

Example of read only:

<Pill variant="readOnly">This is a read only</Pill>

Example of interactive:

<Pill onClick={() => console.log('clicked')}>
<Pill.Avatar /> Regina Skeltor
</Pill>

Example of removable:

<Pill variant="removable">
<Pill.Avatar /> Regina Skeltor
<Pill.IconButton onClick={() => console.log('clicked')} />
</Pill>

If you set the Pill variant to removable, it will render a <span> element. You can then provide a Pill.IconButton that acts as the focus target. This creates a smaller, more intentional click target that prevents users from accidentally deleting an item.

<Pill variant="removable">
Shoes
<Pill.IconButton onClick={() => console.log('handle remove')} />
</Pill>

Layout Component

Pill supports all props from thelayout component.

Props

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

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

NameTypeDescriptionDefault
variant 'default' 'readOnly' 'removable'

Defines what kind of pill to render stylistically and its interaction states

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

Pill.Avatar

This component renders an avatar. It supports all props of the Avatar component.

<Pill variant="removable">
<Pill.Avatar url={avatarUrl} />
Regina Skeltor
<Pill.IconButton onClick={() => console.log('handle remove')} />
</Pill>

Props

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

NameTypeDescriptionDefault
variant

The variant of the Avatar default state. Accepts Light or Dark.

size number

The size of the Avatar.

altTextstring

The alt text of the Avatar image. This prop is also used for the aria-label

urlstring

The url of the Avatar image.

as'div'

The alternative container type for the button. Uses Emotion's special as prop. Will render an div tag instead of a button when defined.

'div'
objectFitProperty.ObjectFit

The object-fit CSS property sets how the content of a replaced element, such as an <img> or <video>, should be resized to fit its container. See object-fit. If your image is not a square, you can use this property to ensure the image is rendered properly.

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.

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.

Pill.Count

This component renders its children as the count.

<Pill onClick={() => console.warn('clicked')}>
Shoes
<Pill.Count>30</Pill.Count>
</Pill>

Layout Component

Pill.Avatar supports all props from thelayout component.

Props

Props extend from span. 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 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
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.

span
refReact.Ref<R = span>

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

Pill.Icon

This component renders an icon. It not be used with the default styling – not readOnly or removable variants. By default it renders a plusIcon but it can be overridden by providing an icon to the icon prop.

<Pill onClick={() => console.warn('clicked')}>
<Pill.Icon />
<Pill.Label>Regina Skeltor</Pill.Label>
</Pill>

Layout Component

Pill.Icon supports all props from thelayout component.

Props

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

NameTypeDescriptionDefault
icon

The system icon rendered by the component

fill

The fill color of the SystemIcon. This overrides color.

color

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

size number string undefined

The size of the SystemIcon in px.

20
styles
shouldMirrorboolean

If set to true, transform the SVG's x-axis to mirror the graphic

false
background

The background color of the SystemIcon.

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 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
accent

The accent color of the SystemIcon. This overrides color.

accentHover

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

backgroundHover

The background color of the SystemIcon on hover.

colorHover

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

fillHover

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

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.

span
refReact.Ref<R = span>

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.

Pill.IconButton

This component renders a custom icon button. It is only intended to be used with the removable variant. By default, it renders a xSmallIcon but can be overridden by providing an icon to the icon prop.

<Pill variant="removable">
Pink Shirts
<Pill.IconButton onClick={() => console.warn('clicked')} />
</Pill>

Layout Component

Pill.IconButton supports all props from thelayout component.

Props

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

NameTypeDescriptionDefault
icon

The system icon rendered by the button

aria-labelstring

The aria label for the removable icon

'remove'
fill

The fill color of the SystemIcon. This overrides color.

color

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

size number string undefined

The size of the SystemIcon in px.

styles
shouldMirrorboolean

If set to true, transform the SVG's x-axis to mirror the graphic

false
background

The background color of the SystemIcon.

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 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
accent

The accent color of the SystemIcon. This overrides color.

accentHover

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

backgroundHover

The background color of the SystemIcon on hover.

colorHover

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

fillHover

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

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.

Pill.Label

This component renders a <span> that automatically handles overflow by rendering a tooltip. There's no need to use this component directly since the overflow is handled for you automatically.

<Pill variant="readOnly">
<Pill.Label>Read-only</Pill.Label>
</Pill>

Layout Component

Pill.Label supports all props from thelayout component.

Props

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

NameTypeDescriptionDefault
tooltipProps<, 'children'>
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 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
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.

span
refReact.Ref<R = span>

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.

Model

usePillModel

usePillModel (config: ):

Accessibility Guidelines

  • If the content exceeds the max-width, an ellipses must appear to communicate overflow. Full content will appear on hover or focus within a Tooltip.
  • Pills are intended to be placed on white UI backgrounds. Consider contrast requirements when placing elsewhere.
  • The click and touch targets for Pills are expanded beyond the Pill container to better support responsive, touch screen devices.
  • Removable Pills have an intentionally small, more specific touch target to avoid accidental Pill removal.
  • Pill names must be clear and distinctive from one another. Avoid using many Pills on the page with generic identical names. This places additional burden on users to correctly understand the surrounding context for each of the identical pills on the screen.
  • When a Pill is disabled, it typically will not appear in the keyboard focus order. However, this can make it more difficult for users to discover, especially with reduced contrast. If a disabled Pill is blocking users' progress through a flow, it's be beneficial to add it back into keyboard focus order. Also, when a lengthy, disabled Pill is truncated, then keyboard users will not have access to the full length text if they cannot focus it.
  • Screen-readers must announce the entire Pill Label, regardless of width or truncation.

For more accessibility considerations, refer to the Accessibility Guide.

Content Guidelines

  • Pill labels should be kept simple, short and concise. They’re great for organizing and providing cues for what’s been selected, but you can’t fit a lot into that space. Max-width is defined by the width of the parent container of the Pill plus padding.
  • If the content exceeds the max-width, an ellipses must appear to communicate overflow.
  • Full content will appear on hover in a Tooltip. If you have more content than a simple label to display, use another component recommended above under guidelines.
  • When writing content for Pill Labels, refer to our 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.

FAQ Section