Skip to content

Commit a5dc510

Browse files
committed
docs: 📝 ajoute la documentation pour segmented
1 parent 381f806 commit a5dc510

File tree

10 files changed

+231
-8
lines changed

10 files changed

+231
-8
lines changed

.vitepress/config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export default defineConfig({
1414
appearance: { listenToStorageChanges: false }, // handling this in Story.vue itself to avoid flickering
1515

1616
rewrites: {
17+
'src/components/DsfrSegmented/DsfrSegmentedSet.md': 'composants/DsfrSegmentedSet.md',
1718
'src/components/:comp/:comp.md': 'composants/:comp.md',
1819
'docs/:splat*': ':splat*',
1920
},
@@ -100,6 +101,14 @@ export default defineConfig({
100101
text: 'DsfrNotice',
101102
link: '/composants/DsfrNotice.md',
102103
},
104+
{
105+
text: 'DsfrSegmented',
106+
link: '/composants/DsfrSegmented.md',
107+
},
108+
{
109+
text: 'DsfrSegmentedSet',
110+
link: '/composants/DsfrSegmentedSet.md',
111+
},
103112
]
104113
},
105114
{

.vitepress/theme/icons.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export {
2+
GiChocolateBar,
23
RiCloseLine,
34
RiArrowDropDownLine,
45
RiArrowDropUpLine,

docs/types.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ outline: [2,3]
174174
<<< ../src/components/DsfrSearchBar/DsfrSearchBar.types.ts
175175
:::
176176

177+
### `DsfrSegmented` et `DsfrSegmentedSet`
178+
179+
::: code-group
180+
<<< ../src/components/DsfrSegmented/DsfrSegmented.types.ts
181+
:::
182+
177183
### `DsfrSelect`
178184

179185
::: code-group

src/components/DsfrBackToTop/DsfrBactToTop.md

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Documentation du Composant `DsfrSegmented`
2+
3+
👋 Bonjour et bienvenue dans la documentation de `DsfrSegmented`, un composant radio boutonné avec une touche de « je ne sais quoi » à la française! C'est chic, c'est pratique, et en plus, ça supporte des icônes. Alors, allons-y !
4+
5+
Le composant « contrôle segmenté » incite l'utilisateur à choisir entre plusieurs options d'affichage disponibles (vues), mutuellement exclusives avec une valeur sélectionnée par défaut (oui, ça c’est la version sérieuse de l’introduction à ce composant).
6+
7+
La documentation sur les boutons segmentés sur le [DSFR sera ici](https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/controle-segmente) (n’existe pas encore à l’heure où cette documentation est écrite, on est dans l’turfu, nous, qu’on vous dit !).
8+
9+
La story sur l’alerte sur le storybook de [VueDsfr est ici](https://vue-ds.fr/?path=/docs/composants-dsfrsegmented--docs) (merci [Vincent Lainé](https://github.com/vincentlaine/) !).
10+
11+
## Props
12+
13+
| Nom | Type | Défaut | Description |
14+
|------------|------------------------------------------|----------------|-------------------------------------------------------------------|
15+
| `id` | `string` | ID aléatoire | Identifiant unique pour le composant. |
16+
| `name` | `string` | `undefined` | Nom du groupe de boutons radio. |
17+
| `modelValue` | `string \| number` | `''` | La valeur actuellement sélectionnée. |
18+
| `value` | `string \| number` | (requis) | Valeur du bouton radio. |
19+
| `label` | `string` | `''` | Texte du label associé au bouton. |
20+
| `disabled` | `boolean` | `false` | Si `true`, désactive le bouton radio. |
21+
| `icon` | `string \| InstanceType<typeof VIcon>['$props']` | `undefined` | Icône à afficher à côté du label (facultatif). Si la valeur est une string commençant par `'fr-'`, cette classe sera ajoutée à la balise `<label>`, sinon c’est une icône OhVueIcon qui sera utilisée |
22+
23+
::: info Astuce 1
24+
25+
`id`: Si non fourni, un ID est généré automatiquement pour éviter les conflits.
26+
27+
:::
28+
29+
::: info Astuce 2
30+
31+
`icon`: Peut être soit une chaîne représentant le nom de l'icône, soit un objet de props pour `VIcon`.
32+
33+
:::
34+
35+
## Événements
36+
37+
| Nom | Valeur | Description |
38+
|--------------------|----------------------|----------------------------------------------|
39+
| `update:modelValue` | `string \| number` | Émis lorsqu'une nouvelle valeur est sélectionnée. |
40+
41+
## Slots
42+
43+
Pas de slots ici ! Ce composant est aussi direct qu'un express Paris-Marseille.
44+
45+
## Exemple
46+
47+
```vue
48+
<DsfrSegmented
49+
name="group1"
50+
label="Option 1"
51+
value="opt1"
52+
v-model="selectedOption"
53+
icon="some-icon-name"
54+
/>
55+
```
56+
57+
`DsfrSegmented` s’utilise forcément à l’intérieur d’un `DsfrSegmentedSet`, ainsi, pour un résultat, consultez la documentation de [`DsfrSegmentedSet`](/composants/DsfrSegmentedSet).
58+
59+
---
60+
61+
Voilà ! Votre composant `DsfrSegmented` est prêt à ajouter une touche d'élégance et de fonctionnalité à votre interface. Amusez-vous bien ! 🎉

src/components/DsfrSegmented/DsfrSegmented.vue

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
11
<script lang="ts" setup>
2+
import { computed } from 'vue'
3+
import { OhVueIcon as VIcon } from 'oh-vue-icons'
4+
25
import { getRandomId } from '../../utils/random-utils'
36
47
import type { DsfrSegmentedProps } from './DsfrSegmented.types'
5-
import { computed } from 'vue'
68
79
export type { DsfrSegmentedProps }
810
911
const props = withDefaults(defineProps<DsfrSegmentedProps>(), {
1012
id: () => getRandomId('basic', 'checkbox'),
11-
modelValue: '',
12-
label: '',
1313
hint: '',
1414
icon: undefined,
15+
label: '',
16+
modelValue: '',
17+
name: undefined,
1518
})
1619
1720
defineEmits<{(e: 'update:modelValue', payload: string | number): void}>()
1821
1922
const iconProps = computed(() => typeof props.icon === 'string' ? { name: props.icon } : props.icon)
23+
24+
const dsfrIcon = computed(() => {
25+
return props.icon && typeof props.icon === 'string' && props.icon.startsWith('fr-') ? props.icon : ''
26+
})
2027
</script>
2128

2229
<template>
@@ -36,9 +43,10 @@ const iconProps = computed(() => typeof props.icon === 'string' ? { name: props.
3643
<label
3744
:for="id"
3845
class="fr-label"
46+
:class="{ [dsfrIcon]: dsfrIcon }"
3947
>
4048
<VIcon
41-
v-if="icon"
49+
v-if="icon && !dsfrIcon"
4250
v-bind="iconProps"
4351
/>
4452
<span v-if="icon">&nbsp;</span>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Contrôle segmenté - `DsfrSegmentedSet`
2+
3+
🌟 Bienvenue dans l'univers de `DsfrSegmentedSet`, le chef d'orchestre de vos composants radio boutonnés `DsfrSegmented`. Ce composant est là pour vous aider à organiser et afficher un ensemble de choix avec élégance et fonctionnalité. Préparez-vous, ça va être aussi sympa qu'une balade sur la Seine !
4+
5+
Le composant « contrôle segmenté » incite l'utilisateur à choisir entre plusieurs options d'affichage disponibles (vues), mutuellement exclusives avec une valeur sélectionnée par défaut (Il faut toujours ramener un peu de sérieux dans l’affaire...).
6+
7+
La documentation sur les boutons segmentés sur le [DSFR sera ici](https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/controle-segmente) (n’existe pas non plus à l’heure où cette documentation est écrite, on est trop en avance, nous !).
8+
9+
La story sur l’alerte sur le storybook de [VueDsfr est ici](https://vue-ds.fr/?path=/docs/composants-dsfrsegmentedset--docs) (oui parce que nous on fait rien à moitié, nous 😏, merci [Vincent Lainé](https://github.com/vincentlaine/) !).
10+
11+
## Props
12+
13+
| Nom | Type | Défaut | Description |
14+
|-------------|---------------------------------------|----------------|----------------------------------------------------------------|
15+
| `titleId` | `string` | ID aléatoire | Identifiant unique pour le titre du groupe. |
16+
| `disabled` | `boolean` | `false` | Si `true`, désactive tous les boutons radio du groupe. |
17+
| `small` | `boolean` | `false` | Si `true`, Utilise la version réduite des contrôles segmentés. |
18+
| `inline` | `boolean` | `false` | Si `true`, la légende sera alignée avec les boutons, sinon, ils seront chacun sur une ligne (`false`, défaut). |
19+
| `name` | `string` | `'no-name'` | Nom par défaut pour le groupe de boutons radio. |
20+
| `hint` | `string` | `undefined` | Texte d'indice affiché sous la légende (facultatif). |
21+
| `legend` | `string` | `''` | Texte de la légende pour le groupe de boutons radio. |
22+
| `modelValue`| `string \| number` | (requis) | La valeur actuellement sélectionnée. |
23+
| `options` | `DsfrSegmentedProps[]` | `[]` | Tableau d’objets : chaque objet contient les props à passer à [`DsfrSegmented`](/composants/DsfrSegmented). |
24+
25+
### Notes
26+
27+
- `titleId`: Généré automatiquement si non spécifié.
28+
- `options`: Chaque élément représente un bouton radio avec ses props spécifiques.
29+
30+
## Événements
31+
32+
| Nom | Valeur | Description |
33+
|--------------------|----------------------|----------------------------------------------|
34+
| `update:modelValue` | `string \| number` | Émis lorsqu'une nouvelle valeur est sélectionnée dans le groupe. |
35+
36+
## Slots
37+
38+
1. **slot par défaut**: Permet de personnaliser les boutons radio individuellement.
39+
2. **Slot `legend`**: Permet de personnaliser la légende avec du contenu riche.
40+
41+
## Exemple
42+
43+
```vue
44+
<DsfrSegmentedSet
45+
legend="Votre Choix"
46+
:options="[
47+
{
48+
label: 'Croissant',
49+
value: 'croissant',
50+
},
51+
{
52+
label: 'Pain au chocolat (noooon ! Cho-co-la-tine ! C’est pas compliqué, pourtant !)',
53+
value: 'chocolatine',
54+
disabled: true,
55+
}
56+
]"
57+
v-model="selectedOption"
58+
/>
59+
```
60+
61+
## Utilisation
62+
63+
Assurez-vous d'importer `DsfrSegmentedSet` ainsi que `DsfrSegmented` dans votre projet. Puis, utilisez-le dans votre template en fournissant les props et les options nécessaires.
64+
65+
::: code-group
66+
67+
<Story data-title="Démo" min-h="150px">
68+
<DsfrSegmentedDemo />
69+
</Story>
70+
71+
<<< docs-demo/DsfrSegmentedDemo.vue [Code de la démo]
72+
73+
<<< DsfrSegmentedSet.vue
74+
<<< DsfrSegmented.vue
75+
<<< DsfrSegmented.types.ts
76+
:::
77+
78+
<script setup lang="ts">
79+
import DsfrSegmentedDemo from './docs-demo/DsfrSegmentedDemo.vue'
80+
</script>
81+
82+
---
83+
84+
Voilà, vous êtes prêt à utiliser `DsfrSegmentedSet` pour créer un ensemble élégant et fonctionnel de boutons radio. À vos marques, prêt, codez ! 🚀

src/components/DsfrSegmented/DsfrSegmentedSet.stories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default {
1313
},
1414
inline: {
1515
control: 'boolean',
16-
description: 'Indique si la légende doit être allignée avec les boutons (`true`) ou chacun sur une ligne (`false`, défaut)',
16+
description: 'Indique si la légende doit être alignée avec les boutons (`true`) ou chacun sur une ligne (`false`, défaut)',
1717
},
1818
name: {
1919
control: 'text',

src/components/DsfrSegmented/DsfrSegmentedSet.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ const onChange = ($event: string) => {
5858
<DsfrSegmented
5959
v-for="(option, i) of options"
6060
:key="option.value || i"
61-
:name="name"
62-
v-bind="option"
61+
:name="name || option.name"
62+
v-bind="{ ...option, disabled: disabled || option.disabled }"
6363
:model-value="modelValue"
6464
@update:model-value="onChange($event as string)"
6565
/>
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<script lang="ts" setup>
2+
import { ref } from 'vue'
3+
4+
import DsfrSegmented from '../DsfrSegmented.vue'
5+
import DsfrSegmentedSet from '../DsfrSegmentedSet.vue'
6+
7+
const region = ref<string | number>('')
8+
const viennoiserie = ref<string | number>('')
9+
10+
const options = [
11+
{ label: 'Sud-ouest', value: 'Chocolatine' },
12+
{ label: 'Ailleurs', value: 'Pain au chocolat' },
13+
]
14+
</script>
15+
16+
<template>
17+
<div class="fr-container">
18+
<div>
19+
<DsfrSegmentedSet
20+
name="region"
21+
label="Région"
22+
:options="options"
23+
@update:model-value="region = $event"
24+
/>
25+
</div>
26+
27+
<div
28+
v-if="region"
29+
class="fr-mt-4w"
30+
>
31+
<DsfrSegmentedSet
32+
name="viennoiserie"
33+
label="Viennoiserie"
34+
>
35+
<DsfrSegmented
36+
icon="fr-icon-moon-line"
37+
label="Croissant"
38+
value="croissant"
39+
:model-value="viennoiserie"
40+
@update:model-value="viennoiserie = $event"
41+
/>
42+
<DsfrSegmented
43+
:label="region.toString()"
44+
value="chocolatine"
45+
:icon="{ name: 'gi-chocolate-bar' }"
46+
:model-value="viennoiserie"
47+
@update:model-value="viennoiserie = $event"
48+
/>
49+
</DsfrSegmentedSet>
50+
<p>
51+
Vrai nom : {{ viennoiserie }}
52+
</p>
53+
</div>
54+
</div>
55+
</template>

0 commit comments

Comments
 (0)