0
# Layout & Structure Utilities
1
2
Flexible layout components and utilities for organizing content with consistent spacing, responsive behavior, and structured presentation. These components provide the foundational building blocks for creating well-organized user interfaces.
3
4
## Capabilities
5
6
### Box
7
8
Flexible container component providing padding, margin, background, and border control with design token integration.
9
10
```typescript { .api }
11
/**
12
* Flexible container with spacing and styling controls
13
* @param children - Box content
14
* @param padding - Padding on all sides
15
* @param background - Background color token
16
* @returns JSX element with box container
17
*/
18
function Box(props: BoxProps): JSX.Element;
19
20
interface BoxProps {
21
/** Box content */
22
children?: React.ReactNode;
23
/** Padding on all sides */
24
padding?: SpaceScale;
25
/** Padding inline start (left in LTR) */
26
paddingInlineStart?: SpaceScale;
27
/** Padding inline end (right in LTR) */
28
paddingInlineEnd?: SpaceScale;
29
/** Padding block start (top) */
30
paddingBlockStart?: SpaceScale;
31
/** Padding block end (bottom) */
32
paddingBlockEnd?: SpaceScale;
33
/** Background color */
34
background?: ColorBackgroundAlias;
35
/** Color styling */
36
color?: ColorTextAlias;
37
/** Border radius */
38
borderRadius?: BorderRadiusScale;
39
/** Border width */
40
borderWidth?: BorderWidthScale;
41
/** Border color */
42
borderColor?: ColorBorderAlias;
43
/** Box shadow */
44
shadow?: ShadowAlias;
45
/** Overflow behavior */
46
overflow?: 'hidden' | 'visible';
47
/** Minimum height */
48
minHeight?: string;
49
/** Minimum width */
50
minWidth?: string;
51
/** Maximum width */
52
maxWidth?: string;
53
/** Width */
54
width?: string;
55
/** Height */
56
height?: string;
57
/** Position */
58
position?: 'static' | 'relative' | 'absolute' | 'fixed' | 'sticky';
59
/** Inset positioning */
60
insetBlockStart?: string;
61
/** Inset positioning */
62
insetBlockEnd?: string;
63
/** Inset positioning */
64
insetInlineStart?: string;
65
/** Inset positioning */
66
insetInlineEnd?: string;
67
/** Opacity */
68
opacity?: string;
69
/** Z-index */
70
zIndex?: string;
71
/** Role for accessibility */
72
role?: string;
73
/** Tab index */
74
tabIndex?: number;
75
/** ID attribute */
76
id?: string;
77
}
78
79
/** Spacing scale values from design tokens */
80
type SpaceScale =
81
| '025' | '050' | '100' | '150' | '200' | '300' | '400' | '500' | '600'
82
| '800' | '1000' | '1200' | '1600' | '2000' | '2400' | '2800' | '3200';
83
84
/** Background color aliases from design tokens */
85
type ColorBackgroundAlias =
86
| 'bg' | 'bg-inverse' | 'bg-subdued' | 'bg-surface' | 'bg-surface-neutral'
87
| 'bg-surface-neutral-subdued' | 'bg-surface-success' | 'bg-surface-success-subdued'
88
| 'bg-surface-warning' | 'bg-surface-warning-subdued' | 'bg-surface-critical'
89
| 'bg-surface-critical-subdued' | 'bg-fill' | 'bg-fill-active' | 'bg-fill-selected'
90
| 'bg-fill-disabled' | 'bg-fill-success' | 'bg-fill-warning' | 'bg-fill-critical';
91
```
92
93
**Usage Example:**
94
95
```typescript
96
import React from 'react';
97
import { Box, Text, BlockStack } from '@shopify/polaris';
98
99
function ProductCard() {
100
return (
101
<Box
102
background="bg-surface"
103
padding="400"
104
borderRadius="200"
105
shadow="card"
106
>
107
<BlockStack gap="300">
108
<Text variant="headingMd" as="h3">
109
Product Title
110
</Text>
111
<Text variant="bodyMd" color="subdued">
112
Product description with details about features and benefits.
113
</Text>
114
<Box
115
background="bg-surface-success"
116
padding="200"
117
borderRadius="100"
118
>
119
<Text variant="bodySm" color="success">
120
In Stock
121
</Text>
122
</Box>
123
</BlockStack>
124
</Box>
125
);
126
}
127
```
128
129
### BlockStack
130
131
Vertical stacking layout component for organizing content in a column with consistent spacing and alignment.
132
133
```typescript { .api }
134
/**
135
* Vertical stacking layout component
136
* @param children - Content to stack vertically
137
* @param gap - Space between items
138
* @param align - Horizontal alignment of items
139
* @returns JSX element with vertical stack
140
*/
141
function BlockStack(props: BlockStackProps): JSX.Element;
142
143
interface BlockStackProps {
144
/** Content to stack */
145
children?: React.ReactNode;
146
/** Space between stack items */
147
gap?: SpaceScale;
148
/** Horizontal alignment */
149
align?: 'start' | 'center' | 'end' | 'stretch';
150
/** Inline size behavior */
151
inlineAlign?: 'start' | 'center' | 'end' | 'baseline' | 'stretch';
152
/** HTML element type */
153
as?: 'div' | 'section' | 'span' | 'fieldset' | 'ul' | 'ol' | 'li';
154
/** Reverse stack order */
155
reverseOrder?: boolean;
156
}
157
```
158
159
### InlineStack
160
161
Horizontal stacking layout component for organizing content in a row with wrapping and alignment options.
162
163
```typescript { .api }
164
/**
165
* Horizontal stacking layout component
166
* @param children - Content to stack horizontally
167
* @param gap - Space between items
168
* @param align - Vertical alignment of items
169
* @returns JSX element with horizontal stack
170
*/
171
function InlineStack(props: InlineStackProps): JSX.Element;
172
173
interface InlineStackProps {
174
/** Content to stack */
175
children?: React.ReactNode;
176
/** Space between stack items */
177
gap?: SpaceScale;
178
/** Vertical alignment */
179
align?: 'start' | 'center' | 'end' | 'baseline' | 'stretch';
180
/** Horizontal alignment */
181
blockAlign?: 'start' | 'center' | 'end' | 'baseline' | 'stretch';
182
/** Allow items to wrap */
183
wrap?: boolean;
184
/** HTML element type */
185
as?: 'div' | 'section' | 'span' | 'ul' | 'ol' | 'li';
186
}
187
```
188
189
### InlineGrid
190
191
Responsive grid layout component with automatic column sizing and gap control.
192
193
```typescript { .api }
194
/**
195
* Responsive grid layout component
196
* @param children - Grid items
197
* @param columns - Column configuration
198
* @param gap - Space between grid items
199
* @returns JSX element with grid layout
200
*/
201
function InlineGrid(props: InlineGridProps): JSX.Element;
202
203
interface InlineGridProps {
204
/** Grid content */
205
children?: React.ReactNode;
206
/** Number of columns or responsive configuration */
207
columns?: number | string[] | ResponsiveValue<number | string>;
208
/** Gap between grid items */
209
gap?: SpaceScale | ResponsiveValue<SpaceScale>;
210
/** Vertical alignment of grid items */
211
alignItems?: 'start' | 'center' | 'end' | 'baseline' | 'stretch';
212
/** HTML element type */
213
as?: 'div' | 'section' | 'ul' | 'ol' | 'li';
214
}
215
216
/** Responsive value configuration */
217
type ResponsiveValue<T> = {
218
xs?: T;
219
sm?: T;
220
md?: T;
221
lg?: T;
222
xl?: T;
223
};
224
```
225
226
### Grid
227
228
CSS Grid layout component with named areas and responsive configuration for complex layouts.
229
230
```typescript { .api }
231
/**
232
* CSS Grid layout with named areas
233
* @param children - Grid content
234
* @param areas - Named grid areas configuration
235
* @param columns - Column track sizing
236
* @returns JSX element with CSS grid
237
*/
238
function Grid(props: GridProps): JSX.Element;
239
240
interface GridProps {
241
/** Grid content */
242
children?: React.ReactNode;
243
/** Named grid areas */
244
areas?: string[] | ResponsiveValue<string[]>;
245
/** Grid template columns */
246
columns?: string[] | ResponsiveValue<string[]>;
247
/** Grid template rows */
248
rows?: string[] | ResponsiveValue<string[]>;
249
/** Gap between grid items */
250
gap?: SpaceScale | ResponsiveValue<SpaceScale>;
251
/** HTML element type */
252
as?: 'div' | 'section';
253
}
254
255
/**
256
* Individual grid cell component
257
* @param children - Cell content
258
* @param area - Named grid area
259
* @param columnStart - Column start position
260
* @param columnEnd - Column end position
261
* @returns JSX element with grid cell
262
*/
263
function GridCell(props: GridCellProps): JSX.Element;
264
265
interface GridCellProps {
266
/** Cell content */
267
children?: React.ReactNode;
268
/** Named grid area */
269
area?: string | ResponsiveValue<string>;
270
/** Column start position */
271
columnStart?: number | ResponsiveValue<number>;
272
/** Column end position */
273
columnEnd?: number | ResponsiveValue<number>;
274
/** Row start position */
275
rowStart?: number | ResponsiveValue<number>;
276
/** Row end position */
277
rowEnd?: number | ResponsiveValue<number>;
278
}
279
```
280
281
### LegacyStack
282
283
Legacy stack component (deprecated in favor of BlockStack/InlineStack) maintained for backward compatibility.
284
285
```typescript { .api }
286
/**
287
* Legacy stack component (use BlockStack/InlineStack instead)
288
* @param children - Stack content
289
* @param vertical - Vertical stack direction
290
* @param spacing - Space between items
291
* @returns JSX element with legacy stack
292
* @deprecated Use BlockStack or InlineStack instead
293
*/
294
function LegacyStack(props: LegacyStackProps): JSX.Element;
295
296
interface LegacyStackProps {
297
/** Stack content */
298
children?: React.ReactNode;
299
/** Vertical stacking */
300
vertical?: boolean;
301
/** Spacing between items */
302
spacing?: 'extraTight' | 'tight' | 'loose' | 'extraLoose';
303
/** Item distribution */
304
distribution?: 'equalSpacing' | 'leading' | 'trailing' | 'center' | 'fill' | 'fillEvenly';
305
/** Item alignment */
306
alignment?: 'leading' | 'trailing' | 'center' | 'fill' | 'baseline';
307
/** Wrap items */
308
wrap?: boolean;
309
}
310
311
/**
312
* Legacy stack item component
313
* @param children - Item content
314
* @param fill - Fill available space
315
* @returns JSX element with stack item
316
*/
317
function LegacyStackItem(props: LegacyStackItemProps): JSX.Element;
318
319
interface LegacyStackItemProps {
320
/** Item content */
321
children?: React.ReactNode;
322
/** Fill available space */
323
fill?: boolean;
324
}
325
```
326
327
### Bleed
328
329
Negative margin utility component for extending content beyond its container boundaries.
330
331
```typescript { .api }
332
/**
333
* Negative margin utility for extending content
334
* @param children - Content to bleed
335
* @param marginInline - Horizontal negative margin
336
* @param marginBlock - Vertical negative margin
337
* @returns JSX element with negative margins
338
*/
339
function Bleed(props: BleedProps): JSX.Element;
340
341
interface BleedProps {
342
/** Content to apply bleed margins */
343
children: React.ReactNode;
344
/** Horizontal negative margin */
345
marginInline?: SpaceScale;
346
/** Vertical negative margin */
347
marginBlock?: SpaceScale;
348
/** Negative margin on inline start */
349
marginInlineStart?: SpaceScale;
350
/** Negative margin on inline end */
351
marginInlineEnd?: SpaceScale;
352
/** Negative margin on block start */
353
marginBlockStart?: SpaceScale;
354
/** Negative margin on block end */
355
marginBlockEnd?: SpaceScale;
356
}
357
```
358
359
### Divider
360
361
Visual separator component for creating clear content boundaries with customizable styling.
362
363
```typescript { .api }
364
/**
365
* Visual separator for content boundaries
366
* @param borderColor - Divider border color
367
* @param borderWidth - Divider border width
368
* @returns JSX element with divider line
369
*/
370
function Divider(props: DividerProps): JSX.Element;
371
372
interface DividerProps {
373
/** Border color */
374
borderColor?: ColorBorderAlias;
375
/** Border width */
376
borderWidth?: BorderWidthScale;
377
}
378
379
/** Border width scale values */
380
type BorderWidthScale = '025' | '050' | '100';
381
382
/** Border color aliases from design tokens */
383
type ColorBorderAlias =
384
| 'border' | 'border-inverse' | 'border-subdued' | 'border-success'
385
| 'border-success-subdued' | 'border-warning' | 'border-warning-subdued'
386
| 'border-critical' | 'border-critical-subdued' | 'border-focus'
387
| 'border-disabled';
388
```
389
390
**Usage Example:**
391
392
```typescript
393
import React from 'react';
394
import { BlockStack, InlineStack, Box, Text, Divider, Button } from '@shopify/polaris';
395
396
function OrderSummary() {
397
return (
398
<Box padding="400" background="bg-surface" borderRadius="200">
399
<BlockStack gap="400">
400
<Text variant="headingMd" as="h2">
401
Order Summary
402
</Text>
403
404
<Divider />
405
406
<BlockStack gap="200">
407
<InlineStack align="space-between">
408
<Text variant="bodyMd">Subtotal</Text>
409
<Text variant="bodyMd">$99.00</Text>
410
</InlineStack>
411
412
<InlineStack align="space-between">
413
<Text variant="bodyMd">Shipping</Text>
414
<Text variant="bodyMd">$5.99</Text>
415
</InlineStack>
416
417
<InlineStack align="space-between">
418
<Text variant="bodyMd">Tax</Text>
419
<Text variant="bodyMd">$8.40</Text>
420
</InlineStack>
421
</BlockStack>
422
423
<Divider />
424
425
<InlineStack align="space-between">
426
<Text variant="headingSm" as="h3">Total</Text>
427
<Text variant="headingSm" as="h3">$113.39</Text>
428
</InlineStack>
429
430
<Button primary fullWidth>
431
Complete Order
432
</Button>
433
</BlockStack>
434
</Box>
435
);
436
}
437
```
438
439
## Layout Design Tokens
440
441
```typescript { .api }
442
/** Border radius scale values */
443
type BorderRadiusScale =
444
| '050' | '100' | '150' | '200' | '300' | '400' | '500' | '750';
445
446
/** Text color aliases from design tokens */
447
type ColorTextAlias =
448
| 'text' | 'text-inverse' | 'text-subdued' | 'text-disabled'
449
| 'text-success' | 'text-warning' | 'text-critical' | 'text-interactive'
450
| 'text-on-color';
451
452
/** Shadow aliases from design tokens */
453
type ShadowAlias =
454
| 'card' | 'popover' | 'modal' | 'button' | 'button-hover'
455
| 'button-inset' | 'button-primary' | 'button-primary-hover'
456
| 'button-primary-inset';
457
458
/** Responsive breakpoints configuration */
459
interface BreakpointsConfig {
460
xs: string;
461
sm: string;
462
md: string;
463
lg: string;
464
xl: string;
465
}
466
```
467
468
### Scrollable
469
470
Scrollable container component with customizable scrollbars and scroll event handling for content overflow management.
471
472
```typescript { .api }
473
/**
474
* Scrollable container with custom scrollbars
475
* @param children - Content to make scrollable
476
* @param vertical - Allow vertical scrolling
477
* @param horizontal - Allow horizontal scrolling
478
* @returns JSX element with scrollable container
479
*/
480
function Scrollable(props: ScrollableProps): JSX.Element;
481
482
interface ScrollableProps {
483
/** Content to display in scrollable area */
484
children?: React.ReactNode;
485
/** Adds a shadow when content is scrollable */
486
shadow?: boolean;
487
/** Adds a hint for touch devices */
488
hint?: boolean;
489
/** Allow horizontal scrolling */
490
horizontal?: boolean;
491
/** Allow vertical scrolling */
492
vertical?: boolean;
493
/** Callback when the scrollable is scrolled */
494
onScrolledToBottom?(): void;
495
/** The scrollable element to observe */
496
scrollbarWidth?: 'thin' | 'none';
497
/** Focus ring when scrollable is focused */
498
focusable?: boolean;
499
}
500
501
interface ScrollableRef {
502
/** Scroll to a specific position */
503
scrollTo(scrollTop: number, scrollLeft?: number): void;
504
}
505
```
506
507
### Sticky
508
509
Sticky positioning component that keeps content visible during scroll, with customizable offset and boundary detection.
510
511
```typescript { .api }
512
/**
513
* Sticky positioning component for persistent content
514
* @param children - Content to make sticky
515
* @param top - Top offset for sticky positioning
516
* @param boundaryElement - Element that defines sticky boundary
517
* @returns JSX element with sticky positioning
518
*/
519
function Sticky(props: StickyProps): JSX.Element;
520
521
interface StickyProps {
522
/** Element outlining the fixed position boundaries */
523
boundaryElement?: HTMLElement | null;
524
/** Offset from the top of the viewport */
525
offset?: boolean;
526
/** Should the element remain in a fixed position when the layout is stacked (smaller screens) */
527
disableWhenStacked?: boolean;
528
/** Content to display in sticky container */
529
children?: React.ReactNode;
530
}
531
```