Skip to main content

Stack
component

A container for other components that allows them to be stacked horizontally or vertically. When building complex UIs, this will be your primary building block. Stacks always wrap the content to the next column or row.

'stretch' | |
Default: 'start'

Aligns the Stack along the cross axis.

'stretch' | 'baseline' |
Default: 'stretch'

Aligns the Stack's children along the cross axis.

Default: 'auto'

Adjust the block size.

Auto takes the block size of the box's children.

| ''
Default: '' - meaning no override

Adjust spacing between elements in the inline axis.

This overrides the column value of gap.

'inline' | 'block' |
Default: 'inline'

Sets how the Stack's children are placed within the Stack. 'vertical' and 'horizontal' are deprecated. Using these values will use the Stack implementation from 2024-10.

number

The flex value for the stack. Flex 1 will stretch the stack to fill the parent.

boolean

Whether the children should be stretched to fill the cross axis.

Default: '0'

The size of the gap between each child in the stack.

Default: 'auto'

Adjust the inline size.

Auto takes the inline size of the box's children.

|
Default: 'start'

Aligns the Stack along the main axis.

Default: 'none'

Adjust the maximum block size.

Default: 'none'

Adjust the maximum inline size.

Default: '0'

Adjust the minimum block size.

Default: '0'

Adjust the minimum inline size.

Default: '0'

Adjust the padding of all edges in pixels.

Default: '0'

Adjust the block-padding.

This overrides the block value of padding.

Default: '0'

Adjust the block-end padding.

This overrides the block-end value of paddingBlock.

Default: '0'

Adjust the block-start padding.

This overrides the block-start value of paddingBlock.

Default: '0'

Adjust the inline padding.

This overrides the inline value of padding.

Default: '0'

Adjust the inline-end padding.

This overrides the inline-end value of paddingInline.

Default: '0'

Adjust the inline-start padding.

This overrides the inline-start value of paddingInline.

| ''
Default: '' - meaning no override

Adjust spacing between elements in the block axis.

This overrides the row value of gap.

|
Default: 'flex-start'

The alignment of the children along the main axis.

Deprecated

Use the justifyContent prop instead.

'wrap' | 'nowrap' | 'wrap-reverse'

Wrap behavior for the children of the stack.

Deprecated

Has no effect, content will always wrap.

The horizontal padding around the stack.

Deprecated

Use the paddingInline prop instead.

The vertical padding around the stack.

Deprecated

Use the paddingBlock prop instead.

Default: 1

The spacing between each child in the stack.

Deprecated

Use the gap prop instead.

Was this section helpful?

Stack

import {
reactExtension,
Button,
Stack,
Screen,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<Stack direction="inline" gap="200">
<Button title="Hello" />
<Button title="Hello" />
</Stack>
</Screen>
));

Preview

The following examples will demonstrate some, but not all of the abilities of the Stack component. For simplicity, these examples use the React version of the Stack component, but the same results will be achieved by using the same properties with the regular JS library.

Was this section helpful?

Anchor to inline-defaultInline Stack with default values

In this example, we specify inline for the direction. As you can see, we have two small buttons occupying just the amount of space that they need, at the left side of the Stack. This is because justifyContent is set to start by default. We also include a gap of "200".

Was this section helpful?

Inline Stack with default values

import {
reactExtension,
Button,
Stack,
Screen,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<Stack direction="inline" gap="200">
<Button title="Hello" />
<Button title="Hello" />
</Stack>
</Screen>
));

Anchor to inline-flex-childrenInline Stack with flexChildren

Similar to the example above, but this time we are specifying flexChildren to be true. This means that the two buttons will take up the max amount of space that they can within the inline stack.

Was this section helpful?

Inline Stack with flexChildren

import {
reactExtension,
Button,
Stack,
Screen,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<Stack direction="inline" gap="200" flexChildren>
<Button title="Hello" />
<Button title="Hello" />
</Stack>
</Screen>
));

Anchor to inline-center-childrenInline Stack with centered children

You can also center elements in your inline stack. For this, you can specify the justifyContent to be center. However, in this case you also want flexChildren to be false (which is the default), so that the children can take up the minimal amount of space that they need, and be centered.

Was this section helpful?

Inline Stack with centered children

import {
reactExtension,
Button,
Stack,
Screen,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<Stack direction="inline" gap="200" justifyContent="center">
<Button title="Hello" />
<Button title="Hello" />
</Stack>
</Screen>
));

Anchor to inline-align-items-centerInline Stack with vertical axis centering

Here we have an inline stack with two children. The first is a block stack with two buttons, and the second is a single button. Since the first element has a greater intrinsic height, our main inline stack's intrinsic height is also increased. We can center both children component along the main axis (x-axis) by setting the alignItems property to center.

Was this section helpful?

Inline Stack with vertical axis centering

import {
reactExtension,
Button,
Stack,
Screen,
ScrollView,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<ScrollView>
<Stack
direction="inline"
gap="200"
alignItems="center"
alignContent="center"
>
<Stack direction="block" gap="200">
<Button title="Hello" />
<Button title="Hello" />
</Stack>
<Button title="Hello" />
</Stack>
</ScrollView>
</Screen>
));

