@cnamts/synapse 1.0.26 → 1.0.27

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 (253) hide show
  1. package/dist/{AutocompleteFilter-BPR-a55G.js → AutocompleteFilter-C9eLKyW8.js} +3 -3
  2. package/dist/{DateFilter-CknrJWs2.js → DateFilter-y-GLkAkn.js} +8 -8
  3. package/dist/{NumberFilter-DJ-yNlzv.js → NumberFilter-DN6hIBS7.js} +1 -1
  4. package/dist/{PeriodFilter-CiB5Oa9Z.js → PeriodFilter-MoUUp9qS.js} +1 -1
  5. package/dist/{SelectFilter-EiafX97M.js → SelectFilter-bCbrdLmu.js} +1 -1
  6. package/dist/{TextFilter-BzOmpdxj.js → TextFilter-CvjgEaoM.js} +4 -4
  7. package/dist/apLightTheme2026-ug4Y23ns.js +611 -0
  8. package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +2369 -353
  9. package/dist/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.d.ts +18 -0
  10. package/dist/components/Customs/Selects/SyAutocomplete/utils/ariaManager.d.ts +1 -1
  11. package/dist/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.d.ts +3 -1
  12. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +9 -10
  13. package/dist/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.d.ts +1 -0
  14. package/dist/components/Customs/Selects/SySelect/composables/useSySelectValidation.d.ts +15 -0
  15. package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +3 -3
  16. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +3 -3
  17. package/dist/components/Customs/SyIconButton/SyIconButton.d.ts +18 -0
  18. package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +20 -38
  19. package/dist/components/Customs/SyRadioGroup/composables/useSyRadioGroupValidation.d.ts +50 -0
  20. package/dist/components/Customs/SyTextField/SyTextField.d.ts +6 -6
  21. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +147 -136
  22. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +62 -54
  23. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +27 -24
  24. package/dist/components/DatePicker/composables/index.d.ts +1 -0
  25. package/dist/components/DatePicker/composables/useDatePickerValidationBridge.d.ts +51 -0
  26. package/dist/components/MonthPicker/MonthPicker.d.ts +23 -23
  27. package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +23 -23
  28. package/dist/components/NirField/NirField.d.ts +56 -56
  29. package/dist/components/PasswordField/PasswordField.d.ts +3 -3
  30. package/dist/components/PeriodField/PeriodField.d.ts +236 -212
  31. package/dist/components/PhoneField/PhoneField.d.ts +23 -23
  32. package/dist/components/SyTextArea/SyTextArea.d.ts +25 -15
  33. package/dist/components/SyTextArea/composables/useSyTextAreaValidation.d.ts +20 -0
  34. package/dist/components/SyTextArea/locales.d.ts +1 -0
  35. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +1 -0
  36. package/dist/components/Tables/SyTable/SyTable.d.ts +1 -0
  37. package/dist/components/Tables/common/SyTablePagination.d.ts +25 -25
  38. package/dist/components/Tables/common/types.d.ts +2 -0
  39. package/dist/components/index.d.ts +1 -0
  40. package/dist/composables/unifyValidation/documentationValidationProps.d.ts +160 -160
  41. package/dist/composables/unifyValidation/useValidation.d.ts +16 -14
  42. package/dist/design-system-v3.js +81 -80
  43. package/dist/designTokens/tokens/amelipro/apContextual.d.ts +6 -6
  44. package/dist/designTokens/tokens/amelipro/apDarkTheme.d.ts +3 -1
  45. package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +53 -100
  46. package/dist/designTokens/tokens/baseContextualTokens.d.ts +0 -6
  47. package/dist/designTokens/tokens/baseTokens.d.ts +232 -0
  48. package/dist/designTokens/tokens/cnam/cnamContextual.d.ts +6 -6
  49. package/dist/designTokens/tokens/cnam/cnamDarkTheme.d.ts +1 -1
  50. package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +57 -101
  51. package/dist/designTokens/tokens/pa/paContextual.d.ts +0 -6
  52. package/dist/designTokens/tokens/pa/paDarkTheme.d.ts +1 -1
  53. package/dist/designTokens/tokens/pa/paLightTheme.d.ts +53 -97
  54. package/dist/designTokens/tokens/pa/paSemantic.d.ts +1 -0
  55. package/dist/designTokens/tokens/semanticTokens.d.ts +112 -0
  56. package/dist/main-CI6Q9nmO.js +39234 -0
  57. package/dist/synapse.css +1 -1
  58. package/dist/vuetifyConfig.js +208 -72
  59. package/package.json +4 -2
  60. package/src/assets/overrides/_icons.scss +5 -4
  61. package/src/assets/overrides/_otp.scss +4 -4
  62. package/src/assets/overrides/_typography.scss +2 -1
  63. package/src/assets/overrides/_utilities.scss +1 -42
  64. package/src/components/ChipList/ChipList.vue +30 -18
  65. package/src/components/ChipList/tests/chipList.spec.ts +4 -4
  66. package/src/components/CopyBtn/CopyBtn.vue +2 -2
  67. package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.stories.ts +4 -0
  68. package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.vue +7 -6
  69. package/src/components/Customs/Selects/SelectBtnField/tests/SelectBtnField.spec.ts +223 -0
  70. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +283 -351
  71. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +182 -218
  72. package/src/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.ts +101 -0
  73. package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +761 -1
  74. package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +3 -1
  75. package/src/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.ts +79 -5
  76. package/src/components/Customs/Selects/SyAutocomplete/validation/Validation.stories.ts +1029 -0
  77. package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +9 -491
  78. package/src/components/Customs/Selects/SySelect/SySelect.vue +46 -79
  79. package/src/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.ts +3 -0
  80. package/src/components/Customs/Selects/SySelect/composables/useSySelectValidation.ts +64 -0
  81. package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +196 -0
  82. package/src/components/Customs/Selects/SySelect/validation/Validation.stories.ts +1026 -0
  83. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.stories.ts +18 -7
  84. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +2 -2
  85. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +8 -8
  86. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +8 -8
  87. package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +1 -1
  88. package/src/components/Customs/SyIcon/accessibilite/Accessibility.mdx +0 -6
  89. package/src/components/Customs/SyIcon/utils/tests/iconUtils.spec.ts +107 -0
  90. package/src/components/Customs/SyRadioGroup/SyRadioGroup.mdx +2 -2
  91. package/src/components/Customs/SyRadioGroup/SyRadioGroup.stories.ts +395 -200
  92. package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +82 -127
  93. package/src/components/Customs/SyRadioGroup/composables/useSyRadioGroupValidation.ts +127 -0
  94. package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.a11y.spec.ts +93 -1
  95. package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.spec.ts +146 -9
  96. package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.visual.cy.ts +165 -0
  97. package/src/components/Customs/SyRadioGroup/validation/Validation.stories.ts +773 -0
  98. package/src/components/Customs/SyTabs/config.ts +3 -3
  99. package/src/components/Customs/SyTabs/tests/SyTabs.spec.ts +265 -0
  100. package/src/components/Customs/SyTabs/tests/useTabTransition.spec.ts +188 -0
  101. package/src/components/Customs/SyTextField/SyTextField.stories.ts +10 -29
  102. package/src/components/Customs/SyTextField/SyTextField.vue +23 -15
  103. package/src/components/DataList/DataList.stories.ts +1 -1
  104. package/src/components/DataListItem/tests/DataListItem.spec.ts +3 -1
  105. package/src/components/DatePicker/CalendarMode/DatePicker.vue +37 -142
  106. package/src/components/DatePicker/CalendarMode/tests/DatePicker.coverage.spec.ts +156 -0
  107. package/src/components/DatePicker/CalendarMode/tests/DatePicker.spec.ts +495 -4
  108. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +47 -66
  109. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +206 -0
  110. package/src/components/DatePicker/ComplexDatePicker/tests/bridge-integration.regression.spec.ts +210 -0
  111. package/src/components/DatePicker/ComplexDatePicker/tests/calendar-navigation.regression.spec.ts +214 -0
  112. package/src/components/DatePicker/ComplexDatePicker/tests/validation-cross.regression.spec.ts +194 -0
  113. package/src/components/DatePicker/ComplexDatePicker/tests/validation-success-messages.regression.spec.ts +83 -0
  114. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +129 -54
  115. package/src/components/DatePicker/DateTextInput/tests/DateTextInput.spec.ts +320 -0
  116. package/src/components/DatePicker/composables/index.ts +1 -0
  117. package/src/components/DatePicker/composables/tests/useCalendarKeyboardNavigation.spec.ts +360 -0
  118. package/src/components/DatePicker/composables/tests/useDatePickerValidationBridge.spec.ts +129 -0
  119. package/src/components/DatePicker/composables/useDatePickerValidationBridge.ts +205 -0
  120. package/src/components/DatePicker/docExamples/BidirectionalComplexValidation.vue +1 -1
  121. package/src/components/DatePicker/docExamples/DatePickerBidirectionalValidation.vue +1 -1
  122. package/src/components/DatePicker/tests/exposed-methods.coverage.spec.ts +75 -0
  123. package/src/components/DialogBox/DialogBox.vue +1 -1
  124. package/src/components/FileList/UploadItem/UploadItem.vue +4 -4
  125. package/src/components/FileUpload/FileUpload.vue +2 -2
  126. package/src/components/FileUpload/FileUploadContent.vue +1 -1
  127. package/src/components/FilterInline/FilterInline.mdx +2 -2
  128. package/src/components/FilterSideBar/FilterSideBar.stories.ts +1 -1
  129. package/src/components/FilterSideBar/FilterSideBar.vue +2 -2
  130. package/src/components/FooterBar/FooterBar.vue +7 -7
  131. package/src/components/FranceConnectBtn/FranceConnectBtn.vue +1 -1
  132. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +2 -2
  133. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +7 -7
  134. package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +2 -2
  135. package/src/components/HeaderLoading/tests/HeaderLoading.spec.ts +87 -8
  136. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +3 -3
  137. package/src/components/HeaderNavigationBar/HorizontalNavbar/tests/HorizontalNavbar.spec.ts +589 -0
  138. package/src/components/HeaderToolbar/tests/HeaderToolBar.spec.ts +153 -1
  139. package/src/components/HeaderToolbar/tests/useMobileRightMenu.spec.ts +258 -0
  140. package/src/components/LogoBrandSection/tests/LogoBrandSection.spec.ts +2 -2
  141. package/src/components/LogoBrandSection/tests/__snapshots__/LogoBrandSection.spec.ts.snap +1 -1
  142. package/src/components/LunarCalendar/tests/useLunarCalendarRules.spec.ts +184 -0
  143. package/src/components/MonthPicker/MonthPickerVisual/MonthSelector.vue +3 -3
  144. package/src/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.vue +1 -1
  145. package/src/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.vue +2 -2
  146. package/src/components/MonthPicker/MonthPickerVisual/YearSelector.vue +1 -1
  147. package/src/components/NirField/NirField.vue +3 -3
  148. package/src/components/NotificationBar/Notification/Notification.vue +12 -12
  149. package/src/components/NotificationBar/NotificationBar.stories.ts +8 -8
  150. package/src/components/PaginatedTable/Pagination.vue +2 -2
  151. package/src/components/PasswordField/PasswordField.vue +8 -8
  152. package/src/components/PasswordField/tests/PasswordField.spec.ts +3 -3
  153. package/src/components/RangeField/RangeSlider/RangeSlider.vue +2 -2
  154. package/src/components/RangeField/RangeSlider/Tooltip/Tooltip.vue +1 -1
  155. package/src/components/StatusPage/tests/StatusPage.spec.ts +149 -0
  156. package/src/components/SubHeader/SubHeader.vue +1 -1
  157. package/src/components/SyAlert/SyAlert.vue +23 -23
  158. package/src/components/SyTextArea/SyTextArea.stories.ts +177 -131
  159. package/src/components/SyTextArea/SyTextArea.vue +235 -83
  160. package/src/components/SyTextArea/composables/useSyTextAreaValidation.ts +81 -0
  161. package/src/components/SyTextArea/locales.ts +1 -0
  162. package/src/components/SyTextArea/tests/SyTextArea.spec.ts +449 -1
  163. package/src/components/SyTextArea/useDefaultValidationRules.ts +2 -7
  164. package/src/components/SyTextArea/validation/Validation.stories.ts +856 -0
  165. package/src/components/TableToolbar/TableToolbar.vue +6 -6
  166. package/src/components/TableToolbar/accessibilite/Accessibility.mdx +81 -7
  167. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +163 -0
  168. package/src/components/Tables/SyServerTable/SyServerTable.vue +2 -1
  169. package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +67 -0
  170. package/src/components/Tables/SyTable/SyTable.stories.ts +94 -0
  171. package/src/components/Tables/SyTable/SyTable.vue +2 -1
  172. package/src/components/Tables/SyTable/tests/SyTable.spec.ts +64 -0
  173. package/src/components/Tables/common/TableHeader.vue +2 -2
  174. package/src/components/Tables/common/filters/logics/tests/NumberFilterLogic.spec.ts +176 -0
  175. package/src/components/Tables/common/filters/logics/tests/SelectFilterLogic.spec.ts +111 -0
  176. package/src/components/Tables/common/tableStyles.scss +6 -6
  177. package/src/components/Tables/common/types.ts +2 -0
  178. package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +2 -0
  179. package/src/components/index.ts +1 -0
  180. package/src/composables/date/tests/useDateFormatDayjs.spec.ts +31 -0
  181. package/src/composables/date/tests/useHolidayDay.spec.ts +109 -0
  182. package/src/composables/rules/tests/useFieldValidation.spec.ts +374 -0
  183. package/src/composables/tests/useError.spec.ts +30 -0
  184. package/src/composables/tests/useFormFieldErrorHandling.spec.ts +234 -0
  185. package/src/composables/unifyValidation/documentationValidationProps.ts +5 -5
  186. package/src/composables/unifyValidation/tests/documentationValidationProps.spec.ts +177 -0
  187. package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +30 -0
  188. package/src/composables/unifyValidation/tests/useValidation.spec.ts +6 -2
  189. package/src/composables/unifyValidation/useCustomValidation.ts +19 -9
  190. package/src/composables/unifyValidation/useValidation.ts +18 -21
  191. package/src/composables/useFilterable/useFilterable.spec.ts +42 -0
  192. package/src/composables/useFilterable/useFilterable.ts +11 -7
  193. package/src/composables/useFormFieldErrorHandling.ts +2 -2
  194. package/src/composantsVuetify/VBtn/VBtn.mdx +9 -39
  195. package/src/composantsVuetify/VBtn/v-btn.stories.ts +26 -86
  196. package/src/designTokens/tokens/amelipro/apContextual.ts +6 -0
  197. package/src/designTokens/tokens/amelipro/apDarkTheme.ts +2 -2
  198. package/src/designTokens/tokens/amelipro/apLightTheme.ts +72 -103
  199. package/src/designTokens/tokens/amelipro/apSemantic.ts +1 -1
  200. package/src/designTokens/tokens/baseContextualTokens.ts +1 -6
  201. package/src/designTokens/tokens/baseTokens.ts +232 -0
  202. package/src/designTokens/tokens/cnam/cnamContextual.ts +6 -0
  203. package/src/designTokens/tokens/cnam/cnamDarkTheme.ts +2 -2
  204. package/src/designTokens/tokens/cnam/cnamLightTheme.ts +76 -104
  205. package/src/designTokens/tokens/pa/paDarkTheme.ts +2 -2
  206. package/src/designTokens/tokens/pa/paLightTheme.ts +73 -99
  207. package/src/designTokens/tokens/pa/paSemantic.ts +2 -0
  208. package/src/designTokens/tokens/semanticTokens.ts +114 -0
  209. package/src/stories/Components/Components.stories.ts +7 -3
  210. package/src/stories/DesignTokens/ColorIntegrationExample.vue +2 -3
  211. package/src/stories/DesignTokens/Colors.mdx +6 -8
  212. package/src/stories/DesignTokens/colors.stories.ts +244 -1081
  213. package/src/utils/amelipro/toKebabCase/tests/toKebabCase.spec.ts +52 -0
  214. package/src/utils/formatNir/tests/formatNir.spec.ts +34 -0
  215. package/src/utils/tests/insertAt.spec.ts +44 -0
  216. package/dist/apLightTheme-DS0Uy44H.js +0 -954
  217. package/dist/components/RatingPicker/tests/RatingPicker.a11y.spect.d.ts +0 -1
  218. package/dist/main-BsJ9ec3i.js +0 -38954
  219. package/src/components/BackBtn/tests/__snapshots__/back-btn-custom-bg.snap.png +0 -0
  220. package/src/components/BackBtn/tests/__snapshots__/back-btn-dark-mode.snap.png +0 -0
  221. package/src/components/BackBtn/tests/__snapshots__/back-btn-default.snap.png +0 -0
  222. package/src/components/BackBtn/tests/__snapshots__/back-btn-no-icon.snap.png +0 -0
  223. package/src/components/DatePicker/CalendarMode/tests/DatePicker.events.spec.ts +0 -178
  224. package/src/components/DialogBox/tests/__snapshots__/dialog-box-custom-texts.snap.png +0 -0
  225. package/src/components/DialogBox/tests/__snapshots__/dialog-box-default.snap.png +0 -0
  226. package/src/components/DialogBox/tests/__snapshots__/dialog-box-no-actions.snap.png +0 -0
  227. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated-submenu-open.snap.png +0 -0
  228. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated.snap.png +0 -0
  229. package/src/components/HeaderBar/tests/__snapshots__/header-bar-custom-width.snap.png +0 -0
  230. package/src/components/HeaderBar/tests/__snapshots__/header-bar-default.snap.png +0 -0
  231. package/src/components/HeaderBar/tests/__snapshots__/header-bar-no-sticky.snap.png +0 -0
  232. package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-prepend.snap.png +0 -0
  233. package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-side.snap.png +0 -0
  234. package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-subtitle.snap.png +0 -0
  235. package/src/components/Logo/tests/__snapshots__/logo-avatar.snap.png +0 -0
  236. package/src/components/Logo/tests/__snapshots__/logo-dark.snap.png +0 -0
  237. package/src/components/Logo/tests/__snapshots__/logo-default.snap.png +0 -0
  238. package/src/components/Logo/tests/__snapshots__/logo-no-organism.snap.png +0 -0
  239. package/src/components/Logo/tests/__snapshots__/logo-no-signature.snap.png +0 -0
  240. package/src/components/Logo/tests/__snapshots__/logo-risque-pro.snap.png +0 -0
  241. package/src/components/RangeField/tests/__snapshots__/range-field-custom-bg.snap.png +0 -0
  242. package/src/components/RangeField/tests/__snapshots__/range-field-custom-range.snap.png +0 -0
  243. package/src/components/RangeField/tests/__snapshots__/range-field-default.snap.png +0 -0
  244. package/src/components/RangeField/tests/__snapshots__/range-field-step.snap.png +0 -0
  245. package/src/components/RangeField/tests/__snapshots__/range-field-with-label.snap.png +0 -0
  246. package/src/components/SyAlert/tests/__snapshots__/sy-alert-closable.snap.png +0 -0
  247. package/src/components/SyAlert/tests/__snapshots__/sy-alert-error.snap.png +0 -0
  248. package/src/components/SyAlert/tests/__snapshots__/sy-alert-info.snap.png +0 -0
  249. package/src/components/SyAlert/tests/__snapshots__/sy-alert-success.snap.png +0 -0
  250. package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-outlined.snap.png +0 -0
  251. package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-tonal.snap.png +0 -0
  252. package/src/components/SyAlert/tests/__snapshots__/sy-alert-warning.snap.png +0 -0
  253. /package/src/components/RatingPicker/tests/{RatingPicker.a11y.spect.ts → RatingPicker.a11y.spec.ts} +0 -0
