import type { Meta, StoryObj } from '@storybook/vue3' import { ref } from 'vue' import SyRadioGroup from '@/components/Customs/SyRadioGroup/SyRadioGroup.vue' import SyForm from '../SyForm/SyForm.vue' import { VBtn } from 'vuetify/components' import { getValidationDocumentation } from '@/composables/unifyValidation/documentationValidationProps' const meta: Meta = { title: 'Composants/Formulaires/SyRadioGroup', component: SyRadioGroup, decorators: [ () => ({ template: '
', }), ], parameters: { layout: 'fullscreen', docs: { description: { component: ` SyRadioGroup est un composant de groupe de boutons radio. Il permet de choisir **une seule valeur** parmi une liste d’options. `, }, }, }, argTypes: { ...getValidationDocumentation(), modelValue: { control: false }, label: { description: 'Label du groupe', control: 'text', }, options: { description: 'Liste des options du radio-group', control: 'object', }, color: { control: 'select', options: ['primary', 'secondary', 'success', 'error', 'warning'], description: 'Couleur du groupe', }, density: { control: 'select', options: ['default', 'comfortable', 'compact'], description: 'Densité du groupe', }, displayAsterisk: { description: 'Affiche un astérisque pour les champs requis', control: 'boolean', }, helpText: { description: 'Texte d\'aide affiché sous le champ', control: 'text', }, ariaLabel: { description: 'Label ARIA pour les lecteurs d\'écran', control: 'text', }, ariaLabelledby: { description: 'ID d\'un élément qui labelise le groupe', control: 'text', }, title: { description: 'Attribut title du groupe', control: 'text', }, name: { description: 'Nom du groupe (attribut name)', control: 'text', }, }, } export default meta type Story = StoryObj export const Default: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { label: 'Choisissez une option', options: [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, { label: 'Option C', value: 'c' }, ], showSuccessMessages: true, }, render: args => ({ components: { SyRadioGroup }, setup() { const selected = ref('a') return { args, selected } }, template: ` `, }), } export const Required: Story = { args: { label: 'Choisissez une option (obligatoire)', required: true, options: [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, ], }, render: args => ({ components: { SyRadioGroup, SyForm, VBtn }, setup() { const selected = ref(null) return { args, selected } }, template: ` Valider `, }), parameters: { sourceCode: [ { name: 'Template', code: ` Valider `, }, { name: 'Script', code: ` `, }, ], }, } export const RequiredWithAsterisk: Story = { args: { label: 'Champ obligatoire', required: true, displayAsterisk: true, options: [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, ], }, parameters: { docs: { description: { story: ` ### Affichage de l'astérisque Ce story démontre l'affichage d'un astérisque (*) sur le label pour indiquer qu'un champ est obligatoire. `, }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { SyRadioGroup }, setup() { const selected = ref(null) return { args, selected } }, template: ` `, }), } export const CustomColors: Story = { parameters: { sourceCode: [ { name: 'Template', code: `
`, }, { name: 'Script', code: ``, }, ], docs: { description: { story: ` ### Couleurs personnalisées Le composant SyRadioGroup peut être personnalisé avec différentes couleurs pour s'adapter à votre thème. `, }, }, }, render: args => ({ components: { SyRadioGroup }, setup() { const value1 = ref('a') const value2 = ref('a') const value3 = ref('a') const value4 = ref('a') const value5 = ref('a') return { args, value1, value2, value3, value4, value5 } }, template: `
`, }), } export const DifferentDensities: Story = { parameters: { sourceCode: [ { name: 'Template', code: `
`, }, { name: 'Script', code: ``, }, ], docs: { description: { story: ` ### Différentes densités Le composant SyRadioGroup prend en charge différentes densités pour s'adapter à différents contextes d'interface utilisateur. `, }, }, }, render: () => ({ components: { SyRadioGroup }, setup() { const val1 = ref(null) const val2 = ref(null) const val3 = ref(null) return { val1, val2, val3 } }, template: `
`, }), } export const Disabled: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { label: 'Radio-group désactivé', disabled: true, options: [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, ], }, render: args => ({ components: { SyRadioGroup }, setup() { const selected = ref('a') return { args, selected } }, template: ` `, }), } export const EventShowcase: Story = { parameters: { docs: { description: { story: ` ### Événements Ce story démontre les événements émis par le composant : - **update:modelValue** : Émis lorsque la valeur change - **change** : Émis lorsque la sélection change `, }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { SyRadioGroup }, setup() { const selected = ref(null) const lastEvent = ref('Aucun événement') const options = [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, { label: 'Option C', value: 'c' }, ] const onUpdate = (value: string | null) => { lastEvent.value = `update:modelValue: ${value}` } const onChange = (value: string | null) => { lastEvent.value = `change: ${value}` } return { args, selected, options, lastEvent, onUpdate, onChange } }, template: `

Valeur sélectionnée : {{ selected || 'Aucune' }}

Dernier événement : {{ lastEvent }}

`, }), } export const Readonly: Story = { args: { readonly: true, options: [ { label: 'Option A', value: 'a' }, ], }, render: args => ({ components: { SyRadioGroup }, setup() { const selected = ref('a') return { args, selected } }, template: ``, }), parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ` `, }, ], docs: { description: { story: ` ### VRadio en lecture seule Ce button radio est en lecture seule et ne peut pas être modifiée par l'utilisateur, mais elle n'est pas visuellement désactivée comme la version disabled. `, }, }, }, } export const HideDetails: Story = { parameters: { docs: { description: { story: ` ### hideDetails Contrôle l'affichage de la zone de messages sous le champ. | Valeur | Comportement | |--------|-------------| | \`'auto'\` (défaut) | Zone affichée uniquement si un message est présent | | \`false\` | Zone toujours affichée (espace réservé même sans message) | | \`true\` | Zone toujours masquée | `, }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ``, }, ], }, render: () => ({ components: { SyRadioGroup, SyForm, VBtn }, setup() { const selected = ref(null) const options = [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, ] const onSubmit = (event: { isValid: boolean }) => { if (event.isValid) alert('Formulaire valide !') } return { selected, options, onSubmit } }, template: `

hide-details="auto" (défaut)

:hide-details="false" (espace toujours réservé)

:hide-details="true" (messages jamais affichés)

Valider
`, }), } export const HelpText: Story = { parameters: { docs: { description: { story: ` ### helpText Texte d'aide contextuel affiché sous le champ. **Comportement :** - Sans message de validation → affiché **à la place du message** - Avec message (erreur/warning/succès) → affiché **en dessous** du message `, }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ``, }, ], }, render: () => ({ components: { SyRadioGroup, SyForm, VBtn }, setup() { const selected = ref(null) const selectedWithError = ref(null) const options = [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, ] const onSubmit = (event: { isValid: boolean }) => { if (event.isValid) alert('Formulaire valide !') } return { selected, selectedWithError, options, onSubmit } }, template: `

Sans erreur : helpText affiché à la place du message

Avec erreur (required + soumis vide) : helpText affiché en dessous

Valider
`, }), }