Anchor to blockBlock Stack

You can specify your Stack to layout its children vertically by setting the direction property to block.

Was this section helpful?

Block Stack

import {
reactExtension,
Button,
Stack,
Screen,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<Stack direction="block" gap="200" paddingInline="450">
<Button title="Hello" />
<Button title="Hello" />
<Button title="Hello" />
</Stack>
</Screen>
));

Anchor to extension-stack-block-space-betweenBlock Stack with space between children

Here we are spacing out the children of our block stack by setting justifyContent to space-between in order to space the children out as much as possible along the vertical axis. Note that in this example, we removed the wrapping ScrollView in order to introduce a custom height by setting the blockSize to 50%. We are also adding inlinePadding of 450 in order to mimic the padding applied to the UI Extension screen header.

Was this section helpful?

Block Stack with space between children

import {
reactExtension,
Button,
Stack,
Screen,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<Stack
direction="block"
gap="200"
justifyContent="space-between"
blockSize="50%"
paddingInline="450"
>
<Button title="Hello" />
<Button title="Hello" />
<Button title="Hello" />
</Stack>
</Screen>
));

Anchor to block-center-allBlock Stack centered on both axes

You can center your block stack on the vertical axis by setting justifyContent to center. Next, you can set a custom size on your block stack by setting the blockSize and inlineSize. In this example we set them to 50% and 100% respectively. We can then center our elements along both axis of the stack by setting justifyContent to center to center the children vertically, and setting both alignContent and alignItems to center.

Was this section helpful?

Block Stack centered on both axes

import {
reactExtension,
Button,
Stack,
Screen,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<Stack
direction="block"
gap="200"
justifyContent="center"
alignContent="center"
alignItems="center"
inlineSize="100%"
paddingInline="450"
blockSize="50%"
>
<Button title="Hello" />
<Button title="Hello" />
</Stack>
</Screen>
));

Anchor to block-align-content-stretchBlock Stack with horizontal stretching

This example demonstrates a block stack with elements stretched to fill the width of the container. By setting alignContent to 'stretch', the children will expand to fill the available horizontal space. This is useful when you want all elements to have consistent width, regardless of their content.

Was this section helpful?

Block Stack with horizontally stretched contents

import {
reactExtension,
SegmentedControl,
Stack,
Screen,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<Stack direction="block" gap="400" alignContent="stretch" padding="400">
<SegmentedControl
selected="1"
segments={[
{id: '1', label: 'Segment 1', disabled: false},
{id: '2', label: 'Segment 2', disabled: false},
{id: '3', label: 'Segment 3', disabled: false},
{id: '4', label: 'Segment 4', disabled: false},
{id: '5', label: 'Segment 5', disabled: false},
{id: '6', label: 'Segment 6', disabled: false},
{id: '7', label: 'Segment 7', disabled: false},
]}
onSelect={(id) => console.log(`Selected segment with id: ${id}`)}
/>
</Stack>
</Screen>
));

Anchor to nestedNested Stack

Now that we've run through a few examples of what a stack can do, let's move on to something more complex. You can nest multiple stacks of different configurations to achieve a more complex UI. In this example, we will create a row that displays several labels and an icon. This will mimic some of the basic rows that you can find across different POS screens.

Let's put the Selectable aside for now; we'll get to that later. The first stack is which we can refer to as the parent stack, is set to inline. It has two main children, a block stack on the left, and an inline stack on the right. To space them out completely along the horizontal axis, we set our parent inline stack's justifyContent to space-between. We also specify the inlineSize to be 100% to take up the full width of the screen.

The first child stack (the block stack) simply has a gap of 100 to space out the two Text components.

The second child stack (the inline stack) has a gap of 600 to space out the Text and the Icon. We also set the alignItems and alignContent properties to center to center the Text and Icon within their stack.

However, we also need to the alignItems and alignContent properties to center on the parent inline stack to center the two children stacks along the vertical axis.

Finally, we can return to the Selectable. You'll notice that we've wrapped the entire stack in a Selectable. This makes the entire stack within the Selectable become a tappable surface, with an onPress handler, which is part of the Selectable component. It also gives a nice highlight effect when you tap, as you can see in the screenshot.

Was this section helpful?

Nested Stack

import {
reactExtension,
Text,
Icon,
Stack,
Screen,
Selectable,
} from '@shopify/ui-extensions-react/point-of-sale';
import React from 'react';

export default reactExtension('pos.home.modal.render', () => (
<Screen name="Stack" title="Stack">
<Selectable onPress={() => console.log('Pressed')}>
<Stack
direction="inline"
gap="400"
justifyContent="space-between"
alignItems="center"
alignContent="center"
paddingInline="450"
paddingBlock="600"
inlineSize="100%"
>
<Stack direction="block" gap="100">
<Text>Hello world!</Text>
<Text variant="captionRegular">
This is an example of a nested stack!
</Text>
</Stack>
<Stack
direction="inline"
gap="600"
alignItems="center"
alignContent="center"
>
<Text>Let's go!</Text>
<Icon name="chevron-right" />
</Stack>
</Stack>
</Selectable>
</Screen>
));