@@ -0,0 +1,1026 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import SySelect from '../SySelect.vue'
3
+ import SyForm from '../../../SyForm/SyForm.vue'
4
+ import { computed, ref, onMounted } from 'vue'
5
+ import { fn } from '@storybook/test'
6
+ import { VBtn, VForm } from 'vuetify/components'
7
+
8
+ const meta: Meta<typeof SySelect> = {
9
+ title: 'Composants/Formulaires/Selects/SySelect/Validation',
10
+ component: SySelect,
11
+ parameters: {
12
+ layout: 'fullscreen',
13
+ },
14
+ args: {
15
+ 'onUpdate:modelValue': fn(),
16
+ },
17
+ } as Meta<typeof SySelect>
18
+
19
+ export default meta
20
+
21
+ type Story = StoryObj<typeof meta>
22
+
23
+ const items = [
24
+ { text: 'Option 1', value: '1' },
25
+ { text: 'Option 2', value: '2' },
26
+ { text: 'Option 3', value: '3' },
27
+ ]
28
+
29
+ export const WithError: Story = {
30
+ parameters: {
31
+ docs: {
32
+ description: {
33
+ story: '« Option 1 » est présélectionnée et déclenche une erreur bloquante au chargement.',
34
+ },
35
+ },
36
+ sourceCode: [
37
+ {
38
+ name: 'Template',
39
+ code: `
40
+ <template>
41
+ <SySelect
42
+ ref="selectRef"
43
+ v-model="value"
44
+ :items="items"
45
+ label="Option"
46
+ :customRules="[
47
+ {
48
+ type: 'custom',
49
+ options: {
50
+ validate: (v) => v !== '1',
51
+ message: 'Option 1 n\\'est pas autorisée, choisissez Option 2 ou 3.'
52
+ }
53
+ }
54
+ ]"
55
+ />
56
+ </template>`,
57
+ },
58
+ {
59
+ name: 'Script',
60
+ code: `
61
+ <script setup lang="ts">
62
+ import { onMounted, ref } from 'vue'
63
+ import { SySelect } from '@cnamts/synapse'
64
+ const value = ref('1')
65
+ const items = [
66
+ { text: 'Option 1', value: '1' },
67
+ { text: 'Option 2', value: '2' },
68
+ { text: 'Option 3', value: '3' },
69
+ ]
70
+
71
+ const selectRef = ref(null)
72
+
73
+ onMounted(() => {
74
+ selectRef.value?.validateOnSubmit()
75
+ })
76
+ </script>`,
77
+ },
78
+ ],
79
+ },
80
+ args: {
81
+ 'items': items,
82
+ 'label': 'Option',
83
+ 'onUpdate:modelValue': fn(),
84
+ },
85
+ render: args => ({
86
+ components: { SySelect },
87
+ setup() {
88
+ const value = ref('1')
89
+ const selectRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
90
+
91
+ onMounted(() => {
92
+ selectRef.value?.validateOnSubmit()
93
+ })
94
+
95
+ return { args, value, selectRef }
96
+ },
97
+ template: `
98
+ <div class="pa-4">
99
+ <SySelect
100
+ ref="selectRef"
101
+ v-model="value"
102
+ v-bind="args"
103
+ :customRules="[
104
+ {
105
+ type: 'custom',
106
+ options: {
107
+ validate: (v) => v !== '1',
108
+ message: 'Option 1 n\\'est pas autorisée, choisissez Option 2 ou 3.'
109
+ }
110
+ }
111
+ ]"
112
+ />
113
+ </div>
114
+ `,
115
+ }),
116
+ }
117
+
118
+ export const WithWarning: Story = {
119
+ parameters: {
120
+ docs: {
121
+ description: {
122
+ story: '« Option 1 » est présélectionnée et déclenche un avertissement (non bloquant) au chargement.',
123
+ },
124
+ },
125
+ sourceCode: [
126
+ {
127
+ name: 'Template',
128
+ code: `
129
+ <template>
130
+ <SySelect
131
+ ref="selectRef"
132
+ v-model="value"
133
+ :items="items"
134
+ label="Option"
135
+ :customWarningRules="[
136
+ {
137
+ type: 'custom',
138
+ options: {
139
+ validate: (v) => v !== '1',
140
+ message: 'Option 1 est dépréciée, préférez Option 2 ou 3.'
141
+ }
142
+ }
143
+ ]"
144
+ />
145
+ </template>`,
146
+ },
147
+ {
148
+ name: 'Script',
149
+ code: `
150
+ <script setup lang="ts">
151
+ import { ref } from 'vue'
152
+ import { SySelect } from '@cnamts/synapse'
153
+ const value = ref<string | null>(null)
154
+ const items = [
155
+ { text: 'Option 1', value: '1' },
156
+ { text: 'Option 2', value: '2' },
157
+ { text: 'Option 3', value: '3' },
158
+ ]
159
+ </script>`,
160
+ },
161
+ ],
162
+ },
163
+ args: {
164
+ 'items': items,
165
+ 'label': 'Option',
166
+ 'onUpdate:modelValue': fn(),
167
+ },
168
+ render: args => ({
169
+ components: { SySelect },
170
+ setup() {
171
+ const value = ref('1')
172
+ const selectRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
173
+
174
+ onMounted(() => {
175
+ selectRef.value?.validateOnSubmit()
176
+ })
177
+
178
+ return { args, value, selectRef }
179
+ },
180
+ template: `
181
+ <div class="pa-4">
182
+ <SySelect
183
+ ref="selectRef"
184
+ v-model="value"
185
+ v-bind="args"
186
+ :customWarningRules="[
187
+ {
188
+ type: 'custom',
189
+ options: {
190
+ validate: (v) => v !== '1',
191
+ message: 'Option 1 est dépréciée, préférez Option 2 ou 3.'
192
+ }
193
+ }
194
+ ]"
195
+ />
196
+ </div>
197
+ `,
198
+ }),
199
+ }
200
+
201
+ export const WithSuccess: Story = {
202
+ parameters: {
203
+ docs: {
204
+ description: {
205
+ story: 'Une option est présélectionnée et déclenche la confirmation de succès au chargement.',
206
+ },
207
+ },
208
+ sourceCode: [
209
+ {
210
+ name: 'Template',
211
+ code: `
212
+ <template>
213
+ <SySelect
214
+ ref="selectRef"
215
+ v-model="value"
216
+ :items="items"
217
+ label="Option"
218
+ show-success-messages
219
+ :customSuccessRules="[
220
+ {
221
+ type: 'custom',
222
+ options: {
223
+ validate: (v) => v !== null && v !== undefined,
224
+ message: 'Option sélectionnée avec succès.'
225
+ }
226
+ }
227
+ ]"
228
+ />
229
+ </template>`,
230
+ },
231
+ {
232
+ name: 'Script',
233
+ code: `
234
+ <script setup lang="ts">
235
+ import { ref } from 'vue'
236
+ import { SySelect } from '@cnamts/synapse'
237
+ const value = ref(null)
238
+ const items = [
239
+ { text: 'Option 1', value: '1' },
240
+ { text: 'Option 2', value: '2' },
241
+ { text: 'Option 3', value: '3' },
242
+ ]
243
+ </script>`,
244
+ },
245
+ ],
246
+ },
247
+ args: {
248
+ 'items': items,
249
+ 'label': 'Option',
250
+ 'showSuccessMessages': true,
251
+ 'onUpdate:modelValue': fn(),
252
+ },
253
+ render: args => ({
254
+ components: { SySelect },
255
+ setup() {
256
+ const value = ref('1')
257
+ const selectRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
258
+
259
+ onMounted(() => {
260
+ selectRef.value?.validateOnSubmit()
261
+ })
262
+
263
+ return { args, value, selectRef }
264
+ },
265
+ template: `
266
+ <div class="pa-4">
267
+ <SySelect
268
+ ref="selectRef"
269
+ v-model="value"
270
+ v-bind="args"
271
+ :customSuccessRules="[
272
+ {
273
+ type: 'custom',
274
+ options: {
275
+ validate: (v) => v !== null && v !== undefined,
276
+ message: 'Option sélectionnée avec succès.'
277
+ }
278
+ }
279
+ ]"
280
+ />
281
+ </div>
282
+ `,
283
+ }),
284
+ }
285
+
286
+ export const NoSuccessMessage: Story = {
287
+ parameters: {
288
+ docs: {
289
+ description: {
290
+ story: 'Avec `showSuccessMessages: false`, l\'état visuel de succès reste actif (bordure verte, icône) mais le message texte n\'est pas affiché. Utile quand un retour positif silencieux est suffisant.',
291
+ },
292
+ },
293
+ sourceCode: [
294
+ {
295
+ name: 'Template',
296
+ code: `
297
+ <template>
298
+ <SySelect
299
+ ref="selectRef"
300
+ v-model="value"
301
+ :items="items"
302
+ label="Option"
303
+ :show-success-messages="false"
304
+ :customSuccessRules="[
305
+ {
306
+ type: 'custom',
307
+ options: {
308
+ validate: (v) => v !== null && v !== undefined,
309
+ successMessage: 'Option sélectionnée avec succès.'
310
+ }
311
+ }
312
+ ]"
313
+ />
314
+ </template>`,
315
+ },
316
+ {
317
+ name: 'Script',
318
+ code: `
319
+ <script setup lang="ts">
320
+ import { onMounted, ref } from 'vue'
321
+ import { SySelect } from '@cnamts/synapse'
322
+
323
+ const value = ref('1')
324
+ const items = [
325
+ { text: 'Option 1', value: '1' },
326
+ { text: 'Option 2', value: '2' },
327
+ { text: 'Option 3', value: '3' },
328
+ ]
329
+
330
+ const selectRef = ref(null)
331
+
332
+ onMounted(() => {
333
+ selectRef.value?.validateOnSubmit()
334
+ })
335
+ </script>`,
336
+ },
337
+ ],
338
+ },
339
+ args: {
340
+ 'items': items,
341
+ 'label': 'Option',
342
+ 'showSuccessMessages': false,
343
+ 'onUpdate:modelValue': fn(),
344
+ },
345
+ render: args => ({
346
+ components: { SySelect },
347
+ setup() {
348
+ const value = ref('1')
349
+ const selectRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
350
+
351
+ onMounted(() => {
352
+ selectRef.value?.validateOnSubmit()
353
+ })
354
+
355
+ return { args, value, selectRef }
356
+ },
357
+ template: `
358
+ <div class="pa-4">
359
+ <SySelect
360
+ ref="selectRef"
361
+ v-model="value"
362
+ v-bind="args"
363
+ :customSuccessRules="[
364
+ {
365
+ type: 'custom',
366
+ options: {
367
+ validate: (v) => v !== null && v !== undefined,
368
+ successMessage: 'Option sélectionnée avec succès.'
369
+ }
370
+ }
371
+ ]"
372
+ />
373
+ </div>
374
+ `,
375
+ }),
376
+ }
377
+
378
+ export const NoValidateOnBlur: Story = {
379
+ parameters: {
380
+ docs: {
381
+ description: {
382
+ story: 'Dans cette story, une sélection directe garde le composant dans un état neutre. Seuls les boutons activent un scénario de validation visible.',
383
+ },
384
+ },
385
+ sourceCode: [
386
+ {
387
+ name: 'Template',
388
+ code: `
389
+ <template>
390
+ <div class="d-flex flex-column gap-4 pa-4">
391
+ <SySelect
392
+ ref="selectRef"
393
+ :model-value="value"
394
+ :items="items"
395
+ label="Option"
396
+ :is-validate-on-blur="false"
397
+ :show-success-messages="true"
398
+ :custom-rules="customRules"
399
+ :custom-success-rules="customSuccessRules"
400
+ @update:model-value="handleManualChange"
401
+ />
402
+ <div class="d-flex gap-4 mt-2">
403
+ <VBtn color="primary" class="mr-1" @mousedown.prevent @click="applyButtonValue('1')">Définir une valeur invalide</VBtn>
404
+ <VBtn color="primary" class="mr-1" @mousedown.prevent @click="applyButtonValue('2')">Définir une valeur valide</VBtn>
405
+ <VBtn @mousedown.prevent @click="applyButtonValue(null)">Réinitialiser</VBtn>
406
+ </div>
407
+ </div>
408
+ </template>`,
409
+ },
410
+ {
411
+ name: 'Script',
412
+ code: `
413
+ <script setup lang="ts">
414
+ import { computed, ref } from 'vue'
415
+ import { SySelect } from '@cnamts/synapse'
416
+ import { VBtn } from 'vuetify/components'
417
+
418
+ const value = ref(null)
419
+ const selectRef = ref(null)
420
+ const validationMode = ref('neutral')
421
+ const items = [
422
+ { text: 'Option 1', value: '1' },
423
+ { text: 'Option 2', value: '2' },
424
+ { text: 'Option 3', value: '3' },
425
+ ]
426
+
427
+ const customRules = computed(() => validationMode.value === 'invalid'
428
+ ? [{
429
+ type: 'custom',
430
+ options: {
431
+ validate: (v) => v !== '1',
432
+ message: "Option 1 n'est pas autorisée."
433
+ }
434
+ }]
435
+ : [])
436
+
437
+ const customSuccessRules = computed(() => {
438
+ if (validationMode.value === 'neutral') {
439
+ return [{
440
+ type: 'custom',
441
+ options: {
442
+ validate: () => false
443
+ }
444
+ }]
445
+ }
446
+
447
+ if (validationMode.value === 'valid') {
448
+ return [{
449
+ type: 'custom',
450
+ options: {
451
+ validate: (v) => v !== null && v !== undefined,
452
+ successMessage: 'Option sélectionnée avec succès.'
453
+ }
454
+ }]
455
+ }
456
+
457
+ return []
458
+ })
459
+
460
+ const handleManualChange = (newValue) => {
461
+ validationMode.value = 'neutral'
462
+ value.value = newValue
463
+ }
464
+
465
+ const applyButtonValue = async (newValue) => {
466
+ validationMode.value = newValue === '1' ? 'invalid' : newValue ? 'valid' : 'neutral'
467
+ value.value = newValue
468
+ await selectRef.value?.validateOnSubmit()
469
+ }
470
+ </script>`,
471
+ },
472
+ ],
473
+ },
474
+ args: {
475
+ items,
476
+ label: 'Option',
477
+ isValidateOnBlur: false,
478
+ showSuccessMessages: true,
479
+ },
480
+ render: (args) => {
481
+ return {
482
+ components: { SySelect, VBtn },
483
+ setup() {
484
+ const value = ref<string | null>(null)
485
+ const selectRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
486
+ const validationMode = ref<'neutral' | 'invalid' | 'valid'>('neutral')
487
+
488
+ const customRules = computed(() => validationMode.value === 'invalid'
489
+ ? [{
490
+ type: 'custom',
491
+ options: {
492
+ validate: (v: string | null) => v !== '1',
493
+ message: 'Option 1 n\'est pas autorisée.',
494
+ },
495
+ }]
496
+ : [])
497
+
498
+ const customSuccessRules = computed(() => {
499
+ if (validationMode.value === 'neutral') {
500
+ return [{
501
+ type: 'custom',
502
+ options: {
503
+ validate: () => false,
504
+ },
505
+ }]
506
+ }
507
+
508
+ if (validationMode.value === 'valid') {
509
+ return [{
510
+ type: 'custom',
511
+ options: {
512
+ validate: (v: string | null) => v !== null && v !== undefined,
513
+ successMessage: 'Option sélectionnée avec succès.',
514
+ },
515
+ }]
516
+ }
517
+
518
+ return []
519
+ })
520
+
521
+ const handleManualChange = (newValue: string | null) => {
522
+ validationMode.value = 'neutral'
523
+ value.value = newValue
524
+ }
525
+
526
+ const applyButtonValue = async (newValue: string | null) => {
527
+ validationMode.value = newValue === '1' ? 'invalid' : newValue ? 'valid' : 'neutral'
528
+ value.value = newValue
529
+ await selectRef.value?.validateOnSubmit()
530
+ }
531
+
532
+ return { args, value, selectRef, customRules, customSuccessRules, handleManualChange, applyButtonValue }
533
+ },
534
+ template: `
535
+ <div class="d-flex flex-column gap-4 pa-4">
536
+ <SySelect
537
+ ref="selectRef"
538
+ :model-value="value"
539
+ v-bind="args"
540
+ :custom-rules="customRules"
541
+ :custom-success-rules="customSuccessRules"
542
+ @update:model-value="handleManualChange"
543
+ />
544
+ <div class="d-flex gap-4 mt-2">
545
+ <VBtn color="primary" class="mr-1" @mousedown.prevent @click="applyButtonValue('1')">Définir une valeur invalide</VBtn>
546
+ <VBtn color="primary" class="mr-1" @mousedown.prevent @click="applyButtonValue('2')">Définir une valeur valide</VBtn>
547
+ <VBtn @mousedown.prevent @click="applyButtonValue(null)">Réinitialiser</VBtn>
548
+ </div>
549
+ </div>
550
+ `,
551
+ }
552
+ },
553
+ }
554
+
555
+ export const DisableErrorHandling: Story = {
556
+ parameters: {
557
+ sourceCode: [
558
+ {
559
+ name: 'Template',
560
+ code: `
561
+ <template>
562
+ <div class="d-flex flex-column gap-4">
563
+ <SySelect
564
+ v-model="value1"
565
+ :items="items"
566
+ label="Avec validation interne (défaut)"
567
+ required
568
+ />
569
+
570
+ <SySelect
571
+ v-model="value2"
572
+ :items="items"
573
+ label="Validation interne désactivée"
574
+ required
575
+ disable-error-handling
576
+ />
577
+ </div>
578
+ </template>`,
579
+ },
580
+ {
581
+ name: 'Script',
582
+ code: `
583
+ <script setup lang="ts">
584
+ import { ref } from 'vue'
585
+ import { SySelect } from '@cnamts/synapse'
586
+
587
+ const items = [
588
+ { text: 'Option 1', value: '1' },
589
+ { text: 'Option 2', value: '2' },
590
+ { text: 'Option 3', value: '3' },
591
+ ]
592
+
593
+ const value1 = ref(null)
594
+ const value2 = ref(null)
595
+ </script>`,
596
+ },
597
+ ],
598
+ },
599
+ args: {
600
+ items,
601
+ },
602
+ render: (args) => {
603
+ return {
604
+ components: { SySelect },
605
+ setup() {
606
+ const value1 = ref(null)
607
+ const value2 = ref(null)
608
+ return { args, value1, value2 }
609
+ },
610
+ template: `
611
+ <div class="pa-4 d-flex flex-column" style="gap: 16px;">
612
+ <SySelect
613
+ v-model="value1"
614
+ v-bind="args"
615
+ label="Avec validation interne (défaut)"
616
+ required
617
+ />
618
+ <SySelect
619
+ v-model="value2"
620
+ v-bind="args"
621
+ label="Validation interne désactivée"
622
+ required
623
+ disable-error-handling
624
+ />
625
+ </div>
626
+ `,
627
+ }
628
+ },
629
+ }
630
+
631
+ export const SyFormValidation: Story = {
632
+ parameters: {
633
+ docs: {
634
+ description: {
635
+ story: 'Exemple d\'utilisation du SySelect dans un formulaire.',
636
+ },
637
+ },
638
+ sourceCode: [
639
+ {
640
+ name: 'Template',
641
+ code: `
642
+ <template>
643
+ <SyForm @submit="onSubmit">
644
+ <SySelect
645
+ v-model="formData.option"
646
+ :items="options"
647
+ label="Option"
648
+ required
649
+ display-asterisk
650
+ class="mb-4"
651
+ />
652
+ <VBtn
653
+ type="submit"
654
+ color="primary"
655
+ class="mt-4"
656
+ >
657
+ Soumettre
658
+ </VBtn>
659
+ </SyForm>
660
+ </template>
661
+ `,
662
+ },
663
+ {
664
+ name: 'Script',
665
+ code: `
666
+ <script setup lang="ts">
667
+ import { ref } from 'vue'
668
+ import { SySelect, SyForm } from '@cnamts/synapse'
669
+ import { VBtn } from 'vuetify/components'
670
+
671
+ const formData = ref({
672
+ option: ''
673
+ })
674
+
675
+ const options = [
676
+ { text: 'Option 1', value: '1' },
677
+ { text: 'Option 2', value: '2' },
678
+ { text: 'Option 3', value: '3' },
679
+ ]
680
+
681
+ const onSubmit = (event) => {
682
+ if (event.isValid) {
683
+ alert('Formulaire valide : ' + JSON.stringify(formData.value))
684
+ } else {
685
+ alert('Formulaire invalide : veuillez choisir une option.')
686
+ }
687
+ }
688
+ </script>
689
+ `,
690
+ },
691
+ ],
692
+ },
693
+ args: {
694
+ 'items': items,
695
+ 'label': 'Option',
696
+ 'required': true,
697
+ 'displayAsterisk': true,
698
+ 'onUpdate:modelValue': fn(),
699
+ },
700
+ render: (args) => {
701
+ return {
702
+ components: { SySelect, SyForm, VBtn },
703
+ setup() {
704
+ const formData = ref({
705
+ option: '',
706
+ })
707
+
708
+ const onSubmit = (event: { isValid: boolean }) => {
709
+ if (event.isValid) {
710
+ alert(`Formulaire valide : ${JSON.stringify(formData.value)}`)
711
+ }
712
+ else {
713
+ alert('Formulaire invalide : veuillez choisir une option.')
714
+ }
715
+ }
716
+
717
+ return { args, formData, onSubmit }
718
+ },
719
+ template: `
720
+ <div class="pa-4">
721
+ <SyForm @submit="onSubmit">
722
+ <SySelect
723
+ v-model="formData.option"
724
+ v-bind="args"
725
+ class="mb-4"
726
+ />
727
+ <VBtn
728
+ type="submit"
729
+ color="primary"
730
+ class="mt-4"
731
+ >
732
+ Soumettre
733
+ </VBtn>
734
+ </SyForm>
735
+ </div>
736
+ `,
737
+ }
738
+ },
739
+ }
740
+
741
+ export const VFormValidation: Story = {
742
+ parameters: {
743
+ docs: {
744
+ description: {
745
+ story: 'Intégration avec `VForm` natif Vuetify en conservant la validation Synapse. La soumission appelle `validateOnSubmit()` manuellement sur le champ pour déclencher la validation.',
746
+ },
747
+ },
748
+ sourceCode: [
749
+ {
750
+ name: 'Template',
751
+ code: `
752
+ <template>
753
+ <VForm @submit.prevent="onSubmit">
754
+ <SySelect
755
+ ref="selectRef"
756
+ v-model="value"
757
+ :items="items"
758
+ label="Option obligatoire"
759
+ required
760
+ display-asterisk
761
+ class="mb-4"
762
+ />
763
+ <VBtn type="submit" color="primary">Soumettre</VBtn>
764
+ </VForm>
765
+ </template>`,
766
+ },
767
+ {
768
+ name: 'Script',
769
+ code: `
770
+ <script setup lang="ts">
771
+ import { ref } from 'vue'
772
+ import { SySelect } from '@cnamts/synapse'
773
+ import { VBtn, VForm } from 'vuetify/components'
774
+
775
+ const value = ref('')
776
+ const selectRef = ref(null)
777
+ const items = [
778
+ { text: 'Option 1', value: '1' },
779
+ { text: 'Option 2', value: '2' },
780
+ { text: 'Option 3', value: '3' },
781
+ ]
782
+
783
+ async function onSubmit() {
784
+ const isValid = await selectRef.value?.validateOnSubmit()
785
+ if (isValid) {
786
+ alert('Formulaire valide : ' + JSON.stringify(value.value))
787
+ } else {
788
+ alert('Formulaire invalide : veuillez choisir une option.')
789
+ }
790
+ }
791
+ </script>`,
792
+ },
793
+ ],
794
+ },
795
+ args: {
796
+ items,
797
+ label: 'Option obligatoire',
798
+ required: true,
799
+ displayAsterisk: true,
800
+ },
801
+ render: (args) => {
802
+ return {
803
+ components: { SySelect, VBtn, VForm },
804
+ setup() {
805
+ const value = ref('')
806
+ const selectRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
807
+
808
+ async function onSubmit() {
809
+ const isValid = await selectRef.value?.validateOnSubmit()
810
+ if (isValid) {
811
+ alert(`Formulaire valide : ${JSON.stringify(value.value)}`)
812
+ }
813
+ else {
814
+ alert('Formulaire invalide : veuillez choisir une option.')
815
+ }
816
+ }
817
+
818
+ return { args, value, selectRef, onSubmit }
819
+ },
820
+ template: `
821
+ <div class="pa-4">
822
+ <VForm @submit.prevent="onSubmit">
823
+ <SySelect
824
+ ref="selectRef"
825
+ v-model="value"
826
+ v-bind="args"
827
+ class="mb-4"
828
+ />
829
+ <VBtn type="submit" color="primary">Soumettre</VBtn>
830
+ </VForm>
831
+ </div>
832
+ `,
833
+ }
834
+ },
835
+ }
836
+
837
+ export const SyFormVuetifyValidation: Story = {
838
+ parameters: {
839
+ docs: {
840
+ description: {
841
+ story: 'Exemple d\'utilisation de la validation native Vuetify via la prop `useVuetifyValidation`. Les règles sont définies au format Vuetify : des fonctions retournant `true` ou un message d\'erreur. Soumettez le formulaire pour déclencher la validation.',
842
+ },
843
+ },
844
+ sourceCode: [
845
+ {
846
+ name: 'Template',
847
+ code: `
848
+ <template>
849
+ <SyForm @submit="onSubmit">
850
+ <SySelect
851
+ v-model="value"
852
+ :items="items"
853
+ label="Option"
854
+ use-vuetify-validation
855
+ :show-success-messages="false"
856
+ :rules="[v => !!v || 'Ce champ est requis']"
857
+ />
858
+ <VBtn type="submit" color="primary" class="mt-4">
859
+ Soumettre
860
+ </VBtn>
861
+ </SyForm>
862
+ </template>`,
863
+ },
864
+ {
865
+ name: 'Script',
866
+ code: `
867
+ <script setup lang="ts">
868
+ import { ref } from 'vue'
869
+ import { SySelect, SyForm } from '@cnamts/synapse'
870
+ import { VBtn } from 'vuetify/components'
871
+
872
+ const value = ref(null)
873
+ const items = [
874
+ { text: 'Option 1', value: '1' },
875
+ { text: 'Option 2', value: '2' },
876
+ { text: 'Option 3', value: '3' },
877
+ ]
878
+
879
+ function onSubmit(event: { isValid: boolean }) {
880
+ if (event.isValid) {
881
+ alert('Formulaire valide : ' + value.value)
882
+ } else {
883
+ alert('Formulaire invalide : veuillez choisir une option.')
884
+ }
885
+ }
886
+ </script>`,
887
+ },
888
+ ],
889
+ },
890
+ args: {
891
+ 'items': items,
892
+ 'label': 'Option',
893
+ 'useVuetifyValidation': true,
894
+ 'showSuccessMessages': false,
895
+ 'onUpdate:modelValue': fn(),
896
+ },
897
+ render: args => ({
898
+ components: { SySelect, SyForm, VBtn },
899
+ setup() {
900
+ const value = ref(null)
901
+
902
+ function onSubmit(event: { isValid: boolean }) {
903
+ if (event.isValid) {
904
+ alert(`Formulaire valide : ${value.value}`)
905
+ }
906
+ else {
907
+ alert('Formulaire invalide : veuillez choisir une option.')
908
+ }
909
+ }
910
+
911
+ return { args, value, onSubmit }
912
+ },
913
+ template: `
914
+ <div class="pa-4">
915
+ <SyForm @submit="onSubmit">
916
+ <SySelect
917
+ v-model="value"
918
+ v-bind="args"
919
+ :rules="[v => !!v || 'Ce champ est requis']"
920
+ />
921
+ <VBtn
922
+ type="submit"
923
+ color="primary"
924
+ class="mt-4"
925
+ >
926
+ Soumettre
927
+ </VBtn>
928
+ </SyForm>
929
+ </div>
930
+ `,
931
+ }),
932
+ }
933
+
934
+ export const VFormAndVuetifyValidation: Story = {
935
+ parameters: {
936
+ docs: {
937
+ description: {
938
+ story: 'Validation native Vuetify (`useVuetifyValidation`) intégrée dans un `VForm` natif (sans SyForm). La soumission du formulaire déclenche la validation via `form.validate()`.',
939
+ },
940
+ },
941
+ sourceCode: [
942
+ {
943
+ name: 'Template',
944
+ code: `
945
+ <template>
946
+ <VForm ref="formRef" @submit.prevent="onSubmit">
947
+ <SySelect
948
+ v-model="value"
949
+ :items="items"
950
+ label="Option"
951
+ use-vuetify-validation
952
+ :rules="[v => !!v || 'Ce champ est requis']"
953
+ />
954
+ <VBtn type="submit" color="primary" class="mt-4">
955
+ Soumettre
956
+ </VBtn>
957
+ </VForm>
958
+ </template>`,
959
+ },
960
+ {
961
+ name: 'Script',
962
+ code: `
963
+ <script setup lang="ts">
964
+ import { ref } from 'vue'
965
+ import { SySelect } from '@cnamts/synapse'
966
+ import { VBtn, VForm } from 'vuetify/components'
967
+
968
+ const value = ref(null)
969
+ const formRef = ref(null)
970
+ const items = [
971
+ { text: 'Option 1', value: '1' },
972
+ { text: 'Option 2', value: '2' },
973
+ { text: 'Option 3', value: '3' },
974
+ ]
975
+
976
+ async function onSubmit() {
977
+ const result = await formRef.value?.validate()
978
+ if (result?.valid) {
979
+ alert('Formulaire valide : ' + value.value)
980
+ }
981
+ }
982
+ </script>`,
983
+ },
984
+ ],
985
+ },
986
+ args: {
987
+ 'items': items,
988
+ 'label': 'Option',
989
+ 'useVuetifyValidation': true,
990
+ 'onUpdate:modelValue': fn(),
991
+ },
992
+ render: args => ({
993
+ components: { SySelect, VBtn, VForm },
994
+ setup() {
995
+ const value = ref(null)
996
+ const formRef = ref<InstanceType<typeof VForm> | null>(null)
997
+
998
+ async function onSubmit() {
999
+ const result = await formRef.value?.validate()
1000
+ if (result?.valid) {
1001
+ alert(`Formulaire valide : ${value.value}`)
1002
+ }
1003
+ }
1004
+
1005
+ return { args, value, formRef, onSubmit }
1006
+ },
1007
+ template: `
1008
+ <div class="pa-4">
1009
+ <VForm ref="formRef" @submit.prevent="onSubmit">
1010
+ <SySelect
1011
+ v-model="value"
1012
+ v-bind="args"
1013
+ :rules="[v => !!v || 'Ce champ est requis']"
1014
+ />
1015
+ <VBtn
1016
+ type="submit"
1017
+ color="primary"
1018
+ class="mt-4"
1019
+ >
1020
+ Soumettre
1021
+ </VBtn>
1022
+ </VForm>
1023
+ </div>
1024
+ `,
1025
+ }),
1026
+ }