Skip to content

Commit 588a355

Browse files
committed
feat(card): extend to image component
1 parent edb6aaa commit 588a355

File tree

2 files changed

+76
-8
lines changed

2 files changed

+76
-8
lines changed

src/Card.tsx

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,10 @@ export type CardProps = {
1717
title: ReactNode;
1818
titleAs?: `h${2 | 3 | 4 | 5 | 6}`;
1919
desc?: ReactNode;
20-
imageUrl?: string;
21-
imageAlt?: string;
2220
start?: ReactNode;
2321
detail?: ReactNode;
2422
end?: ReactNode;
2523
endDetail?: ReactNode;
26-
badge?: ReactNode;
2724
/** where actions can be placed */
2825
footer?: ReactNode;
2926
/** Default: "medium", only affect the text */
@@ -59,7 +56,8 @@ export type CardProps = {
5956
>;
6057
style?: CSSProperties;
6158
} & (CardProps.EnlargedLink | CardProps.NotEnlargedLink) &
62-
(CardProps.Horizontal | CardProps.Vertical);
59+
(CardProps.Horizontal | CardProps.Vertical) &
60+
(CardProps.WithImageLink | CardProps.WithImageComponent | CardProps.WithoutImage);
6361

6462
export namespace CardProps {
6563
export type EnlargedLink = {
@@ -84,6 +82,27 @@ export namespace CardProps {
8482
horizontal?: false;
8583
ratio?: never;
8684
};
85+
86+
export type WithImageLink = {
87+
badge?: ReactNode;
88+
imageUrl: string;
89+
imageAlt: string;
90+
imageComponent?: never;
91+
};
92+
93+
export type WithImageComponent = {
94+
badge?: ReactNode;
95+
imageUrl?: never;
96+
imageAlt?: never;
97+
imageComponent: ReactNode;
98+
};
99+
100+
export type WithoutImage = {
101+
badge?: never;
102+
imageUrl?: never;
103+
imageAlt?: never;
104+
imageComponent?: never;
105+
};
87106
}
88107

89108
/** @see <https://components.react-dsfr.codegouv.studio/?path=/docs/components-card> */
@@ -98,6 +117,7 @@ export const Card = memo(
98117
desc,
99118
imageUrl,
100119
imageAlt,
120+
imageComponent,
101121
start,
102122
detail,
103123
end,
@@ -216,6 +236,18 @@ export const Card = memo(
216236
)}
217237
</div>
218238
)}
239+
{imageComponent !== undefined && (
240+
<div className={cx(fr.cx("fr-card__header"), classes.header)}>
241+
<div className={cx(fr.cx("fr-card__img"), classes.img)}>
242+
{imageComponent}
243+
</div>
244+
{badge !== undefined && (
245+
<ul className={cx(fr.cx("fr-badges-group"), classes.badge)}>
246+
<li>{badge}</li>
247+
</ul>
248+
)}
249+
</div>
250+
)}
219251
</div>
220252
);
221253
})

stories/Card.stories.tsx

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { getStoryFactory } from "./getStory";
77
import { assert } from "tsafe/assert";
88
import type { Equals } from "tsafe";
99

10+
import artworkOvoidSvgUrl from "../dist/dsfr/artwork/background/ovoid.svg";
11+
import artworkTechnicalErrorSvgUrl from "../dist/dsfr/artwork/pictograms/system/technical-error.svg";
12+
1013
import { fr } from "../dist";
1114

1215
const { meta, getStory } = getStoryFactory({
@@ -151,7 +154,7 @@ export const CardWithShadow = getStory(
151154
);
152155

153156
export const CardWithoutImage = getStory(
154-
{ ...defaultProps, "imageUrl": undefined },
157+
{ ...defaultProps },
155158
{ "description": "Carte sans image" }
156159
);
157160

@@ -351,7 +354,6 @@ export const CardHorizontalWithoutImage = getStory(
351354
...defaultProps,
352355
"horizontal": true,
353356
"size": "large",
354-
"imageUrl": undefined,
355357
"start": (
356358
<ul className={fr.cx("fr-badges-group")}>
357359
<li>
@@ -371,8 +373,7 @@ export const CardHorizontalWithoutImageAndEnlargeLink = getStory(
371373
...defaultProps,
372374
"horizontal": true,
373375
"enlargeLink": false,
374-
"size": "large",
375-
"imageUrl": undefined
376+
"size": "large"
376377
},
377378
{ "description": "Carte horizontale sans image", "defaultContainerWidth": 900 }
378379
);
@@ -432,3 +433,38 @@ export const CardNoLink = getStory(
432433
},
433434
{ "description": "Carte horizontale sans lien", "defaultContainerWidth": 900 }
434435
);
436+
437+
export const CardWithImageComponent = getStory({
438+
...defaultProps,
439+
enlargeLink: false,
440+
imageUrl: undefined,
441+
imageAlt: undefined,
442+
imageComponent: (
443+
<svg
444+
xmlns="http://www.w3.org/2000/svg"
445+
className="fr-responsive-img fr-artwork"
446+
aria-hidden="true"
447+
viewBox="0 0 160 200"
448+
>
449+
<use className="fr-artwork-motif" href={`${artworkOvoidSvgUrl}#artwork-motif`}></use>
450+
<use
451+
className="fr-artwork-background"
452+
href={`${artworkOvoidSvgUrl}#artwork-background`}
453+
></use>
454+
<g transform="translate(40, 60)">
455+
<use
456+
className="fr-artwork-decorative"
457+
href={`${artworkTechnicalErrorSvgUrl}#artwork-decorative`}
458+
></use>
459+
<use
460+
className="fr-artwork-minor"
461+
href={`${artworkTechnicalErrorSvgUrl}#artwork-minor`}
462+
></use>
463+
<use
464+
className="fr-artwork-major"
465+
href={`${artworkTechnicalErrorSvgUrl}#artwork-major`}
466+
></use>
467+
</g>
468+
</svg>
469+
)
470+
});

0 commit comments

Comments
 (0)