@cnamts/synapse 1.0.1 → 1.0.2

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 (217) hide show
  1. package/README.md +1 -1
  2. package/dist/{DateFilter-BmRuzQ9Z.js → DateFilter-YWOTbfeL.js} +1 -1
  3. package/dist/{NumberFilter-CnIPDHqx.js → NumberFilter-DMmMgALM.js} +1 -1
  4. package/dist/{PeriodFilter-CZwZ8CnQ.js → PeriodFilter-Bok5BHcn.js} +1 -1
  5. package/dist/SelectFilter-BKud2WhN.js +136 -0
  6. package/dist/{TextFilter-DTxZHJwX.js → TextFilter-DvMf2thH.js} +1 -1
  7. package/dist/components/Accordion/Accordion.d.ts +2 -1
  8. package/dist/components/Accordion/composables/useAccordionGroupCommunication.d.ts +5 -0
  9. package/dist/components/Accordion/composables/useAccordionKeyboardNavigation.d.ts +12 -0
  10. package/dist/components/Accordion/composables/useAccordionState.d.ts +13 -0
  11. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +85 -0
  12. package/dist/components/Customs/SyInputSelect/SyInputSelect.d.ts +2 -0
  13. package/dist/components/Customs/SySelect/SySelect.d.ts +33 -13
  14. package/dist/components/Customs/SyTextField/SyTextField.d.ts +2 -2
  15. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +1585 -1452
  16. package/dist/components/DatePicker/DatePicker/DatePicker.d.ts +16 -2
  17. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +3 -1
  18. package/dist/components/DatePicker/composables/index.d.ts +2 -0
  19. package/dist/components/DatePicker/composables/useAsteriskDisplay.d.ts +14 -0
  20. package/dist/components/DatePicker/composables/useDateAutoClamp.d.ts +16 -0
  21. package/dist/components/DatePicker/composables/useDateRangeInput.d.ts +1 -1
  22. package/dist/components/DatePicker/composables/useDisplayedDateString.d.ts +3 -0
  23. package/dist/components/DatePicker/composables/useInputBlurHandler.d.ts +1 -0
  24. package/dist/components/DatePicker/composables/useMonthButtonCustomization.d.ts +5 -2
  25. package/dist/components/NirField/NirField.d.ts +7 -3
  26. package/dist/components/NirField/nirValidation.d.ts +1 -1
  27. package/dist/components/PasswordField/PasswordField.d.ts +2 -0
  28. package/dist/components/PeriodField/PeriodField.d.ts +52 -8
  29. package/dist/components/PhoneField/PhoneField.d.ts +2 -2
  30. package/dist/components/RangeField/RangeField.d.ts +2 -0
  31. package/dist/components/SearchListField/SearchListField.d.ts +9 -0
  32. package/dist/components/SyTextArea/SyTextArea.d.ts +2 -0
  33. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +14 -9
  34. package/dist/components/Tables/SyTable/SyTable.d.ts +12 -7
  35. package/dist/components/Tables/common/SyTablePagination.d.ts +1636 -0
  36. package/dist/components/Tables/common/TableHeader.d.ts +2 -20
  37. package/dist/components/Tables/common/filters/SelectFilter.d.ts +5 -5
  38. package/dist/components/Tables/common/filters/getFilterComponent.d.ts +1 -0
  39. package/dist/components/Tables/common/filters/locales.d.ts +4 -0
  40. package/dist/components/Tables/common/filters/logics/date.d.ts +1 -0
  41. package/dist/components/Tables/common/filters/logics/number.d.ts +1 -0
  42. package/dist/components/Tables/common/filters/logics/period.d.ts +1 -0
  43. package/dist/components/Tables/common/filters/logics/select.d.ts +1 -0
  44. package/dist/components/Tables/common/filters/logics/text.d.ts +1 -0
  45. package/dist/components/Tables/common/locales.d.ts +21 -0
  46. package/dist/components/Tables/common/organizeColumns/OrganizeColumns.d.ts +267 -0
  47. package/dist/components/Tables/common/organizeColumns/sortHeaders.d.ts +2 -0
  48. package/dist/components/Tables/common/tableFilterUtils.d.ts +1 -0
  49. package/dist/components/Tables/common/tableStorageUtils.d.ts +41 -1
  50. package/dist/components/Tables/common/tableUtils.d.ts +42 -5
  51. package/dist/components/Tables/common/types.d.ts +19 -8
  52. package/dist/components/Tables/common/usePagination.d.ts +22 -0
  53. package/dist/components/Tables/common/useTableCheckbox.d.ts +20 -0
  54. package/dist/components/Tables/common/useTableHeaders.d.ts +76 -0
  55. package/dist/components/Tables/common/useTableItems.d.ts +24 -0
  56. package/dist/components/Tables/common/useTableOptions.d.ts +18 -0
  57. package/dist/components/ToolbarContainer/ToolbarContainer.d.ts +11 -0
  58. package/dist/components/UserMenuBtn/UserMenuBtn.d.ts +9 -2
  59. package/dist/components/index.d.ts +8 -6
  60. package/dist/design-system-v3.js +58 -56
  61. package/dist/design-system-v3.umd.cjs +22 -22
  62. package/dist/main-Cx8qG7YR.js +16344 -0
  63. package/dist/stories/Accessibilite/Vuetify/VuetifyItems.d.ts +14 -2
  64. package/dist/stories/DesignTokens/StylesTypographiques.stories.new.d.ts +8 -0
  65. package/dist/stories/DesignTokens/TypographyDisplay.d.ts +28 -0
  66. package/dist/stories/DesignTokens/vue-shims.d.ts +6 -0
  67. package/dist/style.css +1 -1
  68. package/package.json +1 -1
  69. package/src/common/imgs/accessibility-svgrepo-com.svg +4 -0
  70. package/src/components/Accordion/Accessibilite/AccessibilityGuide.mdx +249 -0
  71. package/src/components/Accordion/Accordion.vue +48 -76
  72. package/src/components/Accordion/composables/__tests__/useAccordionGroupCommunication.spec.ts +146 -0
  73. package/src/components/Accordion/composables/__tests__/useAccordionKeyboardNavigation.spec.ts +209 -0
  74. package/src/components/Accordion/composables/__tests__/useAccordionState.spec.ts +144 -0
  75. package/src/components/Accordion/composables/useAccordionGroupCommunication.ts +52 -0
  76. package/src/components/Accordion/composables/useAccordionKeyboardNavigation.ts +111 -0
  77. package/src/components/Accordion/composables/useAccordionState.ts +59 -0
  78. package/src/components/Accordion/tests/__snapshots__/accordion.spec.ts.snap +3 -0
  79. package/src/components/Customs/SyCheckbox/Accessibilite.mdx +303 -0
  80. package/src/components/Customs/SyCheckbox/SyCheckbox.mdx +50 -0
  81. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +630 -0
  82. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +326 -0
  83. package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +201 -0
  84. package/src/components/Customs/SyInputSelect/SyInputSelect.stories.ts +1 -0
  85. package/src/components/Customs/SyInputSelect/SyInputSelect.vue +8 -1
  86. package/src/components/Customs/SySelect/SySelect.stories.ts +160 -0
  87. package/src/components/Customs/SySelect/SySelect.vue +291 -32
  88. package/src/components/Customs/SySelect/tests/SySelect.spec.ts +230 -0
  89. package/src/components/Customs/SyTextField/SyTextField.stories.ts +3 -2
  90. package/src/components/Customs/SyTextField/SyTextField.vue +19 -8
  91. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +241 -31
  92. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +305 -57
  93. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.events.spec.ts +161 -0
  94. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +4 -2
  95. package/src/components/DatePicker/DatePicker/DatePicker.stories.ts +259 -137
  96. package/src/components/DatePicker/DatePicker/DatePicker.vue +153 -25
  97. package/src/components/DatePicker/DatePicker/tests/DatePicker.events.spec.ts +189 -0
  98. package/src/components/DatePicker/DatePicker/{DatePicker.spec.ts → tests/DatePicker.spec.ts} +1 -15
  99. package/src/components/DatePicker/DateTextInput/DateRange.stories.ts +24 -14
  100. package/src/components/DatePicker/DateTextInput/DateTextInput.events.spec.ts +148 -0
  101. package/src/components/DatePicker/DateTextInput/DateTextInput.spec.ts +3 -1
  102. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +200 -5
  103. package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +241 -31
  104. package/src/components/DatePicker/composables/index.ts +2 -0
  105. package/src/components/DatePicker/composables/tests/useDateAutoClamp.spec.ts +190 -0
  106. package/src/components/DatePicker/composables/tests/useInputBlurHandler.spec.ts +182 -4
  107. package/src/components/DatePicker/composables/tests/useMonthButtonCustomization.spec.ts +105 -80
  108. package/src/components/DatePicker/composables/useAsteriskDisplay.ts +31 -0
  109. package/src/components/DatePicker/composables/useDateAutoClamp.ts +136 -0
  110. package/src/components/DatePicker/composables/useDateRangeInput.ts +21 -18
  111. package/src/components/DatePicker/composables/useDisplayedDateString.ts +13 -1
  112. package/src/components/DatePicker/composables/useInputBlurHandler.ts +84 -20
  113. package/src/components/DatePicker/composables/useMonthButtonCustomization.ts +149 -51
  114. package/src/components/DiacriticPicker/DiacriticPicker.stories.ts +10 -0
  115. package/src/components/ErrorPage/Accessibilite.stories.ts +8 -0
  116. package/src/components/ErrorPage/ErrorPage.vue +12 -6
  117. package/src/components/ErrorPage/tests/__snapshots__/ErrorPage.spec.ts.snap +4 -4
  118. package/src/components/NirField/NirField.mdx +22 -9
  119. package/src/components/NirField/NirField.stories.ts +26 -2
  120. package/src/components/NirField/NirField.vue +209 -22
  121. package/src/components/NirField/nirValidation.ts +17 -3
  122. package/src/components/NirField/tests/NirField.spec.ts +2 -2
  123. package/src/components/NotFoundPage/Accessibilite.stories.ts +8 -0
  124. package/src/components/NotFoundPage/NotFoundPage.vue +2 -1
  125. package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +8 -6
  126. package/src/components/PaginatedTable/PaginatedTable.mdx +2 -0
  127. package/src/components/PasswordField/PasswordField.stories.ts +4 -0
  128. package/src/components/PasswordField/PasswordField.vue +3 -0
  129. package/src/components/PeriodField/PeriodField.vue +2 -0
  130. package/src/components/PhoneField/PhoneField.stories.ts +15 -15
  131. package/src/components/PhoneField/PhoneField.vue +1 -1
  132. package/src/components/RangeField/RangeField.stories.ts +9 -0
  133. package/src/components/RangeField/RangeField.vue +4 -0
  134. package/src/components/RangeField/tests/__snapshots__/RangeField.spec.ts.snap +12 -0
  135. package/src/components/SearchListField/SearchListField.vue +5 -0
  136. package/src/components/SyTextArea/SyTextArea.vue +3 -0
  137. package/src/components/SyTextArea/tests/SyTextArea.spec.ts +0 -1
  138. package/src/components/Tables/SyServerTable/FilterRules.stories.ts +632 -15
  139. package/src/components/Tables/SyServerTable/SyServerTable.mdx +15 -5
  140. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +2844 -1377
  141. package/src/components/Tables/SyServerTable/SyServerTable.vue +155 -66
  142. package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +256 -4
  143. package/src/components/Tables/SyTable/FilterRules.stories.ts +183 -0
  144. package/src/components/Tables/SyTable/SyTable.mdx +14 -4
  145. package/src/components/Tables/SyTable/SyTable.stories.ts +1265 -477
  146. package/src/components/Tables/SyTable/SyTable.vue +152 -72
  147. package/src/components/Tables/SyTable/tests/SyTable.spec.ts +366 -4
  148. package/src/components/Tables/common/SyTableFilter.vue +3 -56
  149. package/src/components/Tables/common/SyTablePagination.vue +375 -0
  150. package/src/components/Tables/common/TableHeader.vue +10 -26
  151. package/src/components/Tables/common/filters/SelectFilter.vue +131 -22
  152. package/src/components/Tables/common/filters/getFilterComponent.ts +54 -0
  153. package/src/components/Tables/common/filters/locales.ts +4 -0
  154. package/src/components/Tables/common/filters/logics/date.ts +12 -0
  155. package/src/components/Tables/common/filters/logics/number.ts +48 -0
  156. package/src/components/Tables/common/filters/logics/period.ts +25 -0
  157. package/src/components/Tables/common/filters/logics/select.ts +27 -0
  158. package/src/components/Tables/common/filters/logics/tests/TextFilterLogic.spec.ts +177 -0
  159. package/src/components/Tables/common/filters/logics/text.ts +62 -0
  160. package/src/components/Tables/common/filters/tests/TextFilter.spec.ts +11 -11
  161. package/src/components/Tables/common/locales.ts +24 -0
  162. package/src/components/Tables/common/organizeColumns/OrganizeColumns.vue +269 -0
  163. package/src/components/Tables/common/organizeColumns/sortHeaders.ts +9 -0
  164. package/src/components/Tables/common/tableFilterUtils.ts +43 -295
  165. package/src/components/Tables/common/tableStorageUtils.ts +27 -2
  166. package/src/components/Tables/common/tableStyles.scss +26 -0
  167. package/src/components/Tables/common/tableUtils.ts +3 -16
  168. package/src/components/Tables/common/tests/SyTablePagination.spec.ts +170 -0
  169. package/src/components/Tables/common/tests/filterByRange.spec.ts +215 -0
  170. package/src/components/Tables/common/tests/tableFilterUtils.spec.ts +0 -14
  171. package/src/components/Tables/common/tests/tableUtils.spec.ts +7 -51
  172. package/src/components/Tables/common/types.ts +17 -6
  173. package/src/components/Tables/common/usePagination.ts +83 -0
  174. package/src/components/Tables/common/useTableCheckbox.ts +58 -0
  175. package/src/components/Tables/common/useTableHeaders.ts +88 -0
  176. package/src/components/Tables/common/useTableItems.ts +87 -0
  177. package/src/components/Tables/common/useTableOptions.ts +93 -0
  178. package/src/components/ToolbarContainer/ToolbarContainer.mdx +16 -0
  179. package/src/components/ToolbarContainer/ToolbarContainer.stories.ts +675 -0
  180. package/src/components/ToolbarContainer/ToolbarContainer.vue +128 -0
  181. package/src/components/ToolbarContainer/tests/ToolbarContainer.spec.ts +156 -0
  182. package/src/components/UserMenuBtn/UserMenuBtn.stories.ts +74 -0
  183. package/src/components/UserMenuBtn/UserMenuBtn.vue +19 -17
  184. package/src/components/index.ts +8 -6
  185. package/src/stories/Accessibilite/Aculturation/AuditDesignSystem.mdx +293 -20
  186. package/src/stories/Accessibilite/Aculturation/SensibilisationAccessibilite.mdx +448 -54
  187. package/src/stories/Accessibilite/Audit/RGAA.mdx +231 -23
  188. package/src/stories/Accessibilite/Avancement/Avancement.mdx +591 -7
  189. package/src/stories/Accessibilite/Avancement/Avancement.stories.ts +139 -38
  190. package/src/stories/Accessibilite/Introduction.mdx +258 -18
  191. package/src/stories/Accessibilite/KitDePreAudit/Echantillonnage.mdx +221 -31
  192. package/src/stories/Accessibilite/KitDePreAudit/Introduction.mdx +204 -22
  193. package/src/stories/Accessibilite/KitDePreAudit/Outils/Introduction.mdx +537 -24
  194. package/src/stories/Accessibilite/KitDePreAudit/Outils/LecteursDEcran.mdx +577 -70
  195. package/src/stories/Accessibilite/KitDePreAudit/Outils/Tanaguru.mdx +382 -31
  196. package/src/stories/Accessibilite/KitDePreAudit/Preaudit.mdx +419 -81
  197. package/src/stories/Accessibilite/Vuetify/Vuetify.mdx +132 -6
  198. package/src/stories/Accessibilite/Vuetify/Vuetify.stories.ts +370 -146
  199. package/src/stories/Accessibilite/Vuetify/VuetifyItems.ts +35 -57
  200. package/src/stories/Demarrer/Accueil.stories.ts +20 -5
  201. package/src/stories/DesignTokens/StylesTypographiques.mdx +10 -9
  202. package/src/stories/DesignTokens/StylesTypographiques.stories.new.ts +397 -0
  203. package/src/stories/DesignTokens/StylesTypographiques.stories.ts +397 -0
  204. package/src/stories/DesignTokens/TypographyDisplay.vue +155 -0
  205. package/src/stories/DesignTokens/vue-shims.d.ts +6 -0
  206. package/src/stories/GuideDuDev/LesBreackingChanges.mdx +0 -2
  207. package/src/stories/GuideDuDev/MigrationDepuisBridge.mdx +1 -1
  208. package/src/stories/GuideDuDev/MigrationDepuisVue2.mdx +1 -1
  209. package/src/stories/GuideDuDev/PortailAgent.mdx +10 -0
  210. package/src/stories/GuideDuDev/PortailAgent.stories.ts +506 -0
  211. package/src/stories/GuideDuDev/Theme.mdx +41 -0
  212. package/dist/SelectFilter-Cj-GW2Cc.js +0 -97
  213. package/dist/main-WDqeoGM-.js +0 -14788
  214. package/src/components/PaginatedTable/tests/__snapshots__/PaginatedTable.spec.ts.snap +0 -886
  215. package/src/components/Tables/SyServerTable/tests/__snapshots__/SyServerTable.spec.ts.snap +0 -521
  216. package/src/components/Tables/SyTable/tests/__snapshots__/SyTable.spec.ts.snap +0 -521
  217. package/src/stories/DesignTokens/ThemePA.mdx +0 -35
