diff --git a/packages/css/src/components/breakout/README.md b/packages/css/src/components/breakout-spotlight/README.md similarity index 85% rename from packages/css/src/components/breakout/README.md rename to packages/css/src/components/breakout-spotlight/README.md index 8b9dc76a92..42498249a2 100644 --- a/packages/css/src/components/breakout/README.md +++ b/packages/css/src/components/breakout-spotlight/README.md @@ -1,5 +1,5 @@ -# Breakout +# Breakout Spotlight A composition that lets a figure – e.g. an image, video or map – break out of a Spotlight. diff --git a/packages/css/src/components/breakout/breakout.scss b/packages/css/src/components/breakout-spotlight/breakout-spotlight.scss similarity index 54% rename from packages/css/src/components/breakout/breakout.scss rename to packages/css/src/components/breakout-spotlight/breakout-spotlight.scss index fb27c4bccb..8fb193641f 100644 --- a/packages/css/src/components/breakout/breakout.scss +++ b/packages/css/src/components/breakout-spotlight/breakout-spotlight.scss @@ -7,88 +7,88 @@ @import "../grid/grid"; @import "../grid/mixins"; -$ams-breakout-row-span-max: 4; +$ams-breakout-spotlight-row-span-max: 4; -.ams-breakout { +.ams-breakout-spotlight { @include ams-grid; } // Grid gap -.ams-breakout--gap-vertical--none { +.ams-breakout-spotlight--gap-vertical--none { @include ams-grid--gap-vertical--none; } -.ams-breakout--gap-vertical--small { +.ams-breakout-spotlight--gap-vertical--small { @include ams-grid--gap-vertical--small; } -.ams-breakout--gap-vertical--large { +.ams-breakout-spotlight--gap-vertical--large { @include ams-grid--gap-vertical--large; } // Grid padding -.ams-breakout--padding-bottom--small { +.ams-breakout-spotlight--padding-bottom--small { @include ams-grid--padding-bottom--small; } -.ams-breakout--padding-bottom--medium { +.ams-breakout-spotlight--padding-bottom--medium { @include ams-grid--padding-bottom--medium; } -.ams-breakout--padding-bottom--large { +.ams-breakout-spotlight--padding-bottom--large { @include ams-grid--padding-bottom--large; } -.ams-breakout--padding-top--small { +.ams-breakout-spotlight--padding-top--small { @include ams-grid--padding-top--small; } -.ams-breakout--padding-top--medium { +.ams-breakout-spotlight--padding-top--medium { @include ams-grid--padding-top--medium; } -.ams-breakout--padding-top--large { +.ams-breakout-spotlight--padding-top--large { @include ams-grid--padding-top--large; } -.ams-breakout--padding-vertical--small { +.ams-breakout-spotlight--padding-vertical--small { @include ams-grid--padding-vertical--small; } -.ams-breakout--padding-vertical--medium { +.ams-breakout-spotlight--padding-vertical--medium { @include ams-grid--padding-vertical--medium; } -.ams-breakout--padding-vertical--large { +.ams-breakout-spotlight--padding-vertical--large { @include ams-grid--padding-vertical--large; } // Column span // The order of these declaration blocks ensures the intended specificity. -.ams-breakout__cell--col-span-all { +.ams-breakout-spotlight__cell--col-span-all { @include ams-grid__cell--span-all; } @for $i from 1 through $ams-grid-column-count { - .ams-breakout__cell--col-span-#{$i} { + .ams-breakout-spotlight__cell--col-span-#{$i} { @include ams-grid__cell--span($i); } - .ams-breakout__cell--col-start-#{$i} { + .ams-breakout-spotlight__cell--col-start-#{$i} { @include ams-grid__cell--start($i); } } @media screen and (min-width: $ams-breakpoint-medium) { @for $i from 1 through $ams-grid-column-count { - .ams-breakout__cell--col-span-#{$i}-medium { + .ams-breakout-spotlight__cell--col-span-#{$i}-medium { @include ams-grid__cell--span-medium($i); } - .ams-breakout__cell--col-start-#{$i}-medium { + .ams-breakout-spotlight__cell--col-start-#{$i}-medium { @include ams-grid__cell--start-medium($i); } } @@ -96,11 +96,11 @@ $ams-breakout-row-span-max: 4; @media screen and (min-width: $ams-breakpoint-wide) { @for $i from 1 through $ams-grid-column-count { - .ams-breakout__cell--col-span-#{$i}-wide { + .ams-breakout-spotlight__cell--col-span-#{$i}-wide { @include ams-grid__cell--span-wide($i); } - .ams-breakout__cell--col-start-#{$i}-wide { + .ams-breakout-spotlight__cell--col-start-#{$i}-wide { @include ams-grid__cell--start-wide($i); } } @@ -108,55 +108,55 @@ $ams-breakout-row-span-max: 4; // Has content -.ams-breakout__cell--has-figure { +.ams-breakout-spotlight__cell--has-figure { align-self: end; } -.ams-breakout__cell--has-spotlight { +.ams-breakout-spotlight__cell--has-spotlight { display: grid; /* Stretches the empty Spotlight vertically. */ margin-block: calc(var(--ams-space-grid-md) * -1); margin-inline: calc(var(--ams-space-grid-lg) * -1); - .ams-breakout--gap-vertical--small > & { + .ams-breakout-spotlight--gap-vertical--small > & { margin-block: calc(var(--ams-space-grid-sm) * -1); } - .ams-breakout--gap-vertical--large > & { + .ams-breakout-spotlight--gap-vertical--large > & { margin-block: calc(var(--ams-space-grid-lg) * -1); } } // Row span -@for $i from 1 through $ams-breakout-row-span-max { - .ams-breakout__cell--row-span-#{$i} { +@for $i from 1 through $ams-breakout-spotlight-row-span-max { + .ams-breakout-spotlight__cell--row-span-#{$i} { grid-row-end: span $i; } - .ams-breakout__cell--row-start-#{$i} { + .ams-breakout-spotlight__cell--row-start-#{$i} { grid-row-start: $i; } } @media screen and (min-width: $ams-breakpoint-medium) { - @for $i from 1 through $ams-breakout-row-span-max { - .ams-breakout__cell--row-span-#{$i}-medium { + @for $i from 1 through $ams-breakout-spotlight-row-span-max { + .ams-breakout-spotlight__cell--row-span-#{$i}-medium { grid-row-end: span $i; } - .ams-breakout__cell--row-start-#{$i}-medium { + .ams-breakout-spotlight__cell--row-start-#{$i}-medium { grid-row-start: $i; } } } @media screen and (min-width: $ams-breakpoint-wide) { - @for $i from 1 through $ams-breakout-row-span-max { - .ams-breakout__cell--row-span-#{$i}-wide { + @for $i from 1 through $ams-breakout-spotlight-row-span-max { + .ams-breakout-spotlight__cell--row-span-#{$i}-wide { grid-row-end: span $i; } - .ams-breakout__cell--row-start-#{$i}-wide { + .ams-breakout-spotlight__cell--row-start-#{$i}-wide { grid-row-start: $i; } } diff --git a/packages/css/src/components/index.scss b/packages/css/src/components/index.scss index 995f0179fe..9332e81ca5 100644 --- a/packages/css/src/components/index.scss +++ b/packages/css/src/components/index.scss @@ -5,7 +5,7 @@ /* Append here */ @import "./action-group/action-group"; -@import "./breakout/breakout"; +@import "./breakout-spotlight/breakout-spotlight"; @import "./hint/hint"; @import "./password-input/password-input"; @import "./form-error-list/form-error-list"; diff --git a/packages/react/src/Breakout/Breakout.tsx b/packages/react/src/Breakout/Breakout.tsx deleted file mode 100644 index cf670797dd..0000000000 --- a/packages/react/src/Breakout/Breakout.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @license EUPL-1.2+ - * Copyright Gemeente Amsterdam - */ - -import clsx from 'clsx' -import { forwardRef } from 'react' -import type { ForwardedRef } from 'react' -import { BreakoutCell } from './BreakoutCell' -import type { GridProps } from '../Grid' -import { paddingClasses } from '../Grid/paddingClasses' - -export type BreakoutRowNumber = 1 | 2 | 3 | 4 -export type BreakoutRowNumbers = { narrow: BreakoutRowNumber; medium: BreakoutRowNumber; wide: BreakoutRowNumber } - -export type BreakoutProps = GridProps - -const BreakoutRoot = forwardRef( - ( - { children, className, gapVertical, paddingBottom, paddingTop, paddingVertical, ...restProps }: BreakoutProps, - ref: ForwardedRef, - ) => ( -
- {children} -
- ), -) - -BreakoutRoot.displayName = 'Breakout' - -export const Breakout = Object.assign(BreakoutRoot, { Cell: BreakoutCell }) diff --git a/packages/react/src/Breakout/BreakoutCell.test.tsx b/packages/react/src/Breakout/BreakoutCell.test.tsx deleted file mode 100644 index 116e34c3b4..0000000000 --- a/packages/react/src/Breakout/BreakoutCell.test.tsx +++ /dev/null @@ -1,199 +0,0 @@ -import { render, screen } from '@testing-library/react' -import { createRef } from 'react' -import { Breakout } from './Breakout' -import '@testing-library/jest-dom' - -describe('Breakout cell', () => { - it('renders', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toBeInTheDocument() - expect(component).toBeVisible() - }) - - it('renders a design system BEM class name', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass('ams-breakout__cell') - }) - - it('renders an additional class name', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass('ams-breakout__cell extra') - }) - - it('supports ForwardRef in React', () => { - const ref = createRef() - - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(ref.current).toBe(component) - }) - - it('renders no class names for undefined values for colStart and colSpan', () => { - const { container } = render() - - const elementWithColSpanClass = container.querySelector('[class*="ams-breakout__cell--col-span"]') - const elementWithColStartClass = container.querySelector('[class*="ams-breakout__cell--col-start"]') - const elementWithRowSpanClass = container.querySelector('[class*="ams-breakout__cell--row-span"]') - const elementWithRowStartClass = container.querySelector('[class*="ams-breakout__cell--row-start"]') - - expect(elementWithColSpanClass).not.toBeInTheDocument() - expect(elementWithColStartClass).not.toBeInTheDocument() - expect(elementWithRowSpanClass).not.toBeInTheDocument() - expect(elementWithRowStartClass).not.toBeInTheDocument() - }) - - it('renders class names for single number values for colStart and colSpan', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass('ams-breakout__cell--col-span-4 ams-breakout__cell--col-start-2') - }) - - it('renders class names for a single number value for colStart', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass('ams-breakout__cell--col-span-8') - }) - - it('renders class names for a single number value for colSpan', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass('ams-breakout__cell--col-start-6') - }) - - it('renders class names for a single number for colSpan and an object for colStart', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass( - 'ams-breakout__cell--col-span-8 ams-breakout__cell--col-start-2 ams-breakout__cell--col-start-4-medium ams-breakout__cell--col-start-6-wide', - ) - }) - - it('renders class names for an object for colSpan and a single number for colStart', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass( - 'ams-breakout__cell--col-span-3 ams-breakout__cell--col-span-5-medium ams-breakout__cell--col-span-7-wide ams-breakout__cell--col-start-2', - ) - }) - - it('renders class names for an object for both colSpan and colStart', () => { - const { container } = render( - , - ) - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass( - 'ams-breakout__cell--col-span-2 ams-breakout__cell--col-span-4-medium ams-breakout__cell--col-span-6-wide ams-breakout__cell--col-start-1 ams-breakout__cell--col-start-3-medium ams-breakout__cell--col-start-5-wide', - ) - }) - - it('renders the correct class name for the “all” value of colSpan', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass('ams-breakout__cell--col-span-all') - }) - - it('renders class names for single number values for rowStart and rowSpan', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass('ams-breakout__cell--row-span-3 ams-breakout__cell--row-start-2') - }) - - it('renders class names for a single number value for rowStart', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass('ams-breakout__cell--row-start-4') - }) - - it('renders class names for a single number value for rowSpan', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass('ams-breakout__cell--row-span-2') - }) - - it('renders class names for a single number for rowSpan and an object for rowStart', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass( - 'ams-breakout__cell--row-span-3 ams-breakout__cell--row-start-1 ams-breakout__cell--row-start-2-medium ams-breakout__cell--row-start-3-wide', - ) - }) - - it('renders class names for an object for rowSpan and a single number for rowStart', () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass( - 'ams-breakout__cell--row-span-2 ams-breakout__cell--row-span-3-medium ams-breakout__cell--row-span-4-wide ams-breakout__cell--row-start-1', - ) - }) - - it('renders class names for an object for both rowSpan and rowStart', () => { - const { container } = render( - , - ) - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass( - 'ams-breakout__cell--row-span-2 ams-breakout__cell--row-span-3-medium ams-breakout__cell--row-span-4-wide ams-breakout__cell--row-start-1 ams-breakout__cell--row-start-2-medium ams-breakout__cell--row-start-3-wide', - ) - }) -}) - -it(`renders the correct class if it has a Figure`, () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass(`ams-breakout__cell--has-figure`) -}) - -it(`renders the correct class if it has a Spotlight`, () => { - const { container } = render() - - const component = container.querySelector(':only-child') - - expect(component).toHaveClass(`ams-breakout__cell--has-spotlight`) -}) - -it('renders a custom tag', () => { - render() - - const cell = screen.getByRole('article') - - expect(cell).toBeInTheDocument() -}) diff --git a/packages/react/src/Breakout/README.md b/packages/react/src/Breakout/README.md deleted file mode 100644 index 738ec650da..0000000000 --- a/packages/react/src/Breakout/README.md +++ /dev/null @@ -1,5 +0,0 @@ - - -# React Breakout component - -[Breakout documentation](../../../css/src/components/breakout/README.md) diff --git a/packages/react/src/Breakout/breakoutCellClasses.ts b/packages/react/src/Breakout/breakoutCellClasses.ts deleted file mode 100644 index 75bb0e92ed..0000000000 --- a/packages/react/src/Breakout/breakoutCellClasses.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @license EUPL-1.2+ - * Copyright Gemeente Amsterdam - */ - -import type { BreakoutCellProps } from './BreakoutCell' -import { addGridClass } from '../Grid/gridCellClasses' - -export const breakoutCellClasses = ( - colSpan?: BreakoutCellProps['colSpan'], - colStart?: BreakoutCellProps['colStart'], - rowSpan?: BreakoutCellProps['rowSpan'], - rowStart?: BreakoutCellProps['rowStart'], -): string[] => [ - ...addGridClass('ams-breakout__cell--col-span-', colSpan), - ...addGridClass('ams-breakout__cell--col-start-', colStart), - ...addGridClass('ams-breakout__cell--row-span-', rowSpan), - ...addGridClass('ams-breakout__cell--row-start-', rowStart), -] diff --git a/packages/react/src/Breakout/index.ts b/packages/react/src/Breakout/index.ts deleted file mode 100644 index a355f7189d..0000000000 --- a/packages/react/src/Breakout/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { Breakout } from './Breakout' -export type { BreakoutProps } from './Breakout' -export type { BreakoutCellProps } from './BreakoutCell' diff --git a/packages/react/src/Breakout/Breakout.test.tsx b/packages/react/src/BreakoutSpotlight/BreakoutSpotlight.test.tsx similarity index 54% rename from packages/react/src/Breakout/Breakout.test.tsx rename to packages/react/src/BreakoutSpotlight/BreakoutSpotlight.test.tsx index 88e0c1699f..939fe52119 100644 --- a/packages/react/src/Breakout/Breakout.test.tsx +++ b/packages/react/src/BreakoutSpotlight/BreakoutSpotlight.test.tsx @@ -1,14 +1,14 @@ import { render } from '@testing-library/react' import { createRef } from 'react' -import { Breakout } from './Breakout' +import { BreakoutSpotlight } from './BreakoutSpotlight' import type { GridPaddingSize } from '../Grid/Grid' import '@testing-library/jest-dom' const paddingSizes = ['small', 'medium', 'large'] -describe('Breakout', () => { +describe('BreakoutSpotlight', () => { it('renders', () => { - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') @@ -17,79 +17,79 @@ describe('Breakout', () => { }) it('renders a design system BEM class name', () => { - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') - expect(component).toHaveClass('ams-breakout') + expect(component).toHaveClass('ams-breakout-spotlight') }) it('renders an additional class name', () => { - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') - expect(component).toHaveClass('ams-breakout extra') + expect(component).toHaveClass('ams-breakout-spotlight extra') }) it('renders the correct class name for a zero gap', () => { - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') - expect(component).toHaveClass('ams-breakout--gap-vertical--none') + expect(component).toHaveClass('ams-breakout-spotlight--gap-vertical--none') }) it(`renders the correct class name for a small gap`, () => { - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') - expect(component).toHaveClass('ams-breakout--gap-vertical--small') + expect(component).toHaveClass('ams-breakout-spotlight--gap-vertical--small') }) it(`renders the correct class name for a large gap`, () => { - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') - expect(component).toHaveClass('ams-breakout--gap-vertical--large') + expect(component).toHaveClass('ams-breakout-spotlight--gap-vertical--large') }) paddingSizes.forEach((size) => { it(`renders the correct class name for a ${size} bottom padding`, () => { - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') - expect(component).toHaveClass(`ams-breakout--padding-bottom--${size}`) + expect(component).toHaveClass(`ams-breakout-spotlight--padding-bottom--${size}`) }) }) paddingSizes.forEach((size) => { it(`renders the correct class name for a ${size} top padding`, () => { - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') - expect(component).toHaveClass(`ams-breakout--padding-top--${size}`) + expect(component).toHaveClass(`ams-breakout-spotlight--padding-top--${size}`) }) }) paddingSizes.forEach((size) => { it(`renders the correct class name for a ${size} vertical padding`, () => { - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') - expect(component).toHaveClass(`ams-breakout--padding-vertical--${size}`) + expect(component).toHaveClass(`ams-breakout-spotlight--padding-vertical--${size}`) }) }) it('supports ForwardRef in React', () => { const ref = createRef() - const { container } = render() + const { container } = render() const component = container.querySelector(':only-child') diff --git a/packages/react/src/BreakoutSpotlight/BreakoutSpotlight.tsx b/packages/react/src/BreakoutSpotlight/BreakoutSpotlight.tsx new file mode 100644 index 0000000000..53627f308c --- /dev/null +++ b/packages/react/src/BreakoutSpotlight/BreakoutSpotlight.tsx @@ -0,0 +1,52 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +import clsx from 'clsx' +import { forwardRef } from 'react' +import type { ForwardedRef } from 'react' +import { BreakoutSpotlightCell } from './BreakoutSpotlightCell' +import type { GridProps } from '../Grid' +import { paddingClasses } from '../Grid/paddingClasses' + +export type BreakoutSpotlightRowNumber = 1 | 2 | 3 | 4 +export type BreakoutSpotlightRowNumbers = { + narrow: BreakoutSpotlightRowNumber + medium: BreakoutSpotlightRowNumber + wide: BreakoutSpotlightRowNumber +} + +export type BreakoutSpotlightProps = GridProps + +const BreakoutSpotlightRoot = forwardRef( + ( + { + children, + className, + gapVertical, + paddingBottom, + paddingTop, + paddingVertical, + ...restProps + }: BreakoutSpotlightProps, + ref: ForwardedRef, + ) => ( +
+ {children} +
+ ), +) + +BreakoutSpotlightRoot.displayName = 'BreakoutSpotlight' + +export const BreakoutSpotlight = Object.assign(BreakoutSpotlightRoot, { Cell: BreakoutSpotlightCell }) diff --git a/packages/react/src/BreakoutSpotlight/BreakoutSpotlightCell.test.tsx b/packages/react/src/BreakoutSpotlight/BreakoutSpotlightCell.test.tsx new file mode 100644 index 0000000000..e7e0f673cd --- /dev/null +++ b/packages/react/src/BreakoutSpotlight/BreakoutSpotlightCell.test.tsx @@ -0,0 +1,205 @@ +import { render, screen } from '@testing-library/react' +import { createRef } from 'react' +import { BreakoutSpotlight } from './BreakoutSpotlight' +import '@testing-library/jest-dom' + +describe('BreakoutSpotlight cell', () => { + it('renders', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toBeInTheDocument() + expect(component).toBeVisible() + }) + + it('renders a design system BEM class name', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-breakout-spotlight__cell') + }) + + it('renders an additional class name', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-breakout-spotlight__cell extra') + }) + + it('supports ForwardRef in React', () => { + const ref = createRef() + + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(ref.current).toBe(component) + }) + + it('renders no class names for undefined values for colStart and colSpan', () => { + const { container } = render() + + const elementWithColSpanClass = container.querySelector('[class*="ams-breakout-spotlight__cell--col-span"]') + const elementWithColStartClass = container.querySelector('[class*="ams-breakout-spotlight__cell--col-start"]') + const elementWithRowSpanClass = container.querySelector('[class*="ams-breakout-spotlight__cell--row-span"]') + const elementWithRowStartClass = container.querySelector('[class*="ams-breakout-spotlight__cell--row-start"]') + + expect(elementWithColSpanClass).not.toBeInTheDocument() + expect(elementWithColStartClass).not.toBeInTheDocument() + expect(elementWithRowSpanClass).not.toBeInTheDocument() + expect(elementWithRowStartClass).not.toBeInTheDocument() + }) + + it('renders class names for single number values for colStart and colSpan', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-breakout-spotlight__cell--col-span-4 ams-breakout-spotlight__cell--col-start-2') + }) + + it('renders class names for a single number value for colStart', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-breakout-spotlight__cell--col-span-8') + }) + + it('renders class names for a single number value for colSpan', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-breakout-spotlight__cell--col-start-6') + }) + + it('renders class names for a single number for colSpan and an object for colStart', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass( + 'ams-breakout-spotlight__cell--col-span-8 ams-breakout-spotlight__cell--col-start-2 ams-breakout-spotlight__cell--col-start-4-medium ams-breakout-spotlight__cell--col-start-6-wide', + ) + }) + + it('renders class names for an object for colSpan and a single number for colStart', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass( + 'ams-breakout-spotlight__cell--col-span-3 ams-breakout-spotlight__cell--col-span-5-medium ams-breakout-spotlight__cell--col-span-7-wide ams-breakout-spotlight__cell--col-start-2', + ) + }) + + it('renders class names for an object for both colSpan and colStart', () => { + const { container } = render( + , + ) + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass( + 'ams-breakout-spotlight__cell--col-span-2 ams-breakout-spotlight__cell--col-span-4-medium ams-breakout-spotlight__cell--col-span-6-wide ams-breakout-spotlight__cell--col-start-1 ams-breakout-spotlight__cell--col-start-3-medium ams-breakout-spotlight__cell--col-start-5-wide', + ) + }) + + it('renders the correct class name for the “all” value of colSpan', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-breakout-spotlight__cell--col-span-all') + }) + + it('renders class names for single number values for rowStart and rowSpan', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-breakout-spotlight__cell--row-span-3 ams-breakout-spotlight__cell--row-start-2') + }) + + it('renders class names for a single number value for rowStart', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-breakout-spotlight__cell--row-start-4') + }) + + it('renders class names for a single number value for rowSpan', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass('ams-breakout-spotlight__cell--row-span-2') + }) + + it('renders class names for a single number for rowSpan and an object for rowStart', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass( + 'ams-breakout-spotlight__cell--row-span-3 ams-breakout-spotlight__cell--row-start-1 ams-breakout-spotlight__cell--row-start-2-medium ams-breakout-spotlight__cell--row-start-3-wide', + ) + }) + + it('renders class names for an object for rowSpan and a single number for rowStart', () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass( + 'ams-breakout-spotlight__cell--row-span-2 ams-breakout-spotlight__cell--row-span-3-medium ams-breakout-spotlight__cell--row-span-4-wide ams-breakout-spotlight__cell--row-start-1', + ) + }) + + it('renders class names for an object for both rowSpan and rowStart', () => { + const { container } = render( + , + ) + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass( + 'ams-breakout-spotlight__cell--row-span-2 ams-breakout-spotlight__cell--row-span-3-medium ams-breakout-spotlight__cell--row-span-4-wide ams-breakout-spotlight__cell--row-start-1 ams-breakout-spotlight__cell--row-start-2-medium ams-breakout-spotlight__cell--row-start-3-wide', + ) + }) +}) + +it(`renders the correct class if it has a Figure`, () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass(`ams-breakout-spotlight__cell--has-figure`) +}) + +it(`renders the correct class if it has a Spotlight`, () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass(`ams-breakout-spotlight__cell--has-spotlight`) +}) + +it('renders a custom tag', () => { + render() + + const cell = screen.getByRole('article') + + expect(cell).toBeInTheDocument() +}) diff --git a/packages/react/src/Breakout/BreakoutCell.tsx b/packages/react/src/BreakoutSpotlight/BreakoutSpotlightCell.tsx similarity index 60% rename from packages/react/src/Breakout/BreakoutCell.tsx rename to packages/react/src/BreakoutSpotlight/BreakoutSpotlightCell.tsx index 76855d267b..b363491b89 100644 --- a/packages/react/src/Breakout/BreakoutCell.tsx +++ b/packages/react/src/BreakoutSpotlight/BreakoutSpotlightCell.tsx @@ -5,11 +5,11 @@ import clsx from 'clsx' import { forwardRef } from 'react' import type { HTMLAttributes, PropsWithChildren } from 'react' -import type { BreakoutRowNumber, BreakoutRowNumbers } from './Breakout' -import { breakoutCellClasses } from './breakoutCellClasses' +import type { BreakoutSpotlightRowNumber, BreakoutSpotlightRowNumbers } from './BreakoutSpotlight' +import { breakoutSpotlightCellClasses } from './breakoutSpotlightCellClasses' import type { GridColumnNumber, GridColumnNumbers } from '../Grid/Grid' -type BreakoutCellSpanAllProp = { +type BreakoutSpotlightCellSpanAllProp = { /** Lets the cell span the full width of all grid variants. */ colSpan: 'all' colStart?: never @@ -19,7 +19,7 @@ type BreakoutCellSpanAllProp = { has?: 'spotlight' } -type BreakoutCellSpanAndStartProps = { +type BreakoutSpotlightCellSpanAndStartProps = { /** The amount of grid columns the cell spans. */ colSpan?: 'all' | GridColumnNumber | GridColumnNumbers /** The index of the grid column the cell starts at. */ @@ -27,21 +27,21 @@ type BreakoutCellSpanAndStartProps = { has?: 'figure' } -type BreakoutCellRowSpanAndStartProps = { +type BreakoutSpotlightCellRowSpanAndStartProps = { /** The amount of grid rows the cell spans. */ - rowSpan?: BreakoutRowNumber | BreakoutRowNumbers + rowSpan?: BreakoutSpotlightRowNumber | BreakoutSpotlightRowNumbers /** The index of the grid row the cell starts at. */ - rowStart?: BreakoutRowNumber | BreakoutRowNumbers + rowStart?: BreakoutSpotlightRowNumber | BreakoutSpotlightRowNumbers } -export type BreakoutCellProps = { +export type BreakoutSpotlightCellProps = { /** The HTML element to use. */ as?: 'article' | 'div' | 'section' -} & (BreakoutCellSpanAllProp | BreakoutCellSpanAndStartProps) & - BreakoutCellRowSpanAndStartProps & +} & (BreakoutSpotlightCellSpanAllProp | BreakoutSpotlightCellSpanAndStartProps) & + BreakoutSpotlightCellRowSpanAndStartProps & PropsWithChildren> -export const BreakoutCell = forwardRef( +export const BreakoutSpotlightCell = forwardRef( ( { as: Tag = 'div', @@ -53,16 +53,16 @@ export const BreakoutCell = forwardRef( rowSpan, rowStart, ...restProps - }: BreakoutCellProps, + }: BreakoutSpotlightCellProps, ref: any, ) => ( @@ -71,4 +71,4 @@ export const BreakoutCell = forwardRef( ), ) -BreakoutCell.displayName = 'Breakout.Cell' +BreakoutSpotlightCell.displayName = 'BreakoutSpotlight.Cell' diff --git a/packages/react/src/BreakoutSpotlight/README.md b/packages/react/src/BreakoutSpotlight/README.md new file mode 100644 index 0000000000..b7e736df25 --- /dev/null +++ b/packages/react/src/BreakoutSpotlight/README.md @@ -0,0 +1,5 @@ + + +# React Breakout Spotlight component + +[Breakout Spotlight documentation](../../../css/src/components/breakout-spotlight/README.md) diff --git a/packages/react/src/BreakoutSpotlight/breakoutSpotlightCellClasses.ts b/packages/react/src/BreakoutSpotlight/breakoutSpotlightCellClasses.ts new file mode 100644 index 0000000000..47c4b21190 --- /dev/null +++ b/packages/react/src/BreakoutSpotlight/breakoutSpotlightCellClasses.ts @@ -0,0 +1,19 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +import type { BreakoutSpotlightCellProps } from './BreakoutSpotlightCell' +import { addGridClass } from '../Grid/gridCellClasses' + +export const breakoutSpotlightCellClasses = ( + colSpan?: BreakoutSpotlightCellProps['colSpan'], + colStart?: BreakoutSpotlightCellProps['colStart'], + rowSpan?: BreakoutSpotlightCellProps['rowSpan'], + rowStart?: BreakoutSpotlightCellProps['rowStart'], +): string[] => [ + ...addGridClass('ams-breakout-spotlight__cell--col-span-', colSpan), + ...addGridClass('ams-breakout-spotlight__cell--col-start-', colStart), + ...addGridClass('ams-breakout-spotlight__cell--row-span-', rowSpan), + ...addGridClass('ams-breakout-spotlight__cell--row-start-', rowStart), +] diff --git a/packages/react/src/BreakoutSpotlight/index.ts b/packages/react/src/BreakoutSpotlight/index.ts new file mode 100644 index 0000000000..0849f1120f --- /dev/null +++ b/packages/react/src/BreakoutSpotlight/index.ts @@ -0,0 +1,3 @@ +export { BreakoutSpotlight } from './BreakoutSpotlight' +export type { BreakoutSpotlightProps } from './BreakoutSpotlight' +export type { BreakoutSpotlightCellProps } from './BreakoutSpotlightCell' diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 5a1b28f7a6..ba28529ead 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -5,7 +5,7 @@ /* Append here */ export * from './ActionGroup' -export * from './Breakout' +export * from './BreakoutSpotlight' export * from './Hint' export * from './ImageSlider' export * from './PasswordInput' diff --git a/proprietary/tokens/src/components/ams/breakout.tokens.json b/proprietary/tokens/src/components/ams/breakout-spotlight.tokens.json similarity index 87% rename from proprietary/tokens/src/components/ams/breakout.tokens.json rename to proprietary/tokens/src/components/ams/breakout-spotlight.tokens.json index 117d2f1ce6..f50102509b 100644 --- a/proprietary/tokens/src/components/ams/breakout.tokens.json +++ b/proprietary/tokens/src/components/ams/breakout-spotlight.tokens.json @@ -1,6 +1,6 @@ { "ams": { - "breakout": { + "breakout-spotlight": { "row-gap": { "sm": { "value": "{ams.space.grid.sm}" }, "md": { "value": "{ams.space.grid.md}" }, diff --git a/storybook/src/components/Breakout/Breakout.docs.mdx b/storybook/src/components/BreakoutSpotlight/BreakoutSpotlight.docs.mdx similarity index 79% rename from storybook/src/components/Breakout/Breakout.docs.mdx rename to storybook/src/components/BreakoutSpotlight/BreakoutSpotlight.docs.mdx index 54ff6f86dc..7a6951f4a8 100644 --- a/storybook/src/components/Breakout/Breakout.docs.mdx +++ b/storybook/src/components/BreakoutSpotlight/BreakoutSpotlight.docs.mdx @@ -1,10 +1,10 @@ {/* @license CC0-1.0 */} import { Canvas, Controls, Markdown, Meta, Primary } from "@storybook/blocks"; -import * as BreakoutStories from "./Breakout.stories.tsx"; -import README from "../../../../packages/css/src/components/breakout/README.md?raw"; +import * as BreakoutSpotlightStories from "./BreakoutSpotlight.stories.tsx"; +import README from "../../../../packages/css/src/components/breakout-spotlight/README.md?raw"; - + {README} @@ -12,7 +12,7 @@ import README from "../../../../packages/css/src/components/breakout/README.md?r This component is an extension of `Grid`. It offers the same props, although `span` and `start` have been renamed to `colSpan` and `colStart`. -Additionally, `Breakout` allows cells to span multiple rows. +Additionally, `BreakoutSpotlight` allows cells to span multiple rows. The Cell containing the Spotlight must have `has="spotlight"` to extend to the gaps and margins around it. This prop can be used only on Cells that span all columns of the grid, so `span="all"` is required as well. @@ -34,4 +34,4 @@ On narrower screens, let the text move below the image. A large figure can be placed at the top of the Spotlight, with related text positioned underneath. - + diff --git a/storybook/src/components/Breakout/Breakout.stories.tsx b/storybook/src/components/BreakoutSpotlight/BreakoutSpotlight.stories.tsx similarity index 69% rename from storybook/src/components/Breakout/Breakout.stories.tsx rename to storybook/src/components/BreakoutSpotlight/BreakoutSpotlight.stories.tsx index 383261a874..b28fc9c624 100644 --- a/storybook/src/components/Breakout/Breakout.stories.tsx +++ b/storybook/src/components/BreakoutSpotlight/BreakoutSpotlight.stories.tsx @@ -4,12 +4,12 @@ */ import { AspectRatio, Image, Paragraph, Screen, Spotlight } from '@amsterdam/design-system-react' -import { Breakout } from '@amsterdam/design-system-react/src' +import { BreakoutSpotlight } from '@amsterdam/design-system-react/src' import { Meta, StoryObj } from '@storybook/react' const meta = { - title: 'Components/Layout/Breakout', - component: Breakout, + title: 'Components/Layout/Breakout Spotlight', + component: BreakoutSpotlight, decorators: [ (Story) => ( @@ -17,7 +17,7 @@ const meta = { ), ], -} satisfies Meta +} satisfies Meta export default meta @@ -26,10 +26,10 @@ type Story = StoryObj export const Default: Story = { args: { children: [ - + - , - , + Het doel van deze club is om ervoor te zorgen dat de Zuidas steeds duurzamer wordt. - , - , + - , + , ], }, } @@ -56,15 +56,15 @@ export const Default: Story = { export const VerticalLayout: Story = { args: { children: [ - + - , - + , + -
, - , + Daarna vraagt u de vergunning aan in hetzelfde formulier. Of doet u een gratis melding of vooraankondiging. - , + , ], }, }