import type { Meta, StoryObj } from '@storybook/vue3' import { ref, computed } from 'vue' import SyForm from './SyForm.vue' import SyTextField from '@/components/Customs/SyTextField/SyTextField.vue' import SyCheckbox from '@/components/Customs/SyCheckbox/SyCheckbox.vue' import SySelect from '@/components/Customs/Selects/SySelect/SySelect.vue' import { VBtn } from 'vuetify/components' import { fn } from '@storybook/test' export default { title: 'Composants/Formulaires/SyForm', component: SyForm, argTypes: { validateOnSubmit: { control: 'boolean', description: 'Active ou désactive la validation automatique lors de la soumission', defaultValue: true, }, default: { description: 'Contenu du formulaire, généralement des champs de formulaire comme SyTextField, SySelect, etc.', table: { type: { summary: ` { 'isValid': boolean, 'validate': () => Promise, 'reset': () => void, 'clear': () => void }`, }, }, }, }, parameters: { docs: { description: { component: 'SyForm est un composant de formulaire qui prend en charge à la fois les composants personnalisés et les composants natifs Vuetify.', }, }, }, } satisfies Meta type Story = StoryObj export const Basic: Story = { args: { onReset: fn(), onSubmit: fn(), }, render: args => ({ components: { SyForm, SyTextField, VBtn }, setup() { const name = ref('') const email = ref('') const form = ref<{ validate: () => Promise, reset: () => void, clearValidation: () => void } | null>(null) // Règles de validation selon le design system const emailRules = [ { type: 'email', options: { message: 'Format d\'email invalide' } }, { type: 'required', options: { message: 'L\'email est obligatoire' } }, ] const submitForm = async (e: { isValid: boolean }) => { if (e.isValid) { alert('Formulaire valide !') } else { alert('Formulaire invalide, veuillez corriger les erreurs.') } } return { name, email, emailRules, form, submitForm, args } }, template: `
Soumettre
`, }), parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, } export const CustomValidation: Story = { args: { validateOnSubmit: false, onReset: fn(), onSubmit: fn(), }, render: args => ({ components: { SyForm, SyTextField, VBtn }, setup() { const username = ref('') const password = ref('') const confirmPassword = ref('') const form = ref<{ validate: () => Promise, reset: () => void, clearValidation: () => void } | null>(null) // Règles de validation const passwordRules = computed(() => [ { type: 'minLength', options: { length: 8, message: 'Minimum 8 caractères' } }, { type: 'required', options: { message: 'Le mot de passe est obligatoire' } }, ]) const confirmPasswordRules = computed(() => [ { type: 'custom', options: { validate: (value: string) => value === password.value, message: 'Les mots de passe ne correspondent pas', } }, { type: 'required', options: { message: 'Veuillez confirmer le mot de passe' } }, ]) const submitForm = async (e: { isValid: boolean }) => { if (e.isValid) { alert('Inscription réussie ! (validate on submit = ' + args.validateOnSubmit + ')') } else { alert('Formulaire invalide, veuillez corriger les erreurs.') } } const validateManually = async () => { const isValid = await form.value?.validate() if (isValid) { alert('Formulaire valide !') } else { alert('Formulaire invalide !') } } return { username, password, confirmPassword, passwordRules, confirmPasswordRules, form, submitForm, validateManually, args } }, template: `
S'inscrire Valider sans soumettre
`, }), parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, } export const MixedFields: Story = { args: { onReset: fn(), onSubmit: fn(), }, render: args => ({ components: { SyForm, SyTextField, SySelect, SyCheckbox, VBtn }, setup() { const formData = ref({ name: '', email: '', country: '', }) const form = ref<{ validate: () => Promise } | null>(null) // Règles de validation const emailCustomRules = [ { type: 'email', options: { message: 'L\'email n\'est pas valide', successMessage: 'L\'email est valide', }, }, { type: 'required', options: { message: 'L\'email est obligatoire' } }, ] const countries = [ { text: 'France', value: 'fr' }, { text: 'Allemagne', value: 'de' }, { text: 'Espagne', value: 'es' }, { text: 'Italie', value: 'it' }, ] const submitForm = async (e: { isValid: boolean }) => { if (e.isValid) { alert(`Formulaire valide ! Données: ${JSON.stringify(formData.value)}`) } else { alert('Formulaire invalide, veuillez corriger les erreurs.') } } return { formData, countries, form, submitForm, emailCustomRules, args } }, template: `
Enregistrer
`, }), parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, } export const Reset: Story = { args: { onReset: fn(), onSubmit: fn(), }, render: args => ({ components: { SyForm, SyTextField, VBtn }, setup() { const name = ref('') const email = ref('') const form = ref<{ validate: () => Promise, reset: () => void, clearValidation: () => void } | null>(null) // Règles de validation selon le design system const emailRules = [ { type: 'email', options: { message: 'Format d\'email invalide' } }, { type: 'required', options: { message: 'L\'email est obligatoire' } }, ] const submitForm = async (e: { isValid: boolean }) => { if (e.isValid) { alert('Formulaire valide !') } else { alert('Formulaire invalide, veuillez corriger les erreurs.') } } function clearAll() { form.value?.reset() form.value?.clearValidation() } function onFormReset() { alert('Formulaire réinitialisé !') args.onReset?.() } return { name, email, emailRules, form, submitForm, clearAll, onFormReset, args } }, template: `
Reset Soumettre
`, }), parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, }