aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/organisms
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-10-09 18:26:23 +0200
committerArmand Philippot <git@armandphilippot.com>2023-11-11 18:14:41 +0100
commit15522ec9146f6f1956620355c44dea2a6a75b67c (patch)
tree7be0c4ca96cb3e59d2ee989785a6b6a286e6169d /src/components/organisms
parent891441a76173c708c6604fa203b175aefa222333 (diff)
refactor(components): replace ResponsiveImage with Figure component
The styles applied to ResponsiveImage are related to the figure and figcaption elements. Those elements could be use with other contents than images. So I extracted them in a Figure component. The ResponsiveImage component is no longer useful: the consumer should use the Image component from `next` and wrap it in a link if needed.
Diffstat (limited to 'src/components/organisms')
-rw-r--r--src/components/organisms/images/gallery.stories.tsx23
-rw-r--r--src/components/organisms/images/gallery.test.tsx30
-rw-r--r--src/components/organisms/images/gallery.tsx5
-rw-r--r--src/components/organisms/layout/overview.stories.tsx6
-rw-r--r--src/components/organisms/layout/overview.tsx17
-rw-r--r--src/components/organisms/layout/summary.fixture.ts (renamed from src/components/organisms/layout/summary.fixture.tsx)4
-rw-r--r--src/components/organisms/layout/summary.module.scss1
-rw-r--r--src/components/organisms/layout/summary.tsx20
-rw-r--r--src/components/organisms/widgets/image-widget.module.scss1
-rw-r--r--src/components/organisms/widgets/image-widget.tsx33
10 files changed, 77 insertions, 63 deletions
diff --git a/src/components/organisms/images/gallery.stories.tsx b/src/components/organisms/images/gallery.stories.tsx
index 5005ed8..016b18e 100644
--- a/src/components/organisms/images/gallery.stories.tsx
+++ b/src/components/organisms/images/gallery.stories.tsx
@@ -1,5 +1,6 @@
import type { ComponentMeta, ComponentStory } from '@storybook/react';
-import { ResponsiveImage } from '../../molecules';
+import NextImage from 'next/image';
+import { Figure } from '../../atoms';
import { Gallery } from './gallery';
/**
@@ -13,7 +14,7 @@ export default {
control: {
type: null,
},
- description: 'Two or more ResponsiveImage component.',
+ description: 'Two or more images.',
type: {
name: 'function',
required: true,
@@ -37,16 +38,24 @@ export default {
const image = {
alt: 'Modi provident omnis',
height: 480,
- src: 'http://picsum.photos/640/480',
+ src: 'https://picsum.photos/640/480',
width: 640,
};
const Template: ComponentStory<typeof Gallery> = (args) => (
<Gallery {...args}>
- <ResponsiveImage {...image} />
- <ResponsiveImage {...image} />
- <ResponsiveImage {...image} />
- <ResponsiveImage {...image} />
+ <Figure>
+ <NextImage {...image} />
+ </Figure>
+ <Figure>
+ <NextImage {...image} />
+ </Figure>
+ <Figure>
+ <NextImage {...image} />
+ </Figure>
+ <Figure>
+ <NextImage {...image} />
+ </Figure>
</Gallery>
);
diff --git a/src/components/organisms/images/gallery.test.tsx b/src/components/organisms/images/gallery.test.tsx
index ea39348..bffc3b2 100644
--- a/src/components/organisms/images/gallery.test.tsx
+++ b/src/components/organisms/images/gallery.test.tsx
@@ -1,6 +1,6 @@
import { describe, expect, it } from '@jest/globals';
-import { render, screen } from '../../../../tests/utils';
-import { ResponsiveImage } from '../../molecules';
+import { render, screen as rtlScreen } from '@testing-library/react';
+import NextImage from 'next/image';
import { Gallery } from './gallery';
const columns = 3;
@@ -8,7 +8,7 @@ const columns = 3;
const image = {
alt: 'Modi provident omnis',
height: 480,
- src: 'http://placeimg.com/640/480/fashion',
+ src: 'http://picsum.photos/640/480',
width: 640,
};
@@ -16,24 +16,28 @@ describe('Gallery', () => {
it('renders the correct number of items', () => {
render(
<Gallery columns={columns}>
- <ResponsiveImage {...image} />
- <ResponsiveImage {...image} />
- <ResponsiveImage {...image} />
- <ResponsiveImage {...image} />
+ <NextImage {...image} />
+ <NextImage {...image} />
+ <NextImage {...image} />
+ <NextImage {...image} />
</Gallery>
);
- expect(screen.getAllByRole('listitem')).toHaveLength(4);
+
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+ expect(rtlScreen.getAllByRole('listitem')).toHaveLength(4);
});
it('renders the right number of columns', () => {
render(
<Gallery columns={columns}>
- <ResponsiveImage {...image} />
- <ResponsiveImage {...image} />
- <ResponsiveImage {...image} />
- <ResponsiveImage {...image} />
+ <NextImage {...image} />
+ <NextImage {...image} />
+ <NextImage {...image} />
+ <NextImage {...image} />
</Gallery>
);
- expect(screen.getByRole('list')).toHaveClass(`wrapper--${columns}-columns`);
+ expect(rtlScreen.getByRole('list')).toHaveClass(
+ `wrapper--${columns}-columns`
+ );
});
});
diff --git a/src/components/organisms/images/gallery.tsx b/src/components/organisms/images/gallery.tsx
index b35acfe..2f17130 100644
--- a/src/components/organisms/images/gallery.tsx
+++ b/src/components/organisms/images/gallery.tsx
@@ -1,6 +1,5 @@
import { Children, type FC, type ReactElement } from 'react';
import { List, ListItem } from '../../atoms';
-import type { ResponsiveImageProps } from '../../molecules';
import styles from './gallery.module.scss';
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
@@ -8,9 +7,9 @@ export type GalleryColumn = 2 | 3 | 4;
export type GalleryProps = {
/**
- * The images using ResponsiveImage component.
+ * The images.
*/
- children: ReactElement<ResponsiveImageProps>[];
+ children: ReactElement[];
/**
* The columns count.
*/
diff --git a/src/components/organisms/layout/overview.stories.tsx b/src/components/organisms/layout/overview.stories.tsx
index be6db72..8f56d3a 100644
--- a/src/components/organisms/layout/overview.stories.tsx
+++ b/src/components/organisms/layout/overview.stories.tsx
@@ -1,5 +1,5 @@
-import { ComponentMeta, ComponentStory } from '@storybook/react';
-import { Overview, OverviewMeta } from './overview';
+import type { ComponentMeta, ComponentStory } from '@storybook/react';
+import { Overview, type OverviewMeta } from './overview';
/**
* Overview - Storybook Meta
@@ -50,7 +50,7 @@ const Template: ComponentStory<typeof Overview> = (args) => (
const cover = {
alt: 'picture',
height: 480,
- src: 'http://placeimg.com/640/480/cats',
+ src: 'https://picsum.photos/640/480',
width: 640,
};
diff --git a/src/components/organisms/layout/overview.tsx b/src/components/organisms/layout/overview.tsx
index bb319c4..8af58ec 100644
--- a/src/components/organisms/layout/overview.tsx
+++ b/src/components/organisms/layout/overview.tsx
@@ -1,10 +1,7 @@
+import NextImage, { type ImageProps as NextImageProps } from 'next/image';
import type { FC } from 'react';
-import {
- Meta,
- type MetaData,
- ResponsiveImage,
- type ResponsiveImageProps,
-} from '../../molecules';
+import { Figure } from '../../atoms';
+import { Meta, type MetaData } from '../../molecules';
import styles from './overview.module.scss';
export type OverviewMeta = Pick<
@@ -25,7 +22,7 @@ export type OverviewProps = {
/**
* The overview cover.
*/
- cover?: Pick<ResponsiveImageProps, 'alt' | 'src' | 'width' | 'height'>;
+ cover?: Pick<NextImageProps, 'alt' | 'src' | 'width' | 'height'>;
/**
* The overview meta.
*/
@@ -47,7 +44,11 @@ export const Overview: FC<OverviewProps> = ({
return (
<div className={`${styles.wrapper} ${className}`}>
- {cover ? <ResponsiveImage className={styles.cover} {...cover} /> : null}
+ {cover ? (
+ <Figure>
+ <NextImage {...cover} className={styles.cover} />
+ </Figure>
+ ) : null}
<Meta
className={`${styles.meta} ${metaModifier}`}
data={{ ...remainingMeta, technologies }}
diff --git a/src/components/organisms/layout/summary.fixture.tsx b/src/components/organisms/layout/summary.fixture.ts
index bb3ebcb..6f90b4a 100644
--- a/src/components/organisms/layout/summary.fixture.tsx
+++ b/src/components/organisms/layout/summary.fixture.ts
@@ -1,9 +1,9 @@
-import { type SummaryMeta } from './summary';
+import type { SummaryMeta } from './summary';
export const cover = {
alt: 'A cover',
height: 480,
- src: 'http://placeimg.com/640/480',
+ src: 'https://picsum.photos/640/480',
width: 640,
};
diff --git a/src/components/organisms/layout/summary.module.scss b/src/components/organisms/layout/summary.module.scss
index b6cb4f4..9dc1a69 100644
--- a/src/components/organisms/layout/summary.module.scss
+++ b/src/components/organisms/layout/summary.module.scss
@@ -46,6 +46,7 @@
height: fun.convert-px(100);
max-width: 100%;
border: fun.convert-px(1) solid var(--color-border);
+ object-fit: scale-down;
@include mix.media("screen") {
@include mix.dimensions("sm") {
diff --git a/src/components/organisms/layout/summary.tsx b/src/components/organisms/layout/summary.tsx
index e21e4c7..fa3dfe5 100644
--- a/src/components/organisms/layout/summary.tsx
+++ b/src/components/organisms/layout/summary.tsx
@@ -1,3 +1,4 @@
+import NextImage, { type ImageProps as NextImageProps } from 'next/image';
import type { FC, ReactNode } from 'react';
import { useIntl } from 'react-intl';
import type { Article, Meta as MetaType } from '../../../types';
@@ -8,19 +9,12 @@ import {
type HeadingLevel,
Icon,
Link,
+ Figure,
} from '../../atoms';
-import {
- Meta,
- type MetaData,
- ResponsiveImage,
- type ResponsiveImageProps,
-} from '../../molecules';
+import { Meta, type MetaData } from '../../molecules';
import styles from './summary.module.scss';
-export type Cover = Pick<
- ResponsiveImageProps,
- 'alt' | 'src' | 'width' | 'height'
->;
+export type Cover = Pick<NextImageProps, 'alt' | 'src' | 'width' | 'height'>;
export type SummaryMeta = Pick<
MetaType<'article'>,
@@ -108,7 +102,11 @@ export const Summary: FC<SummaryProps> = ({
return (
<article className={styles.wrapper}>
- {cover ? <ResponsiveImage className={styles.cover} {...cover} /> : null}
+ {cover ? (
+ <Figure>
+ <NextImage {...cover} className={styles.cover} />
+ </Figure>
+ ) : null}
<header className={styles.header}>
<Link href={url} className={styles.link}>
<Heading level={titleLevel} className={styles.title}>
diff --git a/src/components/organisms/widgets/image-widget.module.scss b/src/components/organisms/widgets/image-widget.module.scss
index 2174d5b..25de03e 100644
--- a/src/components/organisms/widgets/image-widget.module.scss
+++ b/src/components/organisms/widgets/image-widget.module.scss
@@ -4,6 +4,7 @@
--scale-up: 1.02;
--scale-down: 0.98;
+ width: fit-content;
margin: 0;
padding: fun.convert-px(5);
border: fun.convert-px(1) solid var(--color-border);
diff --git a/src/components/organisms/widgets/image-widget.tsx b/src/components/organisms/widgets/image-widget.tsx
index 07c4b11..5de8dd8 100644
--- a/src/components/organisms/widgets/image-widget.tsx
+++ b/src/components/organisms/widgets/image-widget.tsx
@@ -1,18 +1,12 @@
+import NextImage, { type ImageProps as NextImageProps } from 'next/image';
import type { FC } from 'react';
-import {
- ResponsiveImage,
- type ResponsiveImageProps,
- Collapsible,
- type CollapsibleProps,
-} from '../../molecules';
+import { Figure, Link, type FigureProps } from '../../atoms';
+import { Collapsible, type CollapsibleProps } from '../../molecules';
import styles from './image-widget.module.scss';
export type Alignment = 'left' | 'center' | 'right';
-export type Image = Pick<
- ResponsiveImageProps,
- 'alt' | 'height' | 'src' | 'width'
->;
+export type Image = Pick<NextImageProps, 'alt' | 'height' | 'src' | 'width'>;
export type ImageWidgetProps = Omit<
CollapsibleProps,
@@ -25,7 +19,7 @@ export type ImageWidgetProps = Omit<
/**
* Add a caption to the image.
*/
- description?: ResponsiveImageProps['caption'];
+ description?: FigureProps['caption'];
/**
* An object describing the image.
*/
@@ -37,7 +31,7 @@ export type ImageWidgetProps = Omit<
/**
* Add a link to the image.
*/
- url?: ResponsiveImageProps['target'];
+ url?: string;
};
/**
@@ -62,12 +56,19 @@ export const ImageWidget: FC<ImageWidgetProps> = ({
{...props}
className={`${styles[alignmentClass]} ${className}`}
>
- <ResponsiveImage
- {...image}
+ <Figure
caption={description}
className={`${styles.figure} ${imageClassName}`}
- target={url}
- />
+ hasBorders
+ >
+ {url ? (
+ <Link href={url}>
+ <NextImage {...image} />
+ </Link>
+ ) : (
+ <NextImage {...image} />
+ )}
+ </Figure>
</Collapsible>
);
};