import type { Meta, StoryObj } from '@storybook/vue3' import { ref } from 'vue' import SyCheckBoxGroup from './SyCheckBoxGroup.vue' import SyForm from '@/components/Customs/SyForm/SyForm.vue' import { VBtn } from 'vuetify/components' import { getValidationDocumentation } from '@/composables/unifyValidation/documentationValidationProps' import type { SyCheckBoxGroupProps } from './types' const meta: Meta = { title: 'Composants/Formulaires/SyCheckBoxGroup', component: SyCheckBoxGroup, decorators: [ () => ({ template: '
', }), ], parameters: { layout: 'fullscreen', docs: { description: { component: ` SyCheckBoxGroup est un composant de groupe de cases à cocher. Il permet de choisir **une ou plusieurs valeurs** parmi une liste d'options. `, }, }, }, argTypes: { ...getValidationDocumentation(), modelValue: { control: false }, helpText: { description: 'Texte d\'aide affiché sous le groupe (disparaît en cas de message de validation)', control: 'text', }, label: { description: 'Label du groupe', control: 'text', }, options: { description: 'Liste des options du checkbox-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', }, multiple: { description: 'Permet la sélection multiple (tableau)', control: 'boolean', }, 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 const baseOptions = [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, { label: 'Option C', value: 'c' }, ] export const Default: Story = { parameters: { sourceCode: [ { name: 'Template', code: `
Sélection : {{ value }}
`, }, { name: 'Script', code: ` `, }, ], }, args: { label: 'Choisissez une option', options: baseOptions, multiple: false, required: false, }, render: args => ({ components: { SyCheckBoxGroup }, setup() { const value = ref(null) return { args, value } }, template: `
Sélection : {{ value }}
`, }), } export const Disabled: Story = { parameters: { sourceCode: [ { name: 'Template', code: `
Sélection : {{ value }}
`, }, { name: 'Script', code: ` `, }, ], }, args: { label: 'CheckBoxGroup désactivé', disabled: true, options: baseOptions, multiple: false, hideDetails: true, }, render: args => ({ components: { SyCheckBoxGroup }, setup() { const value = ref('a') return { args, value } }, template: `
Sélection : {{ value }}
`, }), } export const Required: Story = { parameters: { sourceCode: [ { name: 'Template', code: `
Sélection : {{ value }}
Valider
`, }, { name: 'Script', code: ` `, }, ], }, args: { label: 'Choisissez une option (obligatoire)', required: true, options: [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, ], multiple: false, id: 'sy-checkbox-group-required', isValidateOnBlur: false, }, render: args => ({ components: { SyCheckBoxGroup, SyForm, VBtn }, setup() { const value = ref(null) const onSubmit = (event: { isValid: boolean }) => { if (event.isValid) { alert('Formulaire valide !') } } return { args, value, onSubmit } }, template: `
Sélection : {{ value }}
Valider
`, }), } export const RequiredWithAsterisk: Story = { args: { label: 'Champ obligatoire', required: true, displayAsterisk: true, options: [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, ], multiple: false, }, 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: { SyCheckBoxGroup }, setup() { const selected = ref(null) return { args, selected } }, template: ` `, }), } export const Multiple: Story = { parameters: { sourceCode: [ { name: 'Template', code: `
Sélection : {{ values }}
`, }, { name: 'Script', code: ` `, }, ], }, args: { label: 'Choisissez plusieurs options', options: baseOptions, multiple: true, required: false, }, render: args => ({ components: { SyCheckBoxGroup }, setup() { const value = ref>(['a']) return { args, value } }, template: `
Sélection : {{ value }}
`, }), } export const MultipleRequired: Story = { parameters: { sourceCode: [ { name: 'Template', code: `
Sélection : {{ values }}
Valider
`, }, { name: 'Script', code: ` `, }, ], }, args: { label: 'Choisissez au moins une option (multiple requis)', options: baseOptions, multiple: true, required: true, customRules: [ { type: 'custom', options: { message: 'Veuillez sélectionner au moins 2 options.', validate: (value: Array) => Array.isArray(value) && value.length >= 2, }, }, ], id: 'sy-checkbox-group-multiple-required', isValidateOnBlur: false, }, render: args => ({ components: { SyCheckBoxGroup, SyForm, VBtn }, setup() { const value = ref>([]) const onSubmit = (event: { isValid: boolean }) => { if (event.isValid) { alert('Formulaire valide !') } } return { args, value, onSubmit } }, template: `
Sélection : {{ value }}
Valider
`, }), } export const ListModel: Story = { parameters: { sourceCode: [ { name: 'Template', code: `
Sélection : {{ selected }}
`, }, { name: 'Script', code: ` `, }, ], }, args: { label: 'v-model comme une liste (tableau)', options: baseOptions, multiple: true, required: false, hideDetails: true, }, render: args => ({ components: { SyCheckBoxGroup }, setup() { const selected = ref>(['a']) return { args, selected } }, template: `
Sélection : {{ selected }}
`, }), } export const CustomColors: Story = { parameters: { sourceCode: [ { name: 'Template', code: `
`, }, { name: 'Script', code: ``, }, ], docs: { description: { story: ` ### Couleurs personnalisées Le composant SyCheckBoxGroup peut être personnalisé avec différentes couleurs pour s'adapter à votre thème. `, }, }, }, render: args => ({ components: { SyCheckBoxGroup }, setup() { const options = [ { label: 'Value 1', value: 'a' }, { label: 'Value 2', value: 'b' }, ] const value1 = ref('a') const value2 = ref('a') const value3 = ref('a') const value4 = ref('a') const value5 = ref('a') return { args, options, 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 SyCheckBoxGroup prend en charge différentes densités pour s'adapter à différents contextes d'interface utilisateur. `, }, }, }, render: () => ({ components: { SyCheckBoxGroup }, setup() { const val1 = ref(null) const val2 = ref(null) const val3 = ref(null) const options = [ { label: 'Value 1', value: 'a' }, { label: 'Value 2', value: 'b' }, ] return { val1, val2, val3, options } }, template: `
`, }), } export const Readonly: Story = { args: { readonly: true, options: [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, { label: 'Option C', value: 'c' }, ], }, render: args => ({ components: { SyCheckBoxGroup }, setup() { const value = ref('a') return { args, value } }, template: `
Sélection : {{ value }}
`, }), parameters: { sourceCode: [ { name: 'Template', code: `
Sélection : {{ value }}
`, }, { name: 'Script', code: ` `, }, ], }, } 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: { SyCheckBoxGroup }, setup() { const selected = ref<(string | number) | (string | number)[] | null>(null) const lastEvent = ref('Aucun événement') const multiple = ref(true) const options = [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, { label: 'Option C', value: 'c' }, ] const onUpdate = (value: (string | number) | (string | number)[] | null) => { lastEvent.value = `update:modelValue: ${JSON.stringify(value)}` } const onChange = (value: (string | number) | (string | number)[] | null) => { lastEvent.value = `change: ${JSON.stringify(value)}` } return { args, selected, options, multiple, lastEvent, onUpdate, onChange } }, template: `

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

Dernier événement : {{ lastEvent }}

`, }), } export const HelpText: Story = { parameters: { docs: { description: { story: ` ### Texte d'aide (helpText) Affiche un texte d'aide sous les options du groupe. Il disparaît automatiquement lorsqu'un message de validation (erreur, avertissement, succès) est présent, et réapparaît en dessous une fois les messages affichés. `, }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ``, }, ], }, args: { label: 'Choisissez une option', required: true, helpText: 'Sélectionnez au moins une option dans la liste.', options: [ { label: 'Option A', value: 'a' }, { label: 'Option B', value: 'b' }, ], multiple: false, isValidateOnBlur: false, }, render: args => ({ components: { SyCheckBoxGroup, SyForm, VBtn }, setup() { const value = ref(null) const onSubmit = (event: { isValid: boolean }) => { if (event.isValid) { alert('Formulaire valide !') } } return { args, value, onSubmit } }, template: ` Valider `, }), } 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: { SyCheckBoxGroup, 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
`, }), }