Migrate Block Stack from Polaris React
The Polaris stack component arranges related children along the block or inline axis. It replaces the Polaris React BlockStack component from @shopify/polaris and is available as <s-stack>.
s-stack defaults to direction="block", matching BlockStack. Use s-grid instead when children form columns or named page regions rather than one flexible flow.
Migrating BlockStack to s-stack
Polaris web components
export function SalesChannelSettings() {
return (
<s-stack direction="block" gap="base" alignItems="stretch">
<s-heading>Online store</s-heading>
<s-text>Manage the products available to this sales channel.</s-text>
<s-button variant="secondary" inlineSize="fill">
Manage products
</s-button>
</s-stack>
);
}Polaris React
import {BlockStack, Button, Text} from '@shopify/polaris';
export function SalesChannelSettings() {
return (
<BlockStack gap="400" inlineAlign="stretch">
<Text as="h2" variant="headingSm">
Online store
</Text>
<Text as="p">
Manage the products available to this sales channel.
</Text>
<Button>Manage products</Button>
</BlockStack>
);
}Preview
Anchor to Updated propertiesUpdated properties
The following properties are different in the Polaris stack component.
Anchor to alignalign
Rename align to justifyContent. It distributes children on the stack's main axis. The existing values map directly.
| Polaris React | Polaris web components |
|---|---|
align="start" | justifyContent="start" |
align="center" | justifyContent="center" |
align="end" | justifyContent="end" |
align="space-around" | justifyContent="space-around" |
align="space-between" | justifyContent="space-between" |
align="space-evenly" | justifyContent="space-evenly" |
For a block stack, main-axis distribution is vertical. It only creates visible extra space when the stack has more block size than its children need.
Anchor to inlineAligninline Align
Rename inlineAlign to alignItems. It aligns children across a block stack's inline axis.
| Polaris React | Polaris web components |
|---|---|
inlineAlign="start" | alignItems="start" |
inlineAlign="center" | alignItems="center" |
inlineAlign="end" | alignItems="end" |
inlineAlign="baseline" | alignItems="baseline" |
inlineAlign="stretch" | alignItems="stretch" |
alignItems="stretch" stretches the s-button host, but the button control keeps its automatic inline size. Add inlineSize="fill" to a button that needs to fill the stretched stack width.
Keep the gap property, but replace the old numeric spacing token with its Polaris web component value.
| Polaris React value | Polaris web components |
|---|---|
"0" or omitted | "none" or omitted |
"050" | "small-500" |
"100" | "small-400" |
"150" | "small-300" |
"200" | "small-200" |
"300" | "small-100" |
"400" | "base" |
"500" | "large" |
"600" | "large-200" |
"800" | "large-300" |
"1000" | "large-400" |
"1200" | "large-500" |
The old "025", "250", "700", "1600", "2000", "2400", "2800", and "3200" values don't have exact equivalents. Choose the nearest supported value based on how closely the content is related, and verify the result in context. For very large separation, use distinct page regions or sections instead of a stack with an oversized gap.
Replace responsive objects with the documented responsive value string syntax. Don't pass {xs, sm, md, lg, xl} objects to s-stack.
Anchor to role and ARIA attributesrole and ARIA attributes
Rename supported container semantics to accessibilityRole:
| Polaris React | Polaris web components |
|---|---|
role="status" | accessibilityRole="status" |
role="presentation" | accessibilityRole="presentation" |
aria-label="…" | accessibilityLabel="…" |
aria-hidden={true} | accessibilityVisibility="hidden" |
The old menu, listbox, combobox, and group roles aren't supported on s-stack. Migrate the complete interaction to the corresponding component, such as s-menu, s-select, s-choice-list, or a labeled s-section. Don't preserve an interactive ARIA role on a visual layout primitive.
Keep id when another element or app logic still references it. Remove generated IDs that only supported Polaris React styling.
Anchor to childrenchildren
Move the children into the default slot and migrate each nested Polaris React component. Their order remains their reading, focus, and visual order unless the layout explicitly changes direction at a responsive breakpoint.
Anchor to Removed propertiesRemoved properties
s-stack doesn't accept an as property. Choose a semantic component instead of changing the stack's underlying tag.
| Polaris React value | Migration |
|---|---|
"div" | Use s-stack. |
"span" | Use s-text for inline text; use s-stack only when the content is a layout group. |
"ul" | Use s-unordered-list with s-list-item children. |
"ol" | Use s-ordered-list with s-list-item children. |
"li" | Use s-list-item inside a list. |
"fieldset" | Use s-choice-list for related choices, or retain a semantic HTML fieldset around the appropriate web components when needed. |
Anchor to reverseOrderreverse Order
s-stack doesn't support reverseOrder. Put children in the intended reading and focus order in the DOM. If the old visual order differed from the DOM order, treat that as an accessibility bug and correct it during migration.
When the order changes responsively for a legitimate layout, use a grid or render a structure whose DOM order remains understandable at every size. Don't use CSS order to move focusable controls away from their reading order.
Anchor to New propertiesNew properties
The Polaris stack component also provides properties that don't exist on Polaris React BlockStack:
| Property | Description |
|---|---|
direction | Sets "block" or "inline" and accepts responsive values. It defaults to "block". |
rowGap and columnGap | Override one axis of gap when the direction changes or inline content wraps. |
alignContent | Distributes multiple wrapped lines; it doesn't replace alignItems for a single line. |
| Box-style properties | Add supported padding, background, border, size, overflow, and visibility directly when the stack owns that visual boundary. |
Anchor to Test the migrationTest the migration
- Verify the stack at every responsive width used by the embedded iframe.
- Check the numeric-to-scale
gapreplacement in its actual content hierarchy. - Test start and end alignment in both left-to-right and right-to-left languages.
- Confirm list, choice, menu, and status semantics with a screen reader after replacing
asandrole. - Verify DOM, reading, and focus order after removing
reverseOrder. - Remove responsive object helpers and the Polaris React
BlockStackimport after their final consumers are migrated.