@@ -636,4 +636,234 @@ describe('SySelect.vue', () => {
636
636
  await clearBtn.trigger('click')
637
637
  expect(wrapper.emitted()['update:modelValue'][0]).toEqual([null])
638
638
  })
639
+
640
+ describe('Multiple selection mode', () => {
641
+ it('handles multiple selection correctly', async () => {
642
+ const items = [
643
+ { text: '-choisir-', value: null },
644
+ { text: 'Option 1', value: '1' },
645
+ { text: 'Option 2', value: '2' },
646
+ { text: 'Option 3', value: '3' },
647
+ ]
648
+ const wrapper = mount(SySelect, {
649
+ props: {
650
+ items,
651
+ multiple: true,
652
+ modelValue: [],
653
+ textKey: 'text',
654
+ valueKey: 'value',
655
+ },
656
+ global: {
657
+ plugins: [vuetify],
658
+ },
659
+ })
660
+
661
+ // Open the select menu
662
+ await wrapper.find('.sy-select').trigger('click')
663
+ await wrapper.vm.$nextTick()
664
+
665
+ // Select Option 1
666
+ const listItems = wrapper.findAll('.v-list-item')
667
+ await listItems[1].trigger('click')
668
+ await wrapper.vm.$nextTick()
669
+
670
+ // Check that Option 1 is selected
671
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual([['1']])
672
+
673
+ // Select Option 2 as well
674
+ await listItems[2].trigger('click')
675
+ await wrapper.vm.$nextTick()
676
+
677
+ // Check that both options are selected
678
+ expect(wrapper.emitted()['update:modelValue'][1]).toEqual([['1', '2']])
679
+ })
680
+
681
+ it('clears all selections when default option is clicked', async () => {
682
+ const items = [
683
+ { text: '-choisir-', value: null },
684
+ { text: 'Option 1', value: '1' },
685
+ { text: 'Option 2', value: '2' },
686
+ ]
687
+ const wrapper = mount(SySelect, {
688
+ props: {
689
+ items,
690
+ multiple: true,
691
+ modelValue: ['1', '2'],
692
+ textKey: 'text',
693
+ valueKey: 'value',
694
+ },
695
+ global: {
696
+ plugins: [vuetify],
697
+ },
698
+ })
699
+
700
+ // Open the select menu
701
+ await wrapper.find('.sy-select').trigger('click')
702
+ await wrapper.vm.$nextTick()
703
+
704
+ // Click on the default option
705
+ const defaultOption = wrapper.findAll('.v-list-item')[0]
706
+ await defaultOption.trigger('click')
707
+ await wrapper.vm.$nextTick()
708
+
709
+ // Check that all selections are cleared
710
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual([[]])
711
+ })
712
+
713
+ it('treats default option as selected when no items are selected', async () => {
714
+ const items = [
715
+ { text: '-choisir-', value: null },
716
+ { text: 'Option 1', value: '1' },
717
+ { text: 'Option 2', value: '2' },
718
+ ]
719
+ const wrapper = mount(SySelect, {
720
+ props: {
721
+ items,
722
+ multiple: true,
723
+ modelValue: [],
724
+ textKey: 'text',
725
+ valueKey: 'value',
726
+ },
727
+ global: {
728
+ plugins: [vuetify],
729
+ },
730
+ })
731
+
732
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
733
+ const instance = wrapper.vm as any
734
+
735
+ // Check that the selectedItemText is the default option
736
+ expect(instance.selectedItemText).toBe('-choisir-')
737
+
738
+ // Check that isDefaultOption returns true for the default item
739
+ const defaultItem = items[0]
740
+ expect(instance.isDefaultOption(defaultItem)).toBe(true)
741
+
742
+ // Check that isItemSelected returns true for the default item when no selections
743
+ expect(instance.isItemSelected(defaultItem)).toBe(true)
744
+ })
745
+ })
746
+
747
+ describe('Chips mode', () => {
748
+ it('renders chips for selected items', async () => {
749
+ const items = [
750
+ { text: 'Option 1', value: '1' },
751
+ { text: 'Option 2', value: '2' },
752
+ { text: 'Option 3', value: '3' },
753
+ ]
754
+ const wrapper = mount(SySelect, {
755
+ props: {
756
+ items,
757
+ multiple: true,
758
+ chips: true,
759
+ modelValue: ['1', '2'],
760
+ textKey: 'text',
761
+ valueKey: 'value',
762
+ },
763
+ global: {
764
+ plugins: [vuetify],
765
+ },
766
+ })
767
+
768
+ // Check that chips are rendered
769
+ const chips = wrapper.findAll('.v-chip')
770
+ expect(chips.length).toBe(2)
771
+ expect(chips[0].text()).toBe('Option 1')
772
+ expect(chips[1].text()).toBe('Option 2')
773
+ })
774
+
775
+ it('removes a chip when close button is clicked', async () => {
776
+ const items = [
777
+ { text: 'Option 1', value: '1' },
778
+ { text: 'Option 2', value: '2' },
779
+ { text: 'Option 3', value: '3' },
780
+ ]
781
+ const wrapper = mount(SySelect, {
782
+ props: {
783
+ items,
784
+ multiple: true,
785
+ chips: true,
786
+ modelValue: ['1', '2'],
787
+ textKey: 'text',
788
+ valueKey: 'value',
789
+ },
790
+ global: {
791
+ plugins: [vuetify],
792
+ },
793
+ })
794
+
795
+ // Find the first chip's close button and click it
796
+ const closeButton = wrapper.find('.v-chip__close')
797
+ await closeButton.trigger('click')
798
+ await wrapper.vm.$nextTick()
799
+
800
+ // Check that the chip was removed from the model
801
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual([['2']])
802
+ })
803
+
804
+ it('handles chip text correctly for object items', async () => {
805
+ const items = [
806
+ { text: 'Option 1', value: '1', data: { id: 101 } },
807
+ { text: 'Option 2', value: '2', data: { id: 102 } },
808
+ ]
809
+ const wrapper = mount(SySelect, {
810
+ props: {
811
+ items,
812
+ multiple: true,
813
+ chips: true,
814
+ returnObject: true,
815
+ modelValue: [items[0], items[1]],
816
+ textKey: 'text',
817
+ valueKey: 'value',
818
+ },
819
+ global: {
820
+ plugins: [vuetify],
821
+ },
822
+ })
823
+
824
+ // Check that chips display the correct text
825
+ const chips = wrapper.findAll('.v-chip')
826
+ expect(chips.length).toBe(2)
827
+ expect(chips[0].text()).toBe('Option 1')
828
+ expect(chips[1].text()).toBe('Option 2')
829
+ })
830
+
831
+ it('safely handles different item types in chips', async () => {
832
+ // This test verifies our safeChipItem function works correctly
833
+ const items = [
834
+ { text: 'Option 1', value: '1' },
835
+ { text: 'Option 2', value: 2 }, // Number value
836
+ ]
837
+ const wrapper = mount(SySelect, {
838
+ props: {
839
+ items,
840
+ multiple: true,
841
+ chips: true,
842
+ modelValue: ['1', 2],
843
+ textKey: 'text',
844
+ valueKey: 'value',
845
+ },
846
+ global: {
847
+ plugins: [vuetify],
848
+ },
849
+ })
850
+
851
+ // Check that chips are rendered without errors
852
+ const chips = wrapper.findAll('.v-chip')
853
+ expect(chips.length).toBe(2)
854
+ expect(chips[0].text()).toBe('Option 1')
855
+ expect(chips[1].text()).toBe('Option 2')
856
+
857
+ // Test the safeChipItem method directly
858
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
859
+ const instance = wrapper.vm as any
860
+ const stringResult = instance.safeChipItem('test')
861
+ const numberResult = instance.safeChipItem(123)
862
+ const objectResult = instance.safeChipItem({ id: 3 })
863
+
864
+ expect(stringResult).toBe('test')
865
+ expect(numberResult).toBe(123)
866
+ expect(typeof objectResult).toBe('object')
867
+ })
868
+ })
639
869
  })
