From cc376e835e57a43c095bb051d1be6a8a1bb6f2e1 Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 15 Dec 2022 12:41:01 +0100 Subject: [PATCH 1/7] feat: add Quote component --- package.json | 1 + src/Quote.tsx | 54 ++++++++++++++++++++++++++++ stories/Quote.stories.tsx | 74 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 src/Quote.tsx create mode 100644 stories/Quote.stories.tsx diff --git a/package.json b/package.json index db252dc5a..1b3822c36 100755 --- a/package.json +++ b/package.json @@ -126,6 +126,7 @@ "./Tabs": "./dist/Tabs.js", "./Stepper": "./dist/Stepper.js", "./SkipLinks": "./dist/SkipLinks.js", + "./Quote": "./dist/Quote.js", "./Notice": "./dist/Notice.js", "./Highlight": "./dist/Highlight.js", "./Header": "./dist/Header/index.js", diff --git a/src/Quote.tsx b/src/Quote.tsx new file mode 100644 index 000000000..5d4daa831 --- /dev/null +++ b/src/Quote.tsx @@ -0,0 +1,54 @@ +import React, { memo, forwardRef, ReactNode } from "react"; +import { symToStr } from "tsafe/symToStr"; +import { assert } from "tsafe/assert"; +import type { Equals } from "tsafe"; +import { fr } from "./lib"; +import { cx } from "./lib/tools/cx"; + +// We make users import dsfr.css, so we don't need to import the scoped CSS +// but in the future if we have a complete component coverage it +// we could stop requiring users to import the hole CSS and only import on a +// per component basis. +import "./dsfr/component/quote/quote.css"; + +export type QuoteProps = { + className?: string; + text: string; + author?: string; + source?: ReactNode; + sourceUrl?: string; + image?: string; +}; + +/** @see */ +export const Quote = memo( + forwardRef((props, ref) => { + const { className, text, author, source, sourceUrl, image, ...rest } = props; + + assert>(); + + return ( +
+
+

« {text} »

