Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Introduce tokens for stack spacing and Row component #1113

Merged
merged 10 commits into from
Mar 8, 2024
1 change: 1 addition & 0 deletions packages/css/src/components/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

/* Append here */
@import "./row/row";
@import "./radio/radio";
@import "./tabs/tabs";
@import "./text-area/text-area";
Expand Down
3 changes: 3 additions & 0 deletions packages/css/src/components/row/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<!-- @license CC0-1.0 -->

# Row
17 changes: 17 additions & 0 deletions packages/css/src/components/row/row.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @license EUPL-1.2+
* Copyright Gemeente Amsterdam
*/

@import "../../common/size";

.amsterdam-row {
display: flex;
flex-direction: row;
}

@each $size, $label in $amsterdam-sizes {
.amsterdam-row--#{$label} {
VincentSmedinga marked this conversation as resolved.
Show resolved Hide resolved
gap: var(--amsterdam-row-gap-#{$size});
}
}
5 changes: 5 additions & 0 deletions packages/react/src/Row/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!-- @license CC0-1.0 -->

# React Row component

[Row documentation](../../../css/src/components/row/README.md)
67 changes: 67 additions & 0 deletions packages/react/src/Row/Row.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { render, screen } from '@testing-library/react'
import { createRef } from 'react'
import { Row, rowGapSizes } from './Row'
import '@testing-library/jest-dom'

describe('Row', () => {
it('renders', () => {
const { container } = render(<Row />)

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

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

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

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

expect(component).toHaveClass('amsterdam-row--medium')
})

rowGapSizes.map((size) =>
it('renders with ${size} gap', () => {
const { container } = render(<Row gap={size} />)

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

expect(component).toHaveClass(`amsterdam-row--${size}`)
}),
)

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

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

expect(component).toHaveClass('amsterdam-row--medium extra')
})

it('renders with an article tag', () => {
render(<Row as="article" />)

const component = screen.getByRole('article')

expect(component).toBeInTheDocument()
})

it('renders with a section tag', () => {
const { container } = render(<Row as="section" />)

const component = container.querySelector('section')

expect(component).toBeInTheDocument()
})

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

const { container } = render(<Row ref={ref} />)

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

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

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

export const rowGapSizes: Array<string> = ['extra-small', 'small', 'medium', 'large', 'extra-large']

type RowTag = 'article' | 'div' | 'section'
type RowGap = (typeof rowGapSizes)[number]

export type RowProps = {
/** The element to render the row with. */
as?: RowTag
/** The amount of vertical space between the row’s children. */
gap?: RowGap
} & PropsWithChildren<HTMLAttributes<HTMLDivElement>>

export const Row = forwardRef(
(
{ as: Tag = 'div', children, className, gap = 'medium', ...restProps }: RowProps,
ref: ForwardedRef<HTMLDivElement>,
) => (
<Tag {...restProps} ref={ref} className={clsx('amsterdam-row', `amsterdam-row--${gap}`, className)}>
{children}
</Tag>
),
)

Row.displayName = 'Row'
2 changes: 2 additions & 0 deletions packages/react/src/Row/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { Row } from './Row'
export type { RowProps } from './Row'
1 change: 1 addition & 0 deletions packages/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

/* Append here */
export * from './Row'
export * from './Radio'
export * from './Tabs'
export * from './TextArea'
Expand Down
11 changes: 9 additions & 2 deletions proprietary/tokens/src/brand/amsterdam/space.tokens.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@
"xl": { "value": "clamp(2rem, calc(6.25vw + 0.75rem), 7rem)" }
},
"inside": {
"xs": { "value": ".5rem" },
"sm": { "value": ".75rem" },
"xs": { "value": ".25rem" },
"sm": { "value": ".5rem" },
"md": { "value": "1rem" },
"lg": { "value": "1.5rem" },
"xl": { "value": "2rem" }
},
"stack": {
"xs": { "value": ".25rem" },
"sm": { "value": ".5rem" },
"md": { "value": "1rem" },
"lg": { "value": "1.5rem" },
"xl": { "value": "2rem" }
Expand Down
13 changes: 13 additions & 0 deletions proprietary/tokens/src/components/amsterdam/row.tokens.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"amsterdam": {
"row": {
"gap": {
"xs": { "value": "{amsterdam.space.stack.xs}" },
"sm": { "value": "{amsterdam.space.stack.sm}" },
"md": { "value": "{amsterdam.space.stack.md}" },
"lg": { "value": "{amsterdam.space.stack.lg}" },
"xl": { "value": "{amsterdam.space.stack.xl}" }
}
}
}
}
2 changes: 1 addition & 1 deletion storybook/src/components/Column/Column.docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import README from "../../../../packages/css/src/components/column/README.md?raw

## Design

The five [spacing](/docs/docs-design-guidelines-space--docs) sizes are available for the size of the gap.
The five [space](/docs/docs-design-guidelines-space--docs) sizes are available for the size of the gap.

## How to Use

Expand Down
2 changes: 1 addition & 1 deletion storybook/src/components/Overlap/Overlap.docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import README from "../../../../packages/css/src/components/overlap/README.md?ra
### Hero Image with Search Field

This allows for the use of a mood-setting image as a background.
A [Grid](/docs/components-layout-grid--docs) provides horizontal spacing on both sides and columns for layout.
A [Grid](/docs/components-layout-grid--docs) provides horizontal space on both sides and columns for layout.
Note: the library does not yet offer an option to vertically center the form.

<Primary />
Expand Down
23 changes: 23 additions & 0 deletions storybook/src/components/Row/Row.docs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Controls, Markdown, Meta, Primary } from "@storybook/blocks";
import * as RowStories from "./Row.stories.tsx";
import README from "../../../../packages/css/src/components/row/README.md?raw";

<Meta of={RowStories} />

<Markdown>{README}</Markdown>

## Design

The five [space](/docs/docs-design-guidelines-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.

## Examples

### Default

<Primary />

<Controls />
33 changes: 33 additions & 0 deletions storybook/src/components/Row/Row.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @license EUPL-1.2+
* Copyright Gemeente Amsterdam
*/

import { Button, Row } from '@amsterdam/design-system-react'
import { Meta, StoryObj } from '@storybook/react'

const ThreeButtons = Array.from(Array(3).keys()).map((i) => <Button key={i}>Button {i + 1}</Button>)

const meta = {
title: 'Components/Layout/Row',
component: Row,
args: {
children: ThreeButtons,
},
argTypes: {
as: {
control: { type: 'radio' },
options: ['article', 'div', 'section'],
},
gap: {
control: 'radio',
options: ['extra-small', 'small', 'medium', 'large', 'extra-large'],
},
},
} satisfies Meta<typeof Row>

export default meta

type Story = StoryObj<typeof meta>

export const Default: Story = {}
12 changes: 11 additions & 1 deletion storybook/src/docs/space.docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,17 @@ In Compact Mode, the medium grid space grows from 16 to 40 pixels between window
This is the space between sets of components, for example between a list of cards, or next to an image.
It is also used for combinations of components, like an icon accompanying a text, or a row of buttons.

More information on this type of space will follow.
This type of space is static; it is the same for any window width.
Five options are available.
The medium size is 16 pixels wide in both Spacious and Compact Mode.

| | Width |
| --------------: | ----: |
| **Extra small** | 8 |
| **Small** | 12 |
| **Medium** | 16 |
| **Large** | 24 |
| **Extra large** | 32 |

## Inside Space

Expand Down
Loading