@@ -138,7 +138,7 @@ const meta = {
138
138
  },
139
139
  'bgColor': {
140
140
  description: 'Couleur de fond du champ',
141
- control: 'text',
141
+ control: 'color',
142
142
  },
143
143
  'centerAffix': {
144
144
  description: 'Centre verticalement les éléments ajoutés avant/après le champ',
@@ -217,13 +217,14 @@ const meta = {
217
217
  default: false,
218
218
  },
219
219
  'displayPersistentPlaceholder': {
220
- description: 'Garde le placeholder visible même avec une valeur',
220
+ description: 'Garde le placeholder visible. Si le champ est vide, le placeholder reste affiché',
221
221
  control: 'boolean',
222
222
  default: false,
223
223
  },
224
224
  'placeholder': {
225
225
  description: 'Texte affiché quand le champ est vide',
226
226
  control: 'text',
227
+ default: 'Placeholder',
227
228
  },
228
229
  'prefix': {
229
230
  description: 'Texte affiché avant la valeur: prefix="€" : affichera "€" avant la valeur saisie',
@@ -1,4 +1,8 @@
1
1
  <script lang="ts" setup>
2
+ // Prevent display-asterisk from being passed to the DOM
3
+ defineOptions({
4
+ inheritAttrs: false,
5
+ })
2
6
  import { computed, onMounted, ref, watch, nextTick, type ComponentPublicInstance } from 'vue'
3
7
  import type { IconType, VariantStyle, ColorType } from './types'
4
8
  import { useValidation, type ValidationRule } from '@/composables/validation/useValidation'
@@ -92,7 +96,7 @@
92
96
  tooltipLocation: 'top',
93
97
  variantStyle: 'outlined',
94
98
  color: 'primary',
95
- label: 'custom label',
99
+ label: '',
96
100
  errorMessages: null,
97
101
  warningMessages: null,
98
102
  successMessages: null,
@@ -100,7 +104,7 @@
100
104
  isClearable: false,
101
105
  isActive: false,
102
106
  baseColor: undefined,
103
- bgColor: undefined,
107
+ bgColor: 'white',
104
108
  centerAffix: undefined,
105
109
  counter: false,
106
110
  counterValue: undefined,
@@ -253,7 +257,7 @@
253
257
 
254
258
  const hasError = computed(() => validation.hasError.value)
255
259
  const hasWarning = computed(() => validation.hasWarning.value)
256
- const hasSuccess = computed(() => validation.hasSuccess.value)
260
+ const hasSuccess = computed(() => validation.hasSuccess.value && !hasError.value && !hasWarning.value)
257
261
 
258
262
  const errors = computed(() => validation.errors.value)
259
263
  const warnings = computed(() => validation.warnings.value)
@@ -338,6 +342,12 @@
338
342
  setAriaHidden('.v-text-field__suffix')
339
343
  addSrOnlySpan('.v-text-field__prefix')
340
344
  addSrOnlySpan('.v-text-field__suffix')
345
+
346
+ // Remove aria-describedby attribute
347
+ const inputElement = syTextFieldRef.value?.$el?.querySelector('input')
348
+ if (inputElement) {
349
+ inputElement.removeAttribute('aria-describedby')
350
+ }
341
351
  })
