-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic styling and multilevel poc for discussion
- Loading branch information
Showing
12 changed files
with
299 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<!-- @license CC0-1.0 --> | ||
|
||
# Table of Contents |
78 changes: 78 additions & 0 deletions
78
packages/css/src/components/table-of-contents/table-of-contents.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** | ||
* @license EUPL-1.2+ | ||
* Copyright Gemeente Amsterdam | ||
*/ | ||
|
||
@import "../../common/text-rendering"; | ||
|
||
@mixin reset { | ||
box-sizing: border-box; | ||
margin-block: 0; | ||
padding-inline: 0; | ||
} | ||
|
||
.ams-table-of-contents { | ||
display: flex; | ||
flex-direction: column; | ||
font-family: var(--ams-table-of-contents-font-family, inherit); | ||
font-size: var(--ams-table-of-contents-font-size); | ||
font-weight: var(--ams-table-of-contents-font-weight); | ||
gap: var(--ams-table-of-contents-gap); | ||
line-height: var(--ams-table-of-contents-line-height); | ||
} | ||
|
||
.ams-table-of-contents__list { | ||
display: flex; | ||
flex-direction: column; | ||
gap: var(--ams-table-of-contents-list-gap); | ||
list-style: none; | ||
|
||
.ams-table-of-contents__list { | ||
display: none; | ||
padding-block-start: var(--ams-table-of-contents-list-gap); | ||
padding-inline-start: var(--ams-table-of-contents-list-list-padding-inline-start); | ||
} | ||
|
||
@include text-rendering; | ||
@include reset; | ||
} | ||
|
||
.ams-table-of-contents__title { | ||
font-size: var(--ams-table-of-contents-title-font-size); | ||
font-weight: var(--ams-table-of-contents-title-font-weight); | ||
line-height: var(--ams-table-of-contents-title-line-height); | ||
} | ||
|
||
.ams-table-of-contents__item:has(.ams-table-of-contents) { | ||
background-image: var(--ams-table-of-contents-list-item-background-image); | ||
background-position-x: right; | ||
background-position-y: 0.3em; | ||
background-repeat: no-repeat; | ||
background-size: var(--ams-table-of-contents-font-size); | ||
|
||
&:has(.ams-table-of-contents__link--active), | ||
.ams-table-of-contents__item:has(.ams-table-of-contents) { | ||
background-image: var(--ams-table-of-contents-list-item-active-background-image); | ||
|
||
.ams-table-of-contents__list { | ||
display: flex; | ||
} | ||
} | ||
} | ||
|
||
.ams-table-of-contents__link { | ||
color: var(--ams-table-of-contents-link-color); | ||
outline-offset: var(--ams-table-of-contents-link-outline-offset); | ||
text-decoration-line: var(--ams-table-of-contents-link-text-decoration-line); | ||
text-decoration-thickness: var(--ams-table-of-contents-link-text-decoration-thickness); | ||
text-underline-offset: var(--ams-table-of-contents-link-text-underline-offset); | ||
|
||
&--active { | ||
font-weight: 700; | ||
} | ||
|
||
&:hover { | ||
color: var(--ams-table-of-contents-link-hover-color); | ||
text-decoration-line: var(--ams-table-of-contents-link-hover-text-decoration-line); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<!-- @license CC0-1.0 --> | ||
|
||
# React Table of Contents component | ||
|
||
[Table of Contents documentation](../../../css/src/components/table-of-contents/README.md) |
37 changes: 37 additions & 0 deletions
37
packages/react/src/TableOfContents/TableOfContents.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { render } from '@testing-library/react' | ||
import { createRef } from 'react' | ||
import { TableOfContents } from './TableOfContents' | ||
import '@testing-library/jest-dom' | ||
|
||
describe('Table of contents', () => { | ||
it('renders', () => { | ||
const { container } = render(<TableOfContents />) | ||
const component = container.querySelector(':only-child') | ||
|
||
expect(component).toBeInTheDocument() | ||
expect(component).toBeVisible() | ||
}) | ||
|
||
it('renders a design system BEM class name', () => { | ||
const { container } = render(<TableOfContents />) | ||
const component = container.querySelector(':only-child') | ||
|
||
expect(component).toHaveClass('ams-table-of-contents') | ||
}) | ||
|
||
it('renders an additional class name', () => { | ||
const { container } = render(<TableOfContents className="extra" />) | ||
const component = container.querySelector(':only-child') | ||
|
||
expect(component).toHaveClass('ams-table-of-contents extra') | ||
}) | ||
|
||
it('supports ForwardRef in React', () => { | ||
const ref = createRef<HTMLDivElement>() | ||
|
||
const { container } = render(<TableOfContents ref={ref} />) | ||
const component = container.querySelector(':only-child') | ||
|
||
expect(ref.current).toBe(component) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* @license EUPL-1.2+ | ||
* Copyright Gemeente Amsterdam | ||
*/ | ||
|
||
import clsx from 'clsx' | ||
import { forwardRef } from 'react' | ||
import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react' | ||
import { TableOfContentsLink } from './TableOfContentsLink' | ||
|
||
export type TableOfContentsProps = { | ||
title?: string | ||
} & PropsWithChildren<HTMLAttributes<HTMLDivElement>> | ||
|
||
const TableOfContentsRoot = forwardRef( | ||
({ children, className, title, ...restProps }: TableOfContentsProps, ref: ForwardedRef<HTMLDivElement>) => ( | ||
<nav {...restProps} ref={ref} className={clsx('ams-table-of-contents', className)}> | ||
{title && <div className="ams-table-of-contents__title">{title}</div>} | ||
<ol className="ams-table-of-contents__list">{children}</ol> | ||
</nav> | ||
), | ||
) | ||
|
||
TableOfContentsRoot.displayName = 'TableOfContents' | ||
|
||
export const TableOfContents = Object.assign(TableOfContentsRoot, { Link: TableOfContentsLink }) |
33 changes: 33 additions & 0 deletions
33
packages/react/src/TableOfContents/TableOfContentsLink.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { AnchorHTMLAttributes, ForwardedRef } from 'react' | ||
|
||
export type TableOfContentsLinkProps = { | ||
label: string | ||
active?: boolean | ||
} & AnchorHTMLAttributes<HTMLAnchorElement> | ||
|
||
export const TableOfContentsLink = forwardRef( | ||
( | ||
{ children, className, label, active, ...restProps }: TableOfContentsLinkProps, | ||
ref: ForwardedRef<HTMLAnchorElement>, | ||
) => ( | ||
<li className="ams-table-of-contents__item"> | ||
<a | ||
{...restProps} | ||
className={clsx('ams-table-of-contents__link', active && 'ams-table-of-contents__link--active', className)} | ||
ref={ref} | ||
> | ||
{label} | ||
</a> | ||
{children} | ||
</li> | ||
), | ||
) | ||
|
||
TableOfContentsLink.displayName = 'TableOfContents.Link' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { TableOfContents } from './TableOfContents' | ||
export type { TableOfContentsProps } from './TableOfContents' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
proprietary/tokens/src/components/ams/table-of-contents.tokens.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{ | ||
"ams": { | ||
"table-of-contents": { | ||
"color": { "value": "{ams.color.primary-black}" }, | ||
"font-family": { "value": "{ams.text.font-family}" }, | ||
"font-size": { "value": "{ams.text.level.5.font-size}" }, | ||
"font-weight": { "value": "{ams.text.font-weight.normal}" }, | ||
"gap": { "value": "{ams.space.inside.lg}" }, | ||
"line-height": { "value": "{ams.text.level.5.line-height}" }, | ||
"link": { | ||
"color": { "value": "{ams.color.primary-blue}" }, | ||
"inverse-color": { "value": "{ams.color.primary-white}" }, | ||
"hover": { | ||
"color": { "value": "{ams.color.dark-blue}" } | ||
} | ||
}, | ||
"list": { | ||
"gap": { "value": "{ams.space.inside.lg}" }, | ||
"item": { | ||
"background-image": { | ||
"value": "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path fill-rule='evenodd' d='m16 25.757-16-16 2.91-2.9L16 19.937l13.09-13.08 2.91 2.9z'/></svg>\")" | ||
}, | ||
"active": { | ||
"background-image": { | ||
"value": "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path fill-rule='evenodd' d='M29.09 25.757 16 12.677 2.91 25.757 0 22.857l16-16 16 16z'/></svg>\")" | ||
} | ||
} | ||
}, | ||
"list": { | ||
"padding-inline-start": { "value": "{ams.space.inside.lg}" } | ||
} | ||
}, | ||
"title": { | ||
"font-weight": { "value": "{ams.text.font-weight.bold}" }, | ||
"font-size": { "value": "{ams.text.level.4.font-size}" }, | ||
"line-height": { "value": "{ams.text.level.4.line-height}" } | ||
} | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
storybook/src/components/TableOfContents/TableOfContents.docs.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { Controls, Markdown, Meta, Primary } from "@storybook/blocks"; | ||
import * as TableOfContentsStories from "./TableOfContents.stories.tsx"; | ||
import README from "../../../../packages/css/src/components/table-of-contents/README.md?raw"; | ||
|
||
<Meta of={TableOfContentsStories} /> | ||
|
||
<Markdown>{README}</Markdown> | ||
|
||
<Primary /> | ||
|
||
<Controls /> |
62 changes: 62 additions & 0 deletions
62
storybook/src/components/TableOfContents/TableOfContents.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** | ||
* @license EUPL-1.2+ | ||
* Copyright Gemeente Amsterdam | ||
*/ | ||
|
||
import { TableOfContents } from '@amsterdam/design-system-react/src' | ||
import { Meta, StoryObj } from '@storybook/react' | ||
|
||
const meta = { | ||
title: 'Components/Navigation/Table of Contents', | ||
component: TableOfContents, | ||
args: { | ||
title: 'Op deze pagina', | ||
children: [ | ||
<> | ||
<TableOfContents.Link href="#section-1" label="Zo werkt het" /> | ||
<TableOfContents.Link href="#section-2" label="Voorwaarden" /> | ||
<TableOfContents.Link href="#section-4" label="Aanvragen" /> | ||
<TableOfContents.Link href="#section-4" label="Zie ook" /> | ||
</>, | ||
], | ||
}, | ||
} satisfies Meta<typeof TableOfContents> | ||
|
||
export default meta | ||
|
||
type Story = StoryObj<typeof meta> | ||
|
||
export const Default: Story = {} | ||
|
||
export const MultiLevel: Story = { | ||
args: { | ||
title: 'Inhoudsopgave', | ||
children: [ | ||
<> | ||
<TableOfContents.Link href="#section-1" label="Waarom is het belangrijk om helder te schrijven?" /> | ||
<TableOfContents.Link href="#section-2" label="Schrijf in stappen"> | ||
<TableOfContents> | ||
<TableOfContents.Link href="#section-4.1" label="Stap 2" /> | ||
<TableOfContents.Link href="#section-4.2" label="Stap 3" /> | ||
<TableOfContents.Link href="#section-4.3" label="Stap 4" /> | ||
</TableOfContents> | ||
</TableOfContents.Link> | ||
<TableOfContents.Link href="#section-3" label="Structuur van een heldere tekst" active> | ||
<TableOfContents> | ||
<TableOfContents.Link href="#section-3.1" label="Opmaakeisen" /> | ||
<TableOfContents.Link href="#section-3.2" label="Tekstlengte"> | ||
<TableOfContents> | ||
<TableOfContents.Link href="#section-3.2.1" label="Boodschap en achtergronden" /> | ||
</TableOfContents> | ||
</TableOfContents.Link> | ||
<TableOfContents.Link href="#section-3.2" label="Alinea's en tussenkopjes" /> | ||
<TableOfContents.Link href="#section-3.2" label="Opsommingen" /> | ||
</TableOfContents> | ||
</TableOfContents.Link> | ||
<TableOfContents.Link href="#section-4" label="Taalgebruik in heldere taal" /> | ||
<TableOfContents.Link href="#section-5" label="Tekstonderdelen in heldere taal" /> | ||
<TableOfContents.Link href="#section-6" label="Moeilijke woordenboek (inclusief niet te gebruiken)" /> | ||
</>, | ||
], | ||
}, | ||
} |