From a7605caf86185de71ffd25c343c466dd86cc8329 Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Sun, 21 Jul 2024 11:24:47 +0200 Subject: [PATCH 01/10] Add horizontal and vertical alignment options to Column Add horizontal and vertical alignment options to Column 2 --- packages/css/src/components/column/README.md | 2 +- .../css/src/components/column/column.scss | 32 +++++++ packages/react/src/Column/Column.tsx | 23 ++++- packages/react/src/common/layout.ts | 4 +- storybook/config/preview-body.html | 57 ++++++++++++ .../src/components/Column/Column.docs.mdx | 44 ++++++++-- .../src/components/Column/Column.stories.tsx | 86 +++++++++++++++---- storybook/src/components/Row/Row.stories.tsx | 10 ++- 8 files changed, 223 insertions(+), 35 deletions(-) diff --git a/packages/css/src/components/column/README.md b/packages/css/src/components/column/README.md index a23c8a5169..fa064b0233 100644 --- a/packages/css/src/components/column/README.md +++ b/packages/css/src/components/column/README.md @@ -2,4 +2,4 @@ # Column -Stacks its children vertically and adds a vertical gap between them. +Stacks its children vertically with gaps between them and offers alignment options. diff --git a/packages/css/src/components/column/column.scss b/packages/css/src/components/column/column.scss index 56599223b2..0d83e268d3 100644 --- a/packages/css/src/components/column/column.scss +++ b/packages/css/src/components/column/column.scss @@ -16,3 +16,35 @@ gap: var(--ams-column-gap-#{$size}); } } + +.ams-column--align-around { + justify-content: space-around; +} + +.ams-column--align-between { + justify-content: space-between; +} + +.ams-column--align-center { + justify-content: center; +} + +.ams-column--align-end { + justify-content: flex-end; +} + +.ams-column--align-evenly { + justify-content: space-evenly; +} + +.ams-column--align-horizontal-center { + align-items: center; +} + +.ams-column--align-horizontal-end { + align-items: flex-end; +} + +.ams-column--align-horizontal-start { + align-items: flex-start; +} diff --git a/packages/react/src/Column/Column.tsx b/packages/react/src/Column/Column.tsx index 2d55b452e6..66b105e1b5 100644 --- a/packages/react/src/Column/Column.tsx +++ b/packages/react/src/Column/Column.tsx @@ -6,22 +6,37 @@ import clsx from 'clsx' import { forwardRef } from 'react' import type { HTMLAttributes, PropsWithChildren } from 'react' +import type { CrossAlign, MainAlign } from '../common/layout' export const columnGapSizes: Array = ['none', 'extra-small', 'small', 'large', 'extra-large'] as const -type ColumnTag = 'article' | 'div' | 'section' type ColumnGap = (typeof columnGapSizes)[number] +type ColumnTag = 'article' | 'div' | 'section' export type ColumnProps = { + /** The vertical alignment of the items in the column. */ + align?: MainAlign + /** The horizontal alignment of the items in the column. */ + alignHorizontal?: Omit /** The HTML element to use. */ as?: ColumnTag - /** The amount of vertical space between items. */ + /** The amount of space between items. */ gap?: ColumnGap } & PropsWithChildren> export const Column = forwardRef( - ({ as: Tag = 'div', children, className, gap, ...restProps }: ColumnProps, ref: any) => ( - + ({ align, alignHorizontal, as: Tag = 'div', children, className, gap, ...restProps }: ColumnProps, ref: any) => ( + {children} ), diff --git a/packages/react/src/common/layout.ts b/packages/react/src/common/layout.ts index 033a6adf5b..48e8620cb7 100644 --- a/packages/react/src/common/layout.ts +++ b/packages/react/src/common/layout.ts @@ -1,5 +1,5 @@ -export const crossAlignOptions: Array = ['baseline', 'center', 'end', 'start'] as const +export const crossAlignOptions: Array = ['start', 'center', 'baseline', 'end'] as const export type CrossAlign = (typeof crossAlignOptions)[number] -export const mainAlignOptions: Array = ['around', 'between', 'center', 'end', 'evenly'] as const +export const mainAlignOptions: Array = ['center', 'end', 'between', 'around', 'evenly'] as const export type MainAlign = (typeof mainAlignOptions)[number] diff --git a/storybook/config/preview-body.html b/storybook/config/preview-body.html index 9debb3fd07..c38a6b9e79 100644 --- a/storybook/config/preview-body.html +++ b/storybook/config/preview-body.html @@ -1,4 +1,9 @@ diff --git a/storybook/src/components/Column/Column.docs.mdx b/storybook/src/components/Column/Column.docs.mdx index fdb5a262ea..db060fc8dd 100644 --- a/storybook/src/components/Column/Column.docs.mdx +++ b/storybook/src/components/Column/Column.docs.mdx @@ -8,15 +8,12 @@ import README from "../../../../packages/css/src/components/column/README.md?raw {README} -## Design - -The five [space](/docs/foundation-design-tokens-space--docs) sizes are available for the size of the gap. - ## How to Use -Wrap a Column around a set of components that need the same amount of white space between them. - -To add white space below a single element, you can alternatively use a utility class for bottom margins, e.g. `class="ams-mb--md"`. +- Wrap a Column around a set of elements that need the same amount of white space between them. +- The five sizes of [Component Space](/docs/foundation-design-tokens-space--docs) are available for the height of the gap. +- To add white space below a single element, you can add a [Margin Bottom](/docs/utilities-css-margin--docs) instead. +- Align the elements horizontally or vertically through the alignment props. ## Examples @@ -26,9 +23,40 @@ To add white space below a single element, you can alternatively use a utility c -### Use Another HTML Element +### Alignment + +Items in the column can be aligned vertically in several ways: + +- **Center**: center items within the column. +- **End**: align items to the bottom of the column – to the bottom. +- **Space Between**: distribute whitespace between items. +- **Space Around**: distribute whitespace around items. +- **Space Evenly**: distribute whitespace evenly around items. + +By default, items align to the **start** of the column – at the top. +This option has no class name or prop value. + +This example centers three items vertically. + + + +### Horizontal alignment + +Items in the column can be aligned horizontally in several ways: + +- **Start**: align items to the start of the column. This is the left side in left-to-right languages. +- **Center**: center items within the column. +- **End**: align items to the end of the column. This is the right side in left-to-right languages. +- **Start**: align items to the left of the column. + +This example centers three items horizontally. + + + +### Use another HTML element By default, a Column renders a `
`. Use the `as` prop to make your markup more semantic. +In this example, the Column uses a `
` element to group the heading and the cards. diff --git a/storybook/src/components/Column/Column.stories.tsx b/storybook/src/components/Column/Column.stories.tsx index d7f8782858..1bb9749041 100644 --- a/storybook/src/components/Column/Column.stories.tsx +++ b/storybook/src/components/Column/Column.stories.tsx @@ -4,25 +4,51 @@ */ import { Card, Column, Heading, Paragraph } from '@amsterdam/design-system-react/src' +import { crossAlignOptions, mainAlignOptions } from '@amsterdam/design-system-react/src/common/layout' import { Meta, StoryObj } from '@storybook/react' -const ThreeBoxes = Array.from(Array(3).keys()).map((i) => ( - - {i + 1} - -)) +const ThreeItems = [ +
, +
, +
, +] const meta = { title: 'Components/Layout/Column', component: Column, args: { - children: ThreeBoxes, + children: ThreeItems, + className: 'ams-docs-column', }, argTypes: { + align: { + control: { + type: 'radio', + labels: { undefined: 'start' }, + }, + options: [undefined, ...mainAlignOptions], + }, + alignHorizontal: { + control: { + type: 'radio', + labels: { undefined: 'stretch' }, + }, + options: [undefined, ...crossAlignOptions.filter((option) => option !== 'baseline')], + }, + className: { + table: { + disable: true, + }, + }, gap: { control: 'radio', options: ['extra-small', 'small', 'medium', 'large', 'extra-large'], }, + style: { + table: { + disable: true, + }, + }, }, } satisfies Meta @@ -32,34 +58,58 @@ type Story = StoryObj export const Default: Story = {} +export const Alignment: Story = { + args: { + align: 'center', + }, + argTypes: { + alignHorizontal: { table: { disable: true } }, + as: { table: { disable: true } }, + gap: { table: { disable: true } }, + }, +} + +export const HorizontalAlignment: Story = { + args: { + alignHorizontal: 'center', + }, + argTypes: { + align: { table: { disable: true } }, + as: { table: { disable: true } }, + gap: { table: { disable: true } }, + }, +} + export const CustomTagName: Story = { args: { as: 'section', children: [ + Zoekresultaten, - - - Nieuwe manieren om afval op te halen - - + + Nieuwe manieren om afval op te halen + Afvalboten, bakfietsen en ondergrondse containers. We experimenteren met nieuwe manieren om afval op te halen in het centrum. - Gepubliceerd: 1 juli 2023 , - - - Verlenging proef ophalen afval per boot - - + + Verlenging proef ophalen afval per boot + Een proef met het anders ophalen van afval. We halen vuilniszakken hier op met kleine wagentjes, kleine vuilniswagens en een afvalboot. - Gepubliceerd: 15 juni 2023 , ], + className: undefined, + style: undefined, + }, + argTypes: { + align: { table: { disable: true } }, + alignHorizontal: { table: { disable: true } }, + as: { table: { disable: true } }, }, } diff --git a/storybook/src/components/Row/Row.stories.tsx b/storybook/src/components/Row/Row.stories.tsx index b127e6b74a..23f91ca745 100644 --- a/storybook/src/components/Row/Row.stories.tsx +++ b/storybook/src/components/Row/Row.stories.tsx @@ -30,11 +30,17 @@ const meta = { }, argTypes: { align: { - control: 'radio', + control: { + type: 'radio', + labels: { undefined: 'start' }, + }, options: mainAlignOptions, }, alignVertical: { - control: 'radio', + control: { + type: 'radio', + labels: { undefined: 'stretch' }, + }, options: crossAlignOptions, }, gap: { From a2d8ce34dc4acfe5066311f120a73c3b3b227fe2 Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Sun, 21 Jul 2024 11:28:14 +0200 Subject: [PATCH 02/10] Use updated docs approaches in Row and Grid as well --- packages/css/src/components/row/README.md | 2 + packages/react/src/Row/Row.tsx | 2 +- storybook/config/preview-body.html | 12 --- .../src/components/Column/Column.stories.tsx | 1 - .../src/components/Grid/Grid.stories.tsx | 19 ++--- storybook/src/components/Row/Row.docs.mdx | 28 ++++--- storybook/src/components/Row/Row.stories.tsx | 78 ++++++++++++++----- .../src/components/Screen/Screen.stories.tsx | 4 +- 8 files changed, 88 insertions(+), 58 deletions(-) diff --git a/packages/css/src/components/row/README.md b/packages/css/src/components/row/README.md index 72bd3ba63b..4ef926bb02 100644 --- a/packages/css/src/components/row/README.md +++ b/packages/css/src/components/row/README.md @@ -1,3 +1,5 @@ # Row + +Stacks its children horizontally with gaps between them and offers alignment options. diff --git a/packages/react/src/Row/Row.tsx b/packages/react/src/Row/Row.tsx index de9de9842d..2ccd67fad6 100644 --- a/packages/react/src/Row/Row.tsx +++ b/packages/react/src/Row/Row.tsx @@ -20,7 +20,7 @@ export type RowProps = { alignVertical?: CrossAlign /** The HTML element to use. */ as?: RowTag - /** The amount of vertical space between items. */ + /** The amount of space between items. */ gap?: RowGap /** Whether items of the row can wrap onto multiple lines. */ wrap?: boolean diff --git a/storybook/config/preview-body.html b/storybook/config/preview-body.html index c38a6b9e79..3745323c6d 100644 --- a/storybook/config/preview-body.html +++ b/storybook/config/preview-body.html @@ -38,18 +38,6 @@ width: fit-content; } - .ams-docs-paragraph { - font-family: "Amsterdam Sans", sans-serif; - font-size: 1rem; - line-height: 1.5; - } - - .ams-docs-pink-box { - background-color: rgba(229, 0, 130, 25%); /* stylelint-disable-line color-function-notation */ - padding-block: 2rem; - text-align: center; - } - .ams-docs-card { border: 0.0625rem solid hotpink; display: flex; diff --git a/storybook/src/components/Column/Column.stories.tsx b/storybook/src/components/Column/Column.stories.tsx index 1bb9749041..ec3bea79c2 100644 --- a/storybook/src/components/Column/Column.stories.tsx +++ b/storybook/src/components/Column/Column.stories.tsx @@ -105,7 +105,6 @@ export const CustomTagName: Story = { , ], className: undefined, - style: undefined, }, argTypes: { align: { table: { disable: true } }, diff --git a/storybook/src/components/Grid/Grid.stories.tsx b/storybook/src/components/Grid/Grid.stories.tsx index d25052bb18..770ec9d304 100644 --- a/storybook/src/components/Grid/Grid.stories.tsx +++ b/storybook/src/components/Grid/Grid.stories.tsx @@ -10,6 +10,9 @@ import { Meta, StoryObj } from '@storybook/react' const meta = { title: 'Components/Layout/Grid', component: Grid, + args: { + className: 'ams-docs-grid', + }, argTypes: { gapVertical: { control: { @@ -86,7 +89,7 @@ const CellStoryTemplate: CellStory = { render: ({ children, ...args }) => {children}, } -const TwelveGridCells = Array.from(Array(12).keys()).map((i) => ) +const TwelveGridCells = Array.from(Array(12).keys()).map((i) => ) export const Default: Story = { ...StoryTemplate, @@ -106,7 +109,7 @@ export const VerticalSpace: Story = { export const VerticalGap: Story = { ...StoryTemplate, args: { - children: Array.from(Array(6).keys()).map((i) => ), + children: Array.from(Array(6).keys()).map((i) => ), gapVertical: 'small', }, } @@ -114,7 +117,7 @@ export const VerticalGap: Story = { export const SpanMultipleColumns: CellStory = { ...CellStoryTemplate, args: { - children:

Deze cel beslaat 4 kolommen.

, + children:
, span: 4, }, } @@ -122,7 +125,7 @@ export const SpanMultipleColumns: CellStory = { export const ConfigureGridVariants: CellStory = { ...CellStoryTemplate, args: { - children:

Deze cel heeft 3 instellingen voor de breedte.

, + children:
, span: { narrow: 4, medium: 6, wide: 8 }, }, } @@ -130,9 +133,7 @@ export const ConfigureGridVariants: CellStory = { export const SpanAllColumns: CellStory = { ...CellStoryTemplate, args: { - children: ( -

Deze cel beslaat de volledige breedte van het grid.

- ), + children:
, span: 'all', }, } @@ -140,7 +141,7 @@ export const SpanAllColumns: CellStory = { export const StartPosition: CellStory = { ...CellStoryTemplate, args: { - children:

Deze cel start in kolom 2.

, + children:
, span: 3, start: 2, }, @@ -153,7 +154,7 @@ export const CustomTagName: CellStory = { }, render: ({ as }: GridCellProps) => ( -

Deze cel gebruikt het HTML-element `{as}`.

+
), } diff --git a/storybook/src/components/Row/Row.docs.mdx b/storybook/src/components/Row/Row.docs.mdx index b43e869bec..90d0de7af1 100644 --- a/storybook/src/components/Row/Row.docs.mdx +++ b/storybook/src/components/Row/Row.docs.mdx @@ -8,13 +8,11 @@ import README from "../../../../packages/css/src/components/row/README.md?raw"; {README} -## Design - -The five [space](/docs/foundation-design-tokens-space--docs) sizes are available for the width of the gap. - ## How to use -Wrap a Row around a set of components that need the same amount of white space between them. +- Wrap a Row around a set of elements that need the same amount of white space between them. +- The five sizes of [Component Space](/docs/foundation-design-tokens-space--docs) are available for the width of the gap. +- Align the elements horizontally or vertically through the alignment props. ## Examples @@ -24,7 +22,7 @@ Wrap a Row around a set of components that need the same amount of white space b -### Horizontal alignment +### Alignment Items in the row can be aligned horizontally in several ways: @@ -35,13 +33,13 @@ Items in the row can be aligned horizontally in several ways: - **Space Evenly**: distribute whitespace evenly around items. By default, items align to the **start** of the row – the left side in right-to-left languages. -This options has no class name or prop. +This option has no class name or prop value. We left out the word ‘space’ from the values for the alignment prop, e.g. `align="around"`. This example ensures that the spaces between and around all items are equally wide. - + #### End-align a single child @@ -49,12 +47,17 @@ To align a single component to the right (in left-to-right languages), wrap it i +For right-to-left languages, the end of the row is on the left side. + + + #### Align opposing texts This example shows a right-aligned link next to a heading. -Use `align="between"` to position them at opposing ends of the row. -Add `alignVertical="baseline"` to align them vertically to their common baseline. -Include `wrap` to allow the link to wrap to a new line if both components don’t fit on the same line. + +- Use `align="between"` to have all remaining space between them, which pushes the items to the opposing ends of the row. +- Add `alignVertical="baseline"` to align them vertically to their common baseline. +- Include `wrap` to allow the link to wrap to a new line if both components don’t fit on the same line. @@ -67,7 +70,8 @@ Items in the row can be aligned vertically in several ways: - **End**: align items to the bottom of the row. - **Baseline**: align items to their common text baseline. -By default, items **stretch** to the height of the row. This options has no class name or prop. +By default, items **stretch** to the height of the row. +This option has no class name or prop value. This example centers three items vertically. diff --git a/storybook/src/components/Row/Row.stories.tsx b/storybook/src/components/Row/Row.stories.tsx index 23f91ca745..32e90b788c 100644 --- a/storybook/src/components/Row/Row.stories.tsx +++ b/storybook/src/components/Row/Row.stories.tsx @@ -3,30 +3,22 @@ * Copyright Gemeente Amsterdam */ -import { Avatar, Button, Heading, Link, Paragraph, Row } from '@amsterdam/design-system-react/src' +import { Avatar, Heading, Link, Row } from '@amsterdam/design-system-react/src' import { crossAlignOptions, mainAlignOptions } from '@amsterdam/design-system-react/src/common/layout' import { Meta, StoryObj } from '@storybook/react' -const ThreeButtons = Array.from(Array(3).keys()).map((i) => ) -const ThreeParagraphs = [ - - One line - , - - Two -
- lines -
, - - One line - , +const ThreeItems = [ +
, +
, +
, ] const meta = { title: 'Components/Layout/Row', component: Row, args: { - children: ThreeButtons, + children: ThreeItems, + className: 'ams-docs-row', }, argTypes: { align: { @@ -34,14 +26,14 @@ const meta = { type: 'radio', labels: { undefined: 'start' }, }, - options: mainAlignOptions, + options: [undefined, ...mainAlignOptions], }, alignVertical: { control: { type: 'radio', labels: { undefined: 'stretch' }, }, - options: crossAlignOptions, + options: [undefined, ...crossAlignOptions.filter((option) => option !== 'baseline')], }, gap: { control: 'radio', @@ -56,18 +48,44 @@ type Story = StoryObj export const Default: Story = {} -export const HorizontalAlignment: Story = { +export const Alignment: Story = { args: { align: 'evenly', - children: ThreeParagraphs, + }, + argTypes: { + alignVertical: { table: { disable: true } }, + as: { table: { disable: true } }, + gap: { table: { disable: true } }, + wrap: { table: { disable: true } }, }, } export const EndAlignASingleChild: Story = { args: { align: 'end', + alignVertical: 'center', children: , }, + argTypes: { + alignVertical: { table: { disable: true } }, + as: { table: { disable: true } }, + gap: { table: { disable: true } }, + wrap: { table: { disable: true } }, + }, +} + +export const EndAlignASingleChildRtl: Story = { + args: { + align: 'end', + dir: 'rtl', + }, + argTypes: { + alignVertical: { table: { disable: true } }, + as: { table: { disable: true } }, + dir: { table: { disable: true } }, + gap: { table: { disable: true } }, + wrap: { table: { disable: true } }, + }, } export const AlignOpposingTexts: Story = { @@ -75,22 +93,40 @@ export const AlignOpposingTexts: Story = { align: 'between', alignVertical: 'baseline', children: [An example heading, An example link], + className: undefined, wrap: true, }, + argTypes: { + alignVertical: { table: { disable: true } }, + as: { table: { disable: true } }, + gap: { table: { disable: true } }, + wrap: { table: { disable: true } }, + }, } export const VerticalAlignment: Story = { args: { alignVertical: 'center', - children: ThreeParagraphs, + }, + argTypes: { + align: { table: { disable: true } }, + as: { table: { disable: true } }, + gap: { table: { disable: true } }, + wrap: { table: { disable: true } }, }, } export const Wrapping: Story = { args: { children: Array.from(Array(4).keys()).map((i) => ( - + )), wrap: true, }, + argTypes: { + align: { table: { disable: true } }, + alignVertical: { table: { disable: true } }, + as: { table: { disable: true } }, + gap: { table: { disable: true } }, + }, } diff --git a/storybook/src/components/Screen/Screen.stories.tsx b/storybook/src/components/Screen/Screen.stories.tsx index 3dac5062c1..23070d116e 100644 --- a/storybook/src/components/Screen/Screen.stories.tsx +++ b/storybook/src/components/Screen/Screen.stories.tsx @@ -19,12 +19,12 @@ export default meta type Story = StoryObj export const Default: Story = { - args: { children:

Ik pas in het scherm.

}, + args: { children:
Ik pas in het scherm.
}, } export const ExtraWide: Story = { args: { - children:

Ik pas in een extra breed scherm.

, + children:
Ik pas in een extra breed scherm.
, maxWidth: 'x-wide', }, } From 576d2a1c6d3b52c011324634f8fc4565426a5c07 Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Sun, 21 Jul 2024 22:46:18 +0200 Subject: [PATCH 03/10] Improve documentation and autocomplete for props --- packages/react/src/Column/Column.tsx | 22 +++++++++++---- packages/react/src/Row/Row.tsx | 27 ++++++++++++++----- packages/react/src/common/layout.ts | 4 +-- .../src/components/Column/Column.stories.tsx | 14 ++++------ storybook/src/components/Row/Row.stories.tsx | 10 +++++-- 5 files changed, 53 insertions(+), 24 deletions(-) diff --git a/packages/react/src/Column/Column.tsx b/packages/react/src/Column/Column.tsx index 66b105e1b5..ef78f0ed69 100644 --- a/packages/react/src/Column/Column.tsx +++ b/packages/react/src/Column/Column.tsx @@ -8,19 +8,31 @@ import { forwardRef } from 'react' import type { HTMLAttributes, PropsWithChildren } from 'react' import type { CrossAlign, MainAlign } from '../common/layout' -export const columnGapSizes: Array = ['none', 'extra-small', 'small', 'large', 'extra-large'] as const +export const columnGapSizes = ['none', 'extra-small', 'small', 'large', 'extra-large'] as const type ColumnGap = (typeof columnGapSizes)[number] type ColumnTag = 'article' | 'div' | 'section' export type ColumnProps = { - /** The vertical alignment of the items in the column. */ + /** + * The vertical alignment of the items in the column. + * @default start + */ align?: MainAlign - /** The horizontal alignment of the items in the column. */ + /** + * The horizontal alignment of the items in the column. + * @default stretch + */ alignHorizontal?: Omit - /** The HTML element to use. */ + /** + * The HTML element to use. + * @default div + */ as?: ColumnTag - /** The amount of space between items. */ + /** + * The amount of space between items. + * @default medium + */ gap?: ColumnGap } & PropsWithChildren> diff --git a/packages/react/src/Row/Row.tsx b/packages/react/src/Row/Row.tsx index 2ccd67fad6..446829799a 100644 --- a/packages/react/src/Row/Row.tsx +++ b/packages/react/src/Row/Row.tsx @@ -8,21 +8,36 @@ import { forwardRef } from 'react' import type { HTMLAttributes, PropsWithChildren } from 'react' import type { CrossAlign, MainAlign } from '../common/layout' -export const rowGapSizes: Array = ['none', 'extra-small', 'small', 'large', 'extra-large'] as const +export const rowGapSizes = ['none', 'extra-small', 'small', 'large', 'extra-large'] as const type RowGap = (typeof rowGapSizes)[number] type RowTag = 'article' | 'div' | 'section' export type RowProps = { - /** The horizontal alignment of the items in the row. */ + /** + * The horizontal alignment of the items in the row. + * @default start + */ align?: MainAlign - /** The vertical alignment of the items in the row. */ + /** + * The vertical alignment of the items in the row. + * @default stretch + */ alignVertical?: CrossAlign - /** The HTML element to use. */ + /** + * The HTML element to use. + * @default div + */ as?: RowTag - /** The amount of space between items. */ + /** + * The amount of space between items. + * @default medium + */ gap?: RowGap - /** Whether items of the row can wrap onto multiple lines. */ + /** + * Whether items of the row can wrap onto multiple lines. + * @default false + */ wrap?: boolean } & PropsWithChildren> diff --git a/packages/react/src/common/layout.ts b/packages/react/src/common/layout.ts index 48e8620cb7..3777814765 100644 --- a/packages/react/src/common/layout.ts +++ b/packages/react/src/common/layout.ts @@ -1,5 +1,5 @@ -export const crossAlignOptions: Array = ['start', 'center', 'baseline', 'end'] as const +export const crossAlignOptions = ['start', 'center', 'baseline', 'end'] as const export type CrossAlign = (typeof crossAlignOptions)[number] -export const mainAlignOptions: Array = ['center', 'end', 'between', 'around', 'evenly'] as const +export const mainAlignOptions = ['center', 'end', 'between', 'around', 'evenly'] as const export type MainAlign = (typeof mainAlignOptions)[number] diff --git a/storybook/src/components/Column/Column.stories.tsx b/storybook/src/components/Column/Column.stories.tsx index ec3bea79c2..ec72562eb8 100644 --- a/storybook/src/components/Column/Column.stories.tsx +++ b/storybook/src/components/Column/Column.stories.tsx @@ -36,18 +36,14 @@ const meta = { options: [undefined, ...crossAlignOptions.filter((option) => option !== 'baseline')], }, className: { - table: { - disable: true, - }, + table: { disable: true }, }, gap: { - control: 'radio', - options: ['extra-small', 'small', 'medium', 'large', 'extra-large'], - }, - style: { - table: { - disable: true, + control: { + type: 'radio', + labels: { undefined: 'medium' }, }, + options: ['none', 'extra-small', 'small', undefined, 'large', 'extra-large'], }, }, } satisfies Meta diff --git a/storybook/src/components/Row/Row.stories.tsx b/storybook/src/components/Row/Row.stories.tsx index 32e90b788c..865bebb7cf 100644 --- a/storybook/src/components/Row/Row.stories.tsx +++ b/storybook/src/components/Row/Row.stories.tsx @@ -35,9 +35,15 @@ const meta = { }, options: [undefined, ...crossAlignOptions.filter((option) => option !== 'baseline')], }, + className: { + table: { disable: true }, + }, gap: { - control: 'radio', - options: ['extra-small', 'small', 'medium', 'large', 'extra-large'], + control: { + type: 'radio', + labels: { undefined: 'medium' }, + }, + options: ['none', 'extra-small', 'small', undefined, 'large', 'extra-large'], }, }, } satisfies Meta From ce5b7905f24d00d903a5082a093df91e2dce6bfe Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Mon, 22 Jul 2024 11:28:42 +0200 Subject: [PATCH 04/10] Simplify documentation class names --- storybook/config/preview-body.html | 14 ++++---------- storybook/src/components/Column/Column.stories.tsx | 6 +++--- storybook/src/components/Grid/Grid.stories.tsx | 14 +++++++------- storybook/src/components/Row/Row.stories.tsx | 8 ++++---- storybook/src/components/Screen/Screen.stories.tsx | 4 ++-- 5 files changed, 20 insertions(+), 26 deletions(-) diff --git a/storybook/config/preview-body.html b/storybook/config/preview-body.html index 3745323c6d..5f4e3cdbec 100644 --- a/storybook/config/preview-body.html +++ b/storybook/config/preview-body.html @@ -74,18 +74,11 @@ min-block-size: 6rem; } - .ams-docs-row-child { - flex-basis: 8rem; - } - .ams-docs-grid { /* Todo columns background */ } - .ams-docs-child, - .ams-docs-column-child, - .ams-docs-row-child, - .ams-docs-grid-cell { + .ams-docs-item { background-color: var(--ams-docs-pink); border: thin dashed var(--ams-docs-grey); font-family: "Amsterdam Sans", sans-serif; @@ -97,11 +90,12 @@ text-align: center; } - .ams-docs-row-child { + .ams-docs-row > .ams-docs-item { + flex-basis: 8rem; padding-inline: 1.5rem; } - .ams-docs-column-child { + .ams-docs-column > .ams-docs-item { min-inline-size: 3rem; } diff --git a/storybook/src/components/Column/Column.stories.tsx b/storybook/src/components/Column/Column.stories.tsx index ec72562eb8..d95bd67a82 100644 --- a/storybook/src/components/Column/Column.stories.tsx +++ b/storybook/src/components/Column/Column.stories.tsx @@ -8,9 +8,9 @@ import { crossAlignOptions, mainAlignOptions } from '@amsterdam/design-system-re import { Meta, StoryObj } from '@storybook/react' const ThreeItems = [ -
, -
, -
, +
, +
, +
, ] const meta = { diff --git a/storybook/src/components/Grid/Grid.stories.tsx b/storybook/src/components/Grid/Grid.stories.tsx index 770ec9d304..97e05fa4f2 100644 --- a/storybook/src/components/Grid/Grid.stories.tsx +++ b/storybook/src/components/Grid/Grid.stories.tsx @@ -89,7 +89,7 @@ const CellStoryTemplate: CellStory = { render: ({ children, ...args }) => {children}, } -const TwelveGridCells = Array.from(Array(12).keys()).map((i) => ) +const TwelveGridCells = Array.from(Array(12).keys()).map((i) => ) export const Default: Story = { ...StoryTemplate, @@ -109,7 +109,7 @@ export const VerticalSpace: Story = { export const VerticalGap: Story = { ...StoryTemplate, args: { - children: Array.from(Array(6).keys()).map((i) => ), + children: Array.from(Array(6).keys()).map((i) => ), gapVertical: 'small', }, } @@ -117,7 +117,7 @@ export const VerticalGap: Story = { export const SpanMultipleColumns: CellStory = { ...CellStoryTemplate, args: { - children:
, + children:
, span: 4, }, } @@ -125,7 +125,7 @@ export const SpanMultipleColumns: CellStory = { export const ConfigureGridVariants: CellStory = { ...CellStoryTemplate, args: { - children:
, + children:
, span: { narrow: 4, medium: 6, wide: 8 }, }, } @@ -133,7 +133,7 @@ export const ConfigureGridVariants: CellStory = { export const SpanAllColumns: CellStory = { ...CellStoryTemplate, args: { - children:
, + children:
, span: 'all', }, } @@ -141,7 +141,7 @@ export const SpanAllColumns: CellStory = { export const StartPosition: CellStory = { ...CellStoryTemplate, args: { - children:
, + children:
, span: 3, start: 2, }, @@ -154,7 +154,7 @@ export const CustomTagName: CellStory = { }, render: ({ as }: GridCellProps) => ( -
+
), } diff --git a/storybook/src/components/Row/Row.stories.tsx b/storybook/src/components/Row/Row.stories.tsx index 865bebb7cf..b152105a96 100644 --- a/storybook/src/components/Row/Row.stories.tsx +++ b/storybook/src/components/Row/Row.stories.tsx @@ -8,9 +8,9 @@ import { crossAlignOptions, mainAlignOptions } from '@amsterdam/design-system-re import { Meta, StoryObj } from '@storybook/react' const ThreeItems = [ -
, -
, -
, +
, +
, +
, ] const meta = { @@ -125,7 +125,7 @@ export const VerticalAlignment: Story = { export const Wrapping: Story = { args: { children: Array.from(Array(4).keys()).map((i) => ( - + )), wrap: true, }, diff --git a/storybook/src/components/Screen/Screen.stories.tsx b/storybook/src/components/Screen/Screen.stories.tsx index 23070d116e..249551a9b9 100644 --- a/storybook/src/components/Screen/Screen.stories.tsx +++ b/storybook/src/components/Screen/Screen.stories.tsx @@ -19,12 +19,12 @@ export default meta type Story = StoryObj export const Default: Story = { - args: { children:
Ik pas in het scherm.
}, + args: { children:
Ik pas in het scherm.
}, } export const ExtraWide: Story = { args: { - children:
Ik pas in een extra breed scherm.
, + children:
Ik pas in een extra breed scherm.
, maxWidth: 'x-wide', }, } From c3e5525b8c8eba90356f5f7ab393678d75c9aeb7 Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Mon, 22 Jul 2024 12:05:46 +0200 Subject: [PATCH 05/10] Remove baseline cross-alignment for Columns cleanly --- packages/react/src/Column/Column.tsx | 4 ++-- packages/react/src/common/layout.ts | 5 +++++ storybook/src/components/Column/Column.stories.tsx | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/react/src/Column/Column.tsx b/packages/react/src/Column/Column.tsx index ef78f0ed69..fd0e7c584b 100644 --- a/packages/react/src/Column/Column.tsx +++ b/packages/react/src/Column/Column.tsx @@ -6,7 +6,7 @@ import clsx from 'clsx' import { forwardRef } from 'react' import type { HTMLAttributes, PropsWithChildren } from 'react' -import type { CrossAlign, MainAlign } from '../common/layout' +import type { CrossAlignForColumn, MainAlign } from '../common/layout' export const columnGapSizes = ['none', 'extra-small', 'small', 'large', 'extra-large'] as const @@ -23,7 +23,7 @@ export type ColumnProps = { * The horizontal alignment of the items in the column. * @default stretch */ - alignHorizontal?: Omit + alignHorizontal?: CrossAlignForColumn /** * The HTML element to use. * @default div diff --git a/packages/react/src/common/layout.ts b/packages/react/src/common/layout.ts index 3777814765..9b7a20f4f0 100644 --- a/packages/react/src/common/layout.ts +++ b/packages/react/src/common/layout.ts @@ -1,5 +1,10 @@ export const crossAlignOptions = ['start', 'center', 'baseline', 'end'] as const export type CrossAlign = (typeof crossAlignOptions)[number] +// Baseline alignment doesn’t make much sense in a column. +// This separate type for it clarifies its appearance in Storybook. +export const crossAlignOptionsForColumn = crossAlignOptions.filter((option) => option !== 'baseline') +export type CrossAlignForColumn = (typeof crossAlignOptionsForColumn)[number] + export const mainAlignOptions = ['center', 'end', 'between', 'around', 'evenly'] as const export type MainAlign = (typeof mainAlignOptions)[number] diff --git a/storybook/src/components/Column/Column.stories.tsx b/storybook/src/components/Column/Column.stories.tsx index d95bd67a82..3e61d2fbfc 100644 --- a/storybook/src/components/Column/Column.stories.tsx +++ b/storybook/src/components/Column/Column.stories.tsx @@ -4,7 +4,7 @@ */ import { Card, Column, Heading, Paragraph } from '@amsterdam/design-system-react/src' -import { crossAlignOptions, mainAlignOptions } from '@amsterdam/design-system-react/src/common/layout' +import { crossAlignOptionsForColumn, mainAlignOptions } from '@amsterdam/design-system-react/src/common/layout' import { Meta, StoryObj } from '@storybook/react' const ThreeItems = [ @@ -33,7 +33,7 @@ const meta = { type: 'radio', labels: { undefined: 'stretch' }, }, - options: [undefined, ...crossAlignOptions.filter((option) => option !== 'baseline')], + options: [undefined, ...crossAlignOptionsForColumn], }, className: { table: { disable: true }, From bb870b8fa8751836a4e242c9a9ff283d88a40a45 Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Mon, 22 Jul 2024 12:33:30 +0200 Subject: [PATCH 06/10] Fix duplicate class names --- storybook/src/components/Row/Row.stories.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storybook/src/components/Row/Row.stories.tsx b/storybook/src/components/Row/Row.stories.tsx index b152105a96..8127fb727b 100644 --- a/storybook/src/components/Row/Row.stories.tsx +++ b/storybook/src/components/Row/Row.stories.tsx @@ -8,9 +8,9 @@ import { crossAlignOptions, mainAlignOptions } from '@amsterdam/design-system-re import { Meta, StoryObj } from '@storybook/react' const ThreeItems = [ -
, -
, -
, +
, +
, +
, ] const meta = { From 6e683c01276c92326f02400fa9e26c6654f632d5 Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Wed, 24 Jul 2024 13:24:50 +0200 Subject: [PATCH 07/10] Remove erroneous line from docs Co-authored-by: Aram <37216945+alimpens@users.noreply.github.com> --- storybook/src/components/Column/Column.docs.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/storybook/src/components/Column/Column.docs.mdx b/storybook/src/components/Column/Column.docs.mdx index db060fc8dd..12141c341b 100644 --- a/storybook/src/components/Column/Column.docs.mdx +++ b/storybook/src/components/Column/Column.docs.mdx @@ -47,7 +47,6 @@ Items in the column can be aligned horizontally in several ways: - **Start**: align items to the start of the column. This is the left side in left-to-right languages. - **Center**: center items within the column. - **End**: align items to the end of the column. This is the right side in left-to-right languages. -- **Start**: align items to the left of the column. This example centers three items horizontally. From dfe886dd06ab4674d894e72443f29052a887ead8 Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Wed, 24 Jul 2024 13:26:39 +0200 Subject: [PATCH 08/10] Add tests for Column alignment props --- packages/react/src/Column/Column.test.tsx | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/react/src/Column/Column.test.tsx b/packages/react/src/Column/Column.test.tsx index 9ca308e23c..f81fb12027 100644 --- a/packages/react/src/Column/Column.test.tsx +++ b/packages/react/src/Column/Column.test.tsx @@ -1,6 +1,7 @@ import { render, screen } from '@testing-library/react' import { createRef } from 'react' import { Column, columnGapSizes } from './Column' +import { crossAlignOptionsForColumn, mainAlignOptions } from '../common/layout' import '@testing-library/jest-dom' describe('Column', () => { @@ -64,4 +65,26 @@ describe('Column', () => { expect(ref.current).toBe(component) }) + + describe('Alignment', () => { + mainAlignOptions.map((align) => + it(`sets the ‘${align}’ alignment`, () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass(`ams-column--align-${align}`) + }), + ) + + crossAlignOptionsForColumn.map((align) => + it(`sets the ‘${align}’ vertical alignment`, () => { + const { container } = render() + + const component = container.querySelector(':only-child') + + expect(component).toHaveClass(`ams-column--align-horizontal-${align}`) + }), + ) + }) }) From 6ad508656cecda270a658bdeb32782673a9c8030 Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Wed, 24 Jul 2024 13:30:27 +0200 Subject: [PATCH 09/10] =?UTF-8?q?Fix=20=E2=80=98align=20opposiing=20texts?= =?UTF-8?q?=E2=80=99=20story?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- storybook/src/components/Row/Row.stories.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storybook/src/components/Row/Row.stories.tsx b/storybook/src/components/Row/Row.stories.tsx index 8127fb727b..8150d23d2c 100644 --- a/storybook/src/components/Row/Row.stories.tsx +++ b/storybook/src/components/Row/Row.stories.tsx @@ -33,7 +33,7 @@ const meta = { type: 'radio', labels: { undefined: 'stretch' }, }, - options: [undefined, ...crossAlignOptions.filter((option) => option !== 'baseline')], + options: [undefined, ...crossAlignOptions], }, className: { table: { disable: true }, @@ -103,7 +103,6 @@ export const AlignOpposingTexts: Story = { wrap: true, }, argTypes: { - alignVertical: { table: { disable: true } }, as: { table: { disable: true } }, gap: { table: { disable: true } }, wrap: { table: { disable: true } }, From 9dfd35b6e08da61589d0e45ce1858c87153846a8 Mon Sep 17 00:00:00 2001 From: Vincent Smedinga Date: Wed, 24 Jul 2024 14:22:22 +0200 Subject: [PATCH 10/10] Display all props in all controls for now --- .../src/components/Column/Column.stories.tsx | 15 --------- storybook/src/components/Row/Row.stories.tsx | 33 ------------------- 2 files changed, 48 deletions(-) diff --git a/storybook/src/components/Column/Column.stories.tsx b/storybook/src/components/Column/Column.stories.tsx index 3e61d2fbfc..c7a2ef6cbc 100644 --- a/storybook/src/components/Column/Column.stories.tsx +++ b/storybook/src/components/Column/Column.stories.tsx @@ -58,22 +58,12 @@ export const Alignment: Story = { args: { align: 'center', }, - argTypes: { - alignHorizontal: { table: { disable: true } }, - as: { table: { disable: true } }, - gap: { table: { disable: true } }, - }, } export const HorizontalAlignment: Story = { args: { alignHorizontal: 'center', }, - argTypes: { - align: { table: { disable: true } }, - as: { table: { disable: true } }, - gap: { table: { disable: true } }, - }, } export const CustomTagName: Story = { @@ -102,9 +92,4 @@ export const CustomTagName: Story = { ], className: undefined, }, - argTypes: { - align: { table: { disable: true } }, - alignHorizontal: { table: { disable: true } }, - as: { table: { disable: true } }, - }, } diff --git a/storybook/src/components/Row/Row.stories.tsx b/storybook/src/components/Row/Row.stories.tsx index 8150d23d2c..38fea1c2b8 100644 --- a/storybook/src/components/Row/Row.stories.tsx +++ b/storybook/src/components/Row/Row.stories.tsx @@ -58,12 +58,6 @@ export const Alignment: Story = { args: { align: 'evenly', }, - argTypes: { - alignVertical: { table: { disable: true } }, - as: { table: { disable: true } }, - gap: { table: { disable: true } }, - wrap: { table: { disable: true } }, - }, } export const EndAlignASingleChild: Story = { @@ -72,12 +66,6 @@ export const EndAlignASingleChild: Story = { alignVertical: 'center', children: , }, - argTypes: { - alignVertical: { table: { disable: true } }, - as: { table: { disable: true } }, - gap: { table: { disable: true } }, - wrap: { table: { disable: true } }, - }, } export const EndAlignASingleChildRtl: Story = { @@ -86,11 +74,7 @@ export const EndAlignASingleChildRtl: Story = { dir: 'rtl', }, argTypes: { - alignVertical: { table: { disable: true } }, - as: { table: { disable: true } }, dir: { table: { disable: true } }, - gap: { table: { disable: true } }, - wrap: { table: { disable: true } }, }, } @@ -102,23 +86,12 @@ export const AlignOpposingTexts: Story = { className: undefined, wrap: true, }, - argTypes: { - as: { table: { disable: true } }, - gap: { table: { disable: true } }, - wrap: { table: { disable: true } }, - }, } export const VerticalAlignment: Story = { args: { alignVertical: 'center', }, - argTypes: { - align: { table: { disable: true } }, - as: { table: { disable: true } }, - gap: { table: { disable: true } }, - wrap: { table: { disable: true } }, - }, } export const Wrapping: Story = { @@ -128,10 +101,4 @@ export const Wrapping: Story = { )), wrap: true, }, - argTypes: { - align: { table: { disable: true } }, - alignVertical: { table: { disable: true } }, - as: { table: { disable: true } }, - gap: { table: { disable: true } }, - }, }