+
+
+ {author &&

{author}

} + {source &&
    {source}
} + {image && ( +
+ +
+ )} +
+
+ ); + }) +); + +Quote.displayName = symToStr({ Quote }); + +export default Quote; diff --git a/stories/Quote.stories.tsx b/stories/Quote.stories.tsx new file mode 100644 index 000000000..18eb24800 --- /dev/null +++ b/stories/Quote.stories.tsx @@ -0,0 +1,74 @@ +import { Quote } from "../dist/Quote"; +import { sectionName } from "./sectionName"; +import { getStoryFactory } from "./getStory"; + +const { meta, getStory } = getStoryFactory({ + sectionName, + "wrappedComponent": { Quote }, + "description": ` +- [See DSFR documentation](https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/citation) +- [See source code](https://github.com/codegouvfr/react-dsfr/blob/main/src/Quote.tsx)`, + "disabledProps": ["lang"] +}); + +export default meta; + +export const Default = getStory({ + text: "Lorem [...] elit ut. ", + author: "Auteur", + source: ( + <> + {" "} +
  • + Ouvrage +
  • +
  • Détail 1
  • +
  • Détail 2
  • +
  • Détail 3
  • +
  • + + Détail 4 + +
  • + + ), + image: "https://www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" +}); + +export const QuoteWithoutDetails = getStory({ + text: "Lorem [...] elit ut. ", + author: "Auteur", + image: "https://www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" +}); + +export const QuoteWithoutSource = getStory({ + text: "Lorem [...] elit ut. ", + image: "https://www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" +}); + +export const QuoteWithoutIllustration = getStory({ + text: "Lorem [...] elit ut. ", + author: "Auteur", + source: ( + <> + {" "} +
  • + Ouvrage +
  • +
  • Détail 1
  • +
  • Détail 2
  • +
  • Détail 3
  • +
  • + + Détail 4 + +
  • + + ) +}); From 10a26bbdcb80170cd7b155950fd6ff8e20fca93d Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 15 Dec 2022 12:42:36 +0100 Subject: [PATCH 2/7] fix --- src/Quote.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Quote.tsx b/src/Quote.tsx index 5d4daa831..db5fd7426 100644 --- a/src/Quote.tsx +++ b/src/Quote.tsx @@ -20,7 +20,7 @@ export type QuoteProps = { image?: string; }; -/** @see */ +/** @see */ export const Quote = memo( forwardRef((props, ref) => { const { className, text, author, source, sourceUrl, image, ...rest } = props; From 56d10eaed04d5043e563155e1aeef92d4153f424 Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 15 Dec 2022 12:43:06 +0100 Subject: [PATCH 3/7] fix --- stories/Quote.stories.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stories/Quote.stories.tsx b/stories/Quote.stories.tsx index 18eb24800..25a0a7113 100644 --- a/stories/Quote.stories.tsx +++ b/stories/Quote.stories.tsx @@ -1,3 +1,4 @@ +import React from "react"; import { Quote } from "../dist/Quote"; import { sectionName } from "./sectionName"; import { getStoryFactory } from "./getStory"; @@ -18,7 +19,6 @@ export const Default = getStory({ author: "Auteur", source: ( <> - {" "}
  • Ouvrage
  • @@ -54,7 +54,6 @@ export const QuoteWithoutIllustration = getStory({ author: "Auteur", source: ( <> - {" "}
  • Ouvrage
  • From 58ed41e7d6846b45a651d33328da3d00c628e37c Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 15 Dec 2022 14:35:37 +0100 Subject: [PATCH 4/7] fix --- src/Quote.tsx | 14 +++++++++--- stories/Quote.stories.tsx | 45 ++++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/Quote.tsx b/src/Quote.tsx index db5fd7426..0ef95c116 100644 --- a/src/Quote.tsx +++ b/src/Quote.tsx @@ -18,22 +18,30 @@ export type QuoteProps = { source?: ReactNode; sourceUrl?: string; image?: string; + size?: "md" | "lg" | "xl"; }; /** @see */ export const Quote = memo( forwardRef((props, ref) => { - const { className, text, author, source, sourceUrl, image, ...rest } = props; + const { className, text, author, source, sourceUrl, image, size, ...rest } = props; assert>(); return (
    -

    « {text} »

    +

    + « {text} » +

    {author &&

    {author}

    } diff --git a/stories/Quote.stories.tsx b/stories/Quote.stories.tsx index 25a0a7113..4179cca66 100644 --- a/stories/Quote.stories.tsx +++ b/stories/Quote.stories.tsx @@ -7,8 +7,8 @@ const { meta, getStory } = getStoryFactory({ sectionName, "wrappedComponent": { Quote }, "description": ` -- [See DSFR documentation](https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/citation) -- [See source code](https://github.com/codegouvfr/react-dsfr/blob/main/src/Quote.tsx)`, +- [See DSFR documentation](//www.systeme-de-design.gouv.fr/elements-d-interface/composants/citation) +- [See source code](//github.com/codegouvfr/react-dsfr/blob/main/src/Quote.tsx)`, "disabledProps": ["lang"] }); @@ -35,18 +35,46 @@ export const Default = getStory({ ), - image: "https://www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" + image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", + size: "xl", + className: "" +}); + +export const QuoteMediumAndAccent = getStory({ + text: "Lorem [...] elit ut. ", + author: "Auteur", + source: ( + <> +
  • + Ouvrage +
  • +
  • Détail 1
  • +
  • Détail 2
  • +
  • Détail 3
  • +
  • + + Détail 4 + +
  • + + ), + image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", + size: "md", + className: "fr-quote--green-emeraude" }); export const QuoteWithoutDetails = getStory({ text: "Lorem [...] elit ut. ", author: "Auteur", - image: "https://www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" + image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" }); export const QuoteWithoutSource = getStory({ text: "Lorem [...] elit ut. ", - image: "https://www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" + image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" }); export const QuoteWithoutIllustration = getStory({ @@ -71,3 +99,10 @@ export const QuoteWithoutIllustration = getStory({ ) }); + +export const QuoteWithAccent = getStory({ + text: "Lorem [...] elit ut. ", + image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", + className: "fr-quote--green-emeraude", + author: "Someone" +}); From c9b0040f81c77c6b65177572e3565ee914165538 Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Thu, 15 Dec 2022 15:00:49 +0100 Subject: [PATCH 5/7] accentColor --- src/Quote.tsx | 20 ++++++++++++++++++-- stories/Quote.stories.tsx | 4 ++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Quote.tsx b/src/Quote.tsx index 0ef95c116..a0e9d744e 100644 --- a/src/Quote.tsx +++ b/src/Quote.tsx @@ -10,6 +10,7 @@ import { cx } from "./lib/tools/cx"; // we could stop requiring users to import the hole CSS and only import on a // per component basis. import "./dsfr/component/quote/quote.css"; +import { FrClassName } from "./lib/generatedFromCss/classNames"; export type QuoteProps = { className?: string; @@ -19,18 +20,33 @@ export type QuoteProps = { sourceUrl?: string; image?: string; size?: "md" | "lg" | "xl"; + accentColor?: QuoteProps.AccentColor; }; +export namespace QuoteProps { + type ExtractAccentColor = FrClassName extends `fr-quote--${infer AccentColor}` + ? AccentColor + : never; + + export type AccentColor = ExtractAccentColor; +} + /** @see */ export const Quote = memo( forwardRef((props, ref) => { - const { className, text, author, source, sourceUrl, image, size, ...rest } = props; + const { className, text, author, source, sourceUrl, image, size, accentColor, ...rest } = + props; assert>(); return (
    diff --git a/stories/Quote.stories.tsx b/stories/Quote.stories.tsx index 4179cca66..5abd3fdb7 100644 --- a/stories/Quote.stories.tsx +++ b/stories/Quote.stories.tsx @@ -63,7 +63,7 @@ export const QuoteMediumAndAccent = getStory({ ), image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", size: "md", - className: "fr-quote--green-emeraude" + accentColor: "pink-macaron" }); export const QuoteWithoutDetails = getStory({ @@ -103,6 +103,6 @@ export const QuoteWithoutIllustration = getStory({ export const QuoteWithAccent = getStory({ text: "Lorem [...] elit ut. ", image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", - className: "fr-quote--green-emeraude", + accentColor: "yellow-moutarde", author: "Someone" }); From 1d7b06169349920f50bc4992fe0cb344ea918773 Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Fri, 16 Dec 2022 00:45:12 +0100 Subject: [PATCH 6/7] Update src/Quote.tsx Co-authored-by: Joseph Garrone Signed-off-by: Julien Bouquillon --- src/Quote.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Quote.tsx b/src/Quote.tsx index a0e9d744e..a93fbc919 100644 --- a/src/Quote.tsx +++ b/src/Quote.tsx @@ -62,7 +62,7 @@ export const Quote = memo(
    {author &&

    {author}

    } {source &&
      {source}
    } - {image && ( + {image !== undefined && (
    From 57b52ff1ad40159988cf3d9f954e3a22cc667e9f Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Fri, 16 Dec 2022 01:06:39 +0100 Subject: [PATCH 7/7] fix: cleanup --- src/Quote.tsx | 58 +++++++++++++++++++++++++-------------- stories/Quote.stories.tsx | 14 +++++----- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/Quote.tsx b/src/Quote.tsx index a93fbc919..8fd21063e 100644 --- a/src/Quote.tsx +++ b/src/Quote.tsx @@ -2,25 +2,23 @@ import React, { memo, forwardRef, ReactNode } from "react"; import { symToStr } from "tsafe/symToStr"; import { assert } from "tsafe/assert"; import type { Equals } from "tsafe"; -import { fr } from "./lib"; + +import { FrClassName } from "./lib/generatedFromCss/classNames"; import { cx } from "./lib/tools/cx"; +import { fr } from "./lib"; -// We make users import dsfr.css, so we don't need to import the scoped CSS -// but in the future if we have a complete component coverage it -// we could stop requiring users to import the hole CSS and only import on a -// per component basis. import "./dsfr/component/quote/quote.css"; -import { FrClassName } from "./lib/generatedFromCss/classNames"; export type QuoteProps = { className?: string; - text: string; - author?: string; + text: ReactNode; + author?: ReactNode; source?: ReactNode; sourceUrl?: string; - image?: string; - size?: "md" | "lg" | "xl"; + imageUrl?: string; + size?: "medium" | "large" | "xlarge"; accentColor?: QuoteProps.AccentColor; + classes?: Partial>; }; export namespace QuoteProps { @@ -34,8 +32,18 @@ export namespace QuoteProps { /** @see */ export const Quote = memo( forwardRef((props, ref) => { - const { className, text, author, source, sourceUrl, image, size, accentColor, ...rest } = - props; + const { + className, + text, + author, + source, + sourceUrl, + imageUrl, + size = "xlarge", + accentColor, + classes = {}, + ...rest + } = props; assert>(); @@ -43,8 +51,9 @@ export const Quote = memo(

    « {text} »

    - {author &&

    {author}

    } - {source &&
      {source}
    } - {image !== undefined && ( -
    - + {author !== undefined && ( +

    {author}

    + )} + {source !== undefined && ( +
      {source}
    + )} + {imageUrl !== undefined && ( +
    +
    )}
    diff --git a/stories/Quote.stories.tsx b/stories/Quote.stories.tsx index 5abd3fdb7..86fd41e9a 100644 --- a/stories/Quote.stories.tsx +++ b/stories/Quote.stories.tsx @@ -35,8 +35,8 @@ export const Default = getStory({ ), - image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", - size: "xl", + imageUrl: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", + size: "xlarge", className: "" }); @@ -61,20 +61,20 @@ export const QuoteMediumAndAccent = getStory({ ), - image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", - size: "md", + imageUrl: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", + size: "medium", accentColor: "pink-macaron" }); export const QuoteWithoutDetails = getStory({ text: "Lorem [...] elit ut. ", author: "Auteur", - image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" + imageUrl: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" }); export const QuoteWithoutSource = getStory({ text: "Lorem [...] elit ut. ", - image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" + imageUrl: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png" }); export const QuoteWithoutIllustration = getStory({ @@ -102,7 +102,7 @@ export const QuoteWithoutIllustration = getStory({ export const QuoteWithAccent = getStory({ text: "Lorem [...] elit ut. ", - image: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", + imageUrl: "//www.systeme-de-design.gouv.fr/img/placeholder.1x1.png", accentColor: "yellow-moutarde", author: "Someone" });