diff --git a/packages/web-react/src/components/Box/__tests__/Box.test.tsx b/packages/web-react/src/components/Box/__tests__/Box.test.tsx new file mode 100644 index 0000000000..ef33864ff8 --- /dev/null +++ b/packages/web-react/src/components/Box/__tests__/Box.test.tsx @@ -0,0 +1,123 @@ +import '@testing-library/jest-dom'; +import { render, screen } from '@testing-library/react'; +import React from 'react'; +import { restPropsTest } from '../../../../tests/providerTests/restPropsTest'; +import { stylePropsTest } from '../../../../tests/providerTests/stylePropsTest'; +import Box from '../Box'; + +const dataProvider = [ + { + prop: 'backgroundColor', + value: 'primary', + className: 'bg-primary', + description: 'background color', + }, + { + prop: 'borderColor', + value: 'basic', + className: 'border-basic', + description: 'border color', + }, + { + prop: 'borderWidth', + value: '100', + className: 'border-100', + description: 'border width', + }, + { + prop: 'padding', + value: 'space-800', + className: 'p-800', + description: 'padding', + }, + { + prop: 'paddingX', + value: 'space-800', + className: 'px-800', + description: 'horizontal padding', + }, + { + prop: 'paddingY', + value: 'space-800', + className: 'py-800', + description: 'vertical padding', + }, + { + prop: 'paddingTop', + value: 'space-800', + className: 'pt-800', + description: 'padding top', + }, + { + prop: 'paddingBottom', + value: 'space-800', + className: 'pb-800', + description: 'padding bottom', + }, + { + prop: 'paddingLeft', + value: 'space-800', + className: 'pl-800', + description: 'padding left', + }, + { + prop: 'paddingRight', + value: 'space-800', + className: 'pr-800', + description: 'padding right', + }, + { + prop: 'padding', + value: { mobile: 'space-600', tablet: 'space-800', desktop: 'space-1000' }, + className: 'p-600 p-tablet-800 p-desktop-1000', + description: 'responsive padding', + }, +]; + +describe('Box', () => { + stylePropsTest(Box); + + restPropsTest(Box, 'div'); + + it('should render children', () => { + render(Content); + + expect(screen.getByText('Content')).toBeInTheDocument(); + }); + + it('should render with background color', () => { + render(Content); + + expect(screen.getByText('Content')).toHaveStyle('background-color: var(--color-primary)'); + }); + + it('should render with border radius and width', () => { + render( + + Content + , + ); + + expect(screen.getByTestId('Box')).toHaveClass('rounded-200'); + }); + + it('should not render correct border radius class when border width is not set', () => { + render( + + Content + , + ); + + expect(screen.getByTestId('Box')).not.toHaveClass('rounded-200'); + }); + + it.each(dataProvider)('should render with $description', ({ prop, value, className }) => { + render( + + Content + , + ); + + expect(screen.getByTestId('Box')).toHaveClass(className); + }); +}); diff --git a/packages/web-react/src/components/Box/__tests__/Card.test.tsx b/packages/web-react/src/components/Box/__tests__/Card.test.tsx deleted file mode 100644 index 354dbc584e..0000000000 --- a/packages/web-react/src/components/Box/__tests__/Card.test.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import '@testing-library/jest-dom'; -import { render, screen } from '@testing-library/react'; -import React from 'react'; -import { classNamePrefixProviderTest } from '../../../../tests/providerTests/classNamePrefixProviderTest'; -import { restPropsTest } from '../../../../tests/providerTests/restPropsTest'; -import { stylePropsTest } from '../../../../tests/providerTests/stylePropsTest'; -import Card from '../Card'; - -describe('Card', () => { - classNamePrefixProviderTest(Card, 'Card'); - - stylePropsTest(Card); - - restPropsTest(Card, 'article'); - - it('should render card component and have default class names', () => { - render(); - - expect(screen.getByRole('article')).toHaveClass('Card Card--vertical'); - }); - - it('should render custom element', () => { - render(); - - expect(screen.getByTestId('test')).toContainHTML('section'); - }); - - it('should render boxed card', () => { - render(); - - expect(screen.getByRole('article')).toHaveClass('Card--boxed'); - }); - - it('should render horizontal card', () => { - render(); - - expect(screen.getByRole('article')).toHaveClass('Card--horizontal'); - }); - - it('should render horizontal reversed card', () => { - render(); - - expect(screen.getByRole('article')).toHaveClass('Card--horizontalReversed'); - }); - - it('should render text children', () => { - render(Hello World); - - expect(screen.getByRole('article')).toHaveTextContent('Hello World'); - }); -}); diff --git a/packages/web-react/src/components/Box/__tests__/__fixtures__/CardStylePropsDataProvider.ts b/packages/web-react/src/components/Box/__tests__/__fixtures__/CardStylePropsDataProvider.ts deleted file mode 100644 index 9472040248..0000000000 --- a/packages/web-react/src/components/Box/__tests__/__fixtures__/CardStylePropsDataProvider.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { AlignmentX } from '../../../../constants'; -import { AlignmentXDictionaryType, CardDirection, CardSizes } from '../../../../types'; -import { toPascalCase } from '../../../../utils'; -import { UseCardStyleProps, UseCardStylePropsReturn } from '../../useCardStyleProps'; - -type TextPropsDataProviderType = { - props: UseCardStyleProps; - description: string; - expected: UseCardStylePropsReturn; -}; - -export const defaultExpectedClasses = { - artwork: 'CardArtwork', - body: 'CardBody', - eyebrow: 'CardEyebrow', - footer: 'CardFooter', - link: 'CardLink', - logo: 'CardLogo', - media: 'CardMedia', - mediaCanvas: 'CardMedia__canvas', - root: 'Card', - title: 'CardTitle', -}; - -// Helper function to generate classes -const generateExpectedClassProps = (overrides: Partial) => ({ - ...defaultExpectedClasses, - ...overrides, -}); - -// Helper for artworkAlignmentX, footerAlignmentX, and sizes -const alignmentDataProvider = (type: 'artwork' | 'footer', values: { alignment: AlignmentXDictionaryType }[]) => - values.map(({ alignment }) => ({ - props: { [`${type}AlignmentX`]: alignment }, - description: `return correct classProps for ${type}AlignmentX ${alignment!.toLowerCase()}`, - expected: { - classProps: generateExpectedClassProps({ - [type]: `${defaultExpectedClasses[type]} ${defaultExpectedClasses[type]}--alignmentX${toPascalCase(alignment!)}`, - }), - }, - })); - -const sizeDataProvider = Object.values(CardSizes).map((size) => ({ - props: { size }, - description: `return correct classProps for media ${size.toLowerCase()}`, - expected: { - classProps: generateExpectedClassProps({ - media: `${defaultExpectedClasses.media} ${defaultExpectedClasses.media}--${size.toLowerCase()}`, - }), - }, -})); - -export const textPropsDataProvider: TextPropsDataProviderType[] = [ - // Direction-specific classes - { - props: { direction: CardDirection.VERTICAL }, - description: 'return correct classProps for direction vertical', - expected: { classProps: generateExpectedClassProps({ root: 'Card Card--vertical' }) }, - }, - { - props: { direction: CardDirection.HORIZONTAL }, - description: 'return correct classProps for direction horizontal', - expected: { classProps: generateExpectedClassProps({ root: 'Card Card--horizontal' }) }, - }, - { - props: { direction: CardDirection.HORIZONTAL_REVERSED }, - description: 'return correct classProps for direction horizontal reversed', - expected: { classProps: generateExpectedClassProps({ root: 'Card Card--horizontalReversed' }) }, - }, - - // Artwork alignment - ...alignmentDataProvider('artwork', [ - { alignment: AlignmentX.LEFT }, - { alignment: AlignmentX.RIGHT }, - { alignment: AlignmentX.CENTER }, - ]), - - // Footer alignment - ...alignmentDataProvider('footer', [ - { alignment: AlignmentX.LEFT }, - { alignment: AlignmentX.RIGHT }, - { alignment: AlignmentX.CENTER }, - ]), - - // Boxed card - { - props: { isBoxed: true }, - description: 'return correct classProps for boxed card', - expected: { classProps: generateExpectedClassProps({ root: 'Card Card--boxed' }) }, - }, - - // Body-specific properties - { - props: { isSelectable: true }, - description: 'return correct classProps for body selectable', - expected: { - classProps: generateExpectedClassProps({ - body: `${defaultExpectedClasses.body} ${defaultExpectedClasses.body}--selectable`, - }), - }, - }, - - // Media-specific properties - { - props: { hasFilledHeight: true }, - description: 'return correct classProps for media with filled height', - expected: { - classProps: generateExpectedClassProps({ - media: `${defaultExpectedClasses.media} ${defaultExpectedClasses.media}--filledHeight`, - }), - }, - }, - { - props: { isExpanded: true }, - description: 'return correct classProps for media expanded', - expected: { - classProps: generateExpectedClassProps({ - media: `${defaultExpectedClasses.media} ${defaultExpectedClasses.media}--expanded`, - }), - }, - }, - ...sizeDataProvider, - - // Title-specific properties - { - props: { isHeading: true }, - description: 'return correct classProps for title heading', - expected: { - classProps: generateExpectedClassProps({ - title: `${defaultExpectedClasses.title} ${defaultExpectedClasses.title}--heading`, - }), - }, - }, - - // Complex scenario - { - props: { - artworkAlignmentX: AlignmentX.LEFT, - direction: CardDirection.HORIZONTAL, - footerAlignmentX: AlignmentX.RIGHT, - hasFilledHeight: true, - isBoxed: true, - isExpanded: true, - isHeading: false, - isSelectable: true, - size: CardSizes.SMALL, - }, - description: 'return correct classProps for a horizontal, boxed, expanded card with small size', - expected: { - classProps: generateExpectedClassProps({ - artwork: 'CardArtwork CardArtwork--alignmentXLeft', - body: 'CardBody CardBody--selectable', - footer: 'CardFooter CardFooter--alignmentXRight', - media: 'CardMedia CardMedia--small CardMedia--expanded CardMedia--filledHeight', - root: 'Card Card--horizontal Card--boxed', - }), - }, - }, -]; diff --git a/packages/web-react/src/components/Box/__tests__/useBoxStyleProps.test.ts b/packages/web-react/src/components/Box/__tests__/useBoxStyleProps.test.ts new file mode 100644 index 0000000000..29e7805391 --- /dev/null +++ b/packages/web-react/src/components/Box/__tests__/useBoxStyleProps.test.ts @@ -0,0 +1,122 @@ +import { renderHook } from '@testing-library/react'; +import { SpiritBoxProps } from '../../../types'; +import { useBoxStyleProps } from '../useBoxStyleProps'; + +describe('useBoxStyleProps', () => { + it('should return defaults', () => { + const props: SpiritBoxProps = {}; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe(''); + }); + + it('should return background classProps', () => { + const props: SpiritBoxProps = { + backgroundColor: 'secondary', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('bg-secondary'); + }); + + it('should return padding classProps', () => { + const props: SpiritBoxProps = { + padding: 'space-400', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('p-400'); + }); + + it('should return paddingX classProps', () => { + const props: SpiritBoxProps = { + paddingX: 'space-400', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('px-400'); + }); + + it('should return paddingY classProps', () => { + const props: SpiritBoxProps = { + paddingY: 'space-400', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('py-400'); + }); + + it('should return paddingTop classProps', () => { + const props: SpiritBoxProps = { + paddingTop: 'space-400', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('pt-400'); + }); + + it('should return paddingBottom classProps', () => { + const props: SpiritBoxProps = { + paddingBottom: 'space-400', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('pb-400'); + }); + + it('should return paddingLeft classProps', () => { + const props: SpiritBoxProps = { + paddingLeft: 'space-400', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('pl-400'); + }); + + it('should return paddingRight classProps', () => { + const props: SpiritBoxProps = { + paddingRight: 'space-400', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('pr-400'); + }); + + it('should return responsive padding classProps', () => { + const props: SpiritBoxProps = { + padding: { mobile: 'space-400', tablet: 'space-500', desktop: 'space-600' }, + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('p-400 p-tablet-500 p-desktop-600'); + }); + + it('should return border radius classProps', () => { + const props: SpiritBoxProps = { + borderRadius: '200', + borderWidth: '100', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('border-basic rounded-200 border-100'); + }); + + it('should not return border radius classProps if border with is not set', () => { + const props: SpiritBoxProps = { + borderRadius: '200', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).not.toBe('rounded-200'); + }); + + it('should return border color classProps', () => { + const props: SpiritBoxProps = { + borderColor: 'basic', + borderWidth: '100', + }; + const { result } = renderHook(() => useBoxStyleProps(props)); + + expect(result.current.classProps).toBe('border-basic border-100'); + }); +}); diff --git a/packages/web-react/src/components/Box/__tests__/useCardStyleProps.test.ts b/packages/web-react/src/components/Box/__tests__/useCardStyleProps.test.ts deleted file mode 100644 index ae2e00378e..0000000000 --- a/packages/web-react/src/components/Box/__tests__/useCardStyleProps.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { renderHook } from '@testing-library/react'; -import { UseCardStyleProps, useCardStyleProps } from '../useCardStyleProps'; -import { defaultExpectedClasses, textPropsDataProvider } from './__fixtures__/CardStylePropsDataProvider'; - -describe('useCardStyleProps', () => { - it('should return defaults', () => { - const props: UseCardStyleProps = {}; - const { result } = renderHook(() => useCardStyleProps(props)); - - expect(result.current.classProps).toEqual(defaultExpectedClasses); - }); - - it.each(textPropsDataProvider)('should %s', ({ props, expected }) => { - const { result } = renderHook(() => useCardStyleProps(props)); - - expect(result.current.classProps).toEqual(expected.classProps); - }); -}); diff --git a/packages/web-react/src/components/Box/useBoxStyleProps.ts b/packages/web-react/src/components/Box/useBoxStyleProps.ts index 82c761288c..4aebde68d0 100644 --- a/packages/web-react/src/components/Box/useBoxStyleProps.ts +++ b/packages/web-react/src/components/Box/useBoxStyleProps.ts @@ -1,7 +1,6 @@ import classNames from 'classnames'; import { CSSProperties, ElementType } from 'react'; import { BorderColors } from '../../constants'; -import { useClassNamePrefix } from '../../hooks'; import { BreakpointToken, SpaceToken, SpiritBoxProps } from '../../types'; interface BoxCSSProperties extends CSSProperties { @@ -53,8 +52,6 @@ export const useBoxStyleProps = ( paddingY, ...restProps } = props || {}; - const boxClass = useClassNamePrefix('Box'); - const boxStyle: BoxCSSProperties = {}; const boxBackgroundColor = backgroundColor ? `bg-${backgroundColor}` : ''; @@ -80,14 +77,7 @@ export const useBoxStyleProps = ( ...generateResponsiveUtilityClasses('py', paddingY), ]; - const boxClasses = classNames( - boxClass, - boxBackgroundColor, - boxBorderColor, - boxBorderRadius, - boxBorderWidth, - ...paddingClasses, - ); + const boxClasses = classNames(boxBackgroundColor, boxBorderColor, boxBorderRadius, boxBorderWidth, ...paddingClasses); return { classProps: boxClasses,