import type { Meta, StoryObj } from '@storybook/vue3' import PeriodField from './PeriodField.vue' import { ref } from 'vue' // Type pour les méthodes exposées par PeriodField type ValidationMessage = { type: string, message: string }[] interface PeriodFieldExpose { validateOnSubmit: () => boolean errors: Record successes: Record warnings: Record isValid: boolean } const meta: Meta = { title: 'Composants/Formulaires/PeriodField', component: PeriodField, decorators: [ () => ({ template: '
', }), ], parameters: { layout: 'fullscreen', controls: { exclude: ['modelValue'] }, }, argTypes: { modelValue: { control: 'text', description: 'Valeur du champ', table: { type: { summary: 'object', }, }, }, placeholderFrom: { control: 'text', description: 'Placeholder pour la date de début', }, placeholderTo: { control: 'text', description: 'Placeholder pour la date de fin', }, format: { control: 'select', options: ['DD/MM/YYYY', 'MM/DD/YYYY', 'YYYY-MM-DD'], description: 'Format d\'affichage de la date', }, dateFormatReturn: { control: 'select', options: ['', 'DD/MM/YYYY', 'MM/DD/YYYY', 'YYYY-MM-DD'], description: 'Format de la date pour la valeur de retour', }, isOutlined: { control: 'boolean', description: 'Affiche le champ en contour', }, required: { control: 'boolean', description: 'Champ obligatoire', }, displayIcon: { control: 'boolean', description: 'Affiche l\'icône calendrier', }, displayAppendIcon: { control: 'boolean', description: 'Icône à la fin du champ', }, disabled: { control: 'boolean', description: 'Désactive le champ', }, noIcon: { control: 'boolean', description: 'Masque toutes les icônes', }, noCalendar: { control: 'boolean', description: 'Désactive le calendrier', }, customRules: { control: 'object', description: 'Règles de validation', }, customWarningRules: { control: 'object', description: 'Règles d\'avertissement', }, disableErrorHandling: { control: 'boolean', description: 'Désactive la gestion des erreurs', }, showSuccessMessages: { control: 'boolean', description: 'Affiche les messages de succès', }, }, } as Meta export default meta type Story = StoryObj export const Default: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', dateFormatReturn: '', required: false, displayIcon: true, displayAppendIcon: false, disabled: false, noIcon: false, modelValue: { from: null, to: null }, }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value = ref({ from: null, to: null }) return { args, value } }, template: `

Période sélectionnée : {{ value }}

`, }), } export const CustomPlaceholders: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début de la période', placeholderTo: 'Fin de la période', format: 'DD/MM/YYYY', dateFormatReturn: '', required: false, displayIcon: true, displayAppendIcon: false, disabled: false, noIcon: false, modelValue: { from: null, to: null }, }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value = ref({ from: null, to: null }) return { args, value } }, template: `

Période sélectionnée : {{ value }}

`, }), } export const Disabled: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', dateFormatReturn: '', required: false, displayIcon: true, displayAppendIcon: false, disabled: true, noIcon: false, modelValue: { from: null, to: null }, }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value = ref({ from: null, to: null }) return { args, value } }, template: `
`, }), } export const Required: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', dateFormatReturn: '', required: true, displayIcon: true, displayAppendIcon: false, disabled: false, noIcon: false, modelValue: { from: null, to: null }, }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value = ref({ from: null, to: null }) return { args, value } }, template: `

Période sélectionnée : {{ value }}

`, }), } export const AppendIcon: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', required: true, displayIcon: true, displayAppendIcon: true, disabled: false, noIcon: false, modelValue: { from: null, to: null }, }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value = ref({ from: null, to: null }) return { args, value } }, template: `

Période sélectionnée : {{ value }}

`, }), } export const WithoutIcon: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', dateFormatReturn: '', required: true, displayIcon: false, displayAppendIcon: true, disabled: false, noIcon: false, modelValue: { from: null, to: null }, }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value = ref({ from: null, to: null }) return { args, value } }, template: `

Période sélectionnée : {{ value }}

`, }), } export const WithError: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', dateFormatReturn: '', required: true, displayIcon: false, displayAppendIcon: true, disabled: false, noIcon: false, modelValue: { from: '01/01/2100', to: '05/01/2100' }, customRules: [ { type: 'notAfterToday', options: { message: 'La date ne peut pas être après aujourd\'hui' } }, ], }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value = ref({ from: '01/01/2100', to: '05/01/2100' }) return { args, value } }, template: `

Période sélectionnée : {{ value }}

