diff --git a/packages/collections/src/list/shared.tsx b/packages/collections/src/list/shared.tsx index 52bbfe62e..34a6fa151 100644 --- a/packages/collections/src/list/shared.tsx +++ b/packages/collections/src/list/shared.tsx @@ -42,7 +42,7 @@ export function DefaultAddItemComponent({addItemHandler, i18nPrefix = "focus", m if (mode === "mosaic") { return (
- {{i18nKey: `${i18nPrefix}.icons.list.add`}} + {i18next.t(`${i18nPrefix}.list.add`)}
); diff --git a/packages/collections/src/list/table/header.tsx b/packages/collections/src/list/table/header.tsx index b94d3fab7..84f38a642 100644 --- a/packages/collections/src/list/table/header.tsx +++ b/packages/collections/src/list/table/header.tsx @@ -45,13 +45,13 @@ export function TableHeader({ } > {store && sortKey ? ( - - {{ + + /> ) : null} {i18next.t(title)} diff --git a/packages/collections/src/search/search-bar.tsx b/packages/collections/src/search/search-bar.tsx index 9a3a9a2be..ba127996f 100644 --- a/packages/collections/src/search/search-bar.tsx +++ b/packages/collections/src/search/search-bar.tsx @@ -194,9 +194,7 @@ export function SearchBar({
- - {{i18nKey: `${i18nPrefix}.icons.searchBar.search`}} - + + + diff --git a/packages/docs/.storybook/preview.tsx b/packages/docs/.storybook/preview.tsx index 8beeffcd9..33a979a0e 100644 --- a/packages/docs/.storybook/preview.tsx +++ b/packages/docs/.storybook/preview.tsx @@ -2,7 +2,8 @@ import "@focus4/styling/lib/focus4.styling.css"; import "@focus4/toolbox/lib/focus4.toolbox.css"; import "./preview.css"; -import {translation} from "@focus4/forms"; +import {translation as collections} from "@focus4/collections"; +import {translation as forms} from "@focus4/forms"; import {colorScheme, initColorScheme} from "@focus4/styling"; import {DocsContainer as BaseContainer} from "@storybook/blocks"; import type {Preview} from "@storybook/react"; @@ -19,7 +20,9 @@ initColorScheme(true); i18next.init({ lng: "fr", - resources: {fr: {translation: {focus: {...translation.fr, icons: translation.icons}}}}, + resources: { + fr: {translation: {focus: {...collections.fr, ...forms.fr, icons: {...collections.icons, ...forms.icons}}}} + }, nsSeparator: "đŸ€·â€â™‚ïž" }); @@ -30,12 +33,7 @@ function DocsContainer(props) { export default { parameters: { - actions: {argTypesRegex: "^on[A-Z].*"}, controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i - }, sort: "requiredFirst" }, docs: { @@ -48,6 +46,7 @@ export default { "Les bases", "ModĂšle mĂ©tier", "Composants", + ["Composants de base", "@focus4∕toolbox", "@focus4∕forms"], "Routage", "Mise en page", "Listes et recherche", diff --git a/packages/docs/components/components.mdx b/packages/docs/components/components.mdx new file mode 100644 index 000000000..182bb297b --- /dev/null +++ b/packages/docs/components/components.mdx @@ -0,0 +1,24 @@ +import {Meta} from "@storybook/blocks"; + + + +# Composants de base + +Focus met Ă  disposition une sĂ©rie de composants de base qui implĂ©mentent [Material Design 3](https://m3.material.io/components) (avec quelques adaptations). + +Ces composants cherchent Ă  couvrir les besoins les plus standards d'une application, tout en offrant un niveau de personnalisation Ă©levĂ© pour couvrir un +maximum de cas. + +- Le module `@focus4/toolbox` contient les versions de base de ces composants, qui sont directement repris de la spĂ©cification Material Design. +- Le module `@focus4/forms` contient : + - Quelques "surcharges" de ces composants pour pouvoir s'interfacer directement avec un formulaire (`Input` pour `TextField` et `Select` pour + `Dropdown` par exemple) + - Des composants un peu plus avancĂ©s qui combinent des composants de base pour rĂ©aliser des saisies plus complexes (comme `InputDate` ou + `SelectChips`), ou simplifier des cas d'usage courants (comme `BooleanRadio` ou `SelectCheckbox`). Ces composants n'existent pas en tant que + tels dans la spĂ©cification Material Design. + - Les composants d'affichage pour les formulaires (`Display`, `Label` et `Panel`) + +**Un composant de saisie d'un domaine pour un champ doit venir du module `@focus4/forms`**, car il doit respecter le contrat d'interface correspondant du +domaine (`BaseInputProps` / `BaseSelectProps` / `BaseAutocompleteProps`). Si vous voulez construire votre propre composant de saisie, vous pouvez +reproduire ce que font les composants de `@focus4/forms`, en particulier la gestion du `type`, du `onChange`, de l'`error` et du `supportingText`. Ce +mĂ©canisme a vocation Ă  ĂȘtre amĂ©liorĂ© dans le futur, et est suivi par l'[issue #192](https://github.com/klee-contrib/focus4/issues/192) sur Github. diff --git a/packages/docs/components/forms/AutocompleteChips.stories.tsx b/packages/docs/components/forms/AutocompleteChips.stories.tsx index d0ef7f81a..fa864de4c 100644 --- a/packages/docs/components/forms/AutocompleteChips.stories.tsx +++ b/packages/docs/components/forms/AutocompleteChips.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...AutocompleteChipsMeta, title: "Composants/@focus4∕forms/AutocompleteChips", + tags: ["autodocs"], args: {type: "string"} } as Meta; diff --git a/packages/docs/components/forms/AutocompleteSearch.stories.tsx b/packages/docs/components/forms/AutocompleteSearch.stories.tsx index 013b14087..2b3e85015 100644 --- a/packages/docs/components/forms/AutocompleteSearch.stories.tsx +++ b/packages/docs/components/forms/AutocompleteSearch.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...AutocompleteSearchMeta, title: "Composants/@focus4∕forms/AutocompleteSearch", + tags: ["autodocs"], args: {type: "string"} } as Meta; diff --git a/packages/docs/components/forms/BooleanRadio.stories.tsx b/packages/docs/components/forms/BooleanRadio.stories.tsx index 26c56f508..6165053fb 100644 --- a/packages/docs/components/forms/BooleanRadio.stories.tsx +++ b/packages/docs/components/forms/BooleanRadio.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...BooleanRadioMeta, title: "Composants/@focus4∕forms/BooleanRadio", + tags: ["autodocs"], args: {type: "boolean"} } as Meta; diff --git a/packages/docs/components/forms/Display.stories.tsx b/packages/docs/components/forms/Display.stories.tsx index 2a420f20a..507d1af8f 100644 --- a/packages/docs/components/forms/Display.stories.tsx +++ b/packages/docs/components/forms/Display.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...DisplayMeta, title: "Composants/@focus4∕forms/Display", + tags: ["autodocs"], args: {type: "string", value: "Valeur"} } as Meta; diff --git a/packages/docs/components/forms/Input.stories.tsx b/packages/docs/components/forms/Input.stories.tsx index 13ec97b25..48a07371e 100644 --- a/packages/docs/components/forms/Input.stories.tsx +++ b/packages/docs/components/forms/Input.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...InputMeta, title: "Composants/@focus4∕forms/Input", + tags: ["autodocs"], args: {type: "string"} } as Meta; diff --git a/packages/docs/components/forms/InputDate.stories.tsx b/packages/docs/components/forms/InputDate.stories.tsx index 038e8f569..bf7c515fb 100644 --- a/packages/docs/components/forms/InputDate.stories.tsx +++ b/packages/docs/components/forms/InputDate.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...InputDateMeta, title: "Composants/@focus4∕forms/InputDate", + tags: ["autodocs"], args: {type: "string"} } as Meta; diff --git a/packages/docs/components/forms/Label.stories.tsx b/packages/docs/components/forms/Label.stories.tsx index a810353a5..b2198d0e4 100644 --- a/packages/docs/components/forms/Label.stories.tsx +++ b/packages/docs/components/forms/Label.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...LabelMeta, title: "Composants/@focus4∕forms/Label", + tags: ["autodocs"], args: {label: "Label"} } as Meta; diff --git a/packages/docs/components/forms/Panel.stories.tsx b/packages/docs/components/forms/Panel.stories.tsx index f1a3aa0c7..a56e85121 100644 --- a/packages/docs/components/forms/Panel.stories.tsx +++ b/packages/docs/components/forms/Panel.stories.tsx @@ -6,7 +6,8 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...PanelMeta, - title: "Composants/@focus4∕forms/Panel" + title: "Composants/@focus4∕forms/Panel", + tags: ["autodocs"] } as Meta; export const Showcase: StoryObj = {}; diff --git a/packages/docs/components/forms/PanelButtons.stories.tsx b/packages/docs/components/forms/PanelButtons.stories.tsx index b3ddefc74..e61d29a71 100644 --- a/packages/docs/components/forms/PanelButtons.stories.tsx +++ b/packages/docs/components/forms/PanelButtons.stories.tsx @@ -6,7 +6,8 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...PanelButtonsMeta, - title: "Composants/@focus4∕forms/PanelButtons" + title: "Composants/@focus4∕forms/PanelButtons", + tags: ["autodocs"] } as Meta; export const Showcase: StoryObj = {}; diff --git a/packages/docs/components/forms/Select.stories.tsx b/packages/docs/components/forms/Select.stories.tsx index ca125c5a3..0b245b047 100644 --- a/packages/docs/components/forms/Select.stories.tsx +++ b/packages/docs/components/forms/Select.stories.tsx @@ -8,6 +8,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...SelectMeta, title: "Composants/@focus4∕forms/Select", + tags: ["autodocs"], args: { type: "string", values: makeReferenceList([ diff --git a/packages/docs/components/forms/SelectAutocomplete.stories.tsx b/packages/docs/components/forms/SelectAutocomplete.stories.tsx index 88dab0b1f..610b4b3d7 100644 --- a/packages/docs/components/forms/SelectAutocomplete.stories.tsx +++ b/packages/docs/components/forms/SelectAutocomplete.stories.tsx @@ -8,6 +8,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...SelectAutocompleteMeta, title: "Composants/@focus4∕forms/SelectAutocomplete", + tags: ["autodocs"], args: { type: "string-array", values: makeReferenceList([ diff --git a/packages/docs/components/forms/SelectCheckbox.stories.tsx b/packages/docs/components/forms/SelectCheckbox.stories.tsx index adf9d2b56..e9ccc00f3 100644 --- a/packages/docs/components/forms/SelectCheckbox.stories.tsx +++ b/packages/docs/components/forms/SelectCheckbox.stories.tsx @@ -8,6 +8,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...SelectCheckboxMeta, title: "Composants/@focus4∕forms/SelectCheckbox", + tags: ["autodocs"], args: { type: "string-array", values: makeReferenceList([ diff --git a/packages/docs/components/forms/SelectChips.stories.tsx b/packages/docs/components/forms/SelectChips.stories.tsx index c6f4ae6aa..d86b01f25 100644 --- a/packages/docs/components/forms/SelectChips.stories.tsx +++ b/packages/docs/components/forms/SelectChips.stories.tsx @@ -8,6 +8,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...SelectChipsMeta, title: "Composants/@focus4∕forms/SelectChips", + tags: ["autodocs"], args: { type: "string-array", values: makeReferenceList([ diff --git a/packages/docs/components/forms/SelectRadio.stories.tsx b/packages/docs/components/forms/SelectRadio.stories.tsx index 527403f79..a74ac74fc 100644 --- a/packages/docs/components/forms/SelectRadio.stories.tsx +++ b/packages/docs/components/forms/SelectRadio.stories.tsx @@ -8,6 +8,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...SelectRadioMeta, title: "Composants/@focus4∕forms/SelectRadio", + tags: ["autodocs"], args: { type: "string", values: makeReferenceList([ diff --git a/packages/docs/components/toolbox/Autocomplete.stories.tsx b/packages/docs/components/toolbox/Autocomplete.stories.tsx index aad38c676..cf295b127 100644 --- a/packages/docs/components/toolbox/Autocomplete.stories.tsx +++ b/packages/docs/components/toolbox/Autocomplete.stories.tsx @@ -1,3 +1,5 @@ +import {useState} from "react"; + import {Autocomplete} from "@focus4/toolbox"; import {AutocompleteMeta} from "./metas/autocomplete"; @@ -7,6 +9,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...AutocompleteMeta, title: "Composants/@focus4∕toolbox/Autocomplete", + tags: ["autodocs"], args: { values: [ {key: "1", label: "Option 1"}, @@ -15,4 +18,28 @@ export default { } } as Meta; -export const Showcase: StoryObj = {}; +export const Showcase: StoryObj = { + render(props) { + const [selected, setSelected] = useState(); + const [selected2, setSelected2] = useState(); + return ( +
+ setSelected(undefined)}} + value={selected} + {...props} + onChange={setSelected} + /> + + +
+ ); + } +}; diff --git a/packages/docs/components/toolbox/Button.stories.tsx b/packages/docs/components/toolbox/Button.stories.tsx index 92dd53d4d..0d664a99b 100644 --- a/packages/docs/components/toolbox/Button.stories.tsx +++ b/packages/docs/components/toolbox/Button.stories.tsx @@ -6,6 +6,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...ButtonMeta, title: "Composants/@focus4∕toolbox/Button", + tags: ["autodocs"], args: { label: "Button" } diff --git a/packages/docs/components/toolbox/Calendar.stories.tsx b/packages/docs/components/toolbox/Calendar.stories.tsx index 7a82e986b..4f787f18f 100644 --- a/packages/docs/components/toolbox/Calendar.stories.tsx +++ b/packages/docs/components/toolbox/Calendar.stories.tsx @@ -8,7 +8,8 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...CalendarMeta, - title: "Composants/@focus4∕toolbox/Calendar" + title: "Composants/@focus4∕toolbox/Calendar", + tags: ["autodocs"] } as Meta; export const Showcase: StoryObj = { diff --git a/packages/docs/components/toolbox/Checkbox.stories.tsx b/packages/docs/components/toolbox/Checkbox.stories.tsx index 2831013ca..fee462dfb 100644 --- a/packages/docs/components/toolbox/Checkbox.stories.tsx +++ b/packages/docs/components/toolbox/Checkbox.stories.tsx @@ -8,7 +8,8 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...CheckboxMeta, - title: "Composants/@focus4∕toolbox/Checkbox" + title: "Composants/@focus4∕toolbox/Checkbox", + tags: ["autodocs"] } as Meta; export const Showcase: StoryObj = { diff --git a/packages/docs/components/toolbox/Chip.stories.tsx b/packages/docs/components/toolbox/Chip.stories.tsx index 0467abd40..22c1acf91 100644 --- a/packages/docs/components/toolbox/Chip.stories.tsx +++ b/packages/docs/components/toolbox/Chip.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...ChipMeta, title: "Composants/@focus4∕toolbox/Chip", + tags: ["autodocs"], args: { label: "Chip" } diff --git a/packages/docs/components/toolbox/CircularProgressIndicator.stories.tsx b/packages/docs/components/toolbox/CircularProgressIndicator.stories.tsx index def91f5cb..c695469a5 100644 --- a/packages/docs/components/toolbox/CircularProgressIndicator.stories.tsx +++ b/packages/docs/components/toolbox/CircularProgressIndicator.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...CircularProgressIndicatorMeta, title: "Composants/@focus4∕toolbox/CircularProgressIndicator", + tags: ["autodocs"], args: { value: 55 } diff --git a/packages/docs/components/toolbox/Dropdown.stories.tsx b/packages/docs/components/toolbox/Dropdown.stories.tsx index 36f91eec7..d7b2c9596 100644 --- a/packages/docs/components/toolbox/Dropdown.stories.tsx +++ b/packages/docs/components/toolbox/Dropdown.stories.tsx @@ -9,6 +9,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...DropdownMeta, title: "Composants/@focus4∕toolbox/Dropdown", + tags: ["autodocs"], args: { values: [ {key: "1", label: "Option 1"}, diff --git a/packages/docs/components/toolbox/FloatingActionButton.stories.tsx b/packages/docs/components/toolbox/FloatingActionButton.stories.tsx index 82d7813be..85e5153b5 100644 --- a/packages/docs/components/toolbox/FloatingActionButton.stories.tsx +++ b/packages/docs/components/toolbox/FloatingActionButton.stories.tsx @@ -9,6 +9,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...FloatingActionButtonMeta, title: "Composants/@focus4∕toolbox/FloatingActionButton", + tags: ["autodocs"], args: { icon: "add", label: "Ajouter" diff --git a/packages/docs/components/toolbox/FontIcon.stories.tsx b/packages/docs/components/toolbox/FontIcon.stories.tsx index fa2d64d10..840b76562 100644 --- a/packages/docs/components/toolbox/FontIcon.stories.tsx +++ b/packages/docs/components/toolbox/FontIcon.stories.tsx @@ -7,7 +7,26 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...FontIconMeta, title: "Composants/@focus4∕toolbox/FontIcon", - args: {children: "add"} + tags: ["autodocs"], + args: { + children: "lightbulb" + } } as Meta; -export const Showcase: StoryObj = {}; +export const Showcase: StoryObj = { + render(props) { + return ( +
+
+ + + +
+
+
+ +
+
+ ); + } +}; diff --git a/packages/docs/components/toolbox/IconButton.stories.tsx b/packages/docs/components/toolbox/IconButton.stories.tsx index 170418c84..cc5c1635b 100644 --- a/packages/docs/components/toolbox/IconButton.stories.tsx +++ b/packages/docs/components/toolbox/IconButton.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...IconButtonMeta, title: "Composants/@focus4∕toolbox/IconButton", + tags: ["autodocs"], args: { icon: "add" } diff --git a/packages/docs/components/toolbox/LinearProgressIndicator.stories.tsx b/packages/docs/components/toolbox/LinearProgressIndicator.stories.tsx index 114c9f7a5..4b1cbe23e 100644 --- a/packages/docs/components/toolbox/LinearProgressIndicator.stories.tsx +++ b/packages/docs/components/toolbox/LinearProgressIndicator.stories.tsx @@ -7,6 +7,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...LinearProgressIndicatorMeta, title: "Composants/@focus4∕toolbox/LinearProgressIndicator", + tags: ["autodocs"], args: { value: 55 } diff --git a/packages/docs/components/toolbox/Menu.mdx b/packages/docs/components/toolbox/Menu.mdx new file mode 100644 index 000000000..1b9b52673 --- /dev/null +++ b/packages/docs/components/toolbox/Menu.mdx @@ -0,0 +1,18 @@ +import {Meta, Description, Title, Controls, Canvas} from "@storybook/blocks"; + +import MenuStories, {Showcase} from "./Menu.stories"; +import MenuItemStories, {Showcase as MenuItem} from "./MenuItem.stories"; + + + + +<Description /> + +<Canvas of={Showcase} /> + +<Controls of={Showcase} /> + +<Title>{MenuItemStories.title.split("/")[2]} +{MenuItemStories.parameters.docs.description.component} + + diff --git a/packages/docs/components/toolbox/Menu.stories.tsx b/packages/docs/components/toolbox/Menu.stories.tsx index c92b7d16a..52a2403da 100644 --- a/packages/docs/components/toolbox/Menu.stories.tsx +++ b/packages/docs/components/toolbox/Menu.stories.tsx @@ -1,4 +1,4 @@ -import {IconButton, Menu, MenuItem, useMenu} from "@focus4/toolbox"; +import {Button, IconButton, Menu, MenuItem, useMenu} from "@focus4/toolbox"; import {MenuMeta} from "./metas/menu"; @@ -12,13 +12,24 @@ export default { export const Showcase: StoryObj = { render() { const menu = useMenu(); + const menu2 = useMenu(); return ( -
- - - - - +
+
+ + + + + +
+
+
); } diff --git a/packages/docs/components/toolbox/MenuItem.stories.tsx b/packages/docs/components/toolbox/MenuItem.stories.tsx index c6de4c2e5..0c42268b4 100644 --- a/packages/docs/components/toolbox/MenuItem.stories.tsx +++ b/packages/docs/components/toolbox/MenuItem.stories.tsx @@ -6,8 +6,7 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...MenuItemMeta, - title: "Composants/@focus4∕toolbox/MenuItem", - args: {caption: "Action"} + title: "Composants/@focus4∕toolbox/MenuItem" } as Meta; export const Showcase: StoryObj = {}; diff --git a/packages/docs/components/toolbox/RadioButton.mdx b/packages/docs/components/toolbox/RadioButton.mdx new file mode 100644 index 000000000..4b1d3b8f9 --- /dev/null +++ b/packages/docs/components/toolbox/RadioButton.mdx @@ -0,0 +1,18 @@ +import {Meta, Description, Title, Controls, Canvas} from "@storybook/blocks"; + +import RadioButtonStories, {Showcase} from "./RadioButton.stories"; +import RadioGroupStories, {Showcase as RadioGroup} from "./RadioGroup.stories"; + + + + +<Description /> + +<Canvas of={Showcase} /> + +<Controls of={Showcase} /> + +<Title>{RadioGroupStories.title.split("/")[2]} +{RadioGroupStories.parameters.docs.description.component} + + diff --git a/packages/docs/components/toolbox/RadioButton.stories.tsx b/packages/docs/components/toolbox/RadioButton.stories.tsx index 4267817cf..b5f0f50e8 100644 --- a/packages/docs/components/toolbox/RadioButton.stories.tsx +++ b/packages/docs/components/toolbox/RadioButton.stories.tsx @@ -1,4 +1,6 @@ -import {RadioButton} from "@focus4/toolbox"; +import {useState} from "react"; + +import {RadioButton, RadioGroup} from "@focus4/toolbox"; import {RadioButtonMeta} from "./metas/radio-button"; @@ -9,4 +11,15 @@ export default { title: "Composants/@focus4∕toolbox/RadioButton" } as Meta; -export const Showcase: StoryObj = {}; +export const Showcase: StoryObj> = { + render(props) { + const [value, setValue] = useState(); + return ( + + + + + + ); + } +}; diff --git a/packages/docs/components/toolbox/Ripple.stories.tsx b/packages/docs/components/toolbox/Ripple.stories.tsx index 9b0ca2491..5ded9a7e2 100644 --- a/packages/docs/components/toolbox/Ripple.stories.tsx +++ b/packages/docs/components/toolbox/Ripple.stories.tsx @@ -6,14 +6,24 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...RippleMeta, - title: "Composants/@focus4∕toolbox/Ripple" + title: "Composants/@focus4∕toolbox/Ripple", + tags: ["autodocs"] } as Meta; export const Showcase: StoryObj = { render(props) { return ( -
Test
+
+ Test +
); } diff --git a/packages/docs/components/toolbox/Slider.stories.tsx b/packages/docs/components/toolbox/Slider.stories.tsx index 6e2371f89..aa7faf555 100644 --- a/packages/docs/components/toolbox/Slider.stories.tsx +++ b/packages/docs/components/toolbox/Slider.stories.tsx @@ -1,3 +1,5 @@ +import {useState} from "react"; + import {Slider} from "@focus4/toolbox"; import {SliderMeta} from "./metas/slider"; @@ -6,7 +8,19 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...SliderMeta, - title: "Composants/@focus4∕toolbox/Slider" + title: "Composants/@focus4∕toolbox/Slider", + tags: ["autodocs"] } as Meta; -export const Showcase: StoryObj = {}; +export const Showcase: StoryObj> = { + render(props) { + const [selected, setSelected] = useState(23); + const [selected2, setSelected2] = useState(45); + return ( +
+ + +
+ ); + } +}; diff --git a/packages/docs/components/toolbox/Snackbar.stories.tsx b/packages/docs/components/toolbox/Snackbar.stories.tsx index 59f680792..7994a6865 100644 --- a/packages/docs/components/toolbox/Snackbar.stories.tsx +++ b/packages/docs/components/toolbox/Snackbar.stories.tsx @@ -7,7 +7,15 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...SnackbarMeta, title: "Composants/@focus4∕toolbox/Snackbar", - args: {active: true, message: "Salut"} + tags: ["autodocs"], + args: { + active: true, + message: "Salut", + close: () => { + /* */ + }, + action: {label: "Action"} + } } as Meta; export const Showcase: StoryObj = {}; diff --git a/packages/docs/components/toolbox/Switch.stories.tsx b/packages/docs/components/toolbox/Switch.stories.tsx index a965be0d0..8015330b6 100644 --- a/packages/docs/components/toolbox/Switch.stories.tsx +++ b/packages/docs/components/toolbox/Switch.stories.tsx @@ -8,7 +8,8 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...SwitchMeta, - title: "Composants/@focus4∕toolbox/Switch" + title: "Composants/@focus4∕toolbox/Switch", + tags: ["autodocs"] } as Meta; export const Showcase: StoryObj = { diff --git a/packages/docs/components/toolbox/Tabs.mdx b/packages/docs/components/toolbox/Tabs.mdx new file mode 100644 index 000000000..e7e05b8c6 --- /dev/null +++ b/packages/docs/components/toolbox/Tabs.mdx @@ -0,0 +1,18 @@ +import {Meta, Description, Title, Controls, Canvas} from "@storybook/blocks"; + +import TabsStories, {Showcase} from "./Tabs.stories"; +import TabStories, {Showcase as Tab} from "./Tab.stories"; + + + + +<Description /> + +<Canvas of={Showcase} /> + +<Controls of={Showcase} /> + +<Title>{TabStories.title.split("/")[2]} +{TabStories.parameters.docs.description.component} + + diff --git a/packages/docs/components/toolbox/Tabs.stories.tsx b/packages/docs/components/toolbox/Tabs.stories.tsx index ba614fb7b..3f7de0e5f 100644 --- a/packages/docs/components/toolbox/Tabs.stories.tsx +++ b/packages/docs/components/toolbox/Tabs.stories.tsx @@ -1,4 +1,6 @@ -import {Tabs} from "@focus4/toolbox"; +import {useState} from "react"; + +import {Tab, Tabs} from "@focus4/toolbox"; import {TabsMeta} from "./metas/tabs"; @@ -9,4 +11,43 @@ export default { title: "Composants/@focus4∕toolbox/Tabs" } as Meta; -export const Showcase: StoryObj = {}; +export const Showcase: StoryObj = { + render(props) { + const [tab1, setTab1] = useState(0); + const [tab2, setTab2] = useState(0); + + return ( +
+ + + + + + + +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut + labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in + voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat + cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+
+ +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut + labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit +

+
+ +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut + labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco +

+
+
+
+ ); + } +}; diff --git a/packages/docs/components/toolbox/TextField.stories.tsx b/packages/docs/components/toolbox/TextField.stories.tsx index b84dba686..aab377de2 100644 --- a/packages/docs/components/toolbox/TextField.stories.tsx +++ b/packages/docs/components/toolbox/TextField.stories.tsx @@ -6,7 +6,8 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...TextFieldMeta, - title: "Composants/@focus4∕toolbox/TextField" + title: "Composants/@focus4∕toolbox/TextField", + tags: ["autodocs"] } as Meta; export const Showcase: StoryObj = { diff --git a/packages/docs/components/toolbox/Tooltip.stories.tsx b/packages/docs/components/toolbox/Tooltip.stories.tsx index ee5f717bd..b5a76c89a 100644 --- a/packages/docs/components/toolbox/Tooltip.stories.tsx +++ b/packages/docs/components/toolbox/Tooltip.stories.tsx @@ -7,15 +7,18 @@ import type {Meta, StoryObj} from "@storybook/react"; export default { ...TooltipMeta, title: "Composants/@focus4∕toolbox/Tooltip", + tags: ["autodocs"], args: {tooltip: "Tooltip"} } as Meta; export const Showcase: StoryObj = { render(props) { return ( - -
Test
-
+
+ +
Test
+
+
); } }; diff --git a/packages/forms/src/components/label.tsx b/packages/forms/src/components/label.tsx index 377bb7a0d..d7602f84d 100644 --- a/packages/forms/src/components/label.tsx +++ b/packages/forms/src/components/label.tsx @@ -60,9 +60,11 @@ export function Label({ onClick={onTooltipClick} /> ) : ( - - {{i18nKey: `${i18nPrefix}.icons.label.tooltip`}} - + )} ) : null} diff --git a/packages/layout/src/menu/item.tsx b/packages/layout/src/menu/item.tsx index 1fa570f26..35d20ae60 100644 --- a/packages/layout/src/menu/item.tsx +++ b/packages/layout/src/menu/item.tsx @@ -115,7 +115,7 @@ export function MainMenuItem({ {createElement( element, props, - icon ? {icon} : null, + icon ? : null, label ?
{label}
: null )} diff --git a/packages/toolbox/src/components/autocomplete.tsx b/packages/toolbox/src/components/autocomplete.tsx index 10f12b12f..1242769ca 100644 --- a/packages/toolbox/src/components/autocomplete.tsx +++ b/packages/toolbox/src/components/autocomplete.tsx @@ -78,7 +78,12 @@ const defaultGetKey = (x: any) => x.key; const defaultGetLabel = (x: any) => x.label; /** - * Champ de saisie en autocomplĂ©tion Ă  partir d'une **liste de valeurs possibles en entrĂ©e**. + * Un Autocomplete combine un champ texte en autocomplĂ©tion avec un menu dĂ©roulant, pour effectuer une sĂ©lection parmi une **liste de valeurs disponibles en entrĂ©e**. + * + * - Le filtrage des valeurs s'effecue dans le composant selon plusieurs modes de correspondance. + * - Toutes les options du champ texte sont disponibles. + * - Peut ĂȘtre utilisĂ© comme un champ de recherche rapide. + * - Peut afficher des suggestions complĂ©mentaires. */ export const Autocomplete = forwardRef(function Autocomplete( { diff --git a/packages/toolbox/src/components/button.tsx b/packages/toolbox/src/components/button.tsx index 5bae9acc2..7968ae331 100644 --- a/packages/toolbox/src/components/button.tsx +++ b/packages/toolbox/src/components/button.tsx @@ -126,7 +126,7 @@ export function Button({ {createElement( element, props, - icon ? {icon} : null, + icon ? : null, {label ?? "\xa0"} )} diff --git a/packages/toolbox/src/components/chip.tsx b/packages/toolbox/src/components/chip.tsx index d76b96fa9..9e00130f1 100644 --- a/packages/toolbox/src/components/chip.tsx +++ b/packages/toolbox/src/components/chip.tsx @@ -117,7 +117,7 @@ export function Chip({ {createElement( element, props, - icon ? {icon} : null, + icon ? : null, onDeleteClick ? ( {icon} : null, + icon ? : null, { alt?: string; /** Classe CSS Ă  poser sur le composant racine. */ className?: string; - /** IcĂŽne Ă  afficher. */ - children: Icon; - /** Styles inline */ + /** + * Nom de l'icĂŽne Ă  afficher. Ne sera pas posĂ© en enfant du si la classe CSS de l'icĂŽne est un template de `{name}`. + * + * IgnorĂ© si `iconI18nKey` est renseignĂ©. + */ + children?: string; + /** + * DĂ©finition d'icĂŽne mixte, peut ĂȘtre utilisĂ© Ă  la place de `children` / `iconClassName` / `iconI18nKey`. + * + * N'a pas la prioritĂ© sur ces dĂ©finitions-lĂ . + */ + icon?: Icon; + /** + * Classe CSS de l'icĂŽne, pour retrouver la police associĂ©e. Peut ĂȘtre utilisĂ©e comme template du nom de l'icĂŽne (en y remplaçant `{name}`). + * + * IgnorĂ© si `iconI18nKey` est renseignĂ©. + */ + iconClassName?: string; + /** + * ClĂ© i18n pour retrouver l'icĂŽne. Doit correspondre Ă  un objet `{name, className?}`. + * + * Remplace `children` et `iconClassName`. + */ + iconI18nKey?: string; + /** Styles inline. */ style?: CSSProperties; } /** - * Affiche une icĂŽne. Prend une `Icon` comme enfant. + * Affiche une icĂŽne. Une icĂŽne est dĂ©finie par son nom et sa classe CSS, qui servira Ă  retrouver la police d'icĂŽne associĂ©e. + * + * Une icĂŽne dĂ©finie avec seulement un nom utilisera la classe CSS dĂ©finie dans `config.defaultIconClassName` (par dĂ©faut : `"material-icons"`). + * + * La classe CSS sera interprĂ©tĂ©e comme un template du nom si elle contient `{name}` dans sa dĂ©finition. + * Dans ce cas, le `name` ne sera pas posĂ© en enfant du `` qui dĂ©finira l'icĂŽne. + * + * Une icĂŽne peut Ă©galement ĂȘtre dĂ©finie via une clĂ© i18n, qui devra pointer vers un objet `{name, className?}` reprĂ©sentant l'icĂŽne. */ export function FontIcon({ + icon, alt = "", className = "", - children, + children = typeof icon === "string" ? icon : typeof icon === "object" && "name" in icon ? icon.name : undefined, + iconClassName = typeof icon === "object" && "className" in icon ? icon.className : config.defaultIconClassName, + iconI18nKey = typeof icon === "object" && "i18nKey" in icon ? icon.i18nKey : undefined, onPointerDown, onPointerEnter, onPointerLeave, onPointerUp, style }: FontIconProps) { - let inputClassName = config.defaultIconClassName; - let inputName; - - if (typeof children === "string") { - inputName = children; - } else if ("name" in children) { - inputName = children.name; - if (children.className) { - inputClassName = children.className; + if (iconI18nKey) { + const nameKey = `${iconI18nKey}.name`; + const i18nName = i18next.t(nameKey); + if (i18nName !== nameKey) { + children = i18nName; } - } else { - inputName = i18next.t(`${children.i18nKey}.name`); - const classNameKey = `${children.i18nKey}.className`; + const classNameKey = `${iconI18nKey}.className`; const i18nClassName = i18next.t(classNameKey); if (i18nClassName !== classNameKey) { - inputClassName = i18nClassName; + iconClassName = i18nClassName; } } let baseClassName; let name; - if (inputClassName.includes("{name}")) { - baseClassName = inputClassName.replaceAll("{name}", inputName); + if (iconClassName.includes("{name}")) { + baseClassName = iconClassName.replaceAll("{name}", children ?? ""); } else { - baseClassName = inputClassName; - name = inputName; + baseClassName = iconClassName; + name = children; } return ( diff --git a/packages/toolbox/src/components/icon-button.tsx b/packages/toolbox/src/components/icon-button.tsx index cf3b1fcb3..c71d603a6 100644 --- a/packages/toolbox/src/components/icon-button.tsx +++ b/packages/toolbox/src/components/icon-button.tsx @@ -117,7 +117,7 @@ export function IconButton({ onPointerLeave={handlePointerLeave} onPointerUp={handlePointerUp} > - {createElement(element, props, {icon})} + {createElement(element, props, )} ); } diff --git a/packages/toolbox/src/components/menu.tsx b/packages/toolbox/src/components/menu.tsx index 58c2123bb..f3306515f 100644 --- a/packages/toolbox/src/components/menu.tsx +++ b/packages/toolbox/src/components/menu.tsx @@ -134,7 +134,7 @@ export interface MenuItemProps extends PointerEvents { } /** - * Item de Menu a utiliser dans un `Menu`. + * Composant gĂ©nĂ©rique Ă  inclure dans un `Menu`, comprenant un libellĂ© et d'Ă©ventuelles icĂŽnes Ă  l'avant et l'arriĂšre. */ export function MenuItem({ caption, @@ -157,9 +157,9 @@ export function MenuItem({ onPointerUp={onPointerUp} > - {iconLeft ? {iconLeft} : null} + {iconLeft ? : null} {caption} - {iconRight ? {iconRight} : null} + {iconRight ? : null} ); @@ -179,7 +179,13 @@ export function useMenu(): MenuControls< } /** - * Menu dĂ©roulant. Peut s'attacher Ă  un Ă©lĂ©ment parent. A utiliser avec `useMenu()`. + * Un menu permet d'afficher une zone temporaire pour afficher une liste de valeurs qu'un utilisateur peut sĂ©lectionner. + * Il doit s'attacher Ă  un Ă©lĂ©ment parent comme un `Button` ou un `TextField`. + * + * Le hook `useMenu()` permet de crĂ©er les Ă©lĂ©ments nĂ©cessaires pour l'attacher et contrĂŽler son affichage. + * + * L'Ă©lĂ©ment gĂ©nĂ©rique d'un menu est le `MenuItem`, mais il est possible d'y mettre toute sorte de composant Ă  l'intĂ©rieur. + * L'`Autocomplete`, le `Dropdown` ou encore l'`InputDate` utilisent un `Menu` pour afficher leurs listes de sĂ©lection/le calendrier. */ export function Menu({ active, diff --git a/packages/toolbox/src/components/radio.tsx b/packages/toolbox/src/components/radio.tsx index 06d1c55d7..d8cdb6bc1 100644 --- a/packages/toolbox/src/components/radio.tsx +++ b/packages/toolbox/src/components/radio.tsx @@ -40,7 +40,9 @@ export interface RadioButtonProps extends PointerEvents { } /** - * A utiliser dans un RadioGroup. + * Un bouton radio permet aux utilisateurs de choisir une option parmi un ensemble de valeurs. + * + * Un ensemble de `RadioButton` doit ĂȘtre contenu dans un `RadioGroup`. */ export function RadioButton({ className = "", @@ -121,7 +123,10 @@ export interface RadioGroupProps { } /** - * A utiliser avec RadioButton pour faire des radios. Les composants [`BooleanRadio`](components/forms.md#booleanradio) et [`SelectRadio`](components/forms.md#selectradio) en sont des implĂ©mentations pour les usages les plus courants. + * Conteneur pour un ensemble de `RadioButton`, permettant de former un champ de saisie unique. + * + * Les composants `BooleanRadio` et `SelectRadio` sont des implĂ©mentations de plus haut niveau qui couvrent la plupart des cas d'utilisation + * et sont Ă  privilĂ©gier par rapport Ă  l'usage direct d'un `RadioGroup` et de `RadioButton`. */ export function RadioGroup({className = "", children, disabled = false, onChange, value}: RadioGroupProps) { const ctx = useMemo(() => ({disabled, onChange, value}), [disabled, onChange, value]); diff --git a/packages/toolbox/src/components/ripple.tsx b/packages/toolbox/src/components/ripple.tsx index 5ac194d6d..5dc572cc6 100644 --- a/packages/toolbox/src/components/ripple.tsx +++ b/packages/toolbox/src/components/ripple.tsx @@ -22,7 +22,9 @@ export interface RippleProps extends Pointe } /** - * Pose un Ripple au clic sur le composant/Ă©lĂ©ment enfant. + * Le `Ripple` est un composant Ă  poser autour d'un autre Ă©lĂ©ment pour y ajouter un effet "ripple" lors du clic. + * + * Tous les composants qui attendent un clic d'un utilisateur dans leur action principale en sont munis. */ export function Ripple({ centered, diff --git a/packages/toolbox/src/components/slider.tsx b/packages/toolbox/src/components/slider.tsx index 9d5daae97..75a7e669d 100644 --- a/packages/toolbox/src/components/slider.tsx +++ b/packages/toolbox/src/components/slider.tsx @@ -34,7 +34,13 @@ export interface SliderProps extends PointerEvents { value: number; } -/** Slider. */ +/** + * Un slider permet Ă  un utilisateur de choisir une valeur numĂ©rique dans un intervalle donnĂ©. + * + * - Le pas du slider peut ĂȘtre configurĂ©. + * - Peut indiquer la valeur prĂ©cise lors l'interaction. + * - Peut afficher un indicateur Ă  chaque pas sur le slider. + */ export function Slider({ className, disabled = false, diff --git a/packages/toolbox/src/components/snackbar.tsx b/packages/toolbox/src/components/snackbar.tsx index 416fab2f4..6149441be 100644 --- a/packages/toolbox/src/components/snackbar.tsx +++ b/packages/toolbox/src/components/snackbar.tsx @@ -31,7 +31,12 @@ export interface SnackbarProps { } /** - * Le composant pour afficher des toasts utilisĂ© par le [`MessageCenter`](basics/messages.md). + * Une snackbar affiche un message court Ă  un utilisateur en bas de l'Ă©cran pour le notifier du status d'une action dans l'application. + * + * Elle est posĂ©e par dĂ©faut par le `MessageCenter` du `Layout`. + * + * - 4 types de messages : succĂšs, erreur, avertissement ou information + * - Peut inclure une action. */ export function Snackbar({active, action, className, close, level, message, onClose, theme: pTheme}: SnackbarProps) { const theme = useTheme("snackbar", snackbarCss, pTheme); diff --git a/packages/toolbox/src/components/switch.tsx b/packages/toolbox/src/components/switch.tsx index 7e9198a4d..359838002 100644 --- a/packages/toolbox/src/components/switch.tsx +++ b/packages/toolbox/src/components/switch.tsx @@ -99,8 +99,8 @@ export function Switch({ {value !== undefined ? ( <> - {iconOn ? {iconOn} : null} - {iconOff ? {iconOff} : null} + {iconOn ? : null} + {iconOff ? : null} ) : null} diff --git a/packages/toolbox/src/components/tabs.tsx b/packages/toolbox/src/components/tabs.tsx index 7b0e4c349..afaf5ae24 100644 --- a/packages/toolbox/src/components/tabs.tsx +++ b/packages/toolbox/src/components/tabs.tsx @@ -50,7 +50,9 @@ export interface TabsProps { } /** - * Un Tab, Ă  utiliser dans Tabs. + * DĂ©finit un tab Ă  inclure dans une instance de `Tabs`. + * + * Peut inclure le contenu du tab en enfant ou peut ĂȘtre simplement utilisĂ© pour le titre. */ export function Tab({ active = false, @@ -96,14 +98,19 @@ export function Tab({ role="tab" tabIndex={disabled ? undefined : 0} > - {icon ? {icon} : null} + {icon ? : null} {label ? {label} : null}
); } -/** Permet de poser un systÚme de tabs avec Tab. */ +/** + * Les tabs permettent d'organiser du contenu à travers différents écrans ou vues. + * + * - 2 types : primaires et secondaires + * - Les tabs peuvent inclure le contenu ou simplement servir de barre de titres. Le changement de tab animera le contenu s'il est inclus. + */ export function Tabs({children, className = "", index = 0, onChange, secondary, theme: pTheme}: TabsProps) { const theme = useTheme("tabs", tabsCss, pTheme); const navigationNode = useRef(null); diff --git a/packages/toolbox/src/components/text-field.tsx b/packages/toolbox/src/components/text-field.tsx index 11a1022c8..322d507e1 100644 --- a/packages/toolbox/src/components/text-field.tsx +++ b/packages/toolbox/src/components/text-field.tsx @@ -132,6 +132,10 @@ export interface TextFieldProps extends PointerEvents {icon ? (
- {icon} +
) : null} {label ? ( @@ -376,7 +380,7 @@ export const TextField = forwardRef(function TextField( /> ) : (
- {t.icon} +
); if (t.tooltip) { diff --git a/packages/toolbox/src/components/tooltip.tsx b/packages/toolbox/src/components/tooltip.tsx index 1b6feb182..6f70c3a0c 100644 --- a/packages/toolbox/src/components/tooltip.tsx +++ b/packages/toolbox/src/components/tooltip.tsx @@ -22,7 +22,7 @@ export interface TooltipProps extends Point } /** - * Pose une tooltip autour de l'élement enfant qui s'activera au survol. + * Une tooltip permet d'afficher un bref libellé ou message à un utilisateur au survol. */ export function Tooltip({ children,