@cnamts/synapse 1.0.25 → 1.0.26

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 (211) hide show
  1. package/dist/{AutocompleteFilter-D7qBuCAP.js → AutocompleteFilter-BPR-a55G.js} +1 -1
  2. package/dist/{DateFilter-BitMWrMU.js → DateFilter-CknrJWs2.js} +2 -2
  3. package/dist/{NumberFilter-BTLUxw0a.js → NumberFilter-DJ-yNlzv.js} +1 -1
  4. package/dist/{PeriodFilter-B5rUIPAC.js → PeriodFilter-CiB5Oa9Z.js} +1 -1
  5. package/dist/{SelectFilter-l4QnRcuk.js → SelectFilter-EiafX97M.js} +1 -1
  6. package/dist/{TextFilter-C9hj6Qrp.js → TextFilter-BzOmpdxj.js} +1 -1
  7. package/dist/{apLightTheme-DnIM24Lv.js → apLightTheme-DS0Uy44H.js} +20 -16
  8. package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +4 -2
  9. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +60 -289
  10. package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +1 -0
  11. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +1 -0
  12. package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +1 -0
  13. package/dist/components/Customs/SyTextField/SyTextField.d.ts +2 -4
  14. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +50 -49
  15. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +29 -28
  16. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +8 -8
  17. package/dist/components/DatePicker/composables/useDatePickerState.d.ts +3 -3
  18. package/dist/components/DatePicker/composables/useDateTextField.d.ts +2 -2
  19. package/dist/components/DatePicker/composables/useInputBlurHandler.d.ts +2 -2
  20. package/dist/components/DatePicker/types.d.ts +1 -2
  21. package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +1 -0
  22. package/dist/components/MonthPicker/MonthPicker.d.ts +1 -1
  23. package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +1 -1
  24. package/dist/components/NirField/NirField.d.ts +8 -4
  25. package/dist/components/NirField/useNirValidation.d.ts +6 -2
  26. package/dist/components/PeriodField/PeriodField.d.ts +102 -102
  27. package/dist/components/PhoneField/PhoneField.d.ts +11 -1
  28. package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +0 -3
  29. package/dist/components/RatingPicker/EmotionPicker/EmotionPicker.d.ts +3 -1
  30. package/dist/components/RatingPicker/NumberPicker/NumberPicker.d.ts +4 -3
  31. package/dist/components/RatingPicker/RatingPicker.d.ts +18 -5
  32. package/dist/components/RatingPicker/StarsPicker/StarsPicker.d.ts +3 -1
  33. package/dist/components/RatingPicker/tests/RatingPicker.a11y.spect.d.ts +1 -0
  34. package/dist/components/RatingPicker/useRatingFocus.d.ts +18 -0
  35. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +4 -4
  36. package/dist/components/Tables/SyTable/SyTable.d.ts +4 -4
  37. package/dist/components/Tables/common/SyTablePagination.d.ts +152 -364
  38. package/dist/components/Tables/common/TableHeader.d.ts +1 -1
  39. package/dist/components/Tables/common/filters/DateFilter.d.ts +4 -4
  40. package/dist/composables/date/useDateInitializationDayjs.d.ts +3 -1
  41. package/dist/composables/unifyValidation/useCustomValidation.d.ts +3 -1
  42. package/dist/composables/unifyValidation/useValidation.d.ts +12 -6
  43. package/dist/composables/unifyValidation/useVuetifyValidation.d.ts +1 -1
  44. package/dist/composables/validation/useValidation.d.ts +1 -0
  45. package/dist/design-system-v3.js +2 -2
  46. package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +2 -0
  47. package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +2 -0
  48. package/dist/{main-Cpx8Co6H.js → main-BsJ9ec3i.js} +9103 -9018
  49. package/dist/synapse.css +1 -1
  50. package/dist/vuetifyConfig.js +1 -1
  51. package/package.json +8 -7
  52. package/src/assets/overrides/_icons.scss +0 -13
  53. package/src/assets/overrides/_otp.scss +0 -1
  54. package/src/components/Accordion/Accordion.vue +2 -0
  55. package/src/components/CookiesSelection/CookiesInformation/CookiesInformation.vue +2 -1
  56. package/src/components/CookiesSelection/CookiesSelection.vue +2 -1
  57. package/src/components/CopyBtn/CopyBtn.vue +9 -0
  58. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +1 -1
  59. package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +413 -96
  60. package/src/components/Customs/Selects/SySelect/SySelect.vue +270 -225
  61. package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +245 -6
  62. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +3 -3
  63. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +23 -2
  64. package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +23 -5
  65. package/src/components/Customs/SyTabs/SyTabs.stories.ts +5 -5
  66. package/src/components/Customs/SyTabs/config.ts +3 -3
  67. package/src/components/Customs/SyTextField/SyTextField.vue +31 -4
  68. package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +1 -1
  69. package/src/components/DatePicker/CalendarMode/DatePicker.vue +17 -14
  70. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +1 -1
  71. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +8 -7
  72. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +1 -1
  73. package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.stories.ts +1 -1
  74. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +57 -23
  75. package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +1 -1
  76. package/src/components/DatePicker/composables/useDatePickerState.ts +33 -14
  77. package/src/components/DatePicker/composables/useDateRangeInput.ts +2 -1
  78. package/src/components/DatePicker/composables/useDateSelection.ts +2 -1
  79. package/src/components/DatePicker/composables/useDateTextField.ts +2 -2
  80. package/src/components/DatePicker/composables/useInputBlurHandler.ts +2 -2
  81. package/src/components/DatePicker/types.ts +1 -2
  82. package/src/components/DialogBox/DialogBox.stories.ts +8 -8
  83. package/src/components/DialogBox/accessibilite/Accessibility.mdx +86 -22
  84. package/src/components/FilterSideBar/FilterSideBar.vue +2 -1
  85. package/src/components/LangBtn/LangBtn.vue +2 -1
  86. package/src/components/NotificationBar/Notification/Notification.vue +2 -2
  87. package/src/components/PaginatedTable/PaginatedTable.vue +1 -1
  88. package/src/components/PaginatedTable/Pagination.vue +1 -1
  89. package/src/components/PasswordField/PasswordField.vue +7 -3
  90. package/src/components/PhoneField/PhoneField.vue +4 -2
  91. package/src/components/RangeField/RangeSlider/RangeSlider.vue +11 -18
  92. package/src/components/RatingPicker/EmotionPicker/EmotionPicker.vue +32 -48
  93. package/src/components/RatingPicker/EmotionPicker/tests/__snapshots__/EmotionPicker.spec.ts.snap +5 -0
  94. package/src/components/RatingPicker/NumberPicker/NumberPicker.vue +48 -53
  95. package/src/components/RatingPicker/NumberPicker/tests/NumberPicker.spec.ts +2 -1
  96. package/src/components/RatingPicker/NumberPicker/tests/__snapshots__/NumberPicker.spec.ts.snap +40 -13
  97. package/src/components/RatingPicker/RatingPicker.stories.ts +65 -88
  98. package/src/components/RatingPicker/RatingPicker.vue +71 -15
  99. package/src/components/RatingPicker/StarsPicker/StarsPicker.vue +28 -37
  100. package/src/components/RatingPicker/StarsPicker/tests/StarsPicker.spec.ts +1 -1
  101. package/src/components/RatingPicker/StarsPicker/tests/__snapshots__/StarsPicker.spec.ts.snap +5 -0
  102. package/src/components/RatingPicker/accessibilite/Accessibility.mdx +137 -9
  103. package/src/components/RatingPicker/tests/RatingPicker.a11y.spect.ts +123 -0
  104. package/src/components/RatingPicker/tests/RatingPicker.spec.ts +3 -2
  105. package/src/components/RatingPicker/tests/__snapshots__/RatingPicker.spec.ts.snap +40 -11
  106. package/src/components/RatingPicker/useRatingFocus.ts +97 -0
  107. package/src/components/SyTextArea/SyTextArea.vue +32 -1
  108. package/src/components/Tables/SyServerTable/SyServerTable.vue +1 -1
  109. package/src/components/Tables/SyTable/SyTable.vue +1 -1
  110. package/src/components/Tables/common/SyTableFilter.vue +4 -4
  111. package/src/components/Tables/common/SyTablePagination.vue +1 -0
  112. package/src/components/Tables/common/TableHeader.vue +1 -1
  113. package/src/components/Tables/common/filters/DateFilter.vue +2 -2
  114. package/src/composables/date/tests/useDateFormatDayjs.spec.ts +81 -0
  115. package/src/composables/date/tests/{useDateInitialization.spec.ts → useDateInitializationDayjs.spec.ts} +39 -3
  116. package/src/composables/date/useDateInitializationDayjs.ts +4 -1
  117. package/src/composables/unifyValidation/documentationValidationProps.ts +7 -7
  118. package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +2 -1
  119. package/src/composables/unifyValidation/tests/useValidation.spec.ts +22 -0
  120. package/src/composables/unifyValidation/useCustomValidation.ts +16 -4
  121. package/src/composables/unifyValidation/useValidation.ts +46 -15
  122. package/src/composables/unifyValidation/useVuetifyValidation.ts +2 -2
  123. package/src/composables/useFormFieldErrorHandling.ts +4 -1
  124. package/src/composables/validation/tests/useValidation.spec.ts +2 -2
  125. package/src/composables/validation/useValidation.ts +15 -3
  126. package/src/composantsVuetify/VCard/VCard.mdx +59 -0
  127. package/src/composantsVuetify/VCard/v-card.stories.ts +279 -0
  128. package/src/designTokens/tokens/amelipro/apColors2026.ts +1 -1
  129. package/src/designTokens/tokens/amelipro/apLightTheme.ts +3 -0
  130. package/src/designTokens/tokens/cnam/cnamLightTheme.ts +3 -0
  131. package/src/stories/Accessibilite/Aculturation/SensibilisationAccessibilite.mdx +61 -91
  132. package/src/stories/Accessibilite/AuditDesignSystem.mdx +5 -8
  133. package/src/stories/Accessibilite/AuditEtContreAudit/Exemptions-derogations.mdx +1 -1
  134. package/src/stories/Accessibilite/AuditEtContreAudit/Introduction.mdx +11 -8
  135. package/src/stories/Accessibilite/AuditEtContreAudit/RGAA.mdx +6 -7
  136. package/src/stories/Accessibilite/Introduction.mdx +30 -30
  137. package/src/stories/Accessibilite/KitDePreAudit/Echantillonnage.mdx +168 -78
  138. package/src/stories/Accessibilite/KitDePreAudit/Introduction.mdx +13 -6
  139. package/src/stories/Accessibilite/KitDePreAudit/Outils/Introduction.mdx +66 -45
  140. package/src/stories/Accessibilite/KitDePreAudit/Outils/LecteursDEcran.mdx +23 -49
  141. package/src/stories/Accessibilite/KitDePreAudit/Outils/Tanaguru/FauxPositifs.stories.ts +6 -0
  142. package/src/stories/Accessibilite/KitDePreAudit/Outils/Tanaguru/Utilisation.mdx +7 -19
  143. package/src/stories/Accessibilite/KitDePreAudit/Preaudit.mdx +18 -20
  144. package/src/stories/Components/Components.stories.ts +52 -3
  145. package/dist/AutocompleteFilter-Df9i5mAl.cjs +0 -1
  146. package/dist/DateFilter-BJD6FMev.cjs +0 -1
  147. package/dist/NumberFilter-DGCzCXzI.cjs +0 -1
  148. package/dist/PeriodFilter-DO_ecTZW.cjs +0 -1
  149. package/dist/SelectFilter-CGwcKWLm.cjs +0 -1
  150. package/dist/TextFilter-B8nf7xoK.cjs +0 -1
  151. package/dist/apLightTheme-CEK4iY3f.cjs +0 -1
  152. package/dist/composables/date/useDateFormat.d.ts +0 -26
  153. package/dist/composables/date/useDateInitialization.d.ts +0 -18
  154. package/dist/design-system-v3.umd.cjs +0 -1
  155. package/dist/main-ByDPHpae.cjs +0 -1067
  156. package/dist/tooth-11-D3sLWv2n.cjs +0 -1
  157. package/dist/tooth-12-CXrLuH03.cjs +0 -1
  158. package/dist/tooth-13-BSfo5fpT.cjs +0 -1
  159. package/dist/tooth-14-DMzulx0h.cjs +0 -1
  160. package/dist/tooth-15-BKRFVi-9.cjs +0 -1
  161. package/dist/tooth-16-CpuxAbuM.cjs +0 -1
  162. package/dist/tooth-17-BPoahUdg.cjs +0 -1
  163. package/dist/tooth-18-DhHJz8sy.cjs +0 -1
  164. package/dist/tooth-21-Dgd5hn_X.cjs +0 -1
  165. package/dist/tooth-22-C2Tn19sB.cjs +0 -1
  166. package/dist/tooth-23-C9uaaSGb.cjs +0 -1
  167. package/dist/tooth-24-BrK9UGpf.cjs +0 -1
  168. package/dist/tooth-25-CE_EfGNp.cjs +0 -1
  169. package/dist/tooth-26-Ctv4i9Fy.cjs +0 -1
  170. package/dist/tooth-27-C5J7JkWM.cjs +0 -1
  171. package/dist/tooth-28-Z9oWqjo0.cjs +0 -1
  172. package/dist/tooth-31-BrYqmkTi.cjs +0 -1
  173. package/dist/tooth-32-BNNR0oCZ.cjs +0 -1
  174. package/dist/tooth-33-DuxvqO2J.cjs +0 -1
  175. package/dist/tooth-34-BCSCXMB6.cjs +0 -1
  176. package/dist/tooth-35-BLUXkX88.cjs +0 -1
  177. package/dist/tooth-36-IrKHYqlA.cjs +0 -1
  178. package/dist/tooth-37-BYqpdMwo.cjs +0 -1
  179. package/dist/tooth-38-B_eNXXdu.cjs +0 -1
  180. package/dist/tooth-41-Ddva4Ot8.cjs +0 -1
  181. package/dist/tooth-42-szcDqlM0.cjs +0 -1
  182. package/dist/tooth-43-B3ka6rQm.cjs +0 -1
  183. package/dist/tooth-44-CazyQucj.cjs +0 -1
  184. package/dist/tooth-45-B4HQtc8n.cjs +0 -1
  185. package/dist/tooth-46-BPM40gbG.cjs +0 -1
  186. package/dist/tooth-47-Dvr20dlh.cjs +0 -1
  187. package/dist/tooth-48-Bd8ljGsF.cjs +0 -1
  188. package/dist/tooth-51-OBpwCOF3.cjs +0 -1
  189. package/dist/tooth-52-aKxyHcmq.cjs +0 -1
  190. package/dist/tooth-53-vCwJjTOc.cjs +0 -1
  191. package/dist/tooth-54-DsWu2iFy.cjs +0 -1
  192. package/dist/tooth-55-BxC1X2Dn.cjs +0 -1
  193. package/dist/tooth-61-BbLvxMQi.cjs +0 -1
  194. package/dist/tooth-62-CmTkWczP.cjs +0 -1
  195. package/dist/tooth-63-DI7l_2qI.cjs +0 -1
  196. package/dist/tooth-64-B21sOsJh.cjs +0 -1
  197. package/dist/tooth-65-D2ZC2VEr.cjs +0 -1
  198. package/dist/tooth-71-D473PPO5.cjs +0 -1
  199. package/dist/tooth-72-Drh1wnNu.cjs +0 -1
  200. package/dist/tooth-73-DzlwYI23.cjs +0 -1
  201. package/dist/tooth-74-8aGvcZPg.cjs +0 -1
  202. package/dist/tooth-75-BFK7At_r.cjs +0 -1
  203. package/dist/tooth-81-BZmR-I0M.cjs +0 -1
  204. package/dist/tooth-82-euVfUUZV.cjs +0 -1
  205. package/dist/tooth-83-KV010j64.cjs +0 -1
  206. package/dist/tooth-84-BBg1RjhZ.cjs +0 -1
  207. package/dist/tooth-85-Cr-kc1wM.cjs +0 -1
  208. package/dist/vuetifyConfig.umd.cjs +0 -1
  209. package/src/composables/date/tests/useDateFormat.spec.ts +0 -67
  210. package/src/composables/date/useDateFormat.ts +0 -110
  211. package/src/composables/date/useDateInitialization.ts +0 -92
