Skip to content

Commit

Permalink
fix: Correct layout of Description List if multiple terms share a des…
Browse files Browse the repository at this point in the history
…cription (#1763)

Co-authored-by: Vincent Smedinga <[email protected]>
  • Loading branch information
dlnr and VincentSmedinga authored Dec 13, 2024
1 parent adcd819 commit ca913af
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 7 deletions.
34 changes: 28 additions & 6 deletions packages/css/src/components/description-list/description-list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
margin-block: 0;
}

@mixin reset-dd {
margin-inline: 0;
}

.ams-description-list {
box-sizing: border-box;
color: var(--ams-description-list-color);
Expand All @@ -25,19 +29,23 @@
}

@media screen and (min-width: $ams-breakpoint-medium) {
.ams-description-list {
.ams-description-list,
.ams-description-list__section {
grid-template-columns: auto 1fr;
}

.ams-description-list--terms-width-sm {
.ams-description-list--terms-width-sm,
.ams-description-list--terms-width-sm .ams-description-list__section {
grid-template-columns: 1fr 4fr;
}

.ams-description-list--terms-width-md {
.ams-description-list--terms-width-md,
.ams-description-list--terms-width-md .ams-description-list__section {
grid-template-columns: 1fr 2fr;
}

.ams-description-list--terms-width-lg {
.ams-description-list--terms-width-lg,
.ams-description-list--terms-width-lg .ams-description-list__section {
grid-template-columns: 1fr 1fr;
}
}
Expand All @@ -54,8 +62,22 @@
}
}

@mixin reset-dd {
margin-inline: 0;
.ams-description-list__section {
@media screen and (min-width: $ams-breakpoint-medium) {
column-gap: var(--ams-description-list-column-gap);
display: grid;
grid-column: span 2;

> :only-of-type {
grid-row: 1 / 9;
}
}
}

// Aligns terms and descriptions in a section to the grid of the list.
// The extra class selector increases specificity to match earlier declarations.
.ams-description-list .ams-description-list__section {
grid-template-columns: subgrid;
}

.ams-description-list__description {
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/DescriptionList/DescriptionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import clsx from 'clsx'
import { forwardRef } from 'react'
import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react'
import { DescriptionListDescription } from './DescriptionListDescription'
import { DescriptionListSection } from './DescriptionListSection'
import { DescriptionListTerm } from './DescriptionListTerm'

export const descriptionListTermsWidths = ['sm', 'md', 'lg'] as const
Expand Down Expand Up @@ -42,6 +43,7 @@ const DescriptionListRoot = forwardRef(
DescriptionListRoot.displayName = 'DescriptionList'

export const DescriptionList = Object.assign(DescriptionListRoot, {
Term: DescriptionListTerm,
Description: DescriptionListDescription,
Section: DescriptionListSection,
Term: DescriptionListTerm,
})
41 changes: 41 additions & 0 deletions packages/react/src/DescriptionList/DescriptionListSection.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { render } from '@testing-library/react'
import { createRef } from 'react'
import { DescriptionList } from './DescriptionList'
import '@testing-library/jest-dom'

describe('Description List Section', () => {
it('renders', () => {
const { container } = render(<DescriptionList.Section>Test</DescriptionList.Section>)

const component = container.querySelector(':only-child')

expect(component).toBeInTheDocument()
expect(component).toBeVisible()
})

it('renders a design system BEM class name', () => {
const { container } = render(<DescriptionList.Section>Test</DescriptionList.Section>)

const component = container.querySelector(':only-child')

expect(component).toHaveClass('ams-description-list__section')
})

it('renders an additional class name', () => {
const { container } = render(<DescriptionList.Section className="extra">Test</DescriptionList.Section>)

const component = container.querySelector(':only-child')

expect(component).toHaveClass('ams-description-list__section extra')
})

it('supports ForwardRef in React', () => {
const ref = createRef<HTMLDivElement>()

const { container } = render(<DescriptionList.Section ref={ref}>Test</DescriptionList.Section>)

const component = container.querySelector(':only-child')

expect(ref.current).toBe(component)
})
})
20 changes: 20 additions & 0 deletions packages/react/src/DescriptionList/DescriptionListSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @license EUPL-1.2+
* Copyright Gemeente Amsterdam
*/

import clsx from 'clsx'
import { forwardRef } from 'react'
import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react'

export type DescriptionListSectionProps = PropsWithChildren<HTMLAttributes<HTMLDivElement>>

export const DescriptionListSection = forwardRef(
({ children, className, ...restProps }: DescriptionListSectionProps, ref: ForwardedRef<HTMLDivElement>) => (
<div {...restProps} ref={ref} className={clsx('ams-description-list__section', className)}>
{children}
</div>
),
)

DescriptionListSection.displayName = 'DescriptionList.Section'
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ A term may have multiple descriptions.

<Canvas of={DescriptionListStories.MultipleDescriptions} />

### Multiple terms

If multiple terms share a single description, group them in a `DescriptionList.Section` component to ensure proper grid layout.

<Canvas of={DescriptionListStories.MultipleTerms} />

### Rich description

A description can include rich content such as inline formatting, links, paragraphs, and even lists.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ export const MultipleDescriptions: Story = {
},
}

export const MultipleTerms: Story = {
args: {
termsWidth: 'md',
children: [
<DescriptionList.Term key={1}>Achternaam</DescriptionList.Term>,
<DescriptionList.Description key={2}>
De naam die een persoon van zijn of haar ouders krijgt
</DescriptionList.Description>,
<DescriptionList.Section key={3}>
<DescriptionList.Term>Voornaam</DescriptionList.Term>
<DescriptionList.Term>Roepnaam</DescriptionList.Term>
<DescriptionList.Term>Bijnaam</DescriptionList.Term>
<DescriptionList.Description>De naam waarmee een persoon wordt aangesproken</DescriptionList.Description>
</DescriptionList.Section>,
<DescriptionList.Term key={4}>Geboortedatum</DescriptionList.Term>,
<DescriptionList.Description key={5}>De datum waarop een persoon is geboren</DescriptionList.Description>,
],
},
}

export const RichDescription: Story = {
render: (args) => (
<DescriptionList {...args}>
Expand Down

0 comments on commit ca913af

Please sign in to comment.