This box will have no padding until the viewport reaches the desktop
breakpoint.{' '}
diff --git a/src/components/Box/Box.Playground.stories.tsx b/src/components/Box/Box.Playground.stories.tsx
index 000ef4aa4..672ed4bbe 100644
--- a/src/components/Box/Box.Playground.stories.tsx
+++ b/src/components/Box/Box.Playground.stories.tsx
@@ -2,6 +2,7 @@ import React from 'react';
import { Meta, Story } from '@storybook/react/types-6-0';
import { Box, BoxProps } from './Box';
import {
+ BACKGROUND_COLOR_OPTIONS,
BORDER_SIZE_OPTIONS,
BORDER_RADIUS_OPTIONS,
BOX_SHADOW_OPTIONS,
@@ -85,7 +86,14 @@ export default {
alignItems: {
control: {
type: 'select',
- options: [null, 'flex-start', 'flex-end', 'center', 'baseline', 'stretch'],
+ options: [
+ null,
+ 'flex-start',
+ 'flex-end',
+ 'center',
+ 'baseline',
+ 'stretch',
+ ],
},
},
justifyContent: {
@@ -287,7 +295,7 @@ export default {
background: {
control: {
type: 'select',
- options: [null, ...BRAND_COLOR_OPTIONS],
+ options: [null, ...BACKGROUND_COLOR_OPTIONS],
},
},
radius: {
@@ -360,7 +368,7 @@ export default {
childBackground: {
control: {
type: 'select',
- options: [null, ...BRAND_COLOR_OPTIONS],
+ options: [null, ...BACKGROUND_COLOR_OPTIONS],
},
},
className: {
@@ -447,12 +455,12 @@ const Template: Story = ({
export const Playground = Template.bind({});
Playground.args = {
- background: 'info-300',
+ background: 'inverse',
direction: 'row',
childWidth: 'lg',
childHeight: 'lg',
gap: 'sm',
padding: 'lg',
width: '100',
- childBackground: 'white',
+ childBackground: 'primary',
};
diff --git a/src/components/Box/Box.VisualTests.stories.tsx b/src/components/Box/Box.VisualTests.stories.tsx
index 3a9017ea0..a9b3f9f9f 100644
--- a/src/components/Box/Box.VisualTests.stories.tsx
+++ b/src/components/Box/Box.VisualTests.stories.tsx
@@ -2,16 +2,18 @@
/* eslint-disable no-else-return */
import React from 'react';
import { Meta, Story } from '@storybook/react/types-6-0';
+
import { Box, BoxProps } from './Box';
import {
+ BORDER_COLOR_OPTIONS,
FONT_SIZE_OPTIONS,
FONT_COLOR_OPTIONS,
- BRAND_COLOR_NAMES,
SPACING_OPTIONS,
FONT_FAMILY_OPTIONS,
FONT_WEIGHT_OPTIONS,
+ BACKGROUND_COLOR_OPTIONS,
} from '../../lib/tokens';
-import { BrandColor } from '../../types';
+import { BackgroundColor, BorderColor } from '../../types';
import { RESPONSIVE_STORY } from '../../docs/constants';
import { ResponsiveProvider } from '../ResponsiveProvider/ResponsiveProvider';
import { useBreakpoint } from '../../hooks/useBreakpoint/useBreakpoint';
@@ -22,214 +24,22 @@ export default {
} as Meta;
export const AllBackgroundColors: React.FunctionComponent = () => (
-
- {BRAND_COLOR_NAMES.map((color, index) => {
- if (color.includes('inherit')) return null;
- else if (
- color === 'dark'
- || color === 'light'
- || color === 'black'
- || color === 'white'
- || color === 'transparent'
- ) {
- return (
-
- {`${color}`}
-
- );
- } else {
- return (
-
-
- {`${color}-50`}
-
-
- {`${color}-100`}
-
-
- {`${color}-200`}
-
-
- {`${color}-300`}
-
-
- {`${color}-400`}
-
-
- {`${color}-500`}
-
-
- {`${color}-600`}
-
-
- {`${color}-700`}
-
-
- {`${color}-800`}
-
-
- {`${color}-900`}
-
-
- );
- }
- })}
+
+ {BACKGROUND_COLOR_OPTIONS.map((color: BackgroundColor, index: number) => (
+
+ {color}
+
+ ))}
);
export const AllBorderColors: React.FunctionComponent = () => (
-
- {BRAND_COLOR_NAMES.map((color, index) => {
- if (color.includes('inherit')) return null;
- else if (
- color === 'dark'
- || color === 'light'
- || color === 'black'
- || color === 'white'
- || color === 'transparent'
- ) {
- return (
-
- {`${color}`}
-
- );
- } else {
- return (
-
-
- {`${color}-50`}
-
-
- {`${color}-100`}
-
-
- {`${color}-200`}
-
-
- {`${color}-300`}
-
-
- {`${color}-400`}
-
-
- {`${color}-500`}
-
-
- {`${color}-600`}
-
-
- {`${color}-700`}
-
-
- {`${color}-800`}
-
-
- {`${color}-900`}
-
-
- );
- }
- })}
+
+ {BORDER_COLOR_OPTIONS.map((color: BorderColor, index: number) => (
+
+ {color}
+
+ ))}
);
@@ -237,19 +47,19 @@ export const AllGap: React.FunctionComponent = () => (
{[...SPACING_OPTIONS].map((spacing, i) => (
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
@@ -261,19 +71,19 @@ export const AllRowGap: React.FunctionComponent = () => (
{[...SPACING_OPTIONS].map((spacing, i) => (
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
@@ -285,19 +95,19 @@ export const AllColumnGap: React.FunctionComponent = () => (
{[...SPACING_OPTIONS].map((spacing, i) => (
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
@@ -309,19 +119,19 @@ export const AllRowChildGap: React.FunctionComponent = () => (
{[...SPACING_OPTIONS].map((spacing, i) => (
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
@@ -333,19 +143,19 @@ export const AllColumnChildGap: React.FunctionComponent = () => (
{[...SPACING_OPTIONS].map((spacing, i) => (
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
-
+
{spacing}
@@ -389,7 +199,7 @@ export const AllFontSizesWeightsFamily: React.FunctionComponent = () =
export const AllMargin: React.FunctionComponent = () => (
<>
{[...SPACING_OPTIONS].map((spacing, i) => (
-
+
{`${spacing} margin`}
))}
@@ -399,7 +209,7 @@ export const AllMargin: React.FunctionComponent = () => (
export const AllHorizontalMargin: React.FunctionComponent = () => (
<>
{[...SPACING_OPTIONS].map((spacing, i) => (
-
+
{`${spacing} horizontal margin`}
))}
@@ -409,7 +219,7 @@ export const AllHorizontalMargin: React.FunctionComponent = () => (
export const AllVerticalMargin: React.FunctionComponent = () => (
<>
{[...SPACING_OPTIONS].map((spacing, i) => (
-
+
{`${spacing} vertical margin`}
))}
@@ -419,7 +229,7 @@ export const AllVerticalMargin: React.FunctionComponent = () => (
export const AllPadding: React.FunctionComponent = () => (
<>
{[...SPACING_OPTIONS].map((spacing, i) => (
-
+
{`${spacing} padding`}
))}
@@ -431,7 +241,7 @@ export const AllHorizontalPadding: React.FunctionComponent = () => (
{[...SPACING_OPTIONS].map((spacing, i) => (
@@ -446,7 +256,7 @@ export const AllVerticalPadding: React.FunctionComponent = () => (
{[...SPACING_OPTIONS].map((spacing, i) => (
@@ -464,9 +274,7 @@ const BoxTemplate: Story = ({ propertyName, ...args }) => {
{`Breakpoint: ${activeBreakpoint.name}`}
- {`${propertyName}: ${
- args[propertyName][activeBreakpoint.name]
- }`}
+ {`${propertyName}: ${args[propertyName][activeBreakpoint.name]}`}
@@ -685,9 +493,7 @@ const BoxChildrenTemplate: Story = ({ propertyName, ...args }) => {
>
{`Breakpoint: ${activeBreakpoint.name}`}
- {`${propertyName}: ${
- args[propertyName][activeBreakpoint.name]
- }`}
+ {`${propertyName}: ${args[propertyName][activeBreakpoint.name]}`}
= ({ propertyName, ...args }) => {
>
{`Breakpoint: ${activeBreakpoint.name}`}
- {`${propertyName}: ${
- args[propertyName][activeBreakpoint.name]
- }`}
+ {`${propertyName}: ${args[propertyName][activeBreakpoint.name]}`}
= ({ propertyName, ...args }) => {
>
{`Breakpoint: ${activeBreakpoint.name}`}
- {`${propertyName}: ${
- args[propertyName][activeBreakpoint.name]
- }`}
+ {`${propertyName}: ${args[propertyName][activeBreakpoint.name]}`}
@@ -797,115 +599,115 @@ export const AllCursorOptions: React.FunctionComponent = () => (
padding="md"
childGap="md"
flex="auto"
- background="primary-lighter"
+ background="primary-50"
overflow="auto"
>
-
+
auto
-
+
default
-
+
none
-
+
context-menu
-
+
help
-
+
pointer
-
+
progress
-
+
wait
-
+
cell
-
+
crosshair
-
+
text
-
+
vertical-text
-
+
alias
-
+
copy
-
+
move
-
+
no-drop
-
+
not-allowed
-
+
grab
-
+
grabbing
-
+
all-scroll
-
+
col-resize
-
+
row-resize
-
+
n-resize
-
+
e-resize
-
+
s-resize
-
+
w-resize
-
+
ne-resize
-
+
nw-resize
-
+
se-resize
-
+
sw-resize
-
+
ew-resize
-
+
ns-resize
-
+
nesw-resize
-
+
nwse-resize
-
+
zoom-in
-
+
zoom-out
@@ -916,34 +718,34 @@ export const AllPositionOptions: React.FunctionComponent = () => (
padding="md"
childGap="md"
flex="auto"
- background="primary-lighter"
+ background="primary-50"
overflow="auto"
>
-
+
absolute
-
+
relative
-
+
sticky
-
+
fixed
-
+
static
-
+
unset
-
+
initial
-
+
inherit
-
+
revert
diff --git a/src/components/Box/Box.tsx b/src/components/Box/Box.tsx
index 948c1188a..5299704c8 100644
--- a/src/components/Box/Box.tsx
+++ b/src/components/Box/Box.tsx
@@ -11,11 +11,12 @@ import {
import * as CSS from 'csstype';
import classNames from 'classnames';
import {
+ BackgroundColor,
BaseSpacing,
+ BorderColor,
BorderRadiusSize,
BorderSize,
BoxShadowSize,
- BrandColor,
BreakpointSizeWithBase,
CssAlignContentValue,
CssAlignItemsValue,
@@ -41,7 +42,11 @@ import { getElementType } from '../../lib/getElementType';
import { generateResponsiveClasses } from '../../lib/generateResponsiveClasses';
import styles from './Box.module.scss';
-export type HoverableBoxProperties = 'color' | 'borderColor' | 'shadow' | 'background';
+export type HoverableBoxProperties =
+ | 'color'
+ | 'borderColor'
+ | 'shadow'
+ | 'background';
export interface BoxProps {
/**
* The element type to be rendered.
@@ -62,14 +67,13 @@ export interface BoxProps {
*/
alignSelf?: CssAlignItemsValue | ResponsiveProp;
/**
- * Any valid [brand color token](/?path=/story/design-tokens-design-tokens--page#color), or a `url()` for an image
+ * Any valid background color, or a `url()` for an image
*/
- background?: BrandColor;
+ background?: BackgroundColor;
/**
- * Any valid [brand color token](/?path=/story/design-tokens-design-tokens--page#color) for the border color
- * Or a responsive prop with BrandColor for each breakpoint.
+ * Any valid border color
*/
- borderColor?: BrandColor;
+ borderColor?: BorderColor;
/**
* Width of the Box's border
* Can be a single [border width token](/?path=/story/design-tokens-design-tokens--page#border-width).
@@ -175,7 +179,9 @@ export interface BoxProps {
/**
* How space between and around content items is distributed along the main-axis a flex Box
*/
- justifyContent?: CssJustifyContentValue | ResponsiveProp;
+ justifyContent?:
+ | CssJustifyContentValue
+ | ResponsiveProp;
/**
* Amount of space around the element.
* Can be a single [spacing value](/?path=/story/design-tokens-design-tokens--page#spacing).
@@ -265,269 +271,316 @@ export interface BoxProps {
* A `` is a layout component to build UIs with consistent padding and spacing between
* elements.
*/
-export const Box: FC = forwardRef((
- {
- as = 'div',
- alignItems = undefined,
- alignContent = undefined,
- alignSelf = undefined,
- background = undefined,
- borderColor = undefined,
- borderWidth = undefined,
- children = undefined,
- childGap = undefined,
- className = '',
- color = undefined,
- columnGap = undefined,
- cursor = undefined,
- display = 'flex',
- direction = 'column',
- flex = undefined,
- fontFamily = undefined,
- fontSize = 'inherit',
- focus = undefined,
- fontWeight = undefined,
- gap = undefined,
- height = undefined,
- hover = undefined,
- justifyContent = undefined,
- margin = undefined,
- maxHeight = undefined,
- minHeight = undefined,
- maxWidth = undefined,
- minWidth = undefined,
- overflow = undefined,
- padding = undefined,
- position = undefined,
- radius = undefined,
- rowGap = undefined,
- shadow = undefined,
- style = {},
- textAlign = undefined,
- wrap = undefined,
- width = undefined,
- zIndex = undefined,
- ...restProps
- },
- ref,
-) => {
- const heightCss = getDimensionCss('h', height);
- const widthCss = getDimensionCss('w', width);
- const maxHeightCss = getDimensionCss('mh', maxHeight);
- const maxWidthCss = getDimensionCss('mw', maxWidth);
- const minHeightCss = getDimensionCss('minh', minHeight);
- const minWidthCss = getDimensionCss('minw', minWidth);
-
- const isFlexBox = typeof display === 'string' && display.includes('flex');
- const flexDirectionClasses = isFlexBox ? generateResponsiveClasses('flex-direction', direction) : null;
-
- const cssPropertyMap: {
- [key: string]: {
- classPrefix: string;
- transformer: typeof generateResponsiveClasses | typeof cssShorthandToClasses;
- };
- } = {
- color: { classPrefix: 'font-color', transformer: generateResponsiveClasses },
- background: { classPrefix: 'background-color', transformer: generateResponsiveClasses },
- borderColor: { classPrefix: 'border-color', transformer: generateResponsiveClasses },
- borderWidth: { classPrefix: 'border-width', transformer: cssShorthandToClasses },
- shadow: { classPrefix: 'shadow', transformer: generateResponsiveClasses },
- fontSize: { classPrefix: 'font-size', transformer: generateResponsiveClasses },
- };
-
- const getStatefulClasses = (stateKey: 'hover' | 'focus', values: BoxProps['hover' | 'hover']) => values // eslint-disable-line
- ? Object.entries(values).map(([key, value]) => (
- cssPropertyMap[key].transformer(`${stateKey}:${cssPropertyMap[key as keyof BoxProps['focus' | 'hover']].classPrefix}`, value) // eslint-disable-line max-len
- ))
- : undefined;
-
- const hoverClasses = getStatefulClasses('hover', hover);
- const focusClasses = getStatefulClasses('focus', focus);
-
- const boxClasses = classNames(
- className,
- cssShorthandToClasses('m', margin),
- cssShorthandToClasses('p', padding),
- cssShorthandToClasses('br', radius),
- cssShorthandToClasses('g', gap),
- cssShorthandToClasses('cg', columnGap),
- cssShorthandToClasses('rg', rowGap),
- heightCss.classes,
- maxHeightCss.classes,
- minHeightCss.classes,
- maxWidthCss.classes,
- minWidthCss.classes,
- widthCss.classes,
- flexDirectionClasses,
- generateResponsiveClasses('display', display),
- generateResponsiveClasses('justify-content', justifyContent),
- generateResponsiveClasses('align-items', alignItems),
- generateResponsiveClasses('align-content', alignContent),
- generateResponsiveClasses('align-self', alignSelf),
- generateResponsiveClasses('font-family', fontFamily),
- generateResponsiveClasses('font-size', fontSize),
- generateResponsiveClasses('overflow', overflow),
- generateResponsiveClasses('shadow', shadow),
- generateResponsiveClasses('flex', flex),
- cssShorthandToClasses('border-width', borderWidth),
- generateResponsiveClasses('font-weight', fontWeight),
- generateResponsiveClasses('text-align', textAlign),
- generateResponsiveClasses('position', position),
- generateResponsiveClasses('z-index', zIndex),
- ...(hoverClasses ?? []),
- ...(focusClasses ?? []),
+export const Box: FC = forwardRef(
+ (
{
- 'flex-wrap': isFlexBox && wrap,
- 'flex-nowrap': isFlexBox && wrap === false,
- [`background-color-${background}`]: background,
- [`font-color-${color}`]: color,
- [`border-color-${borderColor}`]: borderColor,
- [`cursor-${cursor}`]: cursor,
- [styles['box-transition']]: hover || focus,
+ as = 'div',
+ alignItems = undefined,
+ alignContent = undefined,
+ alignSelf = undefined,
+ background = undefined,
+ borderColor = undefined,
+ borderWidth = undefined,
+ children = undefined,
+ childGap = undefined,
+ className = '',
+ color = undefined,
+ columnGap = undefined,
+ cursor = undefined,
+ display = 'flex',
+ direction = 'column',
+ flex = undefined,
+ fontFamily = undefined,
+ fontSize = 'inherit',
+ focus = undefined,
+ fontWeight = undefined,
+ gap = undefined,
+ height = undefined,
+ hover = undefined,
+ justifyContent = undefined,
+ margin = undefined,
+ maxHeight = undefined,
+ minHeight = undefined,
+ maxWidth = undefined,
+ minWidth = undefined,
+ overflow = undefined,
+ padding = undefined,
+ position = undefined,
+ radius = undefined,
+ rowGap = undefined,
+ shadow = undefined,
+ style = {},
+ textAlign = undefined,
+ wrap = undefined,
+ width = undefined,
+ zIndex = undefined,
+ ...restProps
},
- );
-
- const boxStyles = {
- ...style,
- ...heightCss.styles,
- ...maxHeightCss.styles,
- ...maxWidthCss.styles,
- ...widthCss.styles,
- ...minHeightCss.styles,
- ...minWidthCss.styles,
- };
-
- /**
- * Creates an object that maps the flex direction to either `right` or `bottom`
- * so a margin can be applied to that side.
- */
- const generateChildGapDirection = (): ResponsiveProp => {
- let childGapDirection = {};
-
- const getChildGapMarginDirection = (d: CssFlexDirectionValue) => {
- let marginDirection = '';
- if (d?.includes('row')) marginDirection = 'right';
- else if (d?.includes('column')) marginDirection = 'bottom';
-
- return marginDirection;
+ ref,
+ ) => {
+ const heightCss = getDimensionCss('h', height);
+ const widthCss = getDimensionCss('w', width);
+ const maxHeightCss = getDimensionCss('mh', maxHeight);
+ const maxWidthCss = getDimensionCss('mw', maxWidth);
+ const minHeightCss = getDimensionCss('minh', minHeight);
+ const minWidthCss = getDimensionCss('minw', minWidth);
+
+ const isFlexBox = typeof display === 'string' && display.includes('flex');
+ const flexDirectionClasses = isFlexBox
+ ? generateResponsiveClasses('flex-direction', direction)
+ : null;
+
+ const cssPropertyMap: {
+ [key: string]: {
+ classPrefix: string;
+ transformer:
+ | typeof generateResponsiveClasses
+ | typeof cssShorthandToClasses;
+ };
+ } = {
+ color: {
+ classPrefix: 'font-color',
+ transformer: generateResponsiveClasses,
+ },
+ background: {
+ classPrefix: 'background-color',
+ transformer: generateResponsiveClasses,
+ },
+ borderColor: {
+ classPrefix: 'border-color',
+ transformer: generateResponsiveClasses,
+ },
+ borderWidth: {
+ classPrefix: 'border-width',
+ transformer: cssShorthandToClasses,
+ },
+ shadow: { classPrefix: 'shadow', transformer: generateResponsiveClasses },
+ fontSize: {
+ classPrefix: 'font-size',
+ transformer: generateResponsiveClasses,
+ },
};
- if (typeof direction === 'string') {
- childGapDirection = { base: getChildGapMarginDirection(direction) };
- } else if (typeof direction === 'object' && direction !== null) {
- childGapDirection = Object.keys(direction).reduce(
- (acc, curr) => ({
- ...acc,
- [curr]: getChildGapMarginDirection(direction[curr as BreakpointSizeWithBase]),
- }),
- {},
- );
- }
+ const getStatefulClasses = (
+ stateKey: 'hover' | 'focus',
+ values: BoxProps['hover' | 'hover'],
+ ) =>
+ (values // eslint-disable-line
+ ? Object.entries(values).map(([key, value]) => cssPropertyMap[key].transformer(
+ `${stateKey}:${
+ cssPropertyMap[key as keyof BoxProps['focus' | 'hover']]
+ .classPrefix
+ }`,
+ value,
+ ))
+ : undefined);
+
+ const hoverClasses = getStatefulClasses('hover', hover);
+ const focusClasses = getStatefulClasses('focus', focus);
+
+ const boxClasses = classNames(
+ className,
+ cssShorthandToClasses('m', margin),
+ cssShorthandToClasses('p', padding),
+ cssShorthandToClasses('br', radius),
+ cssShorthandToClasses('g', gap),
+ cssShorthandToClasses('cg', columnGap),
+ cssShorthandToClasses('rg', rowGap),
+ heightCss.classes,
+ maxHeightCss.classes,
+ minHeightCss.classes,
+ maxWidthCss.classes,
+ minWidthCss.classes,
+ widthCss.classes,
+ flexDirectionClasses,
+ generateResponsiveClasses('display', display),
+ generateResponsiveClasses('justify-content', justifyContent),
+ generateResponsiveClasses('align-items', alignItems),
+ generateResponsiveClasses('align-content', alignContent),
+ generateResponsiveClasses('align-self', alignSelf),
+ generateResponsiveClasses('font-family', fontFamily),
+ generateResponsiveClasses('font-size', fontSize),
+ generateResponsiveClasses('overflow', overflow),
+ generateResponsiveClasses('shadow', shadow),
+ generateResponsiveClasses('flex', flex),
+ cssShorthandToClasses('border-width', borderWidth),
+ generateResponsiveClasses('font-weight', fontWeight),
+ generateResponsiveClasses('text-align', textAlign),
+ generateResponsiveClasses('position', position),
+ generateResponsiveClasses('z-index', zIndex),
+ ...(hoverClasses ?? []),
+ ...(focusClasses ?? []),
+ {
+ 'flex-wrap': isFlexBox && wrap,
+ 'flex-nowrap': isFlexBox && wrap === false,
+ [`background-color-${background}`]: background,
+ [`font-color-${color}`]: color,
+ [`border-color-${borderColor}`]: borderColor,
+ [`cursor-${cursor}`]: cursor,
+ [styles['box-transition']]: hover || focus,
+ },
+ );
+
+ const boxStyles = {
+ ...style,
+ ...heightCss.styles,
+ ...maxHeightCss.styles,
+ ...maxWidthCss.styles,
+ ...widthCss.styles,
+ ...minHeightCss.styles,
+ ...minWidthCss.styles,
+ };
- return childGapDirection;
- };
+ /**
+ * Creates an object that maps the flex direction to either `right` or `bottom`
+ * so a margin can be applied to that side.
+ */
+ const generateChildGapDirection = (): ResponsiveProp => {
+ let childGapDirection = {};
+
+ const getChildGapMarginDirection = (d: CssFlexDirectionValue) => {
+ let marginDirection = '';
+ if (d?.includes('row')) marginDirection = 'right';
+ else if (d?.includes('column')) marginDirection = 'bottom';
+
+ return marginDirection;
+ };
+
+ if (typeof direction === 'string') {
+ childGapDirection = { base: getChildGapMarginDirection(direction) };
+ } else if (typeof direction === 'object' && direction !== null) {
+ childGapDirection = Object.keys(direction).reduce(
+ (acc, curr) => ({
+ ...acc,
+ [curr]: getChildGapMarginDirection(
+ direction[curr as BreakpointSizeWithBase],
+ ),
+ }),
+ {},
+ );
+ }
+
+ return childGapDirection;
+ };
- /**
- * Shapes the childGap prop into a ResponsiveSpacing object
- * so that we can cross-reference values between direction and childGap values to generate
- * responsive classes.
- */
- const generateChildGap = (): ResponsiveProp => {
- let childGapObj = {};
+ /**
+ * Shapes the childGap prop into a ResponsiveSpacing object
+ * so that we can cross-reference values between direction and childGap values to generate
+ * responsive classes.
+ */
+ const generateChildGap = (): ResponsiveProp => {
+ let childGapObj = {};
+
+ if (typeof childGap === 'string') {
+ childGapObj = { base: childGap };
+ } else if (typeof childGap === 'object' && childGap !== null) {
+ childGapObj = { ...childGap };
+ }
+
+ return childGapObj;
+ };
- if (typeof childGap === 'string') {
- childGapObj = { base: childGap };
- } else if (typeof childGap === 'object' && childGap !== null) {
- childGapObj = { ...childGap };
+ const childGapClasses: string[] = [];
+
+ if (childGap && direction) {
+ const childGapDirection = generateChildGapDirection();
+ const childGapValues = generateChildGap();
+ const breakpoints: BreakpointSizeWithBase[] = [
+ 'hd',
+ 'desktop',
+ 'tablet',
+ 'base',
+ ];
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const findMatchingBreakpoint = (
+ responsiveObj: ResponsiveProp,
+ key: BreakpointSizeWithBase,
+ ): string => {
+ const index = breakpoints.findIndex(breakpoint => breakpoint === key);
+ let value = '';
+
+ value = responsiveObj[key];
+
+ if (!value) return findMatchingBreakpoint(responsiveObj, breakpoints[index + 1]);
+
+ return value;
+ };
+
+ breakpoints.forEach(breakpoint => {
+ const foundDirection = findMatchingBreakpoint(
+ childGapDirection,
+ breakpoint as BreakpointSizeWithBase,
+ );
+ const foundChildGap = findMatchingBreakpoint(
+ childGapValues,
+ breakpoint as BreakpointSizeWithBase,
+ );
+
+ const classSuffix = breakpoint === 'base' ? '' : `-${breakpoint}`;
+ const oppositeDirection = foundDirection === 'bottom' ? 'right' : 'bottom';
+
+ childGapClasses.push(
+ `m-${foundDirection}-${foundChildGap}${classSuffix}`,
+ );
+ childGapClasses.push(`m-${oppositeDirection}-0${classSuffix}`);
+ });
}
- return childGapObj;
- };
-
- const childGapClasses: string[] = [];
-
- if (childGap && direction) {
- const childGapDirection = generateChildGapDirection();
- const childGapValues = generateChildGap();
- const breakpoints: BreakpointSizeWithBase[] = ['hd', 'desktop', 'tablet', 'base'];
-
+ /**
+ * Shallow merges existing classes of child node with a className based on the childGap value.
+ */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- const findMatchingBreakpoint = (responsiveObj: ResponsiveProp,
- key: BreakpointSizeWithBase): string => {
- const index = breakpoints.findIndex(breakpoint => breakpoint === key);
- let value = '';
-
- value = responsiveObj[key];
-
- if (!value) return findMatchingBreakpoint(responsiveObj, breakpoints[index + 1]);
-
- return value;
+ const decorateChildren = (
+ child: string | number | ReactElement,
+ i: number,
+ array: ReactElement