diff --git a/.changeset/soft-seahorses-relate.md b/.changeset/soft-seahorses-relate.md new file mode 100644 index 0000000000..a17ff1aea4 --- /dev/null +++ b/.changeset/soft-seahorses-relate.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +Fix spacing props not being applied for custom values. diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index ef59d46f68..7fe92e4abb 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -670,14 +670,14 @@ export const marginPropDefs: (spacingValues: string[]) => { type: 'enum | string'; values: string[]; className: string; - customProperties: ('--ml' | '--mr')[]; + customProperties: '--mx'[]; responsive: true; }; my: { type: 'enum | string'; values: string[]; className: string; - customProperties: ('--mt' | '--mb')[]; + customProperties: '--my'[]; responsive: true; }; mt: { @@ -732,14 +732,14 @@ export const paddingPropDefs: (spacingValues: string[]) => { px: { type: 'enum | string'; className: string; - customProperties: ('--pl' | '--pr')[]; + customProperties: '--px'[]; values: string[]; responsive: true; }; py: { type: 'enum | string'; className: string; - customProperties: ('--pt' | '--pb')[]; + customProperties: '--py'[]; values: string[]; responsive: true; }; diff --git a/packages/canon/src/components/Box/Box.stories.tsx b/packages/canon/src/components/Box/Box.stories.tsx index 7b9aecca1a..aec2909743 100644 --- a/packages/canon/src/components/Box/Box.stories.tsx +++ b/packages/canon/src/components/Box/Box.stories.tsx @@ -54,6 +54,13 @@ const Card = () => { }; export const Default: Story = { + args: { + children: 'Hello World', + mb: '4', + }, +}; + +export const Preview: Story = { args: { children: , display: 'inline', @@ -141,6 +148,25 @@ export const Padding: Story = { Padding Left + + + Custom Padding + + + Custom Padding X + + + Custom Padding Y + + + + + Custom Padding Top Bottom + + + Custom Padding Left Right + + ), }; @@ -195,6 +221,35 @@ export const Margin: Story = { + + + + Custom Margin + + + + + Custom Margin X + + + + + Custom Margin Y + + + + + + + Custom Margin Top Bottom + + + + + Custom Margin Left Right + + + ), }; diff --git a/packages/canon/src/components/Box/Box.tsx b/packages/canon/src/components/Box/Box.tsx index 00e15a2b72..7230b0cbba 100644 --- a/packages/canon/src/components/Box/Box.tsx +++ b/packages/canon/src/components/Box/Box.tsx @@ -27,7 +27,7 @@ import { displayPropDefs } from '../../props/display.props'; /** @public */ export const Box = forwardRef((props, ref) => { - const { as = 'div', children } = props; + const { children } = props; const propDefs = { ...spacingPropDefs, @@ -39,7 +39,7 @@ export const Box = forwardRef((props, ref) => { }; const { className, style } = extractProps(props, propDefs); - return createElement(as, { + return createElement(props.as || 'div', { ref, className: clsx('canon-Box', className), style, diff --git a/packages/canon/src/css/utilities/m.css b/packages/canon/src/css/utilities/m.css index 00a30cc8b1..ecee3aca35 100644 --- a/packages/canon/src/css/utilities/m.css +++ b/packages/canon/src/css/utilities/m.css @@ -1,5 +1,5 @@ .cu-m { - margin: var(--p); + margin: var(--m); } .cu-m-0\.5 { diff --git a/packages/canon/src/css/utilities/mb.css b/packages/canon/src/css/utilities/mb.css index 4fbf8d614f..6d3831bad3 100644 --- a/packages/canon/src/css/utilities/mb.css +++ b/packages/canon/src/css/utilities/mb.css @@ -1,5 +1,5 @@ .cu-mb { - margin-bottom: var(--pb); + margin-bottom: var(--mb); } .cu-mb-0\.5 { diff --git a/packages/canon/src/css/utilities/ml.css b/packages/canon/src/css/utilities/ml.css index 887c464df1..b495d1a8bf 100644 --- a/packages/canon/src/css/utilities/ml.css +++ b/packages/canon/src/css/utilities/ml.css @@ -1,5 +1,5 @@ .cu-ml { - margin-left: var(--pl); + margin-left: var(--ml); } .cu-ml-0\.5 { diff --git a/packages/canon/src/css/utilities/mr.css b/packages/canon/src/css/utilities/mr.css index a2c0f8668b..9a179e1103 100644 --- a/packages/canon/src/css/utilities/mr.css +++ b/packages/canon/src/css/utilities/mr.css @@ -1,5 +1,5 @@ .cu-mr { - margin-right: var(--pr); + margin-right: var(--mr); } .cu-mr-0\.5 { diff --git a/packages/canon/src/css/utilities/mt.css b/packages/canon/src/css/utilities/mt.css index b74525b142..2e0815946d 100644 --- a/packages/canon/src/css/utilities/mt.css +++ b/packages/canon/src/css/utilities/mt.css @@ -1,5 +1,5 @@ .cu-mt { - margin-top: var(--pt); + margin-top: var(--mt); } .cu-mt-0\.5 { diff --git a/packages/canon/src/css/utilities/mx.css b/packages/canon/src/css/utilities/mx.css index 6ebbc57367..43f5838e4e 100644 --- a/packages/canon/src/css/utilities/mx.css +++ b/packages/canon/src/css/utilities/mx.css @@ -1,6 +1,6 @@ .cu-mx { - margin-left: var(--px); - margin-right: var(--px); + margin-left: var(--mx); + margin-right: var(--mx); } .cu-mx-0\.5 { diff --git a/packages/canon/src/css/utilities/my.css b/packages/canon/src/css/utilities/my.css index feb4a6f5bd..ae72ea9209 100644 --- a/packages/canon/src/css/utilities/my.css +++ b/packages/canon/src/css/utilities/my.css @@ -1,6 +1,6 @@ .cu-my { - margin-top: var(--py); - margin-bottom: var(--py); + margin-top: var(--my); + margin-bottom: var(--my); } .cu-my-0\.5 { diff --git a/packages/canon/src/props/margin.props.ts b/packages/canon/src/props/margin.props.ts index 94ec01cfc8..12cb0989e2 100644 --- a/packages/canon/src/props/margin.props.ts +++ b/packages/canon/src/props/margin.props.ts @@ -29,14 +29,14 @@ const marginPropDefs = (spacingValues: string[]) => type: 'enum | string', values: spacingValues, className: 'cu-mx', - customProperties: ['--ml', '--mr'], + customProperties: ['--mx'], responsive: true, }, my: { type: 'enum | string', values: spacingValues, className: 'cu-my', - customProperties: ['--mt', '--mb'], + customProperties: ['--my'], responsive: true, }, mt: { diff --git a/packages/canon/src/props/padding.props.ts b/packages/canon/src/props/padding.props.ts index 4ae686adb9..ea42fcd4f1 100644 --- a/packages/canon/src/props/padding.props.ts +++ b/packages/canon/src/props/padding.props.ts @@ -29,14 +29,14 @@ const paddingPropDefs = (spacingValues: string[]) => px: { type: 'enum | string', className: 'cu-px', - customProperties: ['--pl', '--pr'], + customProperties: ['--px'], values: spacingValues, responsive: true, }, py: { type: 'enum | string', className: 'cu-py', - customProperties: ['--pt', '--pb'], + customProperties: ['--py'], values: spacingValues, responsive: true, }, diff --git a/packages/canon/src/utils/extractProps.ts b/packages/canon/src/utils/extractProps.ts index fdd98048cf..8631f4e228 100644 --- a/packages/canon/src/utils/extractProps.ts +++ b/packages/canon/src/utils/extractProps.ts @@ -24,36 +24,35 @@ export function extractProps( }, propDefs: { [key: string]: any }, ) { - let className: string = props.className || ''; - let style: React.CSSProperties = props.style || {}; + let className: string[] = (props.className || '').split(' '); + let style: React.CSSProperties = { ...props.style }; + const hasProp = (key: string) => props.hasOwnProperty(key); for (const key in propDefs) { // Check if the prop is present or has a default value - if ( - !props.hasOwnProperty(key) && - !propDefs[key].hasOwnProperty('default') - ) { + if (!hasProp(key) && !propDefs[key].hasOwnProperty('default')) { continue; // Skip processing if neither is present } - const value = props.hasOwnProperty(key) - ? props[key] - : propDefs[key].default; + const value = hasProp(key) ? props[key] : propDefs[key].default; const propDefsValues = propDefs[key].values; const propDefsCustomProperties = propDefs[key].customProperties; const propDefsClassName = propDefs[key].className; const isResponsive = propDefs[key].responsive; - const handleValue = (val: any, prefix: string = '') => { + const handleValue = (val: string, prefix: string = '') => { + // Skip adding class name if the key is "as" + if (key === 'as') return; + if (propDefsValues.includes(val)) { - className += ` ${prefix}${propDefsClassName}-${val}`; + className.push(`${prefix}${propDefsClassName}-${val}`); } else { const customPropertyKey = isResponsive && prefix ? `${propDefsCustomProperties}-${prefix.slice(0, -1)}` : propDefsCustomProperties; (style as any)[customPropertyKey] = val; - className += ` ${prefix}${propDefsClassName}`; + className.push(`${prefix}${propDefsClassName}`); } }; @@ -76,5 +75,9 @@ export function extractProps( return acc; }, {} as { [key: string]: any }); - return { ...cleanedProps, className, style }; + const newClassNames = className + .filter(name => name && name.trim() !== '') + .join(' '); + + return { ...cleanedProps, className: newClassNames, style }; }