import type { Meta, StoryObj } from '@storybook/vue3' import { ref, watch } from 'vue' import AmeliproRadioGroup from './AmeliproRadioGroup.vue' // --- LabelInfo --- import AmeliproTooltips from '../AmeliproTooltips/AmeliproTooltips.vue' import AmeliproBtn from '../AmeliproBtn/AmeliproBtn.vue' const meta = { argTypes: { '`append-${index}`': { description: 'Permet de rajouter un élément après le label des boutons radios, il y a un slot par item de la liste' }, '`subItem-${index}`': { description: 'Permet de rajouter un élément sous un bouton radio seulement lorsqu’il est coché (existe seulement si les props horizontal et fullHorizontal sont à false)' }, 'append': { description: 'Permet de rajouter un élément générique après le label des boutons radios' }, 'required': { description: 'Permet de rendre la selection obligatoire' }, 'change:selected': { description: 'Événement émis au click sur un bouton radio retourne la valeur sélectionnée' }, 'disabled': { description: 'Permet de désactiver le groupe de boutons radios' }, 'error': { description: 'Permet de mettre le champ en erreur' }, 'fullHorizontal': { description: 'Permet d’afficher le radioGroup ainsi que le titre a l’horizontal' }, 'groupLabel': { description: 'Libellé du groupe de boutons radios' }, 'hiddenLabel': { description: 'Permet de masquer le label du groupe de checkbox, dans une démarche d’amélioration de l’accessibilité, il est recommandé de ne pas utiliser cette property dans la mesure du possible' }, 'horizontal': { description: 'Permet d’afficher le radioGroup à l’horizontal' }, 'horizontalLabel': { description: 'Permet d’afficher le radioGroup avec le label à l’horizontal tout en gardant les boutons radios sous forme de colonnes' }, 'labelInfo': { description: 'Slot pour ajouter une tooltip après le label du groupe si besoin' }, 'modelValue': { description: 'Tableau d’objets qui permet de générer les boutons radios', table: { type: { detail: `Array<{ isChecked: boolean; label: string; value: string; }[]>`, summary: 'AmeliproRadioGroupItem[]', }, }, }, 'pills': { description: 'Change le style du groupe de bouttons radio' }, 'requiredErrorMessage': { description: 'Message d’erreur qui s’affiche si le champ est obligatoire et qu’aucune valeur n’est sélectionnée' }, 'subItem': { description: 'Permet de rajouter un élément générique sous un bouton radio seulement lorsqu’il est coché (existe seulement si les props horizontal et fullHorizontal sont à false)' }, 'uniqueId': { description: 'Id du groupe de boutons radios, il doit être unique' }, 'update:model-value': { description: 'Événement émis au changement du v-model' }, }, component: AmeliproRadioGroup, title: 'Composants/Amelipro/Formulaires/AmeliproRadioGroup', } as Meta export default meta type Story = StoryObj const items = [ { isChecked: false, label: '1', value: 'Valeur 1', }, { isChecked: false, label: '2', value: 'Valeur 2', }, { isChecked: true, label: '3', value: 'Valeur 3', }, { isChecked: false, label: '4', value: 'Valeur 4', }, { isChecked: false, label: '5', value: 'Valeur 5', }, ] export const Default: Story = { args: { groupLabel: 'Libellé du groupe', modelValue: items, uniqueId: 'radio-id', }, parameters: { args: {}, sourceCode: [ { name: 'Template', code: ``, }, { name: 'Scripts', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) // Optional: Keeps v-model in sync with storybook args watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: ` `, }), } // --- Disabled --- export const Disabled: Story = { args: { groupLabel: 'Groupe désactivé', modelValue: items, uniqueId: 'radio-disabled', disabled: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le groupe de boutons radios est entièrement désactivé grâce à la prop disabled.

`, }), } // --- Required --- export const Required: Story = { args: { groupLabel: 'Sélection obligatoire', modelValue: items, uniqueId: 'radio-required', required: true, error: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup, AmeliproBtn }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) const deselect = () => { model.value = model.value.map(item => ({ ...item, isChecked: false, })) } return { args, model, deselect } }, template: `

La sélection d’un bouton est obligatoire grâce à la prop required.

Tout désélectionner`, }), } // --- Erreur personnalisée --- export const RequiredErrorMessage: Story = { args: { groupLabel: 'Erreur personnalisée', modelValue: items, uniqueId: 'radio-errormsg', required: true, requiredErrorMessage: 'Veuillez sélectionner une option', error: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup, AmeliproBtn }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) const deselect = () => { model.value = model.value.map(item => ({ ...item, isChecked: false, })) } return { args, model, deselect } }, template: `

Message d’erreur personnalisé via la prop requiredErrorMessage.

Tout désélectionner`, }), } // --- Pills --- export const Pills: Story = { args: { groupLabel: 'Affichage pills', modelValue: items, uniqueId: 'radio-pills', pills: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Affichage du groupe en mode pills grâce à la prop pills.

`, }), } // --- Horizontal --- export const Horizontal: Story = { args: { groupLabel: 'Affichage horizontal', modelValue: items, uniqueId: 'radio-horizontal', horizontal: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Affichage horizontal du groupe grâce à la prop horizontal.

`, }), } // --- FullHorizontal --- export const FullHorizontal: Story = { args: { groupLabel: 'Affichage full horizontal', modelValue: items, uniqueId: 'radio-fullhorizontal', fullHorizontal: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Affichage full horizontal du groupe grâce à la prop fullHorizontal.

`, }), } // --- HorizontalLabel --- export const HorizontalLabel: Story = { args: { groupLabel: 'Label à l’horizontal', modelValue: items, uniqueId: 'radio-horizontal-label', horizontalLabel: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Affichage du label à l’horizontal grâce à la prop horizontalLabel.

`, }), } // --- HiddenLabel --- export const HiddenLabel: Story = { args: { groupLabel: 'Label masqué', modelValue: items, uniqueId: 'radio-hidden-label', hiddenLabel: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le label du groupe est masqué grâce à la prop hiddenLabel.

`, }), } export const LabelInfo: Story = { args: { groupLabel: 'Label avec info-bulle', modelValue: items, uniqueId: 'radio-labelinfo', }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup, AmeliproTooltips }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le slot labelInfo permet d’ajouter une info-bulle au label du groupe.

`, }), } // --- Append --- export const Append: Story = { args: { groupLabel: 'Append générique', modelValue: items, uniqueId: 'radio-append', }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le slot append permet d’ajouter un élément générique après chaque bouton radio.

`, }), } // --- Append par item --- export const AppendPerItem: Story = { args: { groupLabel: 'Append par item', modelValue: items, uniqueId: 'radio-append-item', }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le slot dynamique append-\${index} permet d’ajouter un élément après le label d’un bouton radio spécifique.

`, }), } // --- SubItem --- export const SubItem: Story = { args: { groupLabel: 'SubItem générique', modelValue: items, uniqueId: 'radio-subitem', }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le slot subItem permet d’ajouter un élément générique sous le bouton radio coché.

`, }), } // --- SubItem par item --- export const SubItemPerItem: Story = { args: { groupLabel: 'SubItem par item', modelValue: items, uniqueId: 'radio-subitem-item', }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproRadioGroup }, setup() { const model = ref(args.modelValue) watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le slot dynamique subItem-\${index} permet d’ajouter un élément sous un bouton radio spécifique coché.

`, }), }