@cnamts/synapse 0.0.14-alpha → 0.0.15-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Customs/SyInputSelect/SyInputSelect.d.ts +2 -2
- package/dist/components/Customs/SySelect/SySelect.d.ts +24 -12
- package/dist/components/Customs/SySelect/locales.d.ts +3 -0
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +2 -2
- package/dist/components/DatePicker/DatePicker.d.ts +732 -16
- package/dist/components/DatePicker/DateTextInput.d.ts +8 -8
- package/dist/components/DialogBox/config.d.ts +1 -1
- package/dist/components/DownloadBtn/DownloadBtn.d.ts +2 -0
- package/dist/components/LangBtn/LangBtn.d.ts +467 -1
- package/dist/components/LangBtn/config.d.ts +1 -3
- package/dist/components/NirField/NirField.d.ts +13 -13
- package/dist/components/PasswordField/PasswordField.d.ts +2 -2
- package/dist/components/PeriodField/PeriodField.d.ts +1462 -30
- package/dist/components/PhoneField/PhoneField.d.ts +3 -3
- package/dist/components/SelectBtnField/SelectBtnField.d.ts +1 -1
- package/dist/components/SkipLink/SkipLink.d.ts +3 -2
- package/dist/components/UserMenuBtn/UserMenuBtn.d.ts +2 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/design-system-v3.js +3038 -2936
- package/dist/design-system-v3.umd.cjs +1 -1
- package/dist/style.css +1 -1
- package/dist/vuetifyConfig.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/BackBtn/Accessibilite.stories.ts +4 -0
- package/src/components/BackBtn/BackBtn.vue +2 -1
- package/src/components/BackToTopBtn/Accessibilite.stories.ts +4 -0
- package/src/components/BackToTopBtn/BackToTopBtn.stories.ts +78 -21
- package/src/components/BackToTopBtn/BackToTopBtn.vue +15 -0
- package/src/components/BackToTopBtn/config.ts +2 -2
- package/src/components/BackToTopBtn/tests/__snapshots__/BackToTopBtn.spec.ts.snap +4 -4
- package/src/components/CopyBtn/Accessibilite.stories.ts +4 -0
- package/src/components/Customs/SyBtnSelect/SyBtnSelect.stories.ts +2 -2
- package/src/components/Customs/SyBtnSelect/SyBtnSelect.vue +0 -1
- package/src/components/Customs/SyInputSelect/SyInputSelect.stories.ts +3 -3
- package/src/components/Customs/SyInputSelect/SyInputSelect.vue +4 -4
- package/src/components/Customs/SySelect/SySelect.stories.ts +4 -0
- package/src/components/Customs/SySelect/SySelect.vue +75 -10
- package/src/components/Customs/SySelect/locales.ts +3 -0
- package/src/components/Customs/SySelect/tests/SySelect.spec.ts +24 -2
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +1 -1
- package/src/components/Customs/SyTextField/SyTextField.vue +3 -3
- package/src/components/DatePicker/DatePicker.vue +82 -57
- package/src/components/DatePicker/DatePickerValidation.mdx +338 -0
- package/src/components/DatePicker/DatePickerValidation.stories.ts +22 -0
- package/src/components/DatePicker/DatePickerValidationExamples.vue +535 -0
- package/src/components/DatePicker/DateTextInput.vue +3 -3
- package/src/components/DatePicker/tests/DateTextInput.spec.ts +2 -2
- package/src/components/DialogBox/DialogBox.stories.ts +5 -2
- package/src/components/DialogBox/DialogBox.vue +1 -1
- package/src/components/DialogBox/config.ts +1 -1
- package/src/components/DownloadBtn/Accessibilite.stories.ts +4 -0
- package/src/components/DownloadBtn/DownloadBtn.stories.ts +17 -8
- package/src/components/DownloadBtn/DownloadBtn.vue +13 -6
- package/src/components/DownloadBtn/tests/__snapshots__/DownloadBtn.spec.ts.snap +0 -2
- package/src/components/FranceConnectBtn/Accessibilite.stories.ts +4 -0
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +3 -0
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +3 -0
- package/src/components/HeaderBar/HeaderBurgerMenu/menu.scss +19 -0
- package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +12 -2
- package/src/components/LangBtn/Accessibilite.stories.ts +4 -0
- package/src/components/LangBtn/LangBtn.stories.ts +1 -4
- package/src/components/LangBtn/LangBtn.vue +68 -9
- package/src/components/LangBtn/config.ts +0 -1
- package/src/components/LangBtn/tests/LangBtn.spec.ts +30 -2
- package/src/components/PageContainer/Accessibilite.stories.ts +36 -23
- package/src/components/PaginatedTable/PaginatedTable.stories.ts +144 -18
- package/src/components/PasswordField/PasswordField.stories.ts +6 -6
- package/src/components/PasswordField/PasswordField.vue +3 -3
- package/src/components/PeriodField/PeriodField.vue +4 -4
- package/src/components/PhoneField/PhoneField.stories.ts +216 -24
- package/src/components/PhoneField/PhoneField.vue +32 -2
- package/src/components/PhoneField/tests/PhoneField.spec.ts +161 -14
- package/src/components/RatingPicker/NumberPicker/NumberPicker.vue +2 -1
- package/src/components/RatingPicker/RatingPicker.stories.ts +1 -1
- package/src/components/SkipLink/Accessibilite.stories.ts +8 -0
- package/src/components/SkipLink/SkipLink.vue +11 -9
- package/src/components/SkipLink/tests/__snapshots__/skipLink.spec.ts.snap +7 -4
- package/src/components/SkipLink/tests/skipLink.spec.ts +120 -6
- package/src/components/UserMenuBtn/UserMenuBtn.stories.ts +56 -0
- package/src/components/UserMenuBtn/UserMenuBtn.vue +4 -2
- package/src/components/UserMenuBtn/tests/UserMenuBtn.spec.ts +41 -0
- package/src/components/index.ts +1 -0
- package/src/composables/rules/useFieldValidation.ts +26 -3
- package/src/stories/Accessibilite/KitDePreAudit/Echantillonnage.mdx +1 -1
- package/src/stories/GuideDuDev/LesBreackingChanges.mdx +31 -2
- package/src/components/LangBtn/tests/Config.spec.ts +0 -24
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
|
|
2
|
+
import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick, type ComponentPublicInstance } from 'vue'
|
|
3
3
|
import SyTextField from '@/components/Customs/SyTextField/SyTextField.vue'
|
|
4
4
|
import DateTextInput from './DateTextInput.vue'
|
|
5
5
|
import { VDatePicker } from 'vuetify/components'
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
noIcon?: boolean
|
|
33
33
|
noCalendar?: boolean
|
|
34
34
|
isOutlined?: boolean
|
|
35
|
-
|
|
35
|
+
readonly?: boolean
|
|
36
36
|
width?: string
|
|
37
37
|
disableErrorHandling?: boolean
|
|
38
38
|
showSuccessMessages?: boolean
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
noIcon: false,
|
|
56
56
|
noCalendar: false,
|
|
57
57
|
isOutlined: true,
|
|
58
|
-
|
|
58
|
+
readonly: false,
|
|
59
59
|
width: '100%',
|
|
60
60
|
disableErrorHandling: false,
|
|
61
61
|
showSuccessMessages: true,
|
|
@@ -377,7 +377,9 @@
|
|
|
377
377
|
document.removeEventListener('click', handleClickOutside)
|
|
378
378
|
})
|
|
379
379
|
|
|
380
|
-
const dateTextInputRef = ref()
|
|
380
|
+
const dateTextInputRef = ref<null | ComponentPublicInstance< typeof DateTextInput>>()
|
|
381
|
+
const dateCalendarTextInputRef = ref<null | ComponentPublicInstance<typeof SyTextField>>()
|
|
382
|
+
const datePickerRef = ref<null | ComponentPublicInstance<typeof VDatePicker>>()
|
|
381
383
|
|
|
382
384
|
const validateOnSubmit = () => {
|
|
383
385
|
if (props.noCalendar) {
|
|
@@ -390,7 +392,7 @@
|
|
|
390
392
|
}
|
|
391
393
|
|
|
392
394
|
const showDatePicker = () => {
|
|
393
|
-
if (props.disabled || props.
|
|
395
|
+
if (props.disabled || props.readonly) return
|
|
394
396
|
|
|
395
397
|
isDatePickerVisible.value = true
|
|
396
398
|
|
|
@@ -430,11 +432,33 @@
|
|
|
430
432
|
}
|
|
431
433
|
}
|
|
432
434
|
|
|
433
|
-
watch(isDatePickerVisible, (isVisible) => {
|
|
435
|
+
watch(isDatePickerVisible, async (isVisible) => {
|
|
434
436
|
if (!isVisible && props.isBirthDate) {
|
|
435
437
|
// Réinitialiser le mode d'affichage au type birthdate
|
|
436
438
|
currentViewMode.value = 'year'
|
|
437
439
|
}
|
|
440
|
+
|
|
441
|
+
if (isVisible) {
|
|
442
|
+
// set the focus on the date picker
|
|
443
|
+
await nextTick()
|
|
444
|
+
const firstButton = datePickerRef.value?.$el.querySelector('button')
|
|
445
|
+
if (firstButton) {
|
|
446
|
+
firstButton.focus()
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
// set the focus on the text input
|
|
451
|
+
// wait for VMenu to finish DOM updates & transition
|
|
452
|
+
setTimeout(() => {
|
|
453
|
+
requestAnimationFrame(() => {
|
|
454
|
+
const inputElement = dateCalendarTextInputRef.value?.$el?.querySelector('input')
|
|
455
|
+
if (inputElement) {
|
|
456
|
+
inputElement.focus()
|
|
457
|
+
isDatePickerVisible.value = false
|
|
458
|
+
}
|
|
459
|
+
})
|
|
460
|
+
}, 0)
|
|
461
|
+
}
|
|
438
462
|
})
|
|
439
463
|
|
|
440
464
|
const getIcon = () => {
|
|
@@ -532,7 +556,7 @@
|
|
|
532
556
|
:custom-rules="props.customRules"
|
|
533
557
|
:custom-warning-rules="props.customWarningRules"
|
|
534
558
|
:disabled="props.disabled"
|
|
535
|
-
:
|
|
559
|
+
:readonly="props.readonly"
|
|
536
560
|
:is-outlined="props.isOutlined"
|
|
537
561
|
:display-icon="props.displayIcon"
|
|
538
562
|
:display-append-icon="props.displayAppendIcon"
|
|
@@ -547,32 +571,6 @@
|
|
|
547
571
|
/>
|
|
548
572
|
</template>
|
|
549
573
|
<template v-else>
|
|
550
|
-
<SyTextField
|
|
551
|
-
v-model="displayFormattedDate"
|
|
552
|
-
:append-icon="displayIcon && displayAppendIcon ? 'calendar' : undefined"
|
|
553
|
-
:append-inner-icon="getIcon()"
|
|
554
|
-
:class="[getMessageClasses(), 'label-hidden-on-focus']"
|
|
555
|
-
:error-messages="errorMessages"
|
|
556
|
-
:warning-messages="warningMessages"
|
|
557
|
-
:success-messages="props.showSuccessMessages ? successMessages : []"
|
|
558
|
-
:disabled="props.disabled"
|
|
559
|
-
:read-only="true"
|
|
560
|
-
:label="props.placeholder"
|
|
561
|
-
:no-icon="props.noIcon"
|
|
562
|
-
:prepend-icon="displayIcon && !displayAppendIcon ? 'calendar' : undefined"
|
|
563
|
-
:variant-style="props.isOutlined ? 'outlined' : 'underlined'"
|
|
564
|
-
color="primary"
|
|
565
|
-
:show-success-messages="props.showSuccessMessages"
|
|
566
|
-
:bg-color="props.bgColor"
|
|
567
|
-
is-clearable
|
|
568
|
-
title="Date Picker"
|
|
569
|
-
@focus="openDatePicker"
|
|
570
|
-
@update:model-value="updateSelectedDates"
|
|
571
|
-
@prepend-icon-click="openDatePicker"
|
|
572
|
-
@append-icon-click="openDatePicker"
|
|
573
|
-
/>
|
|
574
|
-
</template>
|
|
575
|
-
<div>
|
|
576
574
|
<VMenu
|
|
577
575
|
v-if="!props.noCalendar"
|
|
578
576
|
v-model="isDatePickerVisible"
|
|
@@ -586,32 +584,59 @@
|
|
|
586
584
|
attach="body"
|
|
587
585
|
:offset="[-20, 5]"
|
|
588
586
|
>
|
|
589
|
-
<
|
|
590
|
-
<
|
|
591
|
-
v-
|
|
592
|
-
|
|
587
|
+
<template #activator="{ props: menuProps }">
|
|
588
|
+
<SyTextField
|
|
589
|
+
v-bind="menuProps"
|
|
590
|
+
ref="dateCalendarTextInputRef"
|
|
591
|
+
v-model="displayFormattedDate"
|
|
592
|
+
:append-icon="displayIcon && displayAppendIcon ? 'calendar' : undefined"
|
|
593
|
+
:append-inner-icon="getIcon()"
|
|
594
|
+
:class="[getMessageClasses(), 'label-hidden-on-focus']"
|
|
595
|
+
:error-messages="errorMessages"
|
|
596
|
+
:warning-messages="warningMessages"
|
|
597
|
+
:success-messages="props.showSuccessMessages ? successMessages : []"
|
|
598
|
+
:disabled="props.disabled"
|
|
599
|
+
:readonly="true"
|
|
600
|
+
:label="props.placeholder"
|
|
601
|
+
:no-icon="props.noIcon"
|
|
602
|
+
:prepend-icon="displayIcon && !displayAppendIcon ? 'calendar' : undefined"
|
|
603
|
+
:variant-style="props.isOutlined ? 'outlined' : 'underlined'"
|
|
593
604
|
color="primary"
|
|
594
|
-
:
|
|
595
|
-
:
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
@update:
|
|
600
|
-
@
|
|
601
|
-
@
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
605
|
+
:show-success-messages="props.showSuccessMessages"
|
|
606
|
+
:bg-color="props.bgColor"
|
|
607
|
+
is-clearable
|
|
608
|
+
title="Date Picker"
|
|
609
|
+
@focus="openDatePicker"
|
|
610
|
+
@update:model-value="updateSelectedDates"
|
|
611
|
+
@prepend-icon-click="openDatePicker"
|
|
612
|
+
@append-icon-click="openDatePicker"
|
|
613
|
+
/>
|
|
614
|
+
</template>
|
|
615
|
+
<VDatePicker
|
|
616
|
+
v-if="isDatePickerVisible && !props.noCalendar"
|
|
617
|
+
ref="datePickerRef"
|
|
618
|
+
v-model="selectedDates"
|
|
619
|
+
color="primary"
|
|
620
|
+
:first-day-of-week="1"
|
|
621
|
+
:multiple="props.displayRange ? 'range' : false"
|
|
622
|
+
:show-adjacent-months="true"
|
|
623
|
+
:show-week="props.showWeekNumber"
|
|
624
|
+
:view-mode="currentViewMode"
|
|
625
|
+
@update:view-mode="handleViewModeUpdate"
|
|
626
|
+
@update:year="handleYearUpdate"
|
|
627
|
+
@update:month="handleMonthUpdate"
|
|
628
|
+
>
|
|
629
|
+
<template #title>
|
|
630
|
+
Sélectionnez une date
|
|
631
|
+
</template>
|
|
632
|
+
<template #header>
|
|
633
|
+
<h3 class="mx-auto my-auto ml-5 mb-4">
|
|
634
|
+
{{ todayInString }}
|
|
635
|
+
</h3>
|
|
636
|
+
</template>
|
|
637
|
+
</VDatePicker>
|
|
613
638
|
</VMenu>
|
|
614
|
-
</
|
|
639
|
+
</template>
|
|
615
640
|
</div>
|
|
616
641
|
</template>
|
|
617
642
|
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import {Meta, Canvas, Controls, Source} from '@storybook/blocks';
|
|
2
|
+
import * as ValidationStories from './DatePickerValidation.stories.ts';
|
|
3
|
+
|
|
4
|
+
<Meta of={ValidationStories}/>
|
|
5
|
+
|
|
6
|
+
# Documentations des règles de validation du DatePicker
|
|
7
|
+
|
|
8
|
+
Le composant DatePicker prend en charge plusieurs types de règles de validation qui permettent de contrôler les dates saisies par l'utilisateur. Cette documentation décrit toutes les règles disponibles et comment les utiliser.
|
|
9
|
+
|
|
10
|
+
> Pour en savoir plus sur le système global de gestion de validation, consultez la page <a href="/?path=/docs/guide-du-dev-utiliser-le-syst%C3%A8me-de-validation--docs">Utiliser le système de validation</a>.
|
|
11
|
+
|
|
12
|
+
## Exemples de validation
|
|
13
|
+
|
|
14
|
+
## Structure d'une règle de validation
|
|
15
|
+
|
|
16
|
+
Les règles de validation sont définies avec la structure suivante :
|
|
17
|
+
|
|
18
|
+
<Source
|
|
19
|
+
dark code={`
|
|
20
|
+
{
|
|
21
|
+
type: string, // Type de la règle (ex: 'notAfterToday')
|
|
22
|
+
options: {
|
|
23
|
+
message?: string, // Message d'erreur personnalisé
|
|
24
|
+
successMessage?: string, // Message de succès personnalisé
|
|
25
|
+
warningMessage?: string, // Message d'avertissement personnalisé
|
|
26
|
+
fieldIdentifier?: string, // Identifiant du champ pour les messages
|
|
27
|
+
// Autres options spécifiques au type de règle
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`}/>
|
|
31
|
+
|
|
32
|
+
Ces règles peuvent être passées au DatePicker via les props `customRules` (pour les erreurs) ou `customWarningRules` (pour les avertissements).
|
|
33
|
+
|
|
34
|
+
## Types de règles disponibles
|
|
35
|
+
|
|
36
|
+
### 1. `required`
|
|
37
|
+
|
|
38
|
+
Vérifie que la date est renseignée.
|
|
39
|
+
|
|
40
|
+
<Source
|
|
41
|
+
dark code={`
|
|
42
|
+
<DatePicker
|
|
43
|
+
v-model="date"
|
|
44
|
+
:custom-rules="[{
|
|
45
|
+
type: 'required',
|
|
46
|
+
options: {
|
|
47
|
+
message: 'Vous devez sélectionner une date'
|
|
48
|
+
}
|
|
49
|
+
}]"
|
|
50
|
+
/>
|
|
51
|
+
`}/>
|
|
52
|
+
|
|
53
|
+
### 2. `notWeekend`
|
|
54
|
+
|
|
55
|
+
Vérifie que la date sélectionnée n'est pas un jour de weekend (samedi ou dimanche).
|
|
56
|
+
|
|
57
|
+
<Source
|
|
58
|
+
dark code={`
|
|
59
|
+
<DatePicker
|
|
60
|
+
v-model="date"
|
|
61
|
+
:custom-rules="[{
|
|
62
|
+
type: 'notWeekend',
|
|
63
|
+
options: {
|
|
64
|
+
message: 'La date ne peut pas être un weekend'
|
|
65
|
+
}
|
|
66
|
+
}]"
|
|
67
|
+
/>
|
|
68
|
+
`}/>
|
|
69
|
+
|
|
70
|
+
### 3. `notBeforeToday`
|
|
71
|
+
|
|
72
|
+
Vérifie que la date sélectionnée n'est pas antérieure à la date du jour.
|
|
73
|
+
|
|
74
|
+
<Source
|
|
75
|
+
dark code={`
|
|
76
|
+
<DatePicker
|
|
77
|
+
v-model="date"
|
|
78
|
+
:custom-rules="[{
|
|
79
|
+
type: 'notBeforeToday',
|
|
80
|
+
options: {
|
|
81
|
+
message: 'La date ne peut pas être antérieure à aujourd\'hui'
|
|
82
|
+
}
|
|
83
|
+
}]"
|
|
84
|
+
/>
|
|
85
|
+
`}/>
|
|
86
|
+
|
|
87
|
+
### 4. `notAfterToday`
|
|
88
|
+
|
|
89
|
+
Vérifie que la date sélectionnée n'est pas postérieure à la date du jour.
|
|
90
|
+
|
|
91
|
+
<Source
|
|
92
|
+
dark code={`
|
|
93
|
+
<DatePicker
|
|
94
|
+
v-model="date"
|
|
95
|
+
:custom-rules="[{
|
|
96
|
+
type: 'notAfterToday',
|
|
97
|
+
options: {
|
|
98
|
+
message: 'La date ne peut pas être postérieure à aujourd\'hui'
|
|
99
|
+
}
|
|
100
|
+
}]"
|
|
101
|
+
/>
|
|
102
|
+
`}/>
|
|
103
|
+
|
|
104
|
+
### 5. `notBeforeDate`
|
|
105
|
+
|
|
106
|
+
Vérifie que la date sélectionnée n'est pas antérieure à une date de référence.
|
|
107
|
+
|
|
108
|
+
<Source
|
|
109
|
+
dark code={`
|
|
110
|
+
<DatePicker
|
|
111
|
+
v-model="date"
|
|
112
|
+
:custom-rules="[{
|
|
113
|
+
type: 'notBeforeDate',
|
|
114
|
+
options: {
|
|
115
|
+
message: 'La date ne peut pas être antérieure au 01/01/2023',
|
|
116
|
+
date: '01/01/2023' // Date de référence au format DD/MM/YYYY
|
|
117
|
+
}
|
|
118
|
+
}]"
|
|
119
|
+
/>
|
|
120
|
+
`}/>
|
|
121
|
+
|
|
122
|
+
### 6. `notAfterDate`
|
|
123
|
+
|
|
124
|
+
Vérifie que la date sélectionnée n'est pas postérieure à une date de référence.
|
|
125
|
+
|
|
126
|
+
<Source
|
|
127
|
+
dark code={`
|
|
128
|
+
<DatePicker
|
|
129
|
+
v-model="date"
|
|
130
|
+
:custom-rules="[{
|
|
131
|
+
type: 'notAfterDate',
|
|
132
|
+
options: {
|
|
133
|
+
message: 'La date ne peut pas être postérieure au 31/12/2023',
|
|
134
|
+
date: '31/12/2023' // Date de référence au format DD/MM/YYYY
|
|
135
|
+
}
|
|
136
|
+
}]"
|
|
137
|
+
/>
|
|
138
|
+
`}/>
|
|
139
|
+
|
|
140
|
+
### 7. `dateExact`
|
|
141
|
+
|
|
142
|
+
Vérifie que la date sélectionnée est exactement égale à une date de référence.
|
|
143
|
+
|
|
144
|
+
<Source
|
|
145
|
+
dark code={`
|
|
146
|
+
<DatePicker
|
|
147
|
+
v-model="date"
|
|
148
|
+
:custom-rules="[{
|
|
149
|
+
type: 'dateExact',
|
|
150
|
+
options: {
|
|
151
|
+
message: 'La date doit être le 25/12/2023',
|
|
152
|
+
date: '25/12/2023' // Date de référence au format DD/MM/YYYY
|
|
153
|
+
}
|
|
154
|
+
}]"
|
|
155
|
+
/>
|
|
156
|
+
`}/>
|
|
157
|
+
|
|
158
|
+
### 8. `custom`
|
|
159
|
+
|
|
160
|
+
Permet de créer une règle de validation personnalisée avec une fonction de validation.
|
|
161
|
+
|
|
162
|
+
<Source
|
|
163
|
+
dark code={`
|
|
164
|
+
<DatePicker
|
|
165
|
+
v-model="date"
|
|
166
|
+
:custom-rules="[{
|
|
167
|
+
type: 'custom',
|
|
168
|
+
options: {
|
|
169
|
+
validate: (value) => {
|
|
170
|
+
// Si pas de valeur, c'est valide
|
|
171
|
+
if (!value) return true
|
|
172
|
+
// Convertir en chaîne si ce n'est pas déjà le cas
|
|
173
|
+
const dateStr = value.toString()
|
|
174
|
+
// Vérifier si c'est une Date et extraire l'année
|
|
175
|
+
if (value instanceof Date) {
|
|
176
|
+
return value.getFullYear() !== 2024
|
|
177
|
+
}
|
|
178
|
+
// Fallback sur la vérification de chaîne
|
|
179
|
+
return !dateStr.includes('2024')
|
|
180
|
+
},
|
|
181
|
+
message: 'Les dates en 2024 ne sont pas autorisées',
|
|
182
|
+
successMessage: 'Date valide (hors 2024)',
|
|
183
|
+
fieldIdentifier: 'date'
|
|
184
|
+
}
|
|
185
|
+
}]"
|
|
186
|
+
/>
|
|
187
|
+
`}/>
|
|
188
|
+
|
|
189
|
+
La fonction `validate` reçoit la valeur de la date (au format spécifié par la prop `format`) et doit retourner :
|
|
190
|
+
- `true` si la validation réussit
|
|
191
|
+
- `false` ou une chaîne (message d'erreur personnalisé) si la validation échoue
|
|
192
|
+
|
|
193
|
+
## Utilisation des règles d'avertissement
|
|
194
|
+
|
|
195
|
+
Toutes les règles ci-dessus peuvent également être utilisées comme règles d'avertissement avec la prop `customWarningRules`. Les avertissements n'empêchent pas la soumission du formulaire mais affichent un message en orange.
|
|
196
|
+
|
|
197
|
+
<Source
|
|
198
|
+
dark code={`
|
|
199
|
+
<DatePicker
|
|
200
|
+
v-model="date"
|
|
201
|
+
:custom-warning-rules="[{
|
|
202
|
+
type: 'notBeforeDate',
|
|
203
|
+
options: {
|
|
204
|
+
warningMessage: 'Attention : la date est antérieure à la date de référence',
|
|
205
|
+
date: '01/01/2024',
|
|
206
|
+
isWarning: true
|
|
207
|
+
}
|
|
208
|
+
}]"
|
|
209
|
+
/>
|
|
210
|
+
`}/>
|
|
211
|
+
|
|
212
|
+
## Combinaison de plusieurs règles
|
|
213
|
+
|
|
214
|
+
Vous pouvez combiner plusieurs règles de validation :
|
|
215
|
+
|
|
216
|
+
<Source
|
|
217
|
+
dark code={`
|
|
218
|
+
<DatePicker
|
|
219
|
+
v-model="date"
|
|
220
|
+
:custom-rules="[
|
|
221
|
+
{
|
|
222
|
+
type: 'required',
|
|
223
|
+
options: { message: 'La date est requise' }
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
type: 'notWeekend',
|
|
227
|
+
options: { message: 'La date ne peut pas être un weekend' }
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
type: 'notAfterToday',
|
|
231
|
+
options: { message: 'La date ne peut pas être dans le futur' }
|
|
232
|
+
}
|
|
233
|
+
]"
|
|
234
|
+
/>
|
|
235
|
+
`}/>
|
|
236
|
+
|
|
237
|
+
## Messages de succès
|
|
238
|
+
|
|
239
|
+
Vous pouvez personnaliser les messages de succès qui s'affichent lorsque la validation réussit :
|
|
240
|
+
|
|
241
|
+
<Source
|
|
242
|
+
dark code={`
|
|
243
|
+
<DatePicker
|
|
244
|
+
v-model="date"
|
|
245
|
+
:custom-rules="[{
|
|
246
|
+
type: 'notWeekend',
|
|
247
|
+
options: {
|
|
248
|
+
message: 'La date ne peut pas être un weekend',
|
|
249
|
+
successMessage: 'La date sélectionnée est valide (jour de semaine)'
|
|
250
|
+
}
|
|
251
|
+
}]"
|
|
252
|
+
:show-success-messages="true"
|
|
253
|
+
/>
|
|
254
|
+
`}/>
|
|
255
|
+
|
|
256
|
+
Pour afficher les messages de succès, la prop `showSuccessMessages` doit être définie à `true`.
|
|
257
|
+
|
|
258
|
+
## Désactivation de la gestion des erreurs
|
|
259
|
+
|
|
260
|
+
Si vous souhaitez effectuer la validation sans afficher les messages d'erreur, vous pouvez utiliser la prop `disableErrorHandling` :
|
|
261
|
+
|
|
262
|
+
<Source
|
|
263
|
+
dark code={`
|
|
264
|
+
<DatePicker
|
|
265
|
+
v-model="date"
|
|
266
|
+
:custom-rules="[{ type: 'required' }]"
|
|
267
|
+
:disable-error-handling="true"
|
|
268
|
+
/>
|
|
269
|
+
`}/>
|
|
270
|
+
|
|
271
|
+
Cette option est utile lorsque vous gérez la validation à un niveau supérieur, par exemple dans un formulaire parent.
|
|
272
|
+
|
|
273
|
+
## Règles présentes par défaut
|
|
274
|
+
|
|
275
|
+
Le composant DatePicker intègre certaines règles de validation par défaut, sans que vous ayez besoin de les spécifier via `customRules` :
|
|
276
|
+
|
|
277
|
+
### Validation du champ requis
|
|
278
|
+
|
|
279
|
+
Lorsque la prop `required` est définie à `true`, le DatePicker effectue automatiquement une validation pour s'assurer qu'une date est sélectionnée. Si aucune date n'est sélectionnée, le message d'erreur "La date est requise." est affiché.
|
|
280
|
+
|
|
281
|
+
<Source
|
|
282
|
+
dark code={`
|
|
283
|
+
<DatePicker
|
|
284
|
+
v-model="date"
|
|
285
|
+
required
|
|
286
|
+
/>
|
|
287
|
+
`}/>
|
|
288
|
+
|
|
289
|
+
### Validation du format de date
|
|
290
|
+
|
|
291
|
+
Le DatePicker vérifie automatiquement que la date saisie respecte le format spécifié par la prop `format` (par défaut `DD/MM/YYYY`). Cette validation est effectuée lorsque l'utilisateur saisit manuellement une date dans le champ de texte.
|
|
292
|
+
|
|
293
|
+
<Source
|
|
294
|
+
dark code={`
|
|
295
|
+
<DatePicker
|
|
296
|
+
v-model="date"
|
|
297
|
+
format="MM/DD/YYYY" <!-- Format personnalisé -->
|
|
298
|
+
/>
|
|
299
|
+
`}/>
|
|
300
|
+
|
|
301
|
+
### Validation de la plage de dates
|
|
302
|
+
|
|
303
|
+
Lorsque `displayRange` est à `true`, le DatePicker valide automatiquement que la plage de dates est cohérente (date de début antérieure à date de fin) lorsque deux dates sont sélectionnées.
|
|
304
|
+
|
|
305
|
+
<Source
|
|
306
|
+
dark code={`<DatePicker
|
|
307
|
+
v-model="dateRange"
|
|
308
|
+
display-range
|
|
309
|
+
/>
|
|
310
|
+
`}/>
|
|
311
|
+
|
|
312
|
+
## Interaction entre règles personnalisées et validations par défaut
|
|
313
|
+
|
|
314
|
+
Lorsque vous utilisez des règles personnalisées via `customRules` en combinaison avec des validations par défaut (comme `required`), il est important de comprendre comment ces règles interagissent :
|
|
315
|
+
|
|
316
|
+
### Ordre de priorité des validations
|
|
317
|
+
|
|
318
|
+
1. Les validations par défaut (comme `required`) sont exécutées en premier.
|
|
319
|
+
2. Si les validations par défaut réussissent, les règles personnalisées sont ensuite appliquées.
|
|
320
|
+
3. Les règles d'avertissement (`customWarningRules`) ne sont exécutées que si aucune erreur n'est détectée dans les étapes précédentes.
|
|
321
|
+
|
|
322
|
+
### Exemple d'interaction
|
|
323
|
+
|
|
324
|
+
<Source
|
|
325
|
+
dark code={`<DatePicker
|
|
326
|
+
v-model="date"
|
|
327
|
+
required
|
|
328
|
+
:custom-rules="[{
|
|
329
|
+
type: 'notAfterToday',
|
|
330
|
+
options: { message: 'La date ne peut pas être après aujourd\'hui' }
|
|
331
|
+
}]"
|
|
332
|
+
/>
|
|
333
|
+
`}/>
|
|
334
|
+
|
|
335
|
+
Dans cet exemple :
|
|
336
|
+
- Si aucune date n'est sélectionnée, la validation `required` échoue et le message "La date est requise." s'affiche.
|
|
337
|
+
- Si une date est sélectionnée mais qu'elle est postérieure à aujourd'hui, la règle personnalisée `notAfterToday` échoue et son message d'erreur s'affiche.
|
|
338
|
+
- Si une date est sélectionnée et qu'elle est antérieure ou égale à aujourd'hui, toutes les validations réussissent.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Meta, type StoryFn } from '@storybook/vue3'
|
|
2
|
+
import DatePickerValidationExamples from './DatePickerValidationExamples.vue'
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Composants/Formulaires/DatePicker/Validation',
|
|
6
|
+
component: DatePickerValidationExamples,
|
|
7
|
+
argTypes: {},
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: 'Exemples de validation pour le composant DatePicker.',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
} as Meta
|
|
16
|
+
|
|
17
|
+
export const ValidationExamples: StoryFn = () => ({
|
|
18
|
+
components: {
|
|
19
|
+
DatePickerValidationExamples,
|
|
20
|
+
},
|
|
21
|
+
template: '<DatePickerValidationExamples />',
|
|
22
|
+
})
|