diff --git a/packages/css/src/components/description-list/description-list.scss b/packages/css/src/components/description-list/description-list.scss
index b21b7cb7a4..ce8a678d3d 100644
--- a/packages/css/src/components/description-list/description-list.scss
+++ b/packages/css/src/components/description-list/description-list.scss
@@ -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);
@@ -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;
}
}
@@ -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 {
diff --git a/packages/react/src/DescriptionList/DescriptionList.tsx b/packages/react/src/DescriptionList/DescriptionList.tsx
index 7f63876075..ef7069c7b5 100644
--- a/packages/react/src/DescriptionList/DescriptionList.tsx
+++ b/packages/react/src/DescriptionList/DescriptionList.tsx
@@ -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
@@ -42,6 +43,7 @@ const DescriptionListRoot = forwardRef(
DescriptionListRoot.displayName = 'DescriptionList'
export const DescriptionList = Object.assign(DescriptionListRoot, {
- Term: DescriptionListTerm,
Description: DescriptionListDescription,
+ Section: DescriptionListSection,
+ Term: DescriptionListTerm,
})
diff --git a/packages/react/src/DescriptionList/DescriptionListSection.test.tsx b/packages/react/src/DescriptionList/DescriptionListSection.test.tsx
new file mode 100644
index 0000000000..bd12f1c927
--- /dev/null
+++ b/packages/react/src/DescriptionList/DescriptionListSection.test.tsx
@@ -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(Test)
+
+ const component = container.querySelector(':only-child')
+
+ expect(component).toBeInTheDocument()
+ expect(component).toBeVisible()
+ })
+
+ it('renders a design system BEM class name', () => {
+ const { container } = render(Test)
+
+ const component = container.querySelector(':only-child')
+
+ expect(component).toHaveClass('ams-description-list__section')
+ })
+
+ it('renders an additional class name', () => {
+ const { container } = render(Test)
+
+ const component = container.querySelector(':only-child')
+
+ expect(component).toHaveClass('ams-description-list__section extra')
+ })
+
+ it('supports ForwardRef in React', () => {
+ const ref = createRef()
+
+ const { container } = render(Test)
+
+ const component = container.querySelector(':only-child')
+
+ expect(ref.current).toBe(component)
+ })
+})
diff --git a/packages/react/src/DescriptionList/DescriptionListSection.tsx b/packages/react/src/DescriptionList/DescriptionListSection.tsx
new file mode 100644
index 0000000000..81b2771ded
--- /dev/null
+++ b/packages/react/src/DescriptionList/DescriptionListSection.tsx
@@ -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>
+
+export const DescriptionListSection = forwardRef(
+ ({ children, className, ...restProps }: DescriptionListSectionProps, ref: ForwardedRef) => (
+
+ {children}
+
+ ),
+)
+
+DescriptionListSection.displayName = 'DescriptionList.Section'
diff --git a/storybook/src/components/DescriptionList/DescriptionList.docs.mdx b/storybook/src/components/DescriptionList/DescriptionList.docs.mdx
index 88728215f8..4e34bfd49d 100644
--- a/storybook/src/components/DescriptionList/DescriptionList.docs.mdx
+++ b/storybook/src/components/DescriptionList/DescriptionList.docs.mdx
@@ -20,6 +20,12 @@ A term may have multiple descriptions.
+### Multiple terms
+
+If multiple terms share a single description, group them in a `DescriptionList.Section` component to ensure proper grid layout.
+
+
+
### Rich description
A description can include rich content such as inline formatting, links, paragraphs, and even lists.
diff --git a/storybook/src/components/DescriptionList/DescriptionList.stories.tsx b/storybook/src/components/DescriptionList/DescriptionList.stories.tsx
index 5430965a8c..81598822ec 100644
--- a/storybook/src/components/DescriptionList/DescriptionList.stories.tsx
+++ b/storybook/src/components/DescriptionList/DescriptionList.stories.tsx
@@ -54,6 +54,26 @@ export const MultipleDescriptions: Story = {
},
}
+export const MultipleTerms: Story = {
+ args: {
+ termsWidth: 'md',
+ children: [
+ Achternaam,
+
+ De naam die een persoon van zijn of haar ouders krijgt
+ ,
+
+ Voornaam
+ Roepnaam
+ Bijnaam
+ De naam waarmee een persoon wordt aangesproken
+ ,
+ Geboortedatum,
+ De datum waarop een persoon is geboren,
+ ],
+ },
+}
+
export const RichDescription: Story = {
render: (args) => (