@cnamts/synapse 0.0.15-alpha → 0.0.16-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.
Files changed (41) hide show
  1. package/dist/components/CookiesSelection/CookiesSelection.d.ts +26 -26
  2. package/dist/components/Customs/SyTextField/SyTextField.d.ts +1391 -1
  3. package/dist/components/DatePicker/DatePicker.d.ts +2810 -16
  4. package/dist/components/DatePicker/DateTextInput.d.ts +1401 -4
  5. package/dist/components/LangBtn/LangBtn.d.ts +4 -4
  6. package/dist/components/NirField/NirField.d.ts +2794 -4
  7. package/dist/components/PeriodField/PeriodField.d.ts +5636 -48
  8. package/dist/components/SyAlert/SyAlert.d.ts +72 -1
  9. package/dist/components/UploadWorkflow/UploadWorkflow.d.ts +26 -26
  10. package/dist/components/index.d.ts +1 -0
  11. package/dist/composables/date/useDateFormat.d.ts +2 -2
  12. package/dist/composables/date/useDateFormatDayjs.d.ts +23 -0
  13. package/dist/composables/date/useDateInitializationDayjs.d.ts +18 -0
  14. package/dist/design-system-v3.js +3953 -3728
  15. package/dist/design-system-v3.umd.cjs +1 -1
  16. package/dist/style.css +1 -1
  17. package/package.json +1 -1
  18. package/src/components/Customs/SyTextField/Accessibilite.stories.ts +7 -0
  19. package/src/components/Customs/SyTextField/SyTextField.stories.ts +13 -0
  20. package/src/components/Customs/SyTextField/SyTextField.vue +82 -17
  21. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +795 -0
  22. package/src/components/DatePicker/DatePicker.stories.ts +432 -1
  23. package/src/components/DatePicker/DatePicker.vue +66 -24
  24. package/src/components/DatePicker/DatePickerValidation.stories.ts +9 -1
  25. package/src/components/DatePicker/DateTextInput.vue +85 -133
  26. package/src/components/DatePicker/docExamples/DatePickerBidirectionalValidation.vue +282 -0
  27. package/src/components/DatePicker/tests/DatePicker.spec.ts +33 -32
  28. package/src/components/DatePicker/tests/DateTextInput.spec.ts +81 -33
  29. package/src/components/SyAlert/Accessibilite.stories.ts +4 -0
  30. package/src/components/SyAlert/SyAlert.mdx +3 -7
  31. package/src/components/SyAlert/SyAlert.stories.ts +19 -12
  32. package/src/components/SyAlert/SyAlert.vue +88 -51
  33. package/src/components/SyAlert/tests/SyAlert.spec.ts +20 -2
  34. package/src/components/SyAlert/tests/__snapshots__/SyAlert.spec.ts.snap +83 -75
  35. package/src/components/index.ts +1 -0
  36. package/src/composables/date/useDateFormat.ts +17 -1
  37. package/src/composables/date/useDateFormatDayjs.ts +84 -0
  38. package/src/composables/date/useDateInitializationDayjs.ts +133 -0
  39. package/src/stories/Accessibilite/Avancement/Avancement.mdx +12 -0
  40. package/src/stories/Accessibilite/Avancement/Avancement.stories.ts +134 -0
  41. /package/src/components/DatePicker/{DatePickerValidationExamples.vue → docExamples/DatePickerValidationExamples.vue} +0 -0
@@ -1,6 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
2
  import DatePicker from './DatePicker.vue'
3
- import { ref } from 'vue'
3
+ import { ref, watch, computed } from 'vue'
4
+ import { useDateFormat } from '@/composables/date/useDateFormatDayjs'
4
5
 
5
6
  const meta = {
6
7
  title: 'Composants/Formulaires/DatePicker',
@@ -1199,6 +1200,436 @@ export const NoCalendarWithErrorDisabled: Story = {
1199
1200
  },
1200
1201
  }
1201
1202
 
