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

- Container: Background and stroke element containing all other elements within this component
- Pill Label: Describes the Pill meaning or input.
- 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.
- Counter: Number appearing after the label used to show the count of something.
- Counter Container: Contrasting background that houses the Counter.
- 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. 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 access to all SystemIconProps.
Accessibility
You must provide an aria-label to the Pill.Icon for proper accessibility.
import React from 'react';
import {Pill} from '@workday/canvas-kit-preview-react/pill';
import {BodyText} from '@workday/canvas-kit-react/text';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const flexStyles = createStyles({
display: 'flex',
gap: system.space.x2,
});
export default () => {
const [text, setText] = React.useState('');
return (
<div>
<div className={flexStyles}>
<Pill onClick={() => setText('The first pill is clicked!')}>
<Pill.Icon aria-label="Add user" />
<Pill.Label>Regina Skeltor</Pill.Label>
</Pill>
<Pill disabled>
<Pill.Icon aria-label="Add user" />
<Pill.Label>Regina Skeltor</Pill.Label>
</Pill>
</div>
<BodyText size="medium">{text}</BodyText>
</div>
);
};
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.
import React from 'react';
import {Pill} from '@workday/canvas-kit-preview-react/pill';
// @ts-ignore: Cannot find module error
import testAvatar from './test-avatar.png';
import {BodyText} from '@workday/canvas-kit-react/text';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const flexStyles = createStyles({
display: 'flex',
gap: system.space.x2,
});
export default () => {
const [text, setText] = React.useState('');
return (
<div>
<div className={flexStyles}>
<Pill onClick={() => setText('The first pill is clicked!')}>
<Pill.Avatar name="Regina Skeltor" url={testAvatar} />
<Pill.Label>Regina Skeltor</Pill.Label>
</Pill>
<Pill disabled>
<Pill.Avatar name="Regina Skeltor" />
<Pill.Label>Regina Skeltor</Pill.Label>
</Pill>
</div>
<BodyText size="medium">{text}</BodyText>
</div>
);
};
Count
The count appears after the label. It is usually associated with the label. If you have a category, the count will directly correlate to that category.
import React from 'react';
import {Pill} from '@workday/canvas-kit-preview-react/pill';
import {BodyText} from '@workday/canvas-kit-react/text';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const flexStyles = createStyles({
display: 'flex',
gap: system.space.x2,
});
export default () => {
const [text, setText] = React.useState('');
return (
<div>
<div className={flexStyles}>
<Pill onClick={() => setText('The first pill is clicked!')}>
Shoes
<Pill.Count>30</Pill.Count>
</Pill>
<Pill disabled>
Shoes
<Pill.Count>30</Pill.Count>
</Pill>
</div>
<BodyText size="medium">{text}</BodyText>
</div>
);
};
Read Only
The readOnly variant is a non-interactive element that is used to display information.
You can define a read only Pill by providing a variant='readOnly' prop.
import {Pill} from '@workday/canvas-kit-preview-react/pill';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const flexStyles = createStyles({
display: 'flex',
gap: system.space.x2,
});
export default () => (
<div className={flexStyles} id="read-only-list">
<Pill variant="readOnly">Read-only</Pill>
<Pill variant="readOnly" maxWidth={150}>
Read-only but with super long text in case you want to read a paragraph in a Pill which we
don't recommend
</Pill>
</div>
);
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
import React from 'react';
import {Pill} from '@workday/canvas-kit-preview-react/pill';
// @ts-ignore: Cannot find module error
import testAvatar from './test-avatar.png';
import {BodyText} from '@workday/canvas-kit-react/text';
import {system} from '@workday/canvas-tokens-web';
import {createStyles} from '@workday/canvas-kit-styling';
const flexStyles = createStyles({
display: 'flex',
gap: system.space.x2,
});
export default () => {
const [text, setText] = React.useState('');
return (
<div>
<div className={flexStyles}>
<Pill variant="removable">
<Pill.Label>Pink Shirts</Pill.Label>
<Pill.IconButton
aria-label="Remove"
onClick={() => setText('The first pill is clicked!')}
/>
</Pill>
<Pill variant="removable">
<Pill.Avatar name="Avatar" url={testAvatar} />
<Pill.Label>Carolyn Grimaldi</Pill.Label>
<Pill.IconButton
aria-label="Remove"
onClick={() => setText('The second pill is clicked!')}
/>
</Pill>
<Pill variant="removable" disabled>
<Pill.Label>This is a category that should not exist because it is too long</Pill.Label>
<Pill.IconButton aria-label="Remove" />
</Pill>
</div>
<BodyText size="medium">{text}</BodyText>
</div>
);
};
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.
import React from 'react';
import {Pill} from '@workday/canvas-kit-preview-react/pill';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const data = [
'Shoes',
'Pants',
'Dress Shoes',
'Color',
'Accessories',
'Luxury',
'Casual',
'Hats',
'Beanies',
'Glasses',
'Jewelry',
];
const flexWrapStyles = createStyles({
display: 'flex',
flexWrap: 'wrap',
gap: system.space.x2,
});
export default () => {
const [items, setItems] = React.useState(data);
return (
<div className={flexWrapStyles}>
{items.map((cat, index) => {
return (
<Pill key={index} variant="removable">
<Pill.Label>{cat}</Pill.Label>
<Pill.IconButton
aria-label="Remove"
onClick={() => setItems(items.filter(i => i !== cat))}
/>
</Pill>
);
})}
</div>
);
};
Custom Styles
Pill supports custom styling via the cs prop. For more information, check our
“How To Customize Styles”
or view the example below.
import {Pill, pillCountStencil, pillStencil} from '@workday/canvas-kit-preview-react/pill';
import {createStencil} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
import {systemIconStencil} from '@workday/canvas-kit-react/icon';
const customPillStencil = createStencil({
base: {
[pillStencil.vars.background]: system.color.static.green.default,
[pillStencil.vars.border]: system.color.static.green.stronger,
[pillStencil.vars.label]: system.color.static.white,
[systemIconStencil.vars.color]: system.color.static.white,
[pillCountStencil.vars.backgroundColor]: system.color.static.green.default,
[pillCountStencil.vars.borderColor]: system.color.static.green.default,
'&:hover, &.hover': {
[pillStencil.vars.background]: system.color.static.green.stronger,
[pillStencil.vars.label]: system.color.static.white,
[pillCountStencil.vars.backgroundColor]: system.color.static.green.stronger,
[systemIconStencil.vars.color]: system.color.static.white,
[pillCountStencil.vars.borderColor]: system.color.static.green.stronger,
},
'&:active, &.active': {
[pillStencil.vars.background]: system.color.static.green.stronger,
[pillStencil.vars.label]: system.color.static.white,
[systemIconStencil.vars.color]: system.color.static.white,
[pillCountStencil.vars.backgroundColor]: system.color.static.green.stronger,
},
'&:focus, &.focus, &:focus-visible': {
[pillStencil.vars.background]: system.color.static.green.stronger,
[pillStencil.vars.label]: system.color.static.white,
[systemIconStencil.vars.color]: system.color.static.white,
[pillCountStencil.vars.backgroundColor]: system.color.static.green.stronger,
},
'&:disabled, &.disabled': {
[pillStencil.vars.background]: system.color.static.green.default,
[pillStencil.vars.label]: system.color.static.white,
[systemIconStencil.vars.color]: system.color.static.white,
},
},
});
export default () => {
return (
<div>
<Pill cs={customPillStencil()}>
<Pill.Icon aria-label="Add user" />
<Pill.Label>Custom Pill Color</Pill.Label>
<Pill.Count>10</Pill.Count>
</Pill>
</div>
);
};
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 aria-label='Remove user' 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 aria-label='Remove user' 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.
| Name | Type | Description | Default |
|---|---|---|---|
variant | 'readOnly' | 'removable' | Defines what kind of pill to render stylistically and its interaction states | 'default' |
maxWidth | string | number | Determines the max width of the pill. If the pill text is longer than the max width, text will be truncated and a tooltip will show the rest of the content when hovered over | 200 |
cs | | The | |
children | ReactNode | ||
as | React.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 Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | button |
ref | React.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 | |
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 | ( | 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} />
<Pill.Label>Regina Skeltor</Pill.Label>
<Pill.IconButton aria-label='Remove user' onClick={() => console.log('handle remove')} />
</Pill>
Props
Props extend from div. Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
url | string | The URL of the user's photo. For best fit, use square images. | |
objectFit | Property.ObjectFit | An objectFit property that can customize how to resize your image to fit its container. | 'contain' |
isDecorative | boolean | If true, the Avatar won't forward the | |
children | ReactNode | Children of the BaseAvatar. | |
variant | | The variant of the Avatar. | 'blue' |
size | | The size of the Avatar.
| 'medium' |
cs | | The | |
name | string | The alt text of the Avatar image. This prop is also used for the initials. The first letter of the first name and the first letter of the second name are chosen for the initials. | |
preferredInitials | string | If you want full control over the initials, use | |
as | React.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 Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | div |
ref | React.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 | |
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 | ( | 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')}>
<Pill.Label>Shoes</Pill.Label>
<Pill.Count>30</Pill.Count>
</Pill>
Layout Component
Pill.Count supports all props from thelayout component.
Props
Props extend from span. Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
cs | | The | |
children | ReactNode | ||
as | React.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 Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | span |
ref | React.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 |
Pill.Icon
This component renders an icon. By default it renders a plusIcon but it can be overridden by
providing an icon to the icon prop. You must provide an aria-label for the icon.
<Pill onClick={() => console.warn('clicked')}>
<Pill.Icon aria-label='Add user' />
<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.
| Name | Type | Description | Default |
|---|---|---|---|
icon | | The icon to display from | |
size | number | string | The size of the SystemIcon in | |
accent | string | The accent color of the SystemIcon. This overrides | |
accentHover | string | The accent color of the SystemIcon on hover. This overrides | |
background | string | The background color of the SystemIcon. | |
backgroundHover | string | The background color of the SystemIcon on hover. | |
color | string | The color of the SystemIcon. This defines | |
colorHover | string | The hover color of the SystemIcon. This defines | |
fill | string | The fill color of the SystemIcon. This overrides | |
fillHover | string | The fill color of the SystemIcon on hover. This overrides | |
shouldMirror | boolean | If set to | false |
shouldMirrorInRTL | boolean | If set to | false |
cs | | The | |
children | ReactNode | ||
as | React.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 Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | span |
ref | React.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 | |
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 | ( | 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">
<Pill.Label>Pink Shirts</Pill.Label>
<Pill.IconButton aria-label='Remove item' 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.
| Name | Type | Description | Default |
|---|---|---|---|
aria-label | string | The aria label for the removable icon. You must provide a valid string to represent the action. | |
icon | | The icon to display from | |
size | number | string | The size of the SystemIcon in | |
accent | string | The accent color of the SystemIcon. This overrides | |
accentHover | string | The accent color of the SystemIcon on hover. This overrides | |
background | string | The background color of the SystemIcon. | |
backgroundHover | string | The background color of the SystemIcon on hover. | |
color | string | The color of the SystemIcon. This defines | |
colorHover | string | The hover color of the SystemIcon. This defines | |
fill | string | The fill color of the SystemIcon. This overrides | |
fillHover | string | The fill color of the SystemIcon on hover. This overrides | |
shouldMirror | boolean | If set to | false |
shouldMirrorInRTL | boolean | If set to | false |
cs | | The | |
children | ReactNode | ||
as | React.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 Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | button |
ref | React.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 | |
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 | ( | 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 unless you have an icon or other element.
<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.
| Name | Type | Description | Default |
|---|---|---|---|
tooltipProps | <, 'children'> | ||
cs | | The | |
children | ReactNode | ||
as | React.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 Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | span |
ref | React.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 | |
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 | ( | 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.
Anatomy

- Container: Background and border holds all elements within a Pill.
- Label: Describes the Pill meaning or input, ideally a single word or two.
- Leading Area (Optional): An avatar or flag displayed before the label.
- Trailing Area (Optional) : Icons placed after the label are meant to convey the intended interaction of the pill, with the exception of the Count Pills. Trailing icon can be X, check, plus or counter.
Interaction States
Pills support Inactive, Pressed, and Disabled States.

Variations
Default

By default a Pill is interactive, however the resulting interaction may vary based on the location or context of the pill. For example, Pills navigate a user to more details related to the label of the pill. Pills within prompts or inputs open the prompt allowing further interaction.
Size

Medium
This is the default size for pills and should be used within all inputs where pills are utilized. An additional 4pt of tappable top and bottom margins are added to maintain a 48pt tap target.
Small
The small pill is used for tasks that are supplementary to the main task. For example, displaying filtered parameters in relation to primary content. This stage of filtering is supplementary to the main task. The small size pill variant is used to reinforce the hierarchy of the page by adding emphasis to more important elements. Small pills maintain an additional 8pt top and bottom margin to ensure a 48pt tap target.
Filtered
Filtered Pills are the activated version of a pill. These pills are differentiated from default pills by the addition of a checkmark or X icon, depending on the use case.

The checkmark is meant to be used when all filters are displayed alongside each other, with the ability to quickly turn a filter on or off . The checkmark identifies the active filters. The filtered pills with the X icons are meant to be used when displaying only those active filters. Activation of filters would typically be a part of a larger flow. The X allows the user to quickly remove the active filter resulting in the pill disappearing from the screen.
Leading Area

All leading elements are intended to be descriptive, helping support the label. Do not rely on the leading element to indicate the interaction behavior. Trailing elements are for interaction behavior.
Avatar
A XXS avatar is displayed before the label.
Flag
Coming Soon…
Trailing Area

Elements displayed after the label are meant to convey the expected interaction of the pill, with the exception of the count variant.
X Icon
These Pills display an X icon after the label conveying they can be removed from the page. If a Pill is to be removed, there should always be a way for the user to add the Pill again. These should never be used for destructive actions
Plus Icon
Pills with the plus icon are used to add items to a parent container. They can also be used in filtering, conveying the filter can be activated.
Check Icon
Pills with a checkmark are only used with filtered pills. The checkmark conveys the filter attributed to the pill is active or enabled.
Count
Count pills display a number at the end of the pill. This number directly correlates with the pill label. While the number can be as large as possible the count within the pill has a limit of 99, any number larger than that will be displayed as 99+.
Non-Interactive
A non-interactive element used to display information about an object.

Non-interactive pills do not truncate and instead wrap to multiple lines; however, try to keep Pill text as succinct as possible - between 2-7 words or wrap no more than 2 lines.
Usage Guidance
Pills are used to visually label objects on a page for quick recognition. They’re offered as both read-only and interactive elements. They allow users to input a section, filter, or label information to help with scanning and organization.
- Interactive Pills should always truncate, never wrapping to multiple lines.
- Non-interactive Pills should not truncate and can wrap to multiple lines.
- The max-width of a pill is 600pt/dp, or up to the screen margins of the device.
- Pill groups can stack to multiple lines when necessary.
- Use pills in moderation, as they can increase the visual noise of a page.
- Ensure a minimum tap target height of 48dp to ensure easy interaction. This means adding an additional 4dp of tappable top and bottom padding to the medium sized Pills and 8dp for small Pills.

Do
Use a minimum tap target of 48dp for removal of the Pill.

Don't
Use a tap target height smaller than 48dp, even if the Close Icon might appear smaller visually.
- Account for this interaction buffer by spacing multiple pills with 8dp padding between, above, and below each pill in a group.
When to Use
- To visually label applied inputs.
- To aid selection of inputs
- To imply further interaction on individual items within groups
- To visually show filtered parameters
When to Use Something Else
- For static labels that communicate a status, use a Status Indicator.
- For any sort of call-to-action, use a Button.
- 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.
- If you need to switch between related content, use Tabs or Segmented Controls.
- For any external navigation use a hyperlink.
API Guidelines
Component Definition
The component is defined as struct Pill with internal types of enum Variant, enum Indication,
and enum Size.
public struct Pill: View
public enum Variant: Hashable {
case textOnly(_ title: String)
case avatar(title: String, config: AvatarConfig)
}
public enum Indication {
case `default`
case removable
case removableFiltered
case additive
case checkmark
case counter(_ count: Int)
case nonInteractive
}
public enum Size: String, CaseIterable {
case medium // default
case small
}Methods
public init(
featureData: FeatureMetricsData,
variant: Variant,
indication: Indication,
size: Size = .medium,
localizer: LocalizationAdapting,
action: @escaping () -> Void = {}
)Parameters
| Name | Description | Default values |
|---|---|---|
| featureData | The feature name/context and the screen ID in which the component appears. | |
| variant | The content variant of the pill. | .textOnly |
| indication | The type of visual indication (add, remove, etc.) for the pill. | .default |
| size | The visual size of the pill. Default is medium. | .medium |
| localizer | The localizer to use for accessibility labels. | |
| action | The action to perform when the pill is tapped. There is no action for NonInteractive indication. | {} |
Use the .disabled method on the view in order to get the disabled appearance.
Accessibility Guidelines
- If content exceeds the max-width, an ellipses should appear at the end of the text to communicate truncation.
- Pills must exceed a 3:1 contrast ratio against the background color the Pill is placed on. See non-text contrast requirement.
- An additional 4dp of tappable top and bottom padding are added to ensure a minimum tap target area of 48dp.
- X icons in removable pills have a 48dp touch target that removes the pill from the UI.
- Pill names should be distinct from one another. Avoid using many Pills on the same page with similar names as this places additional burden on users to understand the context of each pill.
- Screen readers must announce the entire Pill Label, regardless of width or truncation.
For more accessibility considerations, refer to the Accessibility Guide.
Content Guidelines
- Keep pill labels short and concise.
- Max-width of the pill is defined by the width of its parent container plus padding.
- All interactive pills will display an ellipses to communicate truncated content.
- Non-interactive pills should never truncate and instead wrap to multiple lines.
When writing content for Pill Labels, refer to our Content Style Guide.
Anatomy

- Container: Background and border holds all elements within a Pill.
- Label: Describes the Pill meaning or input, ideally a single word or two.
- Leading Area (Optional): An avatar or flag displayed before the label.
- Trailing Area (Optional): Icons placed after the label are meant to convey the intended interaction of the pill, with the exception of the Count Pills. Trailing icon can be X, check, plus or counter.
Interaction States
Pills support Inactive, Pressed, and Disabled States.

Variations
Default

By default a Pill is interactive, however the resulting interaction may vary based on the location or context of the pill. For example, Pills navigate a user to more details related to the label of the pill. Pills within prompts or inputs open the prompt allowing further interaction.
Size

Medium
This is the default size for pills and should be used within all inputs where pills are utilized. An additional 4pt of tappable top and bottom margins are added to maintain a 48pt tap target.
Small
The small pill is used for tasks that are supplementary to the main task. For example, displaying filtered parameters in relation to primary content. This stage of filtering is supplementary to the main task. The small size pill variant is used to reinforce the hierarchy of the page by adding emphasis to more important elements. Small pills maintain an additional 8pt top and bottom margin to ensure a 48pt tap target.
Filtered
Filtered Pills are the activated version of a pill. These pills are differentiated from default pills by the addition of a checkmark or X icon, depending on the use case.

The checkmark is meant to be used when all filters are displayed alongside each other, with the ability to quickly turn a filter on or off. The checkmark identifies the active filters. The filtered pills with the X are meant to be used when displaying only those active filters. Activation of filters would typically be a part of a larger flow. The X allows the user to quickly remove the active filter resulting in the pill disappearing from the screen.
Leading Area

All leading elements are intended to be descriptive, helping support the label. Do not rely on the leading element to indicate the interaction behavior. Trailing elements are for interaction behavior.
Avatar
A XXS avatar is displayed before the label.
Flag
Coming Soon…
Trailing Area

Elements displayed after the label are meant to convey the expected interaction of the pill, with the exception of the count variant.
X Icon
These Pills display an X icon after the label conveying they can be removed from the page. If a Pill is to be removed, there should always be a way for the user to add the Pill again. These should never be used for destructive actions
Plus Icon
Pills with the plus icon are used to add items to a parent container. They can also be used in filtering, conveying the filter can be activated.
Check Icon
Pills with a checkmark are only used with filtered pills. The checkmark conveys the filter attributed to the pill is active or enabled.
Count
Count pills display a number at the end of the pill. This number directly correlates with the pill label. While the number can be as large as possible the count within the pill has a limit of 99, any number larger than that will be displayed as 99+.
Non-Interactive
A non-interactive element used to display information about an object.

Non-interactive pills do not truncate and instead wrap to multiple lines; however, try to keep Pill text as succinct as possible - between 2-7 words or wrap no more than 2 lines.
Usage Guidance
Pills are used to visually label objects on a page for quick recognition. They’re offered as both read-only and interactive elements. They allow users to input a section, filter, or label information to help with scanning and organization.
- Interactive Pills should always truncate, never wrapping to multiple lines.
- Non-interactive Pills should not truncate and can wrap to multiple lines.
- The max-width of a pill is 600pt/dp, or up to the screen margins of the device.
- Pill groups can stack to multiple lines when necessary.
- Use pills in moderation, as they can increase the visual noise of a page.
- Ensure a minimum tap target height of 48dp to ensure easy interaction. This means adding an additional 4dp of tappable top and bottom padding to the medium sized Pills and 8dp for small Pills.

Do
Use a minimum tap target of 48dp for removal of the Pill.

Don't
Use a tap target height smaller than 48dp, even if the Close Icon might appear smaller visually.
- Account for this interaction buffer by spacing multiple pills with 8dp padding between, above, and below each pill in a group.
When to Use
- To visually label applied inputs.
- To aid selection of inputs
- To imply further interaction on individual items within groups
- To visually show filtered parameters
When to Use Something Else
- For static labels that communicate a status, use a Status Indicator.
- For any sort of call-to-action, use a Button.
- 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.
- If you need to switch between related content, use Tabs or Segmented Controls.
- For any external navigation use a hyperlink.
API Guidelines
Component Definition
@Composable
fun PillUiComponent(
modifier: Modifier = Modifier,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
config: PillConfig
) {Parameters
| Name | Description |
|---|---|
| modifier | Modifier to be applied to the PillUiComponent |
| interactionSource | The MutableInteractionSource representing the stream of Interactions for this LinkPillUiComponent. You can create and pass in your own remembered MutableInteractionSource if you want to observe Interactions and customize the appearance / behavior of this LinkPillUiComponent in different Interactions. |
| pillConfig | The [PillConfig] representing the configuration of the Pill. |
PillConfig
data class PillConfig(
val pillText: String,
val onClick: (() -> Unit)? = null,
val pillType: PillType,
val size: PillSize = PillSize.Medium,
val onClickLabel: String? = null
)| Name | Description |
|---|---|
| pillText | Text to be shown in the pill |
| onClick | Will be called when the user taps the Pill. |
| pillType | Determines which variant of the [PillUiComponent] will be rendered. Variants: Link, Additive, Removable, Checked, NonInteractive |
| size | Determines the size of the [PillUiComponent]. Variants: Medium, Small |
| onClickLabel | The action type to be read(as “Double tap to activate”) by TalkBack when the user taps the Pill, default is “activate” for default pill, “add” for additive pill, “remove” for removable pill, “toggle” for checked pill. |
Link Pill Type
data class Link(
val state: PillState.Interaction = PillState.Interaction(),
val leadingConfig: PillLeadingConfig = PillLeadingConfig.None,
val hasCounter: Boolean = false,
val count: Int = 0
)Parameters
All undocumented parameters are native Android Compose types that can be found in the developer documentation.
| Name | Description |
|---|---|
| state | The state of the pill. This allows for enabling, disabling states. |
| leadingConfig | The leading config of the pill. This allows for adding an avatar to the pill. |
| hasCounter | Determines if the pill has a counter. |
| count | The integer value to be shown in the counter. |
Additive Pill Type
data class Additive(
val state: PillState.Interaction = PillState.Interaction(),
val leadingConfig: PillLeadingConfig = PillLeadingConfig.None
)Parameters
| Name | Description |
|---|---|
| state | The state of the pill. This allows for enabling, disabling states. |
| leadingConfig | The leading config of the pill. This allows for adding an avatar to the pill. |
Removable Pill Type
data class Removable(
val state: PillState = PillState.Interaction(),
val leadingConfig: PillLeadingConfig = PillLeadingConfig.None,
val isPlaceholder: Boolean = false
)Parameters
| Name | Description |
|---|---|
| state | The state of the pill. This allows for enabling, disabling states. |
| leadingConfig | The leading config of the pill. This allows for adding an avatar to the pill. |
| isPlaceholder | Determines if the pill is a placeholder. |
Checked Pill Type
data class Checked(
private val state: PillState.Filtered = PillState.Filtered,
val leadingConfig: PillLeadingConfig = PillLeadingConfig.None
)Parameters
| Name | Description |
|---|---|
| state | The state of the pill, only Filtered state is allowed on Checked Pill. |
| leadingConfig | The leading config of the pill. This allows for adding an avatar to the pill. |
Non-Interactive Pills
object NonInteractive : PillType()Accessibility Guidelines
- If content exceeds the max-width, an ellipses should appear at the end of the text to communicate truncation.
- Pills must exceed a 3:1 contrast ratio against the background color the Pill is placed on. See non-text contrast requirement.
- An additional 4dp of tappable top and bottom padding are added to ensure a minimum tap target area of 48dp.
- X icons in removable pills have a 48dp touch target that removes the pill from the UI.
- Pill names should be distinct from one another. Avoid using many Pills on the same page with similar names as this places additional burden on users to understand the context of each pill.
- Screen readers must announce the entire Pill Label, regardless of width or truncation.
For more accessibility considerations, refer to the Accessibility Guide.
Content Guidelines
- Keep pill labels short and concise.
- Max-width of the pill is defined by the width of its parent container plus padding.
- All interactive pills will display an ellipses to communicate truncated content.
- Non-interactive pills should never truncate and instead wrap to multiple lines.
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. For further information, contact the #ask-canvas-design or #ask-canvas-kitchannels on Slack.