diff --git a/.changeset/small-gifts-hope.md b/.changeset/small-gifts-hope.md
new file mode 100644
index 00000000000..a4c621de259
--- /dev/null
+++ b/.changeset/small-gifts-hope.md
@@ -0,0 +1,5 @@
+---
+'@shopify/polaris': minor
+---
+
+Added support for responsive padding to `Box`
diff --git a/polaris-react/src/components/Box/Box.scss b/polaris-react/src/components/Box/Box.scss
index 7e839dcd6fe..49f5d6fbb66 100644
--- a/polaris-react/src/components/Box/Box.scss
+++ b/polaris-react/src/components/Box/Box.scss
@@ -1,4 +1,32 @@
+@import '../../styles/common';
+
.Box {
+ @include responsive-props('box', 'padding', 'padding');
+ @include responsive-props(
+ 'box',
+ 'padding-block-end',
+ 'padding-block-end',
+ 'padding'
+ );
+ @include responsive-props(
+ 'box',
+ 'padding-block-start',
+ 'padding-block-start',
+ 'padding'
+ );
+ @include responsive-props(
+ 'box',
+ 'padding-inline-start',
+ 'padding-inline-start',
+ 'padding'
+ );
+ @include responsive-props(
+ 'box',
+ 'padding-inline-end',
+ 'padding-inline-end',
+ 'padding'
+ );
+
--pc-box-shadow: initial;
--pc-box-background: initial;
--pc-box-border-radius: initial;
@@ -69,13 +97,6 @@
max-width: var(--pc-box-max-width);
overflow-x: var(--pc-box-overflow-x);
overflow-y: var(--pc-box-overflow-y);
- padding-block-end: var(--pc-box-padding-block-end, var(--pc-box-padding));
- padding-inline-start: var(
- --pc-box-padding-inline-start,
- var(--pc-box-padding)
- );
- padding-inline-end: var(--pc-box-padding-inline-end, var(--pc-box-padding));
- padding-block-start: var(--pc-box-padding-block-start, var(--pc-box-padding));
width: var(--pc-box-width);
-webkit-overflow-scrolling: touch;
}
diff --git a/polaris-react/src/components/Box/Box.stories.tsx b/polaris-react/src/components/Box/Box.stories.tsx
index d35c249f85a..bad0fccc80a 100644
--- a/polaris-react/src/components/Box/Box.stories.tsx
+++ b/polaris-react/src/components/Box/Box.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import type {ComponentMeta} from '@storybook/react';
-import {Box, Icon} from '@shopify/polaris';
+import {AlphaStack, Box, Icon} from '@shopify/polaris';
import {PaintBrushMajor} from '@shopify/polaris-icons';
export default {
@@ -30,3 +30,44 @@ export function BoxWithBorderRadius() {
);
}
+
+export function BoxWithResponsivePadding() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/polaris-react/src/components/Box/Box.tsx b/polaris-react/src/components/Box/Box.tsx
index 09ffbc4feab..d4340faadad 100644
--- a/polaris-react/src/components/Box/Box.tsx
+++ b/polaris-react/src/components/Box/Box.tsx
@@ -10,7 +10,12 @@ import type {
SpacingSpaceScale,
} from '@shopify/polaris-tokens';
-import {classNames, sanitizeCustomProperties} from '../../utilities/css';
+import {
+ getResponsiveProps,
+ ResponsiveProp,
+ classNames,
+ sanitizeCustomProperties,
+} from '../../utilities/css';
import styles from './Box.scss';
@@ -42,6 +47,8 @@ export type BorderTokenAlias =
| 'divider-on-dark'
| 'transparent';
+type Spacing = ResponsiveProp;
+
interface Border {
blockStart: BorderTokenAlias;
blockEnd: BorderTokenAlias;
@@ -75,13 +82,6 @@ interface BorderRadius {
endEnd: BorderRadiusTokenScale;
}
-interface Spacing {
- blockStart: SpacingSpaceScale;
- blockEnd: SpacingSpaceScale;
- inlineStart: SpacingSpaceScale;
- inlineEnd: SpacingSpaceScale;
-}
-
interface BorderWidth {
blockStart: ShapeBorderWidthScale;
blockEnd: ShapeBorderWidthScale;
@@ -139,15 +139,15 @@ export interface BoxProps {
/** Clip vertical content of children */
overflowY?: Overflow;
/** Spacing around children */
- padding?: SpacingSpaceScale;
+ padding?: Spacing;
/** Vertical start spacing around children */
- paddingBlockStart?: SpacingSpaceScale;
+ paddingBlockStart?: Spacing;
/** Vertical end spacing around children */
- paddingBlockEnd?: SpacingSpaceScale;
+ paddingBlockEnd?: Spacing;
/** Horizontal start spacing around children */
- paddingInlineStart?: SpacingSpaceScale;
+ paddingInlineStart?: Spacing;
/** Horizontal end spacing around children */
- paddingInlineEnd?: SpacingSpaceScale;
+ paddingInlineEnd?: Spacing;
/** Shadow */
shadow?: DepthShadowAlias;
/** Set width of container */
@@ -215,13 +215,6 @@ export const Box = forwardRef(
inlineEnd: borderInlineEndWidth,
} as BorderWidth;
- const paddings = {
- blockEnd: paddingBlockEnd,
- inlineStart: paddingInlineStart,
- inlineEnd: paddingInlineEnd,
- blockStart: paddingBlockStart,
- } as Spacing;
-
const style = {
'--pc-box-color': color ? `var(--p-${color})` : undefined,
'--pc-box-background': background ? `var(--p-${background})` : undefined,
@@ -273,19 +266,31 @@ export const Box = forwardRef(
'--pc-box-max-width': maxWidth,
'--pc-box-overflow-x': overflowX,
'--pc-box-overflow-y': overflowY,
- '--pc-box-padding': padding ? `var(--p-space-${padding})` : undefined,
- '--pc-box-padding-block-end': paddings.blockEnd
- ? `var(--p-space-${paddings.blockEnd})`
- : undefined,
- '--pc-box-padding-inline-start': paddings.inlineStart
- ? `var(--p-space-${paddings.inlineStart})`
- : undefined,
- '--pc-box-padding-inline-end': paddings.inlineEnd
- ? `var(--p-space-${paddings.inlineEnd})`
- : undefined,
- '--pc-box-padding-block-start': paddings.blockStart
- ? `var(--p-space-${paddings.blockStart})`
- : undefined,
+ ...getResponsiveProps('box', 'padding', 'space', padding),
+ ...getResponsiveProps(
+ 'box',
+ 'padding-block-end',
+ 'space',
+ paddingBlockEnd,
+ ),
+ ...getResponsiveProps(
+ 'box',
+ 'padding-block-start',
+ 'space',
+ paddingBlockStart,
+ ),
+ ...getResponsiveProps(
+ 'box',
+ 'padding-inline-start',
+ 'space',
+ paddingInlineStart,
+ ),
+ ...getResponsiveProps(
+ 'box',
+ 'padding-inline-end',
+ 'space',
+ paddingInlineEnd,
+ ),
'--pc-box-shadow': shadow ? `var(--p-shadow-${shadow})` : undefined,
'--pc-box-width': width,
} as React.CSSProperties;
diff --git a/polaris-react/src/components/Box/tests/Box.test.tsx b/polaris-react/src/components/Box/tests/Box.test.tsx
index 1c788fe259c..a13be52bcae 100644
--- a/polaris-react/src/components/Box/tests/Box.test.tsx
+++ b/polaris-react/src/components/Box/tests/Box.test.tsx
@@ -79,7 +79,7 @@ describe('Box', () => {
expect(box).toContainReactComponent('div', {
style: {
- '--pc-box-padding-inline-start': 'var(--p-space-2)',
+ '--pc-box-padding-inline-start-xs': 'var(--p-space-2)',
} as React.CSSProperties,
});
});
@@ -93,9 +93,22 @@ describe('Box', () => {
expect(box).toContainReactComponent('div', {
style: {
- '--pc-box-padding': 'var(--p-space-1)',
- '--pc-box-padding-inline-start': 'var(--p-space-2)',
+ '--pc-box-padding-xs': 'var(--p-space-1)',
+ '--pc-box-padding-inline-start-xs': 'var(--p-space-2)',
} as React.CSSProperties,
});
});
+
+ it('accepts padding based on breakpoints', () => {
+ const box = mountWithApp(
+ {children},
+ );
+
+ expect(box).toContainReactComponent('div', {
+ style: expect.objectContaining({
+ '--pc-box-padding-md': 'var(--p-space-8)',
+ '--pc-box-padding-xs': 'var(--p-space-2)',
+ }) as React.CSSProperties,
+ });
+ });
});
diff --git a/polaris-react/src/styles/_common.scss b/polaris-react/src/styles/_common.scss
index 35afcd48810..c1e6f1b2d5d 100644
--- a/polaris-react/src/styles/_common.scss
+++ b/polaris-react/src/styles/_common.scss
@@ -15,6 +15,7 @@
@import './shared/icons';
@import './shared/layout';
@import './shared/page';
+@import './shared/responsive-props';
@import './shared/typography';
@import './shared/interaction-state';
diff --git a/polaris-react/src/styles/shared/_responsive-props.scss b/polaris-react/src/styles/shared/_responsive-props.scss
new file mode 100644
index 00000000000..c2534b1052f
--- /dev/null
+++ b/polaris-react/src/styles/shared/_responsive-props.scss
@@ -0,0 +1,72 @@
+@mixin responsive-props(
+ $componentName,
+ $componentProp,
+ $declartionProp,
+ $shorthandFallback: null
+) {
+ --pc-#{$componentName}-#{$componentProp}-xs: initial;
+ --pc-#{$componentName}-#{$componentProp}-sm: var(
+ --pc-#{$componentName}-#{$componentProp}-xs
+ );
+ --pc-#{$componentName}-#{$componentProp}-md: var(
+ --pc-#{$componentName}-#{$componentProp}-sm
+ );
+ --pc-#{$componentName}-#{$componentProp}-lg: var(
+ --pc-#{$componentName}-#{$componentProp}-md
+ );
+ --pc-#{$componentName}-#{$componentProp}-xl: var(
+ --pc-#{$componentName}-#{$componentProp}-lg
+ );
+ @if $shorthandFallback {
+ #{$declartionProp}: var(
+ --pc-#{$componentName}-#{$componentProp}-xs,
+ var(--pc-#{$componentName}-#{$shorthandFallback}-xs)
+ );
+
+ @media #{$p-breakpoints-sm-up} {
+ #{$declartionProp}: var(
+ --pc-#{$componentName}-#{$componentProp}-sm,
+ var(--pc-#{$componentName}-#{$shorthandFallback}-sm)
+ );
+ }
+
+ @media #{$p-breakpoints-md-up} {
+ #{$declartionProp}: var(
+ --pc-#{$componentName}-#{$componentProp}-md,
+ var(--pc-#{$componentName}-#{$shorthandFallback}-md)
+ );
+ }
+
+ @media #{$p-breakpoints-lg-up} {
+ #{$declartionProp}: var(
+ --pc-#{$componentName}-#{$componentProp}-lg,
+ var(--pc-#{$componentName}-#{$shorthandFallback}-lg)
+ );
+ }
+
+ @media #{$p-breakpoints-xl-up} {
+ #{$declartionProp}: var(
+ --pc-#{$componentName}-#{$componentProp}-xl,
+ var(--pc-#{$componentName}-#{$shorthandFallback}-xl)
+ );
+ }
+ } @else {
+ #{$declartionProp}: var(--pc-#{$componentName}-#{$componentProp}-xs);
+
+ @media #{$p-breakpoints-sm-up} {
+ #{$declartionProp}: var(--pc-#{$componentName}-#{$componentProp}-sm);
+ }
+
+ @media #{$p-breakpoints-md-up} {
+ #{$declartionProp}: var(--pc-#{$componentName}-#{$componentProp}-md);
+ }
+
+ @media #{$p-breakpoints-lg-up} {
+ #{$declartionProp}: var(--pc-#{$componentName}-#{$componentProp}-lg);
+ }
+
+ @media #{$p-breakpoints-xl-up} {
+ #{$declartionProp}: var(--pc-#{$componentName}-#{$componentProp}-xl);
+ }
+ }
+}
diff --git a/polaris-react/src/utilities/css.ts b/polaris-react/src/utilities/css.ts
index fc1f112923b..74c8e02b9f5 100644
--- a/polaris-react/src/utilities/css.ts
+++ b/polaris-react/src/utilities/css.ts
@@ -30,12 +30,14 @@ export function getResponsiveProps(
componentName: string,
componentProp: string,
tokenSubgroup: string,
- responsiveProp:
+ responsiveProp?:
| string
| {
[Breakpoint in BreakpointsAlias]?: string;
},
) {
+ if (!responsiveProp) return {};
+
if (typeof responsiveProp === 'string') {
return {
[`--pc-${componentName}-${componentProp}-xs`]: `var(--p-${tokenSubgroup}-${responsiveProp})`,