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: `
Période sélectionnée :
{{ selectedPeriod }}
`,
},
{
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: `
Période sélectionnée : {{ selectedPeriod }}
`,
},
{
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: `
Période sélectionnée : {{ selectedPeriod }}
`,
},
{
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: `
Période sélectionnée : {{ selectedPeriod }}
`,
},
{
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: `
Période sélectionnée : {{ selectedPeriod }}
`,
},
{
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: `
Période sélectionnée : {{ selectedPeriod }}
`,
},
{
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: `
Période sélectionnée : {{ selectedPeriod }}
`,
},
{
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: `
Période sélectionnée : {{ selectedPeriod }}
`,
},
{
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: `
Période de retour : {{ value1 }}
Période de retour : {{ value2 }}
Période de retour : {{ value3 }}
`,
},
{
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: `
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
`,
},
],
},
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: `
Formulaire avec validation
Valider
Formulaire envoyé avec succès !
{{ formData }}
`,
},
{
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 }}
`,
}),
}