Migrate Action List from Polaris React
Polaris web components don't have a like-for-like ActionList component. Choose the replacement based on the list's purpose:
Existing ActionList | Polaris web components | Migration type |
|---|---|---|
Contextual actions opened from a button or Popover | A trigger s-button and sibling s-menu | Compose |
| Actions that are always visible | An s-stack containing s-button or s-link elements | Compose |
| Selectable options | s-choice-list or s-select | Change pattern |
| Filterable resource actions | A resource index or another visible search-and-list pattern | Change pattern |
Don't move a persistent list into an overflow menu only because s-menu is the closest component by name. Preserve whether the actions are contextual, persistent, or selectable.
Anchor to Migrate a contextual ActionListMigrate a contextual Action List
Polaris React commonly combines Button, Popover, and ActionList. In Polaris web components, the trigger references a sibling menu by ID, and the menu manages its overlay state.
Migrate a contextual ActionList
Polaris web components
function ProductActions({onDuplicate, onArchive, onDelete}) {
return (
<>
<s-button commandFor="product-actions">More actions</s-button>
<s-menu id="product-actions" accessibilityLabel="Product actions">
<s-button icon="duplicate" onClick={onDuplicate}>
Duplicate as draft
</s-button>
<s-button icon="archive" onClick={onArchive}>
Archive product
</s-button>
<s-button icon="delete" tone="critical" onClick={onDelete}>
Delete product
</s-button>
</s-menu>
</>
);
}Polaris React
import {useState} from 'react';
import {ActionList, Button, Popover} from '@shopify/polaris';
import {ArchiveIcon, DeleteIcon, DuplicateIcon} from '@shopify/polaris-icons';
export function ProductActions({onDuplicate, onArchive, onDelete}) {
const [active, setActive] = useState(false);
return (
<Popover
active={active}
activator={
<Button disclosure onClick={() => setActive((open) => !open)}>
More actions
</Button>
}
onClose={() => setActive(false)}
>
<ActionList
actionRole="menuitem"
items={[
{
content: 'Duplicate product',
helpText: 'Creates a new draft product',
icon: DuplicateIcon,
onAction: onDuplicate,
},
{
content: 'Archive product',
icon: ArchiveIcon,
onAction: onArchive,
},
{
content: 'Delete product',
destructive: true,
icon: DeleteIcon,
onAction: onDelete,
},
]}
/>
</Popover>
);
}Preview
The migrated example changes Duplicate product with the help text Creates a new draft product to the self-contained action label Duplicate as draft. s-menu items don't support secondary help text.
Anchor to Map ActionList propertiesMap Action List properties
| Polaris React | Polaris web components | Migration type |
|---|---|---|
items | Root-level s-button children of s-menu | Direct |
sections | s-section children with heading and nested s-button elements | Compose |
actionRole | Remove. s-menu supplies menu semantics and keyboard behavior. | Remove |
allowFiltering and filterLabel | No menu equivalent. Use a visible search-and-list experience or a resource index. | Change pattern |
onActionAnyItem | Call the shared callback from each item's onClick handler. | Compose |
An s-menu only accepts s-button and s-section children. Don't place s-search-field inside a menu to recreate allowFiltering.
Anchor to Map item propertiesMap item properties
| Polaris React item property | Polaris web components | Migration type |
|---|---|---|
id | id on s-button | Direct |
content | Button text content | Direct |
accessibilityLabel | accessibilityLabel | Direct |
url | href | Direct |
external or target | target, such as target="_blank" | Changed |
onAction | onClick | Direct |
onMouseEnter or onTouchStart | Keep a standard DOM event handler only when the behavior is still required. | Changed |
disabled | disabled | Direct |
destructive | tone="critical" | Direct |
icon | A documented icon name string in icon | Changed |
helpText | No menu-item equivalent. Rewrite the label or move essential explanation to visible page content. | Unsupported |
badge | No menu-item badge. Include essential state in the label or show it outside the menu. | Unsupported |
image, prefix, or suffix | No arbitrary menu-item content. Use a persistent composition when that content is essential. | Unsupported |
ellipsis or truncate | Use a shorter action label. The menu owns item layout. | Changed |
active | Don't use an action menu as a selection control. Use s-choice-list or s-select. | Change pattern |
variant or role | Remove. The destination component owns its appearance and semantics. | Remove |
Anchor to Preserve help text intentionallyPreserve help text intentionally
Don't silently discard helpText. Choose one of these migrations:
- Rewrite non-essential supporting text into a concise, self-contained action label.
- Keep the action visible and place essential explanation next to it using
s-textors-paragraph. - Use a resource or settings pattern when the text describes resource state or a configurable choice.
Avoid moving essential instructions into a tooltip. Merchants must be able to understand the action without discovering hidden content.
Anchor to Migrate sectionsMigrate sections
Replace each section descriptor with an s-section inside s-menu. Move sections[].title to heading and render each item as a button. If a title is a custom React node, rewrite it as a concise string heading.
Anchor to Keep persistent actions visibleKeep persistent actions visible
If the ActionList is always visible, replace it with explicit controls rather than introducing an overflow menu.
Migrate a persistent ActionList
Polaris web components
function ProductActions({onEdit, onDuplicate, onDelete}) {
return (
<s-stack gap="small" alignItems="stretch">
<s-button variant="tertiary" inlineSize="fill" onClick={onEdit}>
Edit details
</s-button>
<s-button variant="tertiary" inlineSize="fill" onClick={onDuplicate}>
Duplicate product
</s-button>
<s-button variant="tertiary" inlineSize="fill" tone="critical" onClick={onDelete}>
Delete product
</s-button>
</s-stack>
);
}Polaris React
import {ActionList} from '@shopify/polaris';
export function ProductActions({onEdit, onDuplicate, onDelete}) {
return (
<ActionList
items={[
{content: 'Edit details', onAction: onEdit},
{content: 'Duplicate product', onAction: onDuplicate},
{content: 'Delete product', destructive: true, onAction: onDelete},
]}
/>
);
}Preview
Anchor to Test the migrationTest the migration
- Test opening, closing, and choosing menu items with a keyboard.
- Confirm that destructive and disabled actions retain their behavior.
- Test link actions with normal, modified, and middle clicks.
- Confirm that every removed
helpText, badge, prefix, suffix, and active state has an intentional destination. - Confirm that focus returns to the trigger after the menu closes.
Anchor to Remove Polaris ReactRemove Polaris React
After every ActionList call site is migrated:
- Remove the
ActionListimport. - Remove
Popoveropen state and close callbacks that only controlled the action list. - Remove imported Polaris React icons that were replaced by icon name strings.
- Run interaction and accessibility tests for each destination pattern.