From 2c364ed95a739e841deed3682d12bd1faf30e36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kry=C5=A1p=C3=ADn?= Date: Tue, 3 Dec 2024 18:08:45 +0100 Subject: [PATCH] Feat(web-react): Introduce isFluid prop to Container --- .../src/components/Container/Container.tsx | 20 +++++++------ .../src/components/Container/README.md | 17 +++++++++-- .../Container/__tests__/Container.test.tsx | 28 +++++++++++++++---- .../__tests__/useContainerStyleProps.test.ts | 19 +++++++++++++ .../Container/demo/ContainerFluid.tsx | 11 ++++++++ .../src/components/Container/demo/index.tsx | 4 +++ .../src/components/Container/index.ts | 1 + .../Container/stories/Container.stories.tsx | 7 +++++ .../Container/useContainerStyleProps.ts | 25 +++++++++++++++++ packages/web-react/src/types/container.ts | 7 +++++ packages/web-react/src/types/index.ts | 1 + 11 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 packages/web-react/src/components/Container/__tests__/useContainerStyleProps.test.ts create mode 100644 packages/web-react/src/components/Container/demo/ContainerFluid.tsx create mode 100644 packages/web-react/src/components/Container/useContainerStyleProps.ts create mode 100644 packages/web-react/src/types/container.ts diff --git a/packages/web-react/src/components/Container/Container.tsx b/packages/web-react/src/components/Container/Container.tsx index ae408d6271..f757c35d44 100644 --- a/packages/web-react/src/components/Container/Container.tsx +++ b/packages/web-react/src/components/Container/Container.tsx @@ -2,18 +2,22 @@ import classNames from 'classnames'; import React from 'react'; -import { useStyleProps } from '../../hooks/styleProps'; -import { useClassNamePrefix } from '../../hooks/useClassNamePrefix'; -import { ChildrenProps, StyleProps, TransferProps } from '../../types'; +import { useStyleProps } from '../../hooks'; +import { SpiritContainerProps } from '../../types'; +import { useContainerStyleProps } from './useContainerStyleProps'; -export interface ContainerProps extends ChildrenProps, StyleProps, TransferProps {} +const defaultProps: SpiritContainerProps = { + isFluid: false, +}; -const Container = ({ children, ...restProps }: ContainerProps): JSX.Element => { - const containerClass = useClassNamePrefix('Container'); - const { styleProps, props: otherProps } = useStyleProps(restProps); +const Container = (props: SpiritContainerProps): JSX.Element => { + const propsWithDefaults = { ...defaultProps, ...props }; + const { children, ...restProps } = propsWithDefaults; + const { classProps, props: modifiedProps } = useContainerStyleProps(restProps); + const { styleProps, props: otherProps } = useStyleProps(modifiedProps); return ( -
+
{children}
); diff --git a/packages/web-react/src/components/Container/README.md b/packages/web-react/src/components/Container/README.md index 67cc8cc966..a3ad560512 100644 --- a/packages/web-react/src/components/Container/README.md +++ b/packages/web-react/src/components/Container/README.md @@ -6,14 +6,27 @@ Container centers your content horizontally and sets its max-width with horizont Content ``` +## Fluid Container + +If you need a full-width container, you can use the `isFluid` prop. + +```jsx +Content +``` + ## API -The components accept [additional attributes][readme-additional-attributes]. +| Name | Type | Default | Required | Description | +| --------- | ------ | ------- | -------- | --------------------------- | +| `isFluid` | `bool` | `false` | ✕ | If true, Container is fluid | + +On top of the API options, the components accept [additional attributes][readme-additional-attributes]. If you need more control over the styling of a component, you can use [style props][readme-style-props] and [escape hatches][readme-escape-hatches]. -For detailed information see [Container](https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/src/scss/components/Container/README.md) component +For detailed information see [Container][web-container] component [readme-additional-attributes]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/README.md#additional-attributes [readme-escape-hatches]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/README.md#escape-hatches [readme-style-props]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/README.md#style-props +[web-container]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/src/scss/components/Container/README.md diff --git a/packages/web-react/src/components/Container/__tests__/Container.test.tsx b/packages/web-react/src/components/Container/__tests__/Container.test.tsx index 6f3003a04c..ce370e6850 100644 --- a/packages/web-react/src/components/Container/__tests__/Container.test.tsx +++ b/packages/web-react/src/components/Container/__tests__/Container.test.tsx @@ -1,4 +1,4 @@ -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import React from 'react'; import '@testing-library/jest-dom'; import { classNamePrefixProviderTest } from '../../../../tests/providerTests/classNamePrefixProviderTest'; @@ -7,16 +7,34 @@ import { stylePropsTest } from '../../../../tests/providerTests/stylePropsTest'; import Container from '../Container'; describe('Container', () => { + const text = 'Hello world'; + const testId = 'flex-test-id'; + classNamePrefixProviderTest(Container, 'Container'); stylePropsTest(Container); restPropsTest(Container, 'div'); - it('should render text children', () => { - const dom = render(Hello World); + it('should render', () => { + render({text}); + + expect(screen.getByText(text)).toBeInTheDocument(); + }); + + it('should render with correct class', () => { + render({text}); + + expect(screen.getByTestId(testId)).toHaveClass('Container'); + }); + + it('should render as fluid', () => { + render( + + {text} + , + ); - const element = dom.container.querySelector('div') as HTMLElement; - expect(element.textContent).toBe('Hello World'); + expect(screen.getByTestId(testId)).toHaveClass('Container Container--fluid'); }); }); diff --git a/packages/web-react/src/components/Container/__tests__/useContainerStyleProps.test.ts b/packages/web-react/src/components/Container/__tests__/useContainerStyleProps.test.ts new file mode 100644 index 0000000000..2b45240df9 --- /dev/null +++ b/packages/web-react/src/components/Container/__tests__/useContainerStyleProps.test.ts @@ -0,0 +1,19 @@ +import { renderHook } from '@testing-library/react'; +import { SpiritContainerProps } from '../../../types'; +import { useContainerStyleProps } from '../useContainerStyleProps'; + +describe('useContainerStyleProps', () => { + it('should return defaults', () => { + const props = {}; + const { result } = renderHook(() => useContainerStyleProps(props)); + + expect(result.current.classProps).toBe('Container'); + }); + + it('should return fluid', () => { + const props = { isFluid: true } as SpiritContainerProps; + const { result } = renderHook(() => useContainerStyleProps(props)); + + expect(result.current.classProps).toBe('Container Container--fluid'); + }); +}); diff --git a/packages/web-react/src/components/Container/demo/ContainerFluid.tsx b/packages/web-react/src/components/Container/demo/ContainerFluid.tsx new file mode 100644 index 0000000000..a8407f7556 --- /dev/null +++ b/packages/web-react/src/components/Container/demo/ContainerFluid.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import DocsBox from '../../../../docs/DocsBox'; +import Container from '../Container'; + +const ContainerFluid = () => ( + + Container + +); + +export default ContainerFluid; diff --git a/packages/web-react/src/components/Container/demo/index.tsx b/packages/web-react/src/components/Container/demo/index.tsx index 7a718f1bda..9107566581 100644 --- a/packages/web-react/src/components/Container/demo/index.tsx +++ b/packages/web-react/src/components/Container/demo/index.tsx @@ -2,11 +2,15 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import DocsSection from '../../../../docs/DocsSections'; import ContainerDefault from './ContainerDefault'; +import ContainerFluid from './ContainerFluid'; ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + + + , ); diff --git a/packages/web-react/src/components/Container/index.ts b/packages/web-react/src/components/Container/index.ts index 45a378bdec..af045a1f48 100644 --- a/packages/web-react/src/components/Container/index.ts +++ b/packages/web-react/src/components/Container/index.ts @@ -1,3 +1,4 @@ 'use client'; +export * from './useContainerStyleProps'; export { default as Container } from './Container'; diff --git a/packages/web-react/src/components/Container/stories/Container.stories.tsx b/packages/web-react/src/components/Container/stories/Container.stories.tsx index 5b93ae6fa2..43621da10e 100644 --- a/packages/web-react/src/components/Container/stories/Container.stories.tsx +++ b/packages/web-react/src/components/Container/stories/Container.stories.tsx @@ -17,9 +17,16 @@ const meta: Meta = { children: { control: 'object', }, + isFluid: { + control: 'boolean', + table: { + defaultValue: { summary: 'false' }, + }, + }, }, args: { children: Container, + isFluid: false, }, }; diff --git a/packages/web-react/src/components/Container/useContainerStyleProps.ts b/packages/web-react/src/components/Container/useContainerStyleProps.ts new file mode 100644 index 0000000000..768ef0f006 --- /dev/null +++ b/packages/web-react/src/components/Container/useContainerStyleProps.ts @@ -0,0 +1,25 @@ +import classNames from 'classnames'; +import { useClassNamePrefix } from '../../hooks'; +import { SpiritContainerProps, ContainerProps } from '../../types'; + +export interface ContainerStyles { + /** className props */ + classProps: string; + /** props to be passed to the element */ + props: ContainerProps; +} + +export function useContainerStyleProps(props: SpiritContainerProps): ContainerStyles { + const { isFluid, ...modifiedProps } = props; + + const containerClass = useClassNamePrefix('Container'); + const containerFluidClass = `${containerClass}--fluid`; + const classProps = classNames(containerClass, { + [containerFluidClass]: isFluid, + }); + + return { + classProps, + props: modifiedProps, + }; +} diff --git a/packages/web-react/src/types/container.ts b/packages/web-react/src/types/container.ts new file mode 100644 index 0000000000..64a9db1c06 --- /dev/null +++ b/packages/web-react/src/types/container.ts @@ -0,0 +1,7 @@ +import { ChildrenProps, StyleProps, TransferProps } from './shared'; + +export interface ContainerProps extends ChildrenProps, StyleProps, TransferProps {} + +export interface SpiritContainerProps extends ContainerProps { + isFluid?: boolean; +} diff --git a/packages/web-react/src/types/index.ts b/packages/web-react/src/types/index.ts index 55c79d6dc9..45c359fc65 100644 --- a/packages/web-react/src/types/index.ts +++ b/packages/web-react/src/types/index.ts @@ -5,6 +5,7 @@ export * from './breadcrumbs'; export * from './button'; export * from './checkbox'; export * from './collapse'; +export * from './container'; export * from './divider'; export * from './dropdown'; export * from './fieldGroup';