`, }), } export const WithWarning: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', dateFormatReturn: '', required: true, displayIcon: false, displayAppendIcon: true, disabled: false, noIcon: false, modelValue: { from: '20/12/2023', to: '21/12/2023' }, customWarningRules: [ { type: 'notBeforeDate', options: { warningMessage: 'Attention : les dates sont antérieures au 02/01/2031', date: '02/01/2031', isWarning: true, }, }, ], }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value = ref({ from: '20/12/2023', to: '21/12/2023' }) return { args, value } }, template: `

Période sélectionnée : {{ value }}

`, }), } export const WithSuccess: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', dateFormatReturn: '', displayIcon: false, displayAppendIcon: true, disabled: false, noIcon: false, modelValue: { from: '22/01/2024', to: '23/01/2024' }, customRules: [ { type: 'notWeekend', options: { message: 'La date ne peut pas être un weekend', successMessage: 'La date n\'est pas un week-end', }, }, ], }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value = ref({ from: '22/01/2024', to: '23/01/2024' }) return { args, value } }, template: `

Période sélectionnée : {{ value }}

`, }), } export const DifferentFormats: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', dateFormatReturn: '', required: false, displayIcon: true, displayAppendIcon: false, disabled: false, noIcon: false, modelValue: { from: '12/10/2023', to: '15/10/2023' }, }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value1 = ref({ from: '12/10/2023', to: '15/10/2023' }) const value2 = ref({ from: '10/12/2023', to: '10/15/2023' }) const value3 = ref({ from: '2023-10-12', to: '2023-10-15' }) const value4 = ref({ from: '12-10-23', to: '15-10-23' }) const value5 = ref({ from: '12.10.2023', to: '15.10.2023' }) return { args, value1, value2, value3, value4, value5 } }, template: `
`, }), } export const WithDateFormatReturn: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { placeholderFrom: 'Début', placeholderTo: 'Fin', format: 'DD/MM/YYYY', dateFormatReturn: '', required: false, displayIcon: true, displayAppendIcon: false, disabled: false, noIcon: false, modelValue: { from: null, to: null }, }, render: args => ({ components: { PeriodField: PeriodField }, setup() { const value1 = ref({ from: '12/10/2023', to: '15/10/2023' }) const value2 = ref({ from: '12/10/2023', to: '15/10/2023' }) const value3 = ref({ from: '12/10/2023', to: '15/10/2023' }) const valueReturn1 = ref({ from: '12/10/2023', to: '15/10/2023' }) const valueReturn2 = ref({ from: '10/12/2023', to: '10/15/2023' }) const valueReturn3 = ref({ from: '2023/12/10', to: '2023/15/10' }) return { args, value1, value2, value3, valueReturn1, valueReturn2, valueReturn3 } }, template: `
Période de retour : {{ valueReturn1 }}

Période de retour : {{ valueReturn2 }}

Période de retour : {{ valueReturn3 }}

`, }), } export const ValidationBehaviors: Story = { parameters: { sourceCode: [ { code: ` `, }, ], }, render: args => ({ components: { PeriodField }, setup() { const periodDefault = ref({ from: null, to: null }) const periodNoErrors = ref({ from: null, to: null }) const periodNoSuccess = ref({ from: null, to: null }) const periodNoValidation = ref({ from: null, to: null }) return { args, periodDefault, periodNoErrors, periodNoSuccess, periodNoValidation, } }, template: `

Par défaut (avec validation)

Validation désactivée (disableErrorHandling=true)

Messages de succès désactivés (showSuccessMessages=false)

Validation et messages de succès désactivés

`, }), } export const FormValidation: Story = { parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, render: () => ({ components: { PeriodField }, setup() { // Référence au formulaire const formRef = ref(null) const periodFieldRef = ref(null) const isSubmitting = ref(false) const isFormSubmitted = ref(false) const formData = ref(null) const formStatus = ref('') // Données du formulaire const form = ref({ period: { from: null, to: null }, }) // Règles de validation pour le champ période const periodRules = [ { type: 'notAfterToday', options: { message: 'La date ne peut pas être après aujourdhui' } }, ] // Soumission du formulaire const submitForm = async (): Promise => { if (periodFieldRef.value) { const isValid = await periodFieldRef.value.validateOnSubmit() if (isValid) { formStatus.value = 'Formulaire soumis avec succès !' isFormSubmitted.value = true formData.value = JSON.stringify(form.value) } else { formStatus.value = 'Erreur de validation, veuillez corriger les champs' } } } return { formRef, periodFieldRef, isSubmitting, isFormSubmitted, formData, form, periodRules, formStatus, submitForm, } }, template: `

Formulaire avec validation

Valider
{{ formStatus }}
{{ formData }}
`, }), }