diff --git a/.changeset/wild-lizards-crash.md b/.changeset/wild-lizards-crash.md new file mode 100644 index 00000000000..bf0b5a31a91 --- /dev/null +++ b/.changeset/wild-lizards-crash.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris': patch +--- + +Allow single value for columns. Add oneThird, oneHalf, twoThirds array options diff --git a/polaris-react/src/components/Columns/Columns.scss b/polaris-react/src/components/Columns/Columns.scss index 574457e78e3..0ba17109859 100644 --- a/polaris-react/src/components/Columns/Columns.scss +++ b/polaris-react/src/components/Columns/Columns.scss @@ -6,32 +6,32 @@ --pc-columns-md: var(--pc-columns-sm); --pc-columns-lg: var(--pc-columns-md); --pc-columns-xl: var(--pc-columns-lg); - --pc-columns-space-xs: var(--p-space-4); - --pc-columns-space-sm: var(--pc-columns-space-xs); - --pc-columns-space-md: var(--pc-columns-space-sm); - --pc-columns-space-lg: var(--pc-columns-space-md); - --pc-columns-space-xl: var(--pc-columns-space-lg); + --pc-columns-spacing-xs: var(--p-space-4); + --pc-columns-spacing-sm: var(--pc-columns-spacing-xs); + --pc-columns-spacing-md: var(--pc-columns-spacing-sm); + --pc-columns-spacing-lg: var(--pc-columns-spacing-md); + --pc-columns-spacing-xl: var(--pc-columns-spacing-lg); display: grid; - gap: var(--pc-columns-space-xs); + gap: var(--pc-columns-spacing-xs); grid-template-columns: var(--pc-columns-xs); @media #{$p-breakpoints-sm-up} { - gap: var(--pc-columns-space-sm); + gap: var(--pc-columns-spacing-sm); grid-template-columns: var(--pc-columns-sm); } @media #{$p-breakpoints-md-up} { - gap: var(--pc-columns-space-md); + gap: var(--pc-columns-spacing-md); grid-template-columns: var(--pc-columns-md); } @media #{$p-breakpoints-lg-up} { - gap: var(--pc-columns-space-lg); + gap: var(--pc-columns-spacing-lg); grid-template-columns: var(--pc-columns-lg); } @media #{$p-breakpoints-xl-up} { - gap: var(--pc-columns-space-xl); + gap: var(--pc-columns-spacing-xl); grid-template-columns: var(--pc-columns-xl); } } diff --git a/polaris-react/src/components/Columns/Columns.tsx b/polaris-react/src/components/Columns/Columns.tsx index afe0b18db7c..d8c6a6916e3 100644 --- a/polaris-react/src/components/Columns/Columns.tsx +++ b/polaris-react/src/components/Columns/Columns.tsx @@ -4,13 +4,22 @@ import type { SpacingSpaceScale, } from '@shopify/polaris-tokens'; -import {sanitizeCustomProperties} from '../../utilities/css'; +import { + getResponsiveProps, + sanitizeCustomProperties, +} from '../../utilities/css'; import styles from './Columns.scss'; -type Columns = { - [Breakpoint in BreakpointsAlias]?: number | string; -}; +type ColumnWidths = 'oneThird' | 'oneHalf' | 'twoThirds'; +type ColumnTypes = number | string | ColumnWidths[]; + +type Columns = + | number + | ColumnWidths[] + | { + [Breakpoint in BreakpointsAlias]?: ColumnTypes; + }; type Spacing = { [Breakpoint in BreakpointsAlias]?: SpacingSpaceScale; @@ -31,26 +40,8 @@ export interface ColumnsProps { export function Columns({columns, children, spacing}: ColumnsProps) { const style = { - '--pc-columns-xs': formatColumns(columns?.xs || 6), - '--pc-columns-sm': formatColumns(columns?.sm), - '--pc-columns-md': formatColumns(columns?.md), - '--pc-columns-lg': formatColumns(columns?.lg), - '--pc-columns-xl': formatColumns(columns?.xl), - '--pc-columns-space-xs': spacing?.xs - ? `var(--p-space-${spacing?.xs})` - : undefined, - '--pc-columns-space-sm': spacing?.sm - ? `var(--p-space-${spacing?.sm})` - : undefined, - '--pc-columns-space-md': spacing?.md - ? `var(--p-space-${spacing?.md})` - : undefined, - '--pc-columns-space-lg': spacing?.lg - ? `var(--p-space-${spacing?.lg})` - : undefined, - '--pc-columns-space-xl': spacing?.xl - ? `var(--p-space-${spacing?.xl})` - : undefined, + ...formatColumns(columns), + ...getResponsiveProps('columns', 'spacing', 'space', spacing || '4'), } as React.CSSProperties; return ( @@ -60,10 +51,48 @@ export function Columns({columns, children, spacing}: ColumnsProps) { ); } -function formatColumns(columns?: number | string) { +function formatColumns(columns?: Columns) { + if (typeof columns === 'number') { + return { + '--pc-columns-xs': `repeat(${columns}, minmax(0, 1fr))`, + }; + } + + if (typeof columns === 'string') { + return {'--pc-columns-xs': columns}; + } + + if (typeof columns === 'object' && 'xs' in columns) { + return { + '--pc-columns-xs': formatResponsiveColumns(columns?.xs || 6), + '--pc-columns-sm': formatResponsiveColumns(columns?.sm), + '--pc-columns-md': formatResponsiveColumns(columns?.md), + '--pc-columns-lg': formatResponsiveColumns(columns?.lg), + '--pc-columns-xl': formatResponsiveColumns(columns?.xl), + }; + } + + if (Array.isArray(columns)) { + return { + '--pc-columns-xs': columns.map(getVerboseProperty).join(' '), + }; + } +} + +function formatResponsiveColumns(columns?: ColumnTypes) { if (!columns) return undefined; + if (Array.isArray(columns)) { + return columns.map(getVerboseProperty).join(' '); + } + return typeof columns === 'number' ? `repeat(${columns}, minmax(0, 1fr))` : columns; } + +function getVerboseProperty(column: string) { + return column === 'oneThird' || column === 'oneHalf' + ? 'minmax(0, 1fr)' + : 'minmax(0, 2fr)'; +}