import SyForm from '@/components/Customs/SyForm/SyForm.vue' import PhoneField from '../PhoneField.vue' import type { StoryObj, Meta } from '@storybook/vue3' import { ref, onMounted } from 'vue' import { VBtn } from 'vuetify/components' import { VForm } from 'vuetify/components/VForm' import { default as phoneFieldMeta } from '../PhoneField.stories' const meta: Meta = { ...phoneFieldMeta, title: 'Composants/Formulaires/PhoneField/Validation', } as Meta export default meta type Story = StoryObj export const WithError: Story = { parameters: { docs: { description: { story: 'Un numéro invalide est pré-rempli et déclenche une erreur bloquante au chargement.', }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, render: args => ({ components: { PhoneField }, setup() { const phone = ref('123') const phoneRef = ref<{ validateOnSubmit: () => Promise } | null>(null) onMounted(() => { phoneRef.value?.validateOnSubmit() }) return { args, phone, phoneRef } }, template: `
`, }), } export const WithWarning: Story = { parameters: { docs: { description: { story: 'Un numéro est pré-rempli et déclenche un avertissement (non bloquant) au chargement.', }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, render: args => ({ components: { PhoneField }, setup() { const phone = ref('0812345678') const phoneRef = ref<{ validateOnSubmit: () => Promise } | null>(null) onMounted(() => { phoneRef.value?.validateOnSubmit() }) return { args, phone, phoneRef } }, template: `
`, }), } export const WithSuccess: Story = { parameters: { docs: { description: { story: 'Un numéro valide est pré-rempli et déclenche la confirmation de succès au chargement.', }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { showSuccessMessages: true, } as Record, render: args => ({ components: { PhoneField }, setup() { const phone = ref('0612345678') const phoneRef = ref<{ validateOnSubmit: () => Promise } | null>(null) onMounted(() => { phoneRef.value?.validateOnSubmit() }) return { args, phone, phoneRef } }, template: `
`, }), } export const NoValidateOnBlur: Story = { parameters: { docs: { description: { story: 'Avec `isValidateOnBlur: false`, la validation se déclenche **immédiatement** dès que la valeur change, sans attendre que le champ perde le focus.\n\nCliquez sur « Définir une valeur invalide » : l\'erreur apparaît aussitôt, sans qu\'il soit nécessaire de quitter le champ. Avec le comportement par défaut (`isValidateOnBlur: true`), la même action ne déclencherait aucune erreur tant que l\'utilisateur n\'a pas quitté le champ.', }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { isValidateOnBlur: false, showSuccessMessages: true, } as Record, render: args => ({ components: { PhoneField, VBtn }, setup() { const phone = ref('') return { args, phone } }, template: `
Définir une valeur invalide Définir une valeur valide Réinitialiser
`, }), } export const DisableErrorHandling: Story = { parameters: { docs: { description: { story: 'Avec `disableErrorHandling: true`, les règles d\'erreur sont évaluées mais n\'affectent pas l\'état visuel du champ (pas de bordure rouge ni d\'icône d\'erreur). Utile dans les cas où la validation doit être effectuée en arrière-plan sans perturber l\'expérience utilisateur.', }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, args: { disableErrorHandling: true, } as Record, render: args => ({ components: { PhoneField }, setup() { const phone = ref('123') return { args, phone } }, template: `
`, }), } export const SyFormValidation: Story = { parameters: { docs: { description: { story: 'Le champ peut être intégré dans un formulaire utilisant `SyForm` pour bénéficier de la validation globale du formulaire. Dans cet exemple, le bouton de soumission est désactivé tant que le numéro de téléphone n\'est pas valide.', }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, render: args => ({ components: { SyForm, PhoneField, VBtn }, setup() { const phone = ref('') const onSubmit = (e) => { alert('Le formulaire est : ' + (e.isValid ? 'valide' : 'invalide')) } return { args, phone, onSubmit } }, template: `
Soumettre
`, }), } export const VFormValidation: Story = { parameters: { docs: { description: { story: 'Le champ peut également être utilisé dans un formulaire classique de Vuetify (`VForm`). Dans cet exemple, le bouton de soumission est désactivé tant que le numéro de téléphone n\'est pas valide.', }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, render: args => ({ components: { PhoneField, VForm, VBtn }, setup() { const phone = ref('') const phoneFieldRef = ref<{ validateOnSubmit: () => Promise } | null>(null) async function onSubmit() { const result = await phoneFieldRef.value!.validateOnSubmit() alert('Le formulaire est : ' + (result ? 'valide' : 'invalide')) } return { args, phone, phoneFieldRef, onSubmit } }, template: `

Preferable d'utiliser SyForm pour bénéficier de la validation globale du formulaire.

Soumettre
`, }), } export const SyFormVuetifyValidation: Story = { parameters: { docs: { description: { story: 'Le champ est compatible avec les deux types de formulaires (`SyForm` et `VForm`) dans le même projet, permettant une intégration flexible selon les besoins spécifiques de chaque formulaire.\n\n- **SyForm** : la soumission déclenche automatiquement la validation de tous les champs enregistrés.\n- **VForm** : le bouton de soumission appelle manuellement `validateOnSubmit()` sur le champ.', }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, render: args => ({ components: { SyForm, PhoneField, VForm, VBtn }, setup() { const phone = ref('') function onSyFormSubmit(event: { isValid: boolean }) { if (event.isValid) { alert(`SyForm valide : ${phone.value}`) } else { alert('SyForm invalide : veuillez corriger les erreurs.') } } const rules = [ value => /^0[1-9][0-9]{8}$/.test(value.replace(/\s/g, '')) || 'Le numéro de téléphone n\'est pas valide.', ] return { args, phone, rules, onSyFormSubmit } }, template: ` Soumettre (SyForm) `, }), } export const VFormAndVuetifyValidation: Story = { parameters: { docs: { description: { story: 'En utilisant vuetifyValidation, le champ peut être validé à la fois par `SyForm` et `VForm` selon le contexte d\'utilisation.', }, }, sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, render: args => ({ components: { PhoneField, VForm, VBtn }, setup() { const phone = ref('') async function onSubmit(e: Promise<{ valid: boolean }>) { const result = await e alert('Le formulaire est : ' + (result.valid ? 'valide' : 'invalide')) } return { args, phone, onSubmit } }, template: `
Soumettre
`, }), }