Skip to content

Commit

Permalink
Refactor(web-react): Use Spacing hook in Grid component #DS-1425
Browse files Browse the repository at this point in the history
  • Loading branch information
crishpeen committed Aug 9, 2024
1 parent 2cd0f17 commit 1ccc85f
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 60 deletions.
64 changes: 11 additions & 53 deletions packages/web-react/src/components/Grid/useGridStyleProps.ts
Original file line number Diff line number Diff line change
@@ -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<string, string | undefined>)[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<T> {
/** className props */
classProps: string;
Expand All @@ -34,44 +18,18 @@ export interface GridStyles<T> {
}

export function useGridStyleProps(props: SpiritGridProps<ElementType>): GridStyles<SpiritGridProps<ElementType>> {
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;
Expand Down
5 changes: 5 additions & 0 deletions packages/web-react/src/constants/direction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ export const Direction = {
HORIZONTAL: 'horizontal',
VERTICAL: 'vertical',
} as const;

export enum DirectionAxis {
X = 'x',
Y = 'y',
}
29 changes: 28 additions & 1 deletion packages/web-react/src/hooks/__tests__/useSpacingStyles.test.ts
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand Down Expand Up @@ -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;

Expand Down
17 changes: 11 additions & 6 deletions packages/web-react/src/hooks/useSpacingStyle.ts
Original file line number Diff line number Diff line change
@@ -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<string, string | undefined>)[`--${prefix}-spacing${suffix}`] = `var(--spirit-${spacing[
key as keyof typeof spacing
]?.toString()})`;
const breakpointSuffix = key === 'mobile' ? '' : `-${key}`;
(style as Record<string, string | undefined>)[`--${prefix}-spacing${directionSuffix}${breakpointSuffix}`] =
`var(--spirit-${spacing[key as keyof typeof spacing]?.toString()})`;
});
} else if (spacing) {
(style as Record<string, string | undefined>)[`--${prefix}-spacing`] = `var(--spirit-${spacing})`;
(style as Record<string, string | undefined>)[`--${prefix}-spacing${directionSuffix}`] = `var(--spirit-${spacing})`;
}

return style;
Expand Down

0 comments on commit 1ccc85f

Please sign in to comment.