import type { Meta, StoryObj } from '@storybook/vue3' import { ref, watch } from 'vue' import AmeliproTextField from './AmeliproTextField.vue' const meta = { argTypes: { 'append': { description: 'Permet d\'ajouter un élément juste après le champ' }, 'required': { default: false, description: 'Défini que le champ est obligatoire', name: 'required', type: 'boolean', }, 'classes': { description: 'Classes à appliquer à la racine du composant' }, 'clearable': { description: 'Affiche un bouton permettant de vider le champ' }, 'counter': { description: 'Défini la valeur du compteur de caractères' }, 'disabled': { description: 'Désactive le champ de texte' }, 'fullWidthErrorMsg': { description: 'Donne au messages d’erreurs la largeur totale du composant au lieu de la limiter à la largeur du champ' }, 'globalMaxWidth': { description: 'Gère la largeur maximale du composant, attend une valeur et une unité valide css (ex : 400px ou 25%)' }, 'globalMinWidth': { description: 'Gère la largeur minimale du composant, attend une valeur et une unité valide css (ex : 400px ou 25%)' }, 'globalWidth': { description: 'Gère la largeur du composant, attend une valeur et une unité valide css (ex : 400px ou 25%)' }, 'hideErrorMessage': { description: 'Masque ou affiche le message d’erreur, si la valeur est à "auto" le message ne sera rendu que s’il y en a un' }, 'horizontal': { description: 'Passe le champ au format horizontal' }, 'inputMaxWidth': { description: 'Gère la largeur maximale du champ, attend une valeur et une unité valide css (ex : 400px ou 25%)' }, 'inputMinWidth': { description: 'Gère la largeur minimale du champ, attend une valeur et une unité valide css (ex : 400px ou 25%)' }, 'isValidationList': { description: 'Affiche une liste des règles à valider (uniquemenent avec type email et password)' }, 'label': { description: 'Défini le label du champ' }, 'labelInfo': { description: 'Permet d\'ajouter des infos à la suite du libellé du champ' }, 'labelMaxWidth': { description: 'Gère la largeur maximale du label, attend une valeur et une unité valide css (ex : 400px ou 25%)' }, 'labelMinWidth': { description: 'Gère la largeur minimale du label, attend une valeur et une unité valide css (ex : 400px ou 25%)' }, 'maxDate': { description: 'Date limite maximale pour le champ (uniquement si type date), format attendu YYYY-MM-DD' }, 'maxNumber': { description: 'Nombre maximal pour le champ (uniquement si type number)' }, 'messagesToDisplay': { description: 'Messages à afficher' }, 'minDate': { description: 'Date limite minimale pour le champ (uniquement si type date), format attendu YYYY-MM-DD' }, 'minNumber': { description: 'Nombre minimal pour le champ (uniquement si type number)' }, 'modelValue': { description: 'Défini la valeur du champ' }, 'placeholder': { description: 'Placeholder du champ' }, 'readonly': { description: 'Passe le champ de texte en lecture seule' }, 'rules': { description: 'Liste des règles à respecter pour valider le champ', table: { type: 'ValidationRule[]' }, }, 'type': { description: 'Type du champ' }, 'uniqueId': { description: 'Défini un id pour le champ' }, 'update:model-value': { description: 'Événement émis au changement du v-model' }, 'validateOn': { description: 'Défini le moment où la validation du champ se fait, voir la documentation de Vuetify pour plus d’informtations' }, }, component: AmeliproTextField, title: 'Composants/Amelipro/Formulaires/AmeliproTextField', } as Meta export default meta type Story = StoryObj export const Default: Story = { args: { label: 'Mon label', modelValue: '', uniqueId: 'text-example', }, parameters: { sourceCode: [ { name: 'Template', code: ` `, }, { name: 'Script', code: ` `, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: ``, }), } export const Date: Story = { args: { required: true, label: 'Mon label', maxDate: '2024-02-20', minDate: '2024-01-20', modelValue: '', type: 'date', uniqueId: 'date-example', }, parameters: { sourceCode: [ { name: 'Template', code: `

Exemple de champ texte de type date.

`, }, { name: 'Script', code: ` `, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Exemple de champ texte de type date.

`, }), } export const Number: Story = { args: { required: true, label: 'Mon label', maxNumber: '10', minNumber: '0', modelValue: '', type: 'number', uniqueId: 'number-example', }, parameters: { sourceCode: [ { name: 'Template', code: `

Exemple de champ texte de type number.

`, }, { name: 'Script', code: ` `, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Exemple de champ texte de type number.

`, }), } export const Clearable: Story = { args: { label: 'Champ effaçable', modelValue: 'Texte à effacer', uniqueId: 'text-clearable', clearable: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref('Texte à effacer') watch(() => args.modelValue, (newValue) => { model.value = String(newValue) }) return { args, model } }, template: `

Le champ peut être effacé grâce à la prop clearable.

`, }), } export const Counter: Story = { args: { label: 'Champ avec compteur', modelValue: '', uniqueId: 'text-counter', counter: 20, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le champ affiche un compteur de caractères grâce à la prop counter.

`, }), } export const CustomWidth: Story = { args: { label: 'Largeur personnalisée', modelValue: '', uniqueId: 'text-width', globalWidth: '400px', }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

La largeur du champ est personnalisée grâce à la prop globalWidth.

`, }), } export const Disabled: Story = { args: { label: 'Champ désactivé', modelValue: '', uniqueId: 'text-disabled', disabled: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le champ est désactivé grâce à la prop disabled.

`, }), } export const FullWidthErrorMsg: Story = { args: { label: 'Message d’erreur pleine largeur', modelValue: '', uniqueId: 'text-fullwidth-error', rules: [v => !!v || 'Affichage d’un long message d’erreur pour la démonstration'], fullWidthErrorMsg: true, inputMaxWidth: '100px', }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le message d’erreur occupe toute la largeur grâce à la prop fullWidthErrorMsg.

`, }), } export const HideErrorMessage: Story = { args: { label: 'Masquer le message d’erreur', modelValue: '', uniqueId: 'text-hide-error', rules: [v => !!v || 'Erreur obligatoire'], hideErrorMessage: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le message d’erreur est masqué grâce à la prop hideErrorMessage.

`, }), } export const Horizontal: Story = { args: { label: 'Champ horizontal', modelValue: '', uniqueId: 'text-horizontal', horizontal: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le champ est affiché en mode horizontal grâce à la prop horizontal.

`, }), } export const LabelMaxWidth: Story = { args: { label: 'Un très long label dont la largeur est personnalisée', modelValue: '', uniqueId: 'text-label-maxwidth', labelMaxWidth: '200px', }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

La largeur du label est limitée grâce à la prop labelMaxWidth.

`, }), } export const Placeholder: Story = { args: { label: 'Champ avec placeholder', modelValue: '', uniqueId: 'text-placeholder', placeholder: 'Saisissez votre texte ici...', }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le champ affiche un placeholder grâce à la prop placeholder.

`, }), } export const Readonly: Story = { args: { label: 'Lecture seule', modelValue: 'Valeur non modifiable', uniqueId: 'text-readonly', readonly: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref('Valeur non modifiable') watch(() => args.modelValue, (newValue) => { model.value = String(newValue) }) return { args, model } }, template: `

Le champ est en lecture seule grâce à la prop readonly.

`, }), } export const Required: Story = { args: { label: 'Champ requis', modelValue: '', uniqueId: 'text-required', required: true, }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le champ est requis grâce à la prop required.

`, }), } export const Validation: Story = { args: { label: 'Champ avec validation', modelValue: '', uniqueId: 'text-validation', rules: [v => !!v || 'Ce champ est obligatoire'], }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le champ utilise la prop rules pour valider la saisie.

`, }), } export const ValidationList: Story = { args: { label: 'Champ avec liste de validation validation', modelValue: '', uniqueId: 'list-validation', type: 'password', isValidationList: true, rules: [ v => String(v ?? '').length >= 12 || 'Au moins 12 caractères', v => ((/[A-Z]/.test(String(v ?? '')) && /[a-z]/.test(String(v ?? '')))) || 'Au moins une majuscule (A-Z) et une minuscule (a-z)', v => /\d/.test(String(v ?? '')) || 'Au moins un chiffre (0-9)', v => /[!@#$%^&*?./:;]/.test(String(v ?? '')) || 'Au moins un caractère spécial (! @ # $ % ^ & * ? . / : ;)', ], }, parameters: { sourceCode: [ { name: 'Template', code: ``, }, { name: 'Script', code: ``, }, ], }, render: args => ({ components: { AmeliproTextField }, setup() { const model = ref() watch(() => args.modelValue, (newValue) => { model.value = newValue }) return { args, model } }, template: `

Le champ utilise la prop rules pour valider la saisie ainsi que le prop isValidationList pour afficher la liste des règles à valider.

`, }), }