1203
+ export const WithDayjsFormat: Story = {
1204
+ parameters: {
1205
+ sourceCode: [
1206
+ {
1207
+ name: 'Template',
1208
+ code: `
1209
+ <template>
1210
+ <div>
1211
+ <DatePicker
1212
+ v-model="date"
1213
+ placeholder="Sélectionner une date"
1214
+ format="DD/MM/YYYY"
1215
+ />
1216
+ <p class="mt-4">Date formatée avec dayjs: {{ formattedDate }}</p>
1217
+ <p>Date parsée avec dayjs: {{ parsedDate ? parsedDate.toLocaleDateString() : 'Aucune date' }}</p>
1218
+ </div>
1219
+ </template>
1220
+ `,
1221
+ },
1222
+ {
1223
+ name: 'Script',
1224
+ code: `
1225
+ <script setup lang="ts">
1226
+ import { ref, watch } from 'vue'
1227
+ import { DatePicker } from '@cnamts/synapse'
1228
+ import { useDateFormat } from '@cnamts/synapse'
1229
+
1230
+ const { parseDate, formatDate } = useDateFormat()
1231
+
1232
+ const date = ref('')
1233
+ const formattedDate = ref('')
1234
+ const parsedDate = ref<Date | null>(null)
1235
+
1236
+ watch(date, (newDate) => {
1237
+ if (newDate) {
1238
+ parsedDate.value = parseDate(newDate, 'DD/MM/YYYY')
1239
+ if (parsedDate.value) {
1240
+ formattedDate.value = formatDate(parsedDate.value, 'YYYY-MM-DD')
1241
+ }
1242
+ } else {
1243
+ formattedDate.value = ''
1244
+ parsedDate.value = null
1245
+ }
1246
+ })
1247
+ </script>
1248
+ `,
1249
+ },
1250
+ ],
1251
+ },
1252
+ args: {
1253
+ placeholder: 'Sélectionner une date',
1254
+ format: 'DD/MM/YYYY',
1255
+ isBirthDate: false,
1256
+ showWeekNumber: false,
1257
+ required: false,
1258
+ displayRange: false,
1259
+ displayIcon: true,
1260
+ displayAppendIcon: false,
1261
+ disabled: false,
1262
+ noIcon: false,
1263
+ noCalendar: false,
1264
+ modelValue: '',
1265
+ },
1266
+ render: () => {
1267
+ return {
1268
+ components: { DatePicker },
1269
+ setup() {
1270
+ // Importer le composable useDateFormat depuis useDateFormatDayjs
1271
+ const { parseDate, formatDate } = useDateFormat()
1272
+
1273
+ const date = ref('')
1274
+ const formattedDate = ref('')
1275
+ const parsedDate = ref<Date | null>(null)
1276
+
1277
+ watch(date, (newDate) => {
1278
+ if (newDate) {
1279
+ parsedDate.value = parseDate(newDate, 'DD/MM/YYYY')
1280
+ if (parsedDate.value) {
1281
+ formattedDate.value = formatDate(parsedDate.value, 'YYYY-MM-DD')
1282
+ }
1283
+ }
1284
+ else {
1285
+ formattedDate.value = ''
1286
+ parsedDate.value = null
1287
+ }
1288
+ })
1289
+
1290
+ return { date, formattedDate, parsedDate }
1291
+ },
1292
+
1293
+ template: `
1294
+ <div class="pa-4">
1295
+ <DatePicker
1296
+ v-model="date"
1297
+ placeholder="Sélectionner une date"
1298
+ format="DD/MM/YYYY"
1299
+ />
1300
+ <p class="mt-4">Date formatée avec dayjs: {{ formattedDate }}</p>
1301
+ <p>Date parsée avec dayjs: {{ parsedDate ? parsedDate.toLocaleDateString() : 'Aucune date' }}</p>
1302
+ </div>
1303
+ `,
1304
+ }
1305
+ },
1306
+ }
1307
+
1308
+ export const BidirectionalValidation: Story = {
1309
+ parameters: {
1310
+ sourceCode: [
1311
+ {
1312
+ name: 'Template',
1313
+ code: `
1314
+ <template>
1315
+ <div class="date-validation-playground">
1316
+ <h1>Validation bidirectionnelle des dates</h1>
1317
+ <p class="description">
1318
+ Démonstration de la validation bidirectionnelle entre les DatePickers.
1319
+ Les messages d'erreur apparaissent directement dans les composants.
1320
+ </p>
1321
+ <div class="date-range-container">
1322
+ <div class="date-picker-wrapper">
1323
+ <h3>Date de début</h3>
1324
+ <DatePicker
1325
+ ref="startDatePickerRef"
1326
+ v-model="startDate"
1327
+ placeholder="Date de début"
1328
+ :custom-rules="startDateRules"
1329
+ required
1330
+ @update:model-value="validateEndDate"
1331
+ />
1332
+ </div>
1333
+ <div class="date-picker-wrapper">
1334
+ <h3>Date de fin</h3>
1335
+ <DatePicker
1336
+ ref="endDatePickerRef"
1337
+ v-model="endDate"
1338
+ placeholder="Date de fin"
1339
+ :custom-rules="endDateRules"
1340
+ required
1341
+ @update:model-value="validateStartDate"
1342
+ />
1343
+ </div>
1344
+ </div>
1345
+ <div class="current-values">
1346
+ <p><strong>Date de début:</strong> {{ startDate || 'Non sélectionnée' }}</p>
1347
+ <p><strong>Date de fin:</strong> {{ endDate || 'Non sélectionnée' }}</p>
1348
+ </div>
1349
+ </div>
1350
+ </template>
1351
+ `,
1352
+ },
1353
+ {
1354
+ name: 'Script',
1355
+ code: `
1356
+ <script lang="ts" setup>
1357
+ import { ref, watch, computed } from 'vue'
1358
+ import DatePicker from '@cnamts/synapse'
1359
+ import { useDateFormat } from '@cnamts/synapse'
1360
+
1361
+ const { parseDate } = useDateFormat()
1362
+
1363
+ // État des dates
1364
+ const startDate = ref<string | null>(null)
1365
+ const endDate = ref<string | null>(null)
1366
+
1367
+ // Références aux composants DatePicker pour accéder à leurs méthodes
1368
+ const startDatePickerRef = ref<InstanceType<typeof DatePicker> | null>(null)
1369
+ const endDatePickerRef = ref<InstanceType<typeof DatePicker> | null>(null)
1370
+
1371
+ // Règle de validation pour vérifier que la date de fin n'est pas avant la date de début
1372
+ const createEndDateValidationRule = () => ({
1373
+ type: 'custom',
1374
+ options: {
1375
+ validate: (value: string) => {
1376
+ // Si pas de valeur pour la date de fin, pas besoin de validation
1377
+ if (!value) return true
1378
+
1379
+ // Si pas de date de début mais une date de fin, afficher l'erreur
1380
+ if (!startDate.value) return 'Veuillez d'abord sélectionner une date de début'
1381
+
1382
+ const start = parseDate(startDate.value, 'DD/MM/YYYY')
1383
+ const end = parseDate(value, 'DD/MM/YYYY')
1384
+
1385
+ if (!start || !end) return true
1386
+
1387
+ return end >= start || 'La date de fin ne peut pas être antérieure à la date de début'
1388
+ },
1389
+ message: 'La date de fin ne peut pas être antérieure à la date de début',
1390
+ },
1391
+ })
1392
+
1393
+ // Règle de validation pour vérifier que la date de début n'est pas après la date de fin
1394
+ const createStartDateValidationRule = () => ({
1395
+ type: 'custom',
1396
+ options: {
1397
+ validate: (value: string) => {
1398
+ // Si pas de valeur pour la date de début ou pas de date de fin, pas besoin de validation
1399
+ if (!value || !endDate.value) return true
1400
+
1401
+ const start = parseDate(value, 'DD/MM/YYYY')
1402
+ const end = parseDate(endDate.value, 'DD/MM/YYYY')
1403
+
1404
+ if (!start || !end) return true
1405
+
1406
+ return start <= end || 'La date de début ne peut pas être postérieure à la date de fin'
1407
+ },
1408
+ message: 'La date de début ne peut pas être postérieure à la date de fin',
1409
+ },
1410
+ })
1411
+
1412
+ // Règles de validation pour la date de début
1413
+ const startDateRules = computed(() => [
1414
+ {
1415
+ type: 'required',
1416
+ options: {
1417
+ message: 'La date de début est requise.',
1418
+ },
1419
+ },
1420
+ createStartDateValidationRule(),
1421
+ ])
1422
+
1423
+ // Règles de validation pour la date de fin
1424
+ const endDateRules = computed(() => [
1425
+ {
1426
+ type: 'required',
1427
+ options: {
1428
+ message: 'La date de fin est requise.',
1429
+ },
1430
+ },
1431
+ createEndDateValidationRule(),
1432
+ ])
1433
+
1434
+ // Fonction pour forcer la validation de la date de fin quand la date de début change
1435
+ const validateEndDate = () => {
1436
+ if (endDatePickerRef.value && endDate.value) {
1437
+ // On utilise validateOnSubmit pour forcer la validation complète
1438
+ endDatePickerRef.value.validateOnSubmit()
1439
+ }
1440
+ }
1441
+
1442
+ // Fonction pour forcer la validation de la date de début quand la date de fin change
1443
+ const validateStartDate = () => {
1444
+ if (startDatePickerRef.value && startDate.value) {
1445
+ // On utilise validateOnSubmit pour forcer la validation complète
1446
+ startDatePickerRef.value.validateOnSubmit()
1447
+ }
1448
+ }
1449
+
1450
+ // Watcher pour la date de début qui force la revalidation de la date de fin
1451
+ watch(startDate, () => {
1452
+ // Laisser le temps au système de mettre à jour les valeurs
1453
+ setTimeout(() => {
1454
+ validateEndDate()
1455
+ }, 0)
1456
+ })
1457
+
1458
+ // Watcher pour la date de fin qui force la revalidation de la date de début
1459
+ watch(endDate, () => {
1460
+ // Laisser le temps au système de mettre à jour les valeurs
1461
+ setTimeout(() => {
1462
+ validateStartDate()
1463
+ }, 0)
1464
+ })
1465
+ </script>
1466
+ `,
1467
+ },
1468
+ ],
1469
+ },
1470
+ render: () => {
1471
+ return {
1472
+ components: { DatePicker },
1473
+ setup() {
1474
+ // Importer le composable useDateFormat depuis useDateFormatDayjs
1475
+ const { parseDate } = useDateFormat()
1476
+
1477
+ // État des dates
1478
+ const startDate = ref<string | null>(null)
1479
+ const endDate = ref<string | null>(null)
1480
+
1481
+ // Références aux composants DatePicker pour accéder à leurs méthodes
1482
+ const startDatePickerRef = ref<InstanceType<typeof DatePicker> | null>(null)
1483
+ const endDatePickerRef = ref<InstanceType<typeof DatePicker> | null>(null)
1484
+
1485
+ // Règle de validation pour vérifier que la date de fin n'est pas avant la date de début
1486
+ const createEndDateValidationRule = () => ({
1487
+ type: 'custom',
1488
+ options: {
1489
+ validate: (value: string) => {
1490
+ // Si pas de valeur pour la date de fin, pas besoin de validation
1491
+ if (!value) return true
1492
+
1493
+ // Si pas de date de début mais une date de fin, afficher l'erreur
1494
+ if (!startDate.value) return 'Veuillez d\'abord sélectionner une date de début'
1495
+
1496
+ const start = parseDate(startDate.value, 'DD/MM/YYYY')
1497
+ const end = parseDate(value, 'DD/MM/YYYY')
1498
+
1499
+ if (!start || !end) return true
1500
+
1501
+ return end >= start || 'La date de fin ne peut pas être antérieure à la date de début'
1502
+ },
1503
+ message: 'La date de fin ne peut pas être antérieure à la date de début',
1504
+ },
1505
+ })
1506
+
1507
+ // Règle de validation pour vérifier que la date de début n'est pas après la date de fin
1508
+ const createStartDateValidationRule = () => ({
1509
+ type: 'custom',
1510
+ options: {
1511
+ validate: (value: string) => {
1512
+ // Si pas de valeur pour la date de début ou pas de date de fin, pas besoin de validation
1513
+ if (!value || !endDate.value) return true
1514
+
1515
+ const start = parseDate(value, 'DD/MM/YYYY')
1516
+ const end = parseDate(endDate.value, 'DD/MM/YYYY')
1517
+
1518
+ if (!start || !end) return true
1519
+
1520
+ return start <= end || 'La date de début ne peut pas être postérieure à la date de fin'
1521
+ },
1522
+ message: 'La date de début ne peut pas être postérieure à la date de fin',
1523
+ },
1524
+ })
1525
+
1526
+ // Règles de validation pour la date de début
1527
+ const startDateRules = computed(() => [
1528
+ {
1529
+ type: 'required',
1530
+ options: {
1531
+ message: 'La date de début est requise.',
1532
+ },
1533
+ },
1534
+ createStartDateValidationRule(),
1535
+ ])
1536
+
1537
+ // Règles de validation pour la date de fin
1538
+ const endDateRules = computed(() => [
1539
+ {
1540
+ type: 'required',
1541
+ options: {
1542
+ message: 'La date de fin est requise.',
1543
+ },
1544
+ },
1545
+ createEndDateValidationRule(),
1546
+ ])
1547
+
1548
+ // Fonction pour forcer la validation de la date de fin quand la date de début change
1549
+ const validateEndDate = () => {
1550
+ if (endDatePickerRef.value && endDate.value) {
1551
+ // On utilise validateOnSubmit pour forcer la validation complète
1552
+ endDatePickerRef.value.validateOnSubmit()
1553
+ }
1554
+ }
1555
+
1556
+ // Fonction pour forcer la validation de la date de début quand la date de fin change
1557
+ const validateStartDate = () => {
1558
+ if (startDatePickerRef.value && startDate.value) {
1559
+ // On utilise validateOnSubmit pour forcer la validation complète
1560
+ startDatePickerRef.value.validateOnSubmit()
1561
+ }
1562
+ }
1563
+
1564
+ // Watcher pour la date de début qui force la revalidation de la date de fin
1565
+ watch(startDate, () => {
1566
+ // Laisser le temps au système de mettre à jour les valeurs
1567
+ setTimeout(() => {
1568
+ validateEndDate()
1569
+ }, 0)
1570
+ })
1571
+
1572
+ // Watcher pour la date de fin qui force la revalidation de la date de début
1573
+ watch(endDate, () => {
1574
+ // Laisser le temps au système de mettre à jour les valeurs
1575
+ setTimeout(() => {
1576
+ validateStartDate()
1577
+ }, 0)
1578
+ })
1579
+
1580
+ return {
1581
+ startDate,
1582
+ endDate,
1583
+ startDatePickerRef,
1584
+ endDatePickerRef,
1585
+ startDateRules,
1586
+ endDateRules,
1587
+ validateEndDate,
1588
+ validateStartDate,
1589
+ }
1590
+ },
1591
+
1592
+ template: `
1593
+ <div class="date-validation-playground">
1594
+ <h1>Validation bidirectionnelle des dates</h1>
1595
+ <p class="description">
1596
+ Démonstration de la validation bidirectionnelle entre les DatePickers.
1597
+ Les messages d'erreur apparaissent directement dans les composants.
1598
+ </p>
1599
+ <div class="date-range-container">
1600
+ <div class="date-picker-wrapper">
1601
+ <h3>Date de début</h3>
1602
+ <DatePicker
1603
+ ref="startDatePickerRef"
1604
+ v-model="startDate"
1605
+ placeholder="Date de début"
1606
+ :custom-rules="startDateRules"
1607
+ required
1608
+ @update:model-value="validateEndDate"
1609
+ />
1610
+ </div>
1611
+ <div class="date-picker-wrapper">
1612
+ <h3>Date de fin</h3>
1613
+ <DatePicker
1614
+ ref="endDatePickerRef"
1615
+ v-model="endDate"
1616
+ placeholder="Date de fin"
1617
+ :custom-rules="endDateRules"
1618
+ required
1619
+ @update:model-value="validateStartDate"
1620
+ />
1621
+ </div>
1622
+ </div>
1623
+ <div class="current-values">
1624
+ <p><strong>Date de début:</strong> {{ startDate || 'Non sélectionnée' }}</p>
1625
+ <p><strong>Date de fin:</strong> {{ endDate || 'Non sélectionnée' }}</p>
1626
+ </div>
1627
+ </div>
1628
+ `,
1629
+ }
1630
+ },
1631
+ }
1632
+
1202
1633
  export const WithFormSubmission: Story = {
1203
1634
  parameters: {
1204
1635
  sourceCode: [
@@ -4,9 +4,14 @@
4
4
  import DateTextInput from './DateTextInput.vue'
5
5
  import { VDatePicker } from 'vuetify/components'
6
6
  import { useValidation } from '@/composables/validation/useValidation'
7
- import { useDateFormat } from '@/composables/date/useDateFormat'
8
- import { useDateInitialization, type DateValue, type DateInput } from '@/composables/date/useDateInitialization'
7
+ import { useDateFormat } from '@/composables/date/useDateFormatDayjs'
8
+ import { useDateInitialization, type DateValue, type DateInput } from '@/composables/date/useDateInitializationDayjs'
9
9
  import { useDatePickerAccessibility } from '@/composables/date/useDatePickerAccessibility'
10
+ import dayjs from 'dayjs'
11
+ import customParseFormat from 'dayjs/plugin/customParseFormat'
12
+
13
+ // Initialiser les plugins dayjs
14
+ dayjs.extend(customParseFormat)
10
15
 
11
16
  const { parseDate, formatDate } = useDateFormat()
12
17
  const { initializeSelectedDates } = useDateInitialization()
@@ -93,7 +98,7 @@
93
98
  // Variable pour éviter les mises à jour récursives
94
99
  const isUpdatingFromInternal = ref(false)
95
100
 
96
- // Déclaration de la fonction validateDates avant son utilisation
101
+ // Fonction pour valider les dates
97
102
  const validateDates = (forceValidation = false) => {
98
103
  if (props.noCalendar) {
99
104
  // En mode no-calendar, on délègue la validation au DateTextInput
@@ -320,6 +325,13 @@
320
325
  }
321
326
  })
322
327
 
328
+ // Fonction pour mettre à jour displayFormattedDate quand le VDatePicker change
329
+ const updateDisplayFormattedDate = () => {
330
+ if (displayFormattedDateComputed.value) {
331
+ displayFormattedDate.value = displayFormattedDateComputed.value
332
+ }
333
+ }
334
+
323
335
  const updateSelectedDates = (input: DateValue) => {
324
336
  if (Array.isArray(input)) {
325
337
  const dates = input
@@ -354,11 +366,7 @@
354
366
  }
355
367
 
356
368
  const todayInString = computed(() => {
357
- return (new Date().toLocaleDateString('fr-FR', {
358
- weekday: 'long',
359
- month: 'long',
360
- day: 'numeric',
361
- })).replace(/\b\w/g, l => l.toUpperCase())
369
+ return dayjs().locale('fr').format('dddd D MMMM').replace(/\b\w/g, l => l.toUpperCase())
362
370
  })
363
371
 
364
372
  onMounted(() => {
@@ -377,7 +385,7 @@
377
385
  document.removeEventListener('click', handleClickOutside)
378
386
  })
379
387
 
380
- const dateTextInputRef = ref<null | ComponentPublicInstance< typeof DateTextInput>>()
388
+ const dateTextInputRef = ref<null | ComponentPublicInstance<typeof DateTextInput>>()
381
389
  const dateCalendarTextInputRef = ref<null | ComponentPublicInstance<typeof SyTextField>>()
382
390
  const datePickerRef = ref<null | ComponentPublicInstance<typeof VDatePicker>>()
383
391
 
@@ -391,19 +399,10 @@
391
399
  return errors.value.length === 0
392
400
  }
393
401
 
394
- const showDatePicker = () => {
395
- if (props.disabled || props.readonly) return
396
-
397
- isDatePickerVisible.value = true
398
-
399
- // Mettre à jour l'accessibilité après l'ouverture du DatePicker
400
- nextTick(() => {
401
- updateAccessibility()
402
- })
403
- }
404
-
405
402
  const openDatePicker = () => {
406
- showDatePicker()
403
+ if (!isDatePickerVisible.value) {
404
+ toggleDatePicker()
405
+ }
407
406
  }
408
407
 
409
408
  type ViewMode = 'month' | 'year' | 'months' | undefined
@@ -411,6 +410,10 @@
411
410
  // Variable pour suivre le mode d'affichage actuel du DatePicker
412
411
  const currentViewMode = ref<ViewMode>(props.isBirthDate ? 'year' : 'month')
413
412
 
413
+ watch(() => props.isBirthDate, (newValue) => {
414
+ currentViewMode.value = newValue ? 'year' : 'month'
415
+ })
416
+
414
417
  // Fonction pour gérer le changement de mode d'affichage
415
418
  const handleViewModeUpdate = (newMode: ViewMode) => {
416
419
  currentViewMode.value = newMode
@@ -432,6 +435,11 @@
432
435
  }
433
436
  }
434
437
 
438
+ const handleInputBlur = () => {
439
+ emit('blur')
440
+ validateDates(true)
441
+ }
442
+
435
443
  watch(isDatePickerVisible, async (isVisible) => {
436
444
  if (!isVisible && props.isBirthDate) {
437
445
  // Réinitialiser le mode d'affichage au type birthdate
@@ -526,6 +534,36 @@
526
534
  }
527
535
  }, { immediate: true })
528
536
 
537
+ const toggleDatePicker = () => {
538
+ if (props.disabled || props.readonly) return
539
+
540
+ isDatePickerVisible.value = !isDatePickerVisible.value
541
+
542
+ if (isDatePickerVisible.value) {
543
+ // Mettre à jour l'accessibilité après l'ouverture du DatePicker
544
+ nextTick(() => {
545
+ updateAccessibility()
546
+ })
547
+ }
548
+ else {
549
+ emit('closed')
550
+ validateDates()
551
+ }
552
+ }
553
+
554
+ const openDatePickerOnClick = () => {
555
+ openDatePicker()
556
+ }
557
+
558
+ const openDatePickerOnFocus = () => {
559
+ openDatePicker()
560
+ emit('focus')
561
+ }
562
+
563
+ const openDatePickerOnIconClick = () => {
564
+ toggleDatePicker()
565
+ }
566
+
529
567
  defineExpose({
530
568
  validateOnSubmit,
531
569
  isDatePickerVisible,
@@ -596,6 +634,7 @@
596
634
  :warning-messages="warningMessages"
597
635
  :success-messages="props.showSuccessMessages ? successMessages : []"
598
636
  :disabled="props.disabled"
637
+ :disable-click-button="false"
599
638
  :readonly="true"
600
639
  :label="props.placeholder"
601
640
  :no-icon="props.noIcon"
@@ -606,10 +645,12 @@
606
645
  :bg-color="props.bgColor"
607
646
  is-clearable
608
647
  title="Date Picker"
609
- @focus="openDatePicker"
648
+ @click="openDatePickerOnClick"
649
+ @focus="openDatePickerOnFocus"
650
+ @blur="handleInputBlur"
610
651
  @update:model-value="updateSelectedDates"
611
- @prepend-icon-click="openDatePicker"
612
- @append-icon-click="openDatePicker"
652
+ @prepend-icon-click="openDatePickerOnIconClick"
653
+ @append-icon-click="openDatePickerOnIconClick"
613
654
  />
614
655
  </template>
615
656
  <VDatePicker
@@ -625,6 +666,7 @@
625
666
  @update:view-mode="handleViewModeUpdate"
626
667
  @update:year="handleYearUpdate"
627
668
  @update:month="handleMonthUpdate"
669
+ @update:model-value="updateDisplayFormattedDate"
628
670
  >
629
671
  <template #title>
630
672
  Sélectionnez une date
@@ -1,5 +1,6 @@
1
1
  import { type Meta, type StoryFn } from '@storybook/vue3'
2
- import DatePickerValidationExamples from './DatePickerValidationExamples.vue'
2
+ import DatePickerValidationExamples from './docExamples/DatePickerValidationExamples.vue'
3
+ import DatePickerBidirectionalValidation from './docExamples/DatePickerBidirectionalValidation.vue'
3
4
 
4
5
  export default {
5
6
  title: 'Composants/Formulaires/DatePicker/Validation',
@@ -20,3 +21,10 @@ export const ValidationExamples: StoryFn = () => ({
20
21
  },
21
22
  template: '<DatePickerValidationExamples />',
22
23
  })
24
+
25
+ export const BidirectionalValidation: StoryFn = () => ({
26
+ components: {
27
+ DatePickerBidirectionalValidation,
28
+ },
29
+ template: '<DatePickerBidirectionalValidation />',
30
+ })