Skip to content

Commit

Permalink
Implement Figure Caption subcomponent
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentSmedinga committed Dec 17, 2024
1 parent a51ad85 commit ae9d076
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 16 deletions.
27 changes: 26 additions & 1 deletion packages/css/src/components/figure/figure.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,31 @@
* Copyright Gemeente Amsterdam
*/

@use "../../common/text-rendering" as *;

@mixin reset-figure {
margin-block: 0;
margin-inline: 0;
}

.ams-figure {
/* Add styles here */
display: flex;
flex-direction: column;
gap: var(--ams-figure-gap);

@include reset-figure;
}

.ams-figure__caption {
color: var(--ams-figure-caption-color);
font-family: var(--ams-figure-caption-font-family);
font-size: var(--ams-figure-caption-font-size);
font-weight: var(--ams-figure-caption-font-weight);
line-height: var(--ams-figure-caption-line-height);

@include text-rendering;
}

.ams-figure-caption--inverse-color {
color: var(--ams-figure-caption-inverse-color);
}
17 changes: 9 additions & 8 deletions packages/react/src/Figure/Figure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
import clsx from 'clsx'
import { forwardRef } from 'react'
import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react'
import { FigureCaption } from './FigureCaption'

export type FigureProps = PropsWithChildren<HTMLAttributes<HTMLElement>>

export const Figure = forwardRef(
({ children, className, ...restProps }: FigureProps, ref: ForwardedRef<HTMLElement>) => (
<figure {...restProps} ref={ref} className={clsx('ams-figure', className)}>
{children}
</figure>
),
)
const FigureRoot = forwardRef(({ children, className, ...restProps }: FigureProps, ref: ForwardedRef<HTMLElement>) => (
<figure {...restProps} ref={ref} className={clsx('ams-figure', className)}>
{children}
</figure>
))

Figure.displayName = 'Figure'
FigureRoot.displayName = 'Figure'

export const Figure = Object.assign(FigureRoot, { Caption: FigureCaption })
49 changes: 49 additions & 0 deletions packages/react/src/Figure/FigureCaption.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { render } from '@testing-library/react'
import { createRef } from 'react'
import { FigureCaption } from './FigureCaption'
import '@testing-library/jest-dom'

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

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

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

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

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

expect(component).toHaveClass('ams-figure__caption')
})

it('renders the right inverse color class', () => {
const { container } = render(<FigureCaption inverseColor>Caption</FigureCaption>)

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

expect(component).toHaveClass('ams-figure__caption--inverse-color')
})

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

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

expect(component).toHaveClass('ams-figure__caption extra')
})

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

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

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

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

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

export type FigureCaptionProps = {
/** Changes the text colour for readability on a dark background. */
inverseColor?: boolean
} & PropsWithChildren<HTMLAttributes<HTMLElement>>

export const FigureCaption = forwardRef(
({ children, className, inverseColor, ...restProps }: FigureCaptionProps, ref: ForwardedRef<HTMLElement>) => (
<figcaption
{...restProps}
ref={ref}
className={clsx('ams-figure__caption', inverseColor && 'ams-figure__caption--inverse-color', className)}
>
{children}
</figcaption>
),
)

FigureCaption.displayName = 'Figure.Caption'
12 changes: 11 additions & 1 deletion proprietary/tokens/src/components/ams/figure.tokens.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
{
"ams": {
"figure": {}
"figure": {
"gap": { "value": "{ams.space.sm}" },
"caption": {
"color": { "value": "{ams.brand.color.neutral.100}" },
"font-family": { "value": "{ams.text.font-family}" },
"font-size": { "value": "{ams.text.level.6.font-size}" },
"font-weight": { "value": "{ams.text.font-weight.normal}" },
"line-height": { "value": "{ams.text.level.6.line-height}" },
"inverse-color": { "value": "{ams.brand.color.neutral.0}" }
}
}
}
}
11 changes: 9 additions & 2 deletions storybook/src/components/Figure/Figure.docs.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{/* @license CC0-1.0 */}

import { Controls, Markdown, Meta, Primary } from "@storybook/blocks";
import { Canvas, Markdown, Meta, Primary } from "@storybook/blocks";
import * as FigureStories from "./Figure.stories.tsx";
import README from "../../../../packages/css/src/components/figure/README.md?raw";

Expand All @@ -10,4 +10,11 @@ import README from "../../../../packages/css/src/components/figure/README.md?raw

<Primary />

<Controls />
## Examples

### Inverse colour

Set the `inverseColor` prop if the Figure Caption sits on a dark background.
This ensures the colour of the text provides enough contrast.

<Canvas of={FigureStories.InverseColour} />
43 changes: 39 additions & 4 deletions storybook/src/components/Figure/Figure.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,54 @@
* Copyright Gemeente Amsterdam
*/

import { Image } from '@amsterdam/design-system-react'
import { Figure } from '@amsterdam/design-system-react/src'
import { Meta, StoryObj } from '@storybook/react'

const ExampleImage = () => (
<Image
alt=""
aspectRatio="2x-wide"
sizes="(max-width: 36rem) 640px, (max-width: 68rem) 1280px, 1600px"
src="https://picsum.photos/1600/500"
srcSet="https://picsum.photos/640/200 640w, https://picsum.photos/1280/400 1280w, https://picsum.photos/1600/500 1600w"
/>
)

const exampleCaption =
'Een rustige Amsterdamse gracht met eeuwenoude gevels die weerspiegelen in het water, terwijl fietsen nonchalant tegen de brugleuning rusten – een alledaags tafereel vol historie en charme.'

const meta = {
title: 'Components/Media/Figure',
component: Figure,
args: {
children: 'Nieuw component',
},
} satisfies Meta<typeof Figure>

export default meta

const captionMeta = {
component: Figure.Caption,
} satisfies Meta<typeof Figure.Caption>

type Story = StoryObj<typeof meta>
type CaptionStory = StoryObj<typeof captionMeta>

export const Default: Story = {}
export const Default: Story = {
args: {
children: [<ExampleImage />, <Figure.Caption>{exampleCaption}</Figure.Caption>],
},
}

export const InverseColour: CaptionStory = {
args: {
children: exampleCaption,
inverseColor: true,
},
decorators: [
(Story) => (
<Figure>
<ExampleImage />
<Story />
</Figure>
),
],
}

0 comments on commit ae9d076

Please sign in to comment.