@@ -3,8 +3,9 @@ import SySelect from '@/components/Customs/Selects/SySelect/SySelect.vue'
3
3
  import SyAlert from '../../../SyAlert/SyAlert.vue'
4
4
  import SyForm from '../../SyForm/SyForm.vue'
5
5
  import { VBtn, VMenu, VList, VListItem, VListItemTitle } from 'vuetify/components'
6
- import { ref } from 'vue'
6
+ import { ref, onMounted } from 'vue'
7
7
  import { fn } from '@storybook/test'
8
+ import { getValidationDocumentation } from '@/composables/unifyValidation/documentationValidationProps'
8
9
 
9
10
  const meta: Meta<typeof SySelect> = {
10
11
  title: 'Composants/Formulaires/Selects/SySelect',
@@ -14,10 +15,9 @@ const meta: Meta<typeof SySelect> = {
14
15
  controls: { exclude: ['onUpdate:modelValue', 'selectedValue', 'isOpen', 'closeList'] },
15
16
  },
16
17
  argTypes: {
18
+ ...getValidationDocumentation('string'),
17
19
  selectedValue: { control: 'text' },
18
20
  items: { control: 'object' },
19
- errorMessages: { control: 'object' },
20
- required: { control: 'boolean' },
21
21
  displayAsterisk: { control: 'boolean' },
22
22
  textKey: {
23
23
  control: 'text',
@@ -51,10 +51,6 @@ const meta: Meta<typeof SySelect> = {
51
51
  control: 'boolean',
52
52
  description: 'Affiche les options sélectionnées sous forme de chips',
53
53
  },
54
- hideMessages: {
55
- control: 'boolean',
56
- description: 'Masque les messages d\'erreur',
57
- },
58
54
  variantStyle: {
59
55
  control: 'select',
60
56
  options: ['outlined', 'plain', 'underlined', 'filled', 'solo', 'solo-inverted', 'solo-filled'],
@@ -163,17 +159,26 @@ export const Default: Story = {
163
159
  { text: 'Emensis itaque difficultatibus multis et nive obrutis callibus', value: 'Louis' },
164
160
  { text: 'Plurimis ubi prope Rauracum ventum est ad supercilia', value: 'Valentin' },
165
161
  ],
162
+ 'customSuccessRules': [{
163
+ type: 'custom',
164
+ options: {
165
+ validate: (v: unknown) => v !== null && v !== undefined,
166
+ successMessage: 'Option sélectionnée avec succès.',
167
+ },
168
+ }],
166
169
  'onUpdate:modelValue': fn(),
167
170
  },
168
171
  render: (args) => {
169
172
  return {
170
173
  components: { SySelect, VBtn, VMenu, VList, VListItem, VListItemTitle },
171
174
  setup() {
172
- return { args }
175
+ const value = ref(null)
176
+ return { args, value }
173
177
  },
174
178
  template: `
175
179
  <div class="pa-4">
176
180
  <SySelect
181
+ v-model="value"
177
182
  v-bind="args"
178
183
  />
179
184
  </div>
@@ -234,19 +239,27 @@ export const HelpText: Story = {
234
239
  { text: 'Valentin', value: 'Valentin' },
235
240
  ],
236
241
  'helpText': 'Texte d\'aide à la saisie',
237
- 'hideMessages': false,
238
- 'required': true,
242
+ 'hideDetails': false,
243
+ 'customSuccessRules': [{
244
+ type: 'custom',
245
+ options: {
246
+ validate: (v: unknown) => v !== null && v !== undefined,
247
+ successMessage: 'Option sélectionnée avec succès.',
248
+ },
249
+ }],
239
250
  'onUpdate:modelValue': fn(),
240
251
  },
241
252
  render: (args) => {
242
253
  return {
243
254
  components: { SySelect, VBtn, VMenu, VList, VListItem, VListItemTitle },
244
255
  setup() {
245
- return { args }
256
+ const value = ref(null)
257
+ return { args, value }
246
258
  },
247
259
  template: `
248
260
  <div class="pa-4">
249
261
  <SySelect
262
+ v-model="value"
250
263
  v-bind="args"
251
264
  />
252
265
  </div>
@@ -275,12 +288,13 @@ export const Required: Story = {
275
288
  name: 'Script',
276
289
  code: `
277
290
  <script setup lang="ts">
291
+ import { ref } from 'vue'
278
292
  import { SySelect } from '@cnamts/synapse'
279
-
293
+ const value = ref(null)
280
294
  const items = [
281
295
  { text: 'Option 1', value: '1' },
282
296
  { text: 'Option 2', value: '2' },
283
- ],
297
+ ]
284
298
  </script>
285
299
  `,
286
300
  },
@@ -298,14 +312,15 @@ export const Required: Story = {
298
312
  return {
299
313
  components: { SySelect },
300
314
  setup() {
301
- return { args }
315
+ const value = ref(null)
316
+ return { args, value }
302
317
  },
303
318
  template: `
304
319
  <div class="pa-4">
305
320
  <p class="mb-2 text-caption text-grey-darken-2">Ce champ est obligatoire</p>
306
321
  <SySelect
322
+ v-model="value"
307
323
  v-bind="args"
308
- :required="args.required"
309
324
  />
310
325
  </div>
311
326
  `,
@@ -363,14 +378,14 @@ const items = [
363
378
  return {
364
379
  components: { SySelect },
365
380
  setup() {
366
- return { args }
381
+ const value = ref(null)
382
+ return { args, value }
367
383
  },
368
384
  template: `
369
385
  <div class="pa-4">
370
386
  <SySelect
387
+ v-model="value"
371
388
  v-bind="args"
372
- :required="args.required"
373
- :display-asterisk="args.displayAsterisk"
374
389
  />
375
390
  </div>
376
391
  `,
@@ -378,6 +393,273 @@ const items = [
378
393
  },
379
394
  }
380
395
 
396
+ export const WithError: Story = {
397
+ parameters: {
398
+ docs: {
399
+ description: {
400
+ story: '« Option 1 » est présélectionnée et déclenche une erreur bloquante au chargement.',
401
+ },
402
+ },
403
+ sourceCode: [
404
+ {
405
+ name: 'Template',
406
+ code: `
407
+ <template>
408
+ <SySelect
409
+ ref="selectRef"
410
+ v-model="value"
411
+ :items="items"
412
+ label="Option"
413
+ :customRules="[
414
+ {
415
+ type: 'custom',
416
+ options: {
417
+ validate: (v) => v !== '1',
418
+ message: 'Option 1 n\\'est pas autorisée, choisissez Option 2 ou 3.'
419
+ }
420
+ }
421
+ ]"
422
+ />
423
+ </template>`,
424
+ },
425
+ {
426
+ name: 'Script',
427
+ code: `
428
+ <script setup lang="ts">
429
+ import { onMounted, ref } from 'vue'
430
+ import { SySelect } from '@cnamts/synapse'
431
+ const value = ref('1')
432
+ const items = [
433
+ { text: 'Option 1', value: '1' },
434
+ { text: 'Option 2', value: '2' },
435
+ { text: 'Option 3', value: '3' },
436
+ ]
437
+
438
+ const selectRef = ref(null)
439
+
440
+ onMounted(() => {
441
+ selectRef.value?.validateOnSubmit()
442
+ })
443
+ </script>`,
444
+ },
445
+ ],
446
+ },
447
+ args: {
448
+ 'items': [
449
+ { text: 'Option 1', value: '1' },
450
+ { text: 'Option 2', value: '2' },
451
+ { text: 'Option 3', value: '3' },
452
+ ],
453
+ 'label': 'Option',
454
+ 'onUpdate:modelValue': fn(),
455
+ },
456
+ render: args => ({
457
+ components: { SySelect },
458
+ setup() {
459
+ const value = ref('1')
460
+ const selectRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
461
+
462
+ onMounted(() => {
463
+ selectRef.value?.validateOnSubmit()
464
+ })
465
+
466
+ return { args, value, selectRef }
467
+ },
468
+ template: `
469
+ <div class="pa-4">
470
+ <SySelect
471
+ ref="selectRef"
472
+ v-model="value"
473
+ v-bind="args"
474
+ :customRules="[
475
+ {
476
+ type: 'custom',
477
+ options: {
478
+ validate: (v) => v !== '1',
479
+ message: 'Option 1 n\\'est pas autorisée, choisissez Option 2 ou 3.'
480
+ }
481
+ }
482
+ ]"
483
+ />
484
+ </div>
485
+ `,
486
+ }),
487
+ }
488
+
489
+ export const WithWarning: Story = {
490
+ parameters: {
491
+ docs: {
492
+ description: {
493
+ story: '« Option 1 » est présélectionnée et déclenche un avertissement (non bloquant) au chargement.',
494
+ },
495
+ },
496
+ sourceCode: [
497
+ {
498
+ name: 'Template',
499
+ code: `
500
+ <template>
501
+ <SySelect
502
+ v-model="value"
503
+ :items="items"
504
+ label="Option"
505
+ :customWarningRules="[
506
+ {
507
+ type: 'custom',
508
+ options: {
509
+ validate: (v) => v !== '1',
510
+ message: 'Option 1 est dépréciée, préférez Option 2 ou 3.'
511
+ }
512
+ }
513
+ ]"
514
+ />
515
+ </template>`,
516
+ },
517
+ {
518
+ name: 'Script',
519
+ code: `
520
+ <script setup lang="ts">
521
+ import { ref } from 'vue'
522
+ import { SySelect } from '@cnamts/synapse'
523
+ const value = ref(null)
524
+ const items = [
525
+ { text: 'Option 1', value: '1' },
526
+ { text: 'Option 2', value: '2' },
527
+ { text: 'Option 3', value: '3' },
528
+ ]
529
+ </script>`,
530
+ },
531
+ ],
532
+ },
533
+ args: {
534
+ 'items': [
535
+ { text: 'Option 1', value: '1' },
536
+ { text: 'Option 2', value: '2' },
537
+ { text: 'Option 3', value: '3' },
538
+ ],
539
+ 'label': 'Option',
540
+ 'onUpdate:modelValue': fn(),
541
+ },
542
+ render: args => ({
543
+ components: { SySelect },
544
+ setup() {
545
+ const value = ref('1')
546
+ const selectRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
547
+
548
+ onMounted(() => {
549
+ selectRef.value?.validateOnSubmit()
550
+ })
551
+
552
+ return { args, value, selectRef }
553
+ },
554
+ template: `
555
+ <div class="pa-4">
556
+ <SySelect
557
+ ref="selectRef"
558
+ v-model="value"
559
+ v-bind="args"
560
+ :customWarningRules="[
561
+ {
562
+ type: 'custom',
563
+ options: {
564
+ validate: (v) => v !== '1',
565
+ message: 'Option 1 est dépréciée, préférez Option 2 ou 3.'
566
+ }
567
+ }
568
+ ]"
569
+ />
570
+ </div>
571
+ `,
572
+ }),
573
+ }
574
+
575
+ export const WithSuccess: Story = {
576
+ parameters: {
577
+ docs: {
578
+ description: {
579
+ story: 'Une option est présélectionnée et déclenche la confirmation de succès au chargement.',
580
+ },
581
+ },
582
+ sourceCode: [
583
+ {
584
+ name: 'Template',
585
+ code: `
586
+ <template>
587
+ <SySelect
588
+ v-model="value"
589
+ :items="items"
590
+ label="Option"
591
+ show-success-messages
592
+ :customSuccessRules="[
593
+ {
594
+ type: 'custom',
595
+ options: {
596
+ validate: (v) => v !== null && v !== undefined,
597
+ message: 'Option sélectionnée avec succès.'
598
+ }
599
+ }
600
+ ]"
601
+ />
602
+ </template>`,
603
+ },
604
+ {
605
+ name: 'Script',
606
+ code: `
607
+ <script setup lang="ts">
608
+ import { ref } from 'vue'
609
+ import { SySelect } from '@cnamts/synapse'
610
+ const value = ref(null)
611
+ const items = [
612
+ { text: 'Option 1', value: '1' },
613
+ { text: 'Option 2', value: '2' },
614
+ { text: 'Option 3', value: '3' },
615
+ ]
616
+ </script>`,
617
+ },
618
+ ],
619
+ },
620
+ args: {
621
+ 'items': [
622
+ { text: 'Option 1', value: '1' },
623
+ { text: 'Option 2', value: '2' },
624
+ { text: 'Option 3', value: '3' },
625
+ ],
626
+ 'label': 'Option',
627
+ 'showSuccessMessages': true,
628
+ 'onUpdate:modelValue': fn(),
629
+ },
630
+ render: args => ({
631
+ components: { SySelect },
632
+ setup() {
633
+ const value = ref('1')
634
+ const selectRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
635
+
636
+ onMounted(() => {
637
+ selectRef.value?.validateOnSubmit()
638
+ })
639
+
640
+ return { args, value, selectRef }
641
+ },
642
+ template: `
643
+ <div class="pa-4">
644
+ <SySelect
645
+ ref="selectRef"
646
+ v-model="value"
647
+ v-bind="args"
648
+ :customSuccessRules="[
649
+ {
650
+ type: 'custom',
651
+ options: {
652
+ validate: (v) => v !== null && v !== undefined,
653
+ message: 'Option sélectionnée avec succès.'
654
+ }
655
+ }
656
+ ]"
657
+ />
658
+ </div>
659
+ `,
660
+ }),
661
+ }
662
+
381
663
  export const SlotPrepend: Story = {
382
664
  parameters: {
383
665
  sourceCode: [
@@ -652,7 +934,7 @@ const options = [
652
934
  return {
653
935
  components: { SySelect },
654
936
  setup() {
655
- const selectedOptions = ref([])
937
+ const selectedOptions = ref(null)
656
938
 
657
939
  return { args, selectedOptions }
658
940
  },
@@ -729,7 +1011,7 @@ const options = [
729
1011
  return {
730
1012
  components: { SySelect },
731
1013
  setup() {
732
- const selectedOptions = ref([])
1014
+ const selectedOptions = ref(null)
733
1015
 
734
1016
  return { args, selectedOptions }
735
1017
  },
@@ -745,81 +1027,6 @@ const options = [
745
1027
  },
746
1028
  }
747
1029
 
748
- export const withCustomError: Story = {
749
- parameters: {
750
- sourceCode: [
751
- {
752
- name: 'Template',
753
- code: `
754
- <template>
755
- <SySelect
756
- v-model="value"
757
- :items="items"
758
- :error-messages="errorMessages"
759
- />
760
- <VBtn @click="triggerError">
761
- Trigger Error
762
- </VBtn>
763
- </template>
764
- `,
765
- },
766
- {
767
- name: 'Script',
768
- code: `
769
- <script setup lang="ts">
770
- import { SySelect } from '@cnamts/synapse'
771
- import { ref } from 'vue'
772
-
773
- const items = [
774
- { text: 'Option 1', value: '1' },
775
- { text: 'Option 2', value: '2' },
776
- ],
777
-
778
- const errorMessages = ref([])
779
-
780
- const triggerError = () => {
781
- errorMessages.value = ['This is a test error message']
782
- }
783
- </script>
784
- `,
785
- },
786
- ],
787
- },
788
- args: {
789
- 'items': [
790
- { text: 'Option 1', value: '1' },
791
- { text: 'Option 2', value: '2' },
792
- ],
793
- 'onUpdate:modelValue': fn(),
794
- },
795
- render: (args) => {
796
- return {
797
- components: { SySelect, VBtn, VMenu, VList, VListItem, VListItemTitle },
798
- setup() {
799
- const errorMessages = ref([])
800
- const triggerError = () => {
801
- // @ts-expect-error test error message
802
- errorMessages.value = ['This is a test error message']
803
- }
804
- return { args, errorMessages, triggerError }
805
- },
806
- template: `
807
- <div class="pa-4">
808
- <SySelect
809
- v-bind="args"
810
- :error-messages="errorMessages"
811
- />
812
- </div>
813
- <div class="px-4">
814
- <VBtn @click="triggerError">
815
- Trigger Error
816
- </VBtn>
817
- </div>
818
- `,
819
- }
820
- },
821
- }
822
-
823
1030
  export const withCustomKey: Story = {
824
1031
  parameters: {
825
1032
  sourceCode: [
@@ -855,17 +1062,26 @@ export const withCustomKey: Story = {
855
1062
  { customKey: 'Choix 1', value: '1' },
856
1063
  { customKey: 'Choix 2', value: '2' },
857
1064
  ],
1065
+ 'customSuccessRules': [{
1066
+ type: 'custom',
1067
+ options: {
1068
+ validate: (v: unknown) => v !== null && v !== undefined,
1069
+ successMessage: 'Option sélectionnée avec succès.',
1070
+ },
1071
+ }],
858
1072
  'onUpdate:modelValue': fn(),
859
1073
  },
860
1074
  render: (args) => {
861
1075
  return {
862
1076
  components: { SySelect, VBtn, VMenu, VList, VListItem, VListItemTitle },
863
1077
  setup() {
864
- return { args }
1078
+ const value = ref(null)
1079
+ return { args, value }
865
1080
  },
866
1081
  template: `
867
1082
  <div class="pa-4">
868
1083
  <SySelect
1084
+ v-model="value"
869
1085
  v-bind="args"
870
1086
  text-key="customKey"
871
1087
  />
@@ -1011,3 +1227,104 @@ const onSubmit = (event) => {
1011
1227
  }
1012
1228
  },
1013
1229
  }
1230
+
1231
+ export const VuetifyValidation: Story = {
1232
+ parameters: {
1233
+ docs: {
1234
+ description: {
1235
+ 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.',
1236
+ },
1237
+ },
1238
+ sourceCode: [
1239
+ {
1240
+ name: 'Template',
1241
+ code: `
1242
+ <template>
1243
+ <SyForm @submit="onSubmit">
1244
+ <SySelect
1245
+ v-model="value"
1246
+ :items="items"
1247
+ label="Option"
1248
+ use-vuetify-validation
1249
+ :show-success-messages="false"
1250
+ :rules="[v => !!v || 'Ce champ est requis']"
1251
+ />
1252
+ <VBtn type="submit" color="primary" class="mt-4">
1253
+ Soumettre
1254
+ </VBtn>
1255
+ </SyForm>
1256
+ </template>`,
1257
+ },
1258
+ {
1259
+ name: 'Script',
1260
+ code: `
1261
+ <script setup lang="ts">
1262
+ import { ref } from 'vue'
1263
+ import { SySelect, SyForm } from '@cnamts/synapse'
1264
+ import { VBtn } from 'vuetify/components'
1265
+
1266
+ const value = ref(null)
1267
+ const items = [
1268
+ { text: 'Option 1', value: '1' },
1269
+ { text: 'Option 2', value: '2' },
1270
+ { text: 'Option 3', value: '3' },
1271
+ ]
1272
+
1273
+ function onSubmit(event: { isValid: boolean }) {
1274
+ if (event.isValid) {
1275
+ alert('Formulaire valide : ' + value.value)
1276
+ } else {
1277
+ alert('Formulaire invalide : veuillez choisir une option.')
1278
+ }
1279
+ }
1280
+ </script>`,
1281
+ },
1282
+ ],
1283
+ },
1284
+ args: {
1285
+ 'items': [
1286
+ { text: 'Option 1', value: '1' },
1287
+ { text: 'Option 2', value: '2' },
1288
+ { text: 'Option 3', value: '3' },
1289
+ ],
1290
+ 'label': 'Option',
1291
+ 'useVuetifyValidation': true,
1292
+ 'showSuccessMessages': false,
1293
+ 'onUpdate:modelValue': fn(),
1294
+ },
1295
+ render: args => ({
1296
+ components: { SySelect, SyForm, VBtn },
1297
+ setup() {
1298
+ const value = ref(null)
1299
+
1300
+ function onSubmit(event: { isValid: boolean }) {
1301
+ if (event.isValid) {
1302
+ alert(`Formulaire valide : ${value.value}`)
1303
+ }
1304
+ else {
1305
+ alert('Formulaire invalide : veuillez choisir une option.')
1306
+ }
1307
+ }
1308
+
1309
+ return { args, value, onSubmit }
1310
+ },
1311
+ template: `
1312
+ <div class="pa-4">
1313
+ <SyForm @submit="onSubmit">
1314
+ <SySelect
1315
+ v-model="value"
1316
+ v-bind="args"
1317
+ :rules="[v => !!v || 'Ce champ est requis']"
1318
+ />
1319
+ <VBtn
1320
+ type="submit"
1321
+ color="primary"
1322
+ class="mt-4"
1323
+ >
1324
+ Soumettre
1325
+ </VBtn>
1326
+ </SyForm>
1327
+ </div>
1328
+ `,
1329
+ }),
1330
+ }