342
352
  })
343
353
 
@@ -399,6 +409,7 @@
399
409
  :type="props.type"
400
410
  :variant="props.variantStyle"
401
411
  :width="props.width"
412
+ v-bind="Object.fromEntries(Object.entries($attrs).filter(([key]) => key !== 'display-asterisk'))"
402
413
  :class="{
403
414
  'error-field': hasError,
404
415
  'warning-field': hasWarning,
@@ -519,11 +530,11 @@
519
530
  <style lang="scss" scoped>
520
531
  @use '@/assets/tokens';
521
532
 
522
- :deep(.v-field__input input::placeholder),
523
- :deep(input.v-field__input::placeholder),
524
- :deep(textarea.v-field__input::placeholder) {
525
- opacity: 0;
526
- }
533
+ // :deep(.v-field__input input::placeholder),
534
+ // :deep(input.v-field__input::placeholder),
535
+ // :deep(textarea.v-field__input::placeholder) {
536
+ // opacity: 0;
537
+ // }
527
538
 
528
539
  .warning-field {
529
540
  :deep(.v-input__details > .v-icon),
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/vue3'
2
2
  import DatePicker from '../DatePicker/DatePicker.vue'
3
3
  import SyAlert from '@/components/SyAlert/SyAlert.vue'
4
4
  import { ref, onMounted } from 'vue'
5
+ import { fn } from '@storybook/test'
5
6
 
6
7
  const meta = {
7
8
  title: 'Composants/Formulaires/DatePicker/CombinedMode',
@@ -14,6 +15,7 @@ const meta = {
14
15
  parameters: {
15
16
  layout: 'fullscreen',
16
17
  controls: { exclude: ['modelValue'] },
18
+ actions: { argTypesRegex: '^on.*' },
17
19
  },
18
20
  argTypes: {
19
21
  modelValue: {
@@ -121,10 +123,22 @@ const meta = {
121
123
  control: 'boolean',
122
124
  description: 'Affiche les jours de week-end',
123
125
  },
126
+ displayHolidayDays: {
127
+ control: 'boolean',
128
+ description: 'Affiche les jours fériés',
129
+ },
124
130
  period: {
125
131
  control: 'object',
126
132
  description: 'Période pendant laquelle les dates peuvent être sélectionnées (au format: MM/DD/YYYY)',
127
133
  },
134
+ autoClamp: {
135
+ control: 'boolean',
136
+ description: 'Active le clamping automatique des dates',
137
+ },
138
+ displayAsterisk: {
139
+ control: 'boolean',
140
+ description: 'Affiche l\'astérisque',
141
+ },
128
142
  },
129
143
  } as Meta<typeof DatePicker>
130
144
 
@@ -162,22 +176,28 @@ export const Default: Story = {
162
176
  ],
163
177
  },
164
178
  args: {
165
- placeholder: 'Sélectionner une date',
166
- format: 'DD/MM/YYYY',
167
- isBirthDate: false,
168
- showWeekNumber: false,
169
- required: false,
170
- displayRange: false,
171
- displayIcon: true,
172
- displayAppendIcon: false,
173
- displayPrependIcon: true,
174
- disabled: false,
175
- noIcon: false,
176
- noCalendar: false,
177
- // modelValue est défini dans le setup du render
178
- displayTodayButton: true,
179
- displayWeekendDays: true,
180
- useCombinedMode: true,
179
+ 'placeholder': 'Sélectionner une date',
180
+ 'format': 'DD/MM/YYYY',
181
+ 'isBirthDate': false,
182
+ 'showWeekNumber': false,
183
+ 'required': false,
184
+ 'displayRange': false,
185
+ 'displayIcon': true,
186
+ 'displayAppendIcon': false,
187
+ 'displayPrependIcon': true,
188
+ 'disabled': false,
189
+ 'noIcon': false,
190
+ 'noCalendar': false,
191
+ 'modelValue': '',
192
+ 'onUpdate:modelValue': fn(),
193
+ 'onFocus': fn(),
194
+ 'onBlur': fn(),
195
+ 'onClosed': fn(),
196
+ 'onDate-selected': fn(),
197
+ 'displayTodayButton': true,
198
+ 'displayWeekendDays': true,
199
+ 'displayHolidayDays': true,
200
+ 'useCombinedMode': true,
181
201
  },
182
202
  render: (args) => {
183
203
  return {
@@ -195,6 +215,87 @@ export const Default: Story = {
195
215
  },
196
216
  }
197
217
 
218
+ export const Required: Story = {
219
+ parameters: {
220
+ sourceCode: [
221
+ {
222
+ name: 'Template',
223
+ code: `
224
+ <template>
225
+ <DatePicker
226
+ v-model="date"
227
+ placeholder="Sélectionner une date"
228
+ useCombinedMode
229
+ required
230
+ format="DD/MM/YYYY"
231
+ />
232
+ <DatePicker
233
+ v-model="date"
234
+ placeholder="Sélectionner une date"
235
+ useCombinedMode
236
+ required
237
+ displayAsterisk
238
+ format="DD/MM/YYYY"
239
+ />
240
+ </template>
241
+ `,
242
+ },
243
+ {
244
+ name: 'Script',
245
+ code: `
246
+ <script setup lang="ts">
247
+ import { DatePicker } from '@cnamts/synapse'
248
+ import { ref } from 'vue'
249
+
250
+ const date = ref('')
251
+ </script>
252
+ `,
253
+ },
254
+ ],
255
+ },
256
+ args: {
257
+ 'label': 'Sélectionner une date',
258
+ 'format': 'DD/MM/YYYY',
259
+ 'isBirthDate': false,
260
+ 'showWeekNumber': false,
261
+ 'required': true,
262
+ 'displayRange': false,
263
+ 'displayIcon': true,
264
+ 'displayAppendIcon': false,
265
+ 'displayPrependIcon': true,
266
+ 'disabled': false,
267
+ 'noIcon': false,
268
+ 'noCalendar': false,
269
+ 'modelValue': '',
270
+ 'onUpdate:modelValue': fn(),
271
+ 'onFocus': fn(),
272
+ 'onBlur': fn(),
273
+ 'onClosed': fn(),
274
+ 'onDate-selected': fn(),
275
+ 'displayTodayButton': true,
276
+ 'displayWeekendDays': true,
277
+ 'displayHolidayDays': true,
278
+ 'useCombinedMode': true,
279
+ },
280
+ render: (args) => {
281
+ return {
282
+ components: { DatePicker },
283
+ setup() {
284
+ const value = ref('')
285
+ return { args, value }
286
+ },
287
+ template: `
288
+ <div class="d-flex flex-wrap align-center pa-4">
289
+ <h4 class="mb-4">Sans astérisque :</h4>
290
+ <DatePicker v-bind="args" v-model="value"/>
291
+ <h4 class="mb-4">Avec astérisque :</h4>
292
+ <DatePicker v-bind="args" displayAsterisk v-model="value"/>
293
+ </div>
294
+ `,
295
+ }
296
+ },
297
+ }
298
+
198
299
  export const DateRange: Story = {
199
300
  parameters: {
200
301
  sourceCode: [
@@ -226,21 +327,26 @@ export const DateRange: Story = {
226
327
  ],
227
328
  },
228
329
  args: {
229
- placeholder: 'Sélectionner une période',
230
- format: 'DD/MM/YYYY',
231
- dateFormatReturn: '',
232
- isBirthDate: false,
233
- showWeekNumber: false,
234
- required: false,
235
- displayRange: true,
236
- displayIcon: true,
237
- displayAppendIcon: false,
238
- displayPrependIcon: true,
239
- disabled: false,
240
- noIcon: false,
241
- noCalendar: false,
242
- // modelValue est défini dans le setup du render
243
- useCombinedMode: true,
330
+ 'placeholder': 'Sélectionner une période',
331
+ 'format': 'DD/MM/YYYY',
332
+ 'dateFormatReturn': '',
333
+ 'isBirthDate': false,
334
+ 'showWeekNumber': false,
335
+ 'required': false,
336
+ 'displayRange': true,
337
+ 'displayIcon': true,
338
+ 'displayAppendIcon': false,
339
+ 'displayPrependIcon': true,
340
+ 'disabled': false,
341
+ 'noIcon': false,
342
+ 'noCalendar': false,
343
+ 'modelValue': ['', ''],
344
+ 'onUpdate:modelValue': fn(),
345
+ 'onFocus': fn(),
346
+ 'onBlur': fn(),
347
+ 'onClosed': fn(),
348
+ 'onDate-selected': fn(),
349
+ 'useCombinedMode': true,
244
350
  },
245
351
  render: (args) => {
246
352
  return {
@@ -1004,6 +1110,110 @@ export const WithTextFieldActivator: Story = {
1004
1110
  },
1005
1111
  }
1006
1112
 
1113
+ export const AutoClampFeature: Story = {
1114
+ parameters: {
1115
+ sourceCode: [
1116
+ {
1117
+ name: 'Template',
1118
+ code: `
1119
+ <template>
1120
+ <div class="d-flex flex-column">
1121
+ <h3>Démonstration de l'auto clamp avec différents formats</h3>
1122
+
1123
+ <h4 class="mt-4">Format DD/MM/YYYY (séparateur /)</h4>
1124
+ <DatePicker
1125
+ v-model="dateSlash"
1126
+ placeholder="Saisie avec auto clamp - séparateur /"
1127
+ format="DD/MM/YYYY"
1128
+ useCombinedMode
1129
+ autoClamp
1130
+ />
1131
+
1132
+ <h4 class="mt-4">Format DD-MM-YYYY (séparateur -)</h4>
1133
+ <DatePicker
1134
+ v-model="dateDash"
1135
+ placeholder="Saisie avec auto clamp - séparateur -"
1136
+ format="DD-MM-YYYY"
1137
+ useCombinedMode
1138
+ autoClamp
1139
+ />
1140
+
1141
+ <h4 class="mt-4">Format YYYY.MM.DD (séparateur .)</h4>
1142
+ <DatePicker
1143
+ v-model="dateDot"
1144
+ placeholder="Saisie avec auto clamp - séparateur ."
1145
+ format="YYYY.MM.DD"
1146
+ useCombinedMode
1147
+ autoClamp
1148
+ />
1149
+ </div>
1150
+ </template>
1151
+ `,
1152
+ },
1153
+ {
1154
+ name: 'Script',
1155
+ code: `
1156
+ <script setup lang="ts">
1157
+ import { ref } from 'vue'
1158
+ import { DatePicker } from '@cnamts/synapse'
1159
+
1160
+ const dateSlash = ref('')
1161
+ const dateDash = ref('')
1162
+ const dateDot = ref('')
1163
+ </script>
1164
+ `,
1165
+ },
1166
+ ],
1167
+ },
1168
+ render: () => {
1169
+ return {
1170
+ components: { DatePicker },
1171
+ setup() {
1172
+ const dateSlash = ref('')
1173
+ const dateDash = ref('')
1174
+ const dateDot = ref('')
1175
+ return { dateSlash, dateDash, dateDot }
1176
+ },
1177
+ template: `
1178
+ <div class="d-flex flex-column pa-4">
1179
+ <h3>Démonstration de l'auto clamp avec différents formats</h3>
1180
+ <div class="mb-4 mt-2">Saisissez uniquement des chiffres - les séparateurs seront ajoutés automatiquement selon le format défini</div>
1181
+
1182
+ <h4 class="mb-2">Format DD/MM/YYYY (séparateur /)</h4>
1183
+ <DatePicker
1184
+ v-model="dateSlash"
1185
+ placeholder="Saisie avec auto clamp - séparateur /"
1186
+ format="DD/MM/YYYY"
1187
+ useCombinedMode
1188
+ autoClamp
1189
+ />
1190
+ <div class="caption mb-4">Valeur actuelle: {{ dateSlash || 'aucune date saisie' }}</div>
1191
+
1192
+ <h4 class="mb-2">Format DD-MM-YYYY (séparateur -)</h4>
1193
+ <DatePicker
1194
+ v-model="dateDash"
1195
+ placeholder="Saisie avec auto clamp - séparateur -"
1196
+ format="DD-MM-YYYY"
1197
+ useCombinedMode
1198
+ autoClamp
1199
+ />
1200
+ <div class="caption mb-4">Valeur actuelle: {{ dateDash || 'aucune date saisie' }}</div>
1201
+
1202
+ <h4 class="mb-2">Format YYYY.MM.DD (séparateur .)</h4>
1203
+ <DatePicker
1204
+ v-model="dateDot"
1205
+ placeholder="Saisie avec auto clamp - séparateur ."
1206
+ format="YYYY.MM.DD"
1207
+ useCombinedMode
1208
+ autoClamp
1209
+ />
1210
+ <div class="caption mb-4">Valeur actuelle: {{ dateDot || 'aucune date saisie' }}</div>
1211
+ </div>
1212
+ `,
1213
+ }
1214
+ },
1215
+ }
1216
+
1007
1217
  export const WithFormSubmission: Story = {
1008
1218
  parameters: {
1009
1219
  sourceCode: [