diff --git a/packages/web-react/src/components/Grid/useGridStyleProps.ts b/packages/web-react/src/components/Grid/useGridStyleProps.ts index 07844f5229..d5c4ee41be 100644 --- a/packages/web-react/src/components/Grid/useGridStyleProps.ts +++ b/packages/web-react/src/components/Grid/useGridStyleProps.ts @@ -1,29 +1,13 @@ import classNames from 'classnames'; import { CSSProperties, ElementType } from 'react'; -import { useClassNamePrefix } from '../../hooks'; +import { DirectionAxis } from '../../constants'; +import { useClassNamePrefix, useSpacingStyle } from '../../hooks'; import { SpiritGridProps } from '../../types'; interface GridCSSProperties extends CSSProperties { [key: string]: string | undefined | number; } -const setStyleProperty = (styleObject: GridCSSProperties, propertyName: string, value: string | undefined) => { - (styleObject as Record)[propertyName] = `var(--spirit-${value})`; -}; - -const setGridStyle = (styleObject: GridCSSProperties, baseVarName: string, propValue: GridCSSProperties) => { - if (typeof propValue === 'object' && propValue !== null) { - Object.keys(propValue).forEach((key) => { - const suffix = key === 'mobile' ? '' : `-${key}`; - const propName = `--${baseVarName}${suffix}`; - setStyleProperty(styleObject, propName, propValue[key as keyof GridCSSProperties]?.toString()); - }); - } else { - const propName = `--${baseVarName}`; - setStyleProperty(styleObject, propName, propValue); - } -}; - export interface GridStyles { /** className props */ classProps: string; @@ -34,44 +18,18 @@ export interface GridStyles { } export function useGridStyleProps(props: SpiritGridProps): GridStyles> { - const { cols, ...restProps } = props; + const { cols, spacing, spacingX, spacingY, ...restProps } = props; const gridClass = useClassNamePrefix('Grid'); - const gridStyle: GridCSSProperties = {}; - - const typePropNames = Object.keys(props).filter((propName) => propName.startsWith('spacing')); - - typePropNames.forEach((propName) => { - let type: string; - - if (props[propName]) { - if (propName.startsWith('spacingX')) { - type = 'spacing-x'; - } else if (propName.startsWith('spacingY')) { - type = 'spacing-y'; - } else { - type = propName; - } - - if (type === 'spacing') { - setGridStyle( - gridStyle, - `grid-spacing-x${propName.replace(type, '').toLowerCase()}`, - props[propName] as GridCSSProperties, - ); - setGridStyle( - gridStyle, - `grid-spacing-y${propName.replace(type, '').toLowerCase()}`, - props[propName] as GridCSSProperties, - ); - } else { - setGridStyle(gridStyle, `grid-${type}`, props[propName] as GridCSSProperties); - } - } - - delete props[propName]; - }); + const gridStyle: GridCSSProperties = { + ...{ + ...useSpacingStyle(spacing, 'grid', DirectionAxis.X), + ...useSpacingStyle(spacing, 'grid', DirectionAxis.Y), + }, + ...useSpacingStyle(spacingX, 'grid', DirectionAxis.X), + ...useSpacingStyle(spacingY, 'grid', DirectionAxis.Y), + }; let classes: string; let gridColsClass: string; diff --git a/packages/web-react/src/constants/direction.ts b/packages/web-react/src/constants/direction.ts index 3194280f47..0c1d492884 100644 --- a/packages/web-react/src/constants/direction.ts +++ b/packages/web-react/src/constants/direction.ts @@ -2,3 +2,8 @@ export const Direction = { HORIZONTAL: 'horizontal', VERTICAL: 'vertical', } as const; + +export enum DirectionAxis { + X = 'x', + Y = 'y', +} diff --git a/packages/web-react/src/hooks/__tests__/useSpacingStyles.test.ts b/packages/web-react/src/hooks/__tests__/useSpacingStyles.test.ts index 5bed8c2b72..6d6c43b90b 100644 --- a/packages/web-react/src/hooks/__tests__/useSpacingStyles.test.ts +++ b/packages/web-react/src/hooks/__tests__/useSpacingStyles.test.ts @@ -1,5 +1,6 @@ import { renderHook } from '@testing-library/react'; -import { SpacingProp } from '../../types/shared'; +import { DirectionAxis } from '../../constants'; +import { SpacingProp } from '../../types'; import { useSpacingStyle } from '../useSpacingStyle'; describe('useSpacingStyles', () => { @@ -29,6 +30,32 @@ describe('useSpacingStyles', () => { }); }); + it('should process horizontal direction with spacing if property spacing is an object', () => { + const mockProps = { + mobile: 'space-100', + tablet: 'space-200', + desktop: 'space-300', + }; + + const { result } = renderHook(() => useSpacingStyle(mockProps as SpacingProp, 'test-prefix', DirectionAxis.X)); + + expect(result.current).toEqual({ + '--test-prefix-spacing-x': 'var(--spirit-space-100)', + '--test-prefix-spacing-x-tablet': 'var(--spirit-space-200)', + '--test-prefix-spacing-x-desktop': 'var(--spirit-space-300)', + }); + }); + + it('should process vertical direction with spacing if property spacing is a string', () => { + const mockProps = 'space-100'; + + const { result } = renderHook(() => useSpacingStyle(mockProps as SpacingProp, 'test-prefix', DirectionAxis.Y)); + + expect(result.current).toEqual({ + '--test-prefix-spacing-y': 'var(--spirit-space-100)', + }); + }); + it('should process if spacing is undefined', () => { const mockProps = undefined; diff --git a/packages/web-react/src/hooks/useSpacingStyle.ts b/packages/web-react/src/hooks/useSpacingStyle.ts index 943dc2dc36..583862d123 100644 --- a/packages/web-react/src/hooks/useSpacingStyle.ts +++ b/packages/web-react/src/hooks/useSpacingStyle.ts @@ -1,17 +1,22 @@ +import { DirectionAxis } from '../constants'; import { SpacingProp, SpacingCSSProperties } from '../types'; -export function useSpacingStyle(spacing: SpacingProp | undefined, prefix: string): SpacingCSSProperties { +export function useSpacingStyle( + spacing: SpacingProp | undefined, + prefix: string, + direction: undefined | (typeof DirectionAxis)[keyof typeof DirectionAxis] = undefined, +): SpacingCSSProperties { const style: SpacingCSSProperties = {}; + const directionSuffix = direction ? `-${direction}` : ''; if (typeof spacing === 'object' && spacing !== null) { Object.keys(spacing).forEach((key) => { - const suffix = key === 'mobile' ? '' : `-${key}`; - (style as Record)[`--${prefix}-spacing${suffix}`] = `var(--spirit-${spacing[ - key as keyof typeof spacing - ]?.toString()})`; + const breakpointSuffix = key === 'mobile' ? '' : `-${key}`; + (style as Record)[`--${prefix}-spacing${directionSuffix}${breakpointSuffix}`] = + `var(--spirit-${spacing[key as keyof typeof spacing]?.toString()})`; }); } else if (spacing) { - (style as Record)[`--${prefix}-spacing`] = `var(--spirit-${spacing})`; + (style as Record)[`--${prefix}-spacing${directionSuffix}`] = `var(--spirit-${spacing})`; } return style;