@cnamts/synapse 0.0.11-alpha → 0.0.12-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/design-system-v3.js +3878 -3189
  2. package/dist/design-system-v3.umd.cjs +1 -1
  3. package/dist/src/components/Amelipro/types/languages.d.ts +6 -0
  4. package/dist/src/components/Amelipro/types/types.d.ts +65 -0
  5. package/dist/src/components/CookieBanner/CookieBanner.d.ts +1 -1
  6. package/dist/src/components/Customs/SyInputSelect/SyInputSelect.d.ts +2 -0
  7. package/dist/src/components/Customs/SyTextField/SyTextField.d.ts +29 -23
  8. package/dist/src/components/Customs/SyTextField/types.d.ts +1 -0
  9. package/dist/src/components/DatePicker/DatePicker.d.ts +70 -59
  10. package/dist/src/components/DatePicker/DateTextInput.d.ts +67 -56
  11. package/dist/src/components/ErrorPage/ErrorPage.d.ts +1 -1
  12. package/dist/src/components/FileList/FileList.d.ts +1 -0
  13. package/dist/src/components/FileList/UploadItem/UploadItem.d.ts +1 -1
  14. package/dist/src/components/FilterSideBar/FilterSideBar.d.ts +31 -0
  15. package/dist/src/components/FilterSideBar/locales.d.ts +7 -0
  16. package/dist/src/components/FilterSideBar/tests/FilterSideBar.spec.d.ts +1 -0
  17. package/dist/src/components/LangBtn/LangBtn.d.ts +2 -2
  18. package/dist/src/components/NirField/NirField.d.ts +940 -0
  19. package/dist/src/components/NotificationBar/NotificationBar.d.ts +1 -1
  20. package/dist/src/components/PasswordField/PasswordField.d.ts +40 -8
  21. package/dist/src/components/PeriodField/PeriodField.d.ts +142 -120
  22. package/dist/src/components/PhoneField/PhoneField.d.ts +11 -2
  23. package/dist/src/components/RatingPicker/EmotionPicker/EmotionPicker.d.ts +1 -1
  24. package/dist/src/components/RatingPicker/NumberPicker/NumberPicker.d.ts +1 -1
  25. package/dist/src/components/RatingPicker/StarsPicker/StarsPicker.d.ts +1 -1
  26. package/dist/src/components/UploadWorkflow/config.d.ts +29 -0
  27. package/dist/src/components/UploadWorkflow/locales.d.ts +7 -0
  28. package/dist/src/components/UploadWorkflow/tests/UploadWorkflow.spec.d.ts +1 -0
  29. package/dist/src/components/UploadWorkflow/types.d.ts +19 -0
  30. package/dist/src/components/UploadWorkflow/useFileList.d.ts +10 -0
  31. package/dist/src/components/UploadWorkflow/useFileUploadJourney.d.ts +9 -0
  32. package/dist/src/components/index.d.ts +2 -0
  33. package/dist/src/composables/rules/useFieldValidation.d.ts +1 -0
  34. package/dist/src/composables/validation/tests/useValidation.spec.d.ts +1 -0
  35. package/dist/src/composables/validation/useValidation.d.ts +39 -0
  36. package/dist/src/designTokens/index.d.ts +3 -1
  37. package/dist/src/vuetifyConfig.d.ts +81 -0
  38. package/dist/style.css +1 -1
  39. package/package.json +1 -1
  40. package/src/assets/_elevations.scss +89 -0
  41. package/src/assets/_fonts.scss +6 -0
  42. package/src/assets/_radius.scss +86 -0
  43. package/src/assets/_spacers.scss +149 -0
  44. package/src/assets/settings.scss +7 -3
  45. package/src/assets/tokens.scss +32 -29
  46. package/src/components/Amelipro/types/languages.d.ts +6 -0
  47. package/src/components/Amelipro/types/types.d.ts +65 -0
  48. package/src/components/Customs/SyInputSelect/SyInputSelect.stories.ts +65 -0
  49. package/src/components/Customs/SyInputSelect/SyInputSelect.vue +13 -3
  50. package/src/components/Customs/SySelect/SySelect.stories.ts +88 -5
  51. package/src/components/Customs/SySelect/SySelect.vue +36 -10
  52. package/src/components/Customs/SySelect/tests/SySelect.spec.ts +135 -2
  53. package/src/components/Customs/SyTextField/SyTextField.stories.ts +576 -85
  54. package/src/components/Customs/SyTextField/SyTextField.vue +132 -104
  55. package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +190 -38
  56. package/src/components/Customs/SyTextField/types.d.ts +1 -0
  57. package/src/components/DatePicker/DatePicker.vue +405 -137
  58. package/src/components/DatePicker/DateTextInput.vue +15 -0
  59. package/src/components/DatePicker/tests/DatePicker.spec.ts +8 -15
  60. package/src/components/FileList/FileList.vue +2 -1
  61. package/src/components/FileList/UploadItem/UploadItem.vue +10 -0
  62. package/src/components/FileUpload/FileUpload.stories.ts +84 -0
  63. package/src/components/FileUpload/FileUpload.vue +1 -0
  64. package/src/components/FileUpload/tests/FileUpload.spec.ts +4 -4
  65. package/src/components/FilterInline/FilterInline.mdx +180 -34
  66. package/src/components/FilterInline/FilterInline.stories.ts +363 -6
  67. package/src/components/FilterSideBar/FilterSideBar.mdx +237 -0
  68. package/src/components/FilterSideBar/FilterSideBar.stories.ts +798 -0
  69. package/src/components/FilterSideBar/FilterSideBar.vue +193 -0
  70. package/src/components/FilterSideBar/locales.ts +8 -0
  71. package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +305 -0
  72. package/src/components/FilterSideBar/tests/__snapshots__/FilterSideBar.spec.ts.snap +39 -0
  73. package/src/components/HeaderBar/Usages.mdx +1 -1
  74. package/src/components/NirField/NirField.stories.ts +573 -29
  75. package/src/components/NirField/NirField.vue +397 -359
  76. package/src/components/NirField/tests/NirField.spec.ts +88 -52
  77. package/src/components/NirField/tests//342/200/257dataset/342/200/257.md +12 -0
  78. package/src/components/NotificationBar/Accessibilite.stories.ts +4 -0
  79. package/src/components/NotificationBar/NotificationBar.stories.ts +18 -13
  80. package/src/components/PasswordField/PasswordField.mdx +129 -47
  81. package/src/components/PasswordField/PasswordField.stories.ts +924 -120
  82. package/src/components/PasswordField/PasswordField.vue +209 -99
  83. package/src/components/PasswordField/tests/PasswordField.spec.ts +138 -9
  84. package/src/components/PeriodField/PeriodField.vue +55 -54
  85. package/src/components/PhoneField/PhoneField.stories.ts +69 -0
  86. package/src/components/PhoneField/PhoneField.vue +3 -0
  87. package/src/components/PhoneField/indicatifs.ts +1 -1
  88. package/src/components/UploadWorkflow/UploadWorkflow.mdx +75 -0
  89. package/src/components/UploadWorkflow/UploadWorkflow.stories.ts +943 -0
  90. package/src/components/UploadWorkflow/UploadWorkflow.vue +230 -0
  91. package/src/components/UploadWorkflow/config.ts +29 -0
  92. package/src/components/UploadWorkflow/locales.ts +8 -0
  93. package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +257 -0
  94. package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +54 -0
  95. package/src/components/UploadWorkflow/types.ts +21 -0
  96. package/src/components/UploadWorkflow/useFileList.ts +84 -0
  97. package/src/components/UploadWorkflow/useFileUploadJourney.ts +18 -0
  98. package/src/components/index.ts +2 -0
  99. package/src/composables/rules/useFieldValidation.ts +5 -2
  100. package/src/composables/validation/tests/useValidation.spec.ts +154 -0
  101. package/src/composables/validation/useValidation.ts +165 -0
  102. package/src/designTokens/index.ts +4 -0
  103. package/src/stories/Demarrer/Accueil.mdx +1 -1
  104. package/src/stories/DesignTokens/ThemePA.mdx +4 -30
  105. package/src/stories/GuideDuDev/UtiliserLesRules.mdx +319 -76
  106. package/src/stories/GuideDuDev/moduleDeNotification.mdx +1 -1
  107. package/src/vuetifyConfig.ts +61 -0
  108. package/src/composables/useFilterable/__snapshots__/useFilterable.spec.ts.snap +0 -3
@@ -2,12 +2,20 @@ import { mount } from '@vue/test-utils'
2
2
  import NirField from '../NirField.vue'
3
3
  import { describe, it, expect, beforeEach } from 'vitest'
4
4
  import { createVuetify } from 'vuetify'
5
+ import * as components from 'vuetify/components'
6
+ import * as directives from 'vuetify/directives'
7
+ import { useValidation } from '@/composables/validation/useValidation'
5
8
 
6
- const vuetify = createVuetify()
9
+ const vuetify = createVuetify({
10
+ components,
11
+ directives,
12
+ })
7
13
 
8
14
  describe('NirField.vue', () => {
9
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
10
- let wrapper: any
15
+ let wrapper: ReturnType<typeof mount<typeof NirField & {
16
+ numberValidation: ReturnType<typeof useValidation>
17
+ keyValidation: ReturnType<typeof useValidation>
18
+ }>>
11
19
 
12
20
  beforeEach(() => {
13
21
  wrapper = mount(NirField, {
@@ -15,106 +23,134 @@ describe('NirField.vue', () => {
15
23
  plugins: [vuetify],
16
24
  },
17
25
  props: {
18
- modelValue: '',
26
+ modelValue: undefined,
19
27
  required: true,
20
28
  showSuccessMessages: true,
29
+ outlined: true,
21
30
  },
22
31
  })
23
32
  })
24
33
 
25
34
  it('renders correctly', () => {
26
35
  expect(wrapper.exists()).toBe(true)
27
- expect(wrapper.find('.vd-number-field').exists()).toBe(true)
28
- expect(wrapper.find('.vd-key-field').exists()).toBe(true)
36
+ expect(wrapper.find('.number-field').exists()).toBe(true)
37
+ expect(wrapper.find('.key-field').exists()).toBe(true)
29
38
  })
30
39
 
31
40
  it('displays error message for invalid NIR length', async () => {
32
- const numberField = wrapper.find('.vd-number-field input')
33
- await numberField.setValue('123') // Invalid length
34
- await numberField.trigger('blur')
35
- expect(wrapper.find('.v-messages__message').text()).toContain('Le numéro de sécurité sociale doit contenir 13 caractères.')
41
+ await wrapper.find('.number-field input').setValue('123')
42
+ await wrapper.find('.number-field input').trigger('blur')
43
+ await wrapper.vm.$nextTick()
44
+ expect(wrapper.vm.numberValidation.errors.value[0]).toBe('Le numéro de sécurité sociale est invalide.')
36
45
  })
37
46
 
38
47
  it('validates the NIR field successfully', async () => {
39
- const numberField = wrapper.find('.vd-number-field input')
40
- await numberField.setValue('2940375120005') // Valid NIR length
41
- expect(wrapper.find('.v-messages__message--success').exists()).toBe(true)
48
+ await wrapper.find('.number-field input').setValue('2940375120005')
49
+ await wrapper.find('.number-field input').trigger('blur')
50
+ await wrapper.vm.$nextTick()
51
+ expect(wrapper.vm.numberValidation.successes.value).toContain('Le numéro de sécurité sociale est valide.')
42
52
  })
43
53
 
44
54
  it('displays error message for invalid key length', async () => {
45
- const numberField = wrapper.find('.vd-number-field input')
46
- await numberField.setValue('2940375120005') // Valid NIR length
47
- const keyField = wrapper.find('.vd-key-field input')
48
- await keyField.setValue('1') // Invalid length
49
- await keyField.trigger('blur')
50
- expect(wrapper.find('.v-messages__message').text()).toContain('La clé du numéro de sécurité sociale doit contenir 2 caractères.')
55
+ await wrapper.find('.number-field input').setValue('2940375120005')
56
+ await wrapper.find('.key-field input').setValue('1')
57
+ await wrapper.find('.key-field input').trigger('blur')
58
+ await wrapper.vm.$nextTick()
59
+ expect(wrapper.vm.keyValidation.errors.value[0]).toBe('La clé du numéro de sécurité sociale est invalide.')
51
60
  })
52
61
 
53
62
  it('validates the key field successfully', async () => {
54
- const numberField = wrapper.find('.vd-number-field input')
55
- const keyField = wrapper.find('.vd-key-field input')
56
- await numberField.setValue('2940375120005')
57
- await keyField.setValue('91')
58
- expect(wrapper.find('.v-messages__message--success').exists()).toBe(true)
63
+ await wrapper.find('.number-field input').setValue('2940375120005')
64
+ await wrapper.find('.key-field input').setValue('91')
65
+ await wrapper.find('.key-field input').trigger('blur')
66
+ await wrapper.vm.$nextTick()
67
+ expect(wrapper.vm.keyValidation.successes.value).toContain('Le champ Clé est valide.')
59
68
  })
60
69
 
61
70
  it('hides the key field when displayKey is false', async () => {
62
71
  await wrapper.setProps({ displayKey: false })
63
- expect(wrapper.find('.vd-key-field').exists()).toBe(false)
72
+ expect(wrapper.find('.key-field').exists()).toBe(false)
64
73
  })
65
74
 
66
75
  it('calls validateOnSubmit and returns true if no errors', async () => {
67
- const numberField = wrapper.find('.vd-number-field input')
68
- const keyField = wrapper.find('.vd-key-field input')
76
+ wrapper = mount(NirField, {
77
+ global: {
78
+ plugins: [vuetify],
79
+ },
80
+ props: {
81
+ modelValue: undefined,
82
+ required: false,
83
+ outlined: true,
84
+ },
85
+ })
69
86
 
87
+ const numberField = wrapper.find('.number-field input')
70
88
  await numberField.setValue('2940375120005')
71
- await keyField.setValue('91')
89
+ await numberField.trigger('blur')
72
90
 
73
91
  await wrapper.vm.$nextTick()
74
-
75
- wrapper.vm.validateFields()
76
-
77
- const isValid = wrapper.vm.validateOnSubmit()
92
+ const isValid = await wrapper.vm.validateOnSubmit()
78
93
 
79
94
  expect(isValid).toBe(true)
80
- expect(wrapper.vm.errors.length).toBe(0)
81
95
  })
96
+
82
97
  it('applies custom key rules when provided', async () => {
83
- const customKeyRules = [
84
- {
85
- type: 'custom',
86
- options: {
87
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
88
- validate: (value: any) => value === '91',
89
- message: 'Custom key validation failed.',
90
- successMessage: 'Custom key validation passed.',
91
- },
98
+ const customKeyRules = [{
99
+ type: 'custom',
100
+ options: {
101
+ validate: (value: string) => value === '91',
102
+ message: 'Custom key validation failed.',
103
+ successMessage: 'Custom key validation passed.',
104
+ fieldIdentifier: 'clé',
92
105
  },
93
- ]
106
+ }]
94
107
 
95
108
  wrapper = mount(NirField, {
96
109
  global: {
97
110
  plugins: [vuetify],
98
111
  },
99
112
  props: {
100
- modelValue: '',
101
- required: true,
113
+ modelValue: undefined,
102
114
  customKeyRules,
115
+ showSuccessMessages: true,
116
+ outlined: true,
103
117
  },
104
118
  })
105
- const numberField = wrapper.find('.vd-number-field input')
106
- const keyField = wrapper.find('.vd-key-field input')
119
+
120
+ const numberField = wrapper.find('.number-field input')
121
+ const keyField = wrapper.find('.key-field input')
107
122
  await numberField.setValue('2940375120005')
108
123
  await keyField.setValue('91')
109
-
124
+ await keyField.trigger('blur')
110
125
  await wrapper.vm.$nextTick()
126
+ expect(wrapper.vm.keyValidation.successes.value).toContain('Custom key validation passed.')
127
+ })
111
128
 
112
- expect(wrapper.vm.errors.length).toBe(0)
113
- expect(wrapper.vm.successes).toContain('Custom key validation passed.')
129
+ it('emits update:modelValue with correct format', async () => {
130
+ const numberField = wrapper.find('.number-field input')
131
+ const keyField = wrapper.find('.key-field input')
132
+ await numberField.setValue('2940375120005')
133
+ await wrapper.vm.$nextTick()
134
+ await keyField.setValue('91')
135
+ await wrapper.vm.$nextTick()
136
+ expect(wrapper.emitted('update:modelValue')?.slice(-1)[0]).toEqual(['294037512000591'])
137
+ })
114
138
 
115
- await keyField.setValue('11')
139
+ it('emits undefined when both fields are empty', async () => {
140
+ const numberField = wrapper.find('.number-field input')
141
+ const keyField = wrapper.find('.key-field input')
142
+ await numberField.setValue('')
143
+ await keyField.setValue('')
116
144
  await wrapper.vm.$nextTick()
145
+ expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([undefined])
146
+ })
117
147
 
118
- expect(wrapper.vm.errors).toContain('Custom key validation failed.')
148
+ it('splits modelValue correctly when provided', async () => {
149
+ await wrapper.setProps({ modelValue: '294037512000591' })
150
+ await wrapper.vm.$nextTick()
151
+ const numberInput = wrapper.find('.number-field input').element as HTMLInputElement
152
+ const keyInput = wrapper.find('.key-field input').element as HTMLInputElement
153
+ expect(numberInput.value.replace(/\s/g, '')).toBe('2940375120005')
154
+ expect(keyInput.value).toBe('91')
119
155
  })
120
156
  })
@@ -0,0 +1,12 @@
1
+ | # | Input | Expected Result | Description |
2
+ |----|-------------------|-----------------|-----------------------------------------------------------------------------------------------|
3
+ | 1 | 1840275123456 74 | valid | NIR complet avec clé correcte (ex. homme né en 1984, département 75...). |
4
+ | 2 | 2910256012345 46 | valid | NIR complet avec clé correcte (ex. femme née en 1991, département 25...). |
5
+ | 3 | 198012312345690 | valid | NIR complet (ex. homme né en 1980, département 12...), clé calculée et valide. |
6
+ | 4 | 2551299123457 80 | valid | NIR complet (ex. femme née en 1951, département 29...). |
7
+ | 5 | 2100121101003 73 | valid | NIR complet (ex. femme née en 2000, département 21...). |
8
+ | 6 | 3840275123456 74 | invalid | Le premier chiffre (3) n'est pas valide (doit être 1 ou 2). |
9
+ | 7 | 1841375123456 74 | invalid | Le mois 13 est invalide (doit être compris entre 01 et 12). |
10
+ | 8 | 1840275123456 73 | invalid | Clé de contrôle incorrecte (73 au lieu de 74). |
11
+ | 9 | 1840A75123456 74 | invalid | Contient une lettre 'A' dans la chaîne, format strictement numérique attendu. |
12
+ | 10 | 1840275123456 | invalid | Chaîne trop courte (13 chiffres sans clé). Le NIR doit comporter 15 chiffres. |
@@ -159,6 +159,10 @@ export const Legende: StoryObj = {
159
159
  </div>
160
160
  </div>
161
161
  </div>
162
+ <div class="mt-4">
163
+ <p>Rapport d’audit manuel : <a href="/audits/NotificationBar.xlsx" style="color:#0C41BD;">Voir le rapport</a></p>
164
+ <p style="color: grey; font-size: 14px">Correctifs en cours (<a href="https://github.com/assurance-maladie-digital/design-system/issues/3967" target="_blank" style="color:#0C41BD;">issue #3967</a>)</p>
165
+ </div>
162
166
  `,
163
167
  }
164
168
  },
@@ -115,7 +115,7 @@ Default.args = {
115
115
  closeBtnText: 'Fermer',
116
116
  type: 'info',
117
117
  bottom: false,
118
- rounded: 'rounded',
118
+ rounded: '4',
119
119
  }
120
120
 
121
121
  Default.parameters = {
@@ -128,7 +128,6 @@ Default.parameters = {
128
128
  v-model="showNotification"
129
129
  :close-btn-text="closeBtnText"
130
130
  :bottom="bottom"
131
- :rounded="rounded"
132
131
  :type="type"
133
132
  >
134
133
  <template #default>This is a {{ type }} notification</template>
@@ -150,7 +149,7 @@ Default.parameters = {
150
149
  import { VBtn } from 'vuetify/components'
151
150
  import { NotificationBar } from '@cnamts/synapse'
152
151
  import { ref } from 'vue'
153
- import { useNotificationService } from '@/services/NotificationService'
152
+ import { useNotificationService } from '@cnamts/synpase'
154
153
 
155
154
  const { addNotification } = useNotificationService()
156
155
  const showNotification = ref(false)
@@ -174,6 +173,7 @@ Default.parameters = {
174
173
  export const Success: Story = Default.bind({})
175
174
  Success.args = {
176
175
  ...Default.args,
176
+ rounded: 'pill',
177
177
  type: 'success',
178
178
  }
179
179
  Success.parameters = {
@@ -186,7 +186,7 @@ Success.parameters = {
186
186
  v-model="showNotification"
187
187
  :close-btn-text="closeBtnText"
188
188
  :bottom="bottom"
189
- :rounded="rounded"
189
+ :rounded="pill"
190
190
  type="success"
191
191
  >
192
192
  <template #default>This is a success notification</template>
@@ -208,7 +208,7 @@ Success.parameters = {
208
208
  import { VBtn } from 'vuetify/components'
209
209
  import { NotificationBar } from '@cnamts/synapse'
210
210
  import { ref } from 'vue'
211
- import { useNotificationService } from '@/services/NotificationService'
211
+ import { useNotificationService } from '@cnamts/synpase'
212
212
 
213
213
  const { addNotification } = useNotificationService()
214
214
  const showNotification = ref(false)
@@ -232,6 +232,7 @@ Success.parameters = {
232
232
  export const Warning: Story = Default.bind({})
233
233
  Warning.args = {
234
234
  ...Default.args,
235
+ rounded: 'pill',
235
236
  type: 'warning',
236
237
  }
237
238
  Warning.parameters = {
@@ -244,7 +245,7 @@ Warning.parameters = {
244
245
  v-model="showNotification"
245
246
  :close-btn-text="closeBtnText"
246
247
  :bottom="bottom"
247
- :rounded="rounded"
248
+ :rounded="pill"
248
249
  type="warning"
249
250
  >
250
251
  <template #default>This is a warning notification</template>
@@ -266,7 +267,7 @@ Warning.parameters = {
266
267
  import { VBtn } from 'vuetify/components'
267
268
  import { NotificationBar } from '@cnamts/synapse'
268
269
  import { ref } from 'vue'
269
- import { useNotificationService } from '@/services/NotificationService'
270
+ import { useNotificationService } from '@cnamts/synpase'
270
271
 
271
272
  const { addNotification } = useNotificationService()
272
273
  const showNotification = ref(false)
@@ -290,6 +291,7 @@ Warning.parameters = {
290
291
  export const Error: Story = Default.bind({})
291
292
  Error.args = {
292
293
  ...Default.args,
294
+ rounded: 'pill',
293
295
  type: 'error',
294
296
  }
295
297
  Error.parameters = {
@@ -302,7 +304,7 @@ Error.parameters = {
302
304
  v-model="showNotification"
303
305
  :close-btn-text="closeBtnText"
304
306
  :bottom="bottom"
305
- :rounded="rounded"
307
+ :rounded="pill"
306
308
  type="error"
307
309
  >
308
310
  <template #default>This is an error notification</template>
@@ -324,7 +326,7 @@ Error.parameters = {
324
326
  import { VBtn } from 'vuetify/components'
325
327
  import { NotificationBar } from '@cnamts/synapse'
326
328
  import { ref } from 'vue'
327
- import { useNotificationService } from '@/services/NotificationService'
329
+ import { useNotificationService } from '@cnamts/synpase'
328
330
 
329
331
  const { addNotification } = useNotificationService()
330
332
  const showNotification = ref(false)
@@ -348,6 +350,7 @@ Error.parameters = {
348
350
  export const Bottom: Story = Default.bind({})
349
351
  Bottom.args = {
350
352
  ...Default.args,
353
+ rounded: 'pill',
351
354
  bottom: true,
352
355
  }
353
356
  Bottom.parameters = {
@@ -360,7 +363,7 @@ Bottom.parameters = {
360
363
  v-model="showNotification"
361
364
  :close-btn-text="closeBtnText"
362
365
  :bottom="true"
363
- :rounded="rounded"
366
+ :rounded="pill"
364
367
  :type="type"
365
368
  >
366
369
  <template #default>This is a bottom-positioned notification</template>
@@ -382,7 +385,7 @@ Bottom.parameters = {
382
385
  import { VBtn } from 'vuetify/components'
383
386
  import { NotificationBar } from '@cnamts/synapse'
384
387
  import { ref } from 'vue'
385
- import { useNotificationService } from '@/services/NotificationService'
388
+ import { useNotificationService } from '@cnamts/synpase'
386
389
 
387
390
  const { addNotification } = useNotificationService()
388
391
  const showNotification = ref(false)
@@ -406,6 +409,7 @@ Bottom.parameters = {
406
409
  export const CustomCloseBtnText: Story = Default.bind({})
407
410
  CustomCloseBtnText.args = {
408
411
  ...Default.args,
412
+ rounded: 'pill',
409
413
  closeBtnText: 'Masquer',
410
414
  }
411
415
  CustomCloseBtnText.parameters = {
@@ -418,7 +422,7 @@ CustomCloseBtnText.parameters = {
418
422
  v-model="showNotification"
419
423
  close-btn-text="Masquer"
420
424
  :bottom="bottom"
421
- :rounded="rounded"
425
+ :rounded="pill"
422
426
  :type="type"
423
427
  >
424
428
  <template #default>This is a notification with custom close button text</template>
@@ -440,10 +444,11 @@ CustomCloseBtnText.parameters = {
440
444
  import { VBtn } from 'vuetify/components'
441
445
  import { NotificationBar } from '@cnamts/synapse'
442
446
  import { ref } from 'vue'
443
- import { useNotificationService } from '@/services/NotificationService'
447
+ import { useNotificationService } from '@cnamts/synpase'
444
448
 
445
449
  const { addNotification } = useNotificationService()
446
450
  const showNotification = ref(false)
451
+ const rounded = 'pill'
447
452
 
448
453
  const envoyerNotification = (message: string) => {
449
454
  const notification = {
@@ -1,70 +1,152 @@
1
- import {Canvas, Meta, Controls, Source} from '@storybook/blocks';
2
- import * as PasswordFieldStories from './PasswordField.stories';
3
- import PasswordField from './PasswordField.vue';
1
+ import { Meta, Canvas, Controls, Source } from '@storybook/blocks'
2
+ import * as PasswordFieldStories from './PasswordField.stories'
4
3
 
5
- <Meta title="Composants/Formulaires/PasswordField" component={PasswordField}/>
4
+ <Meta of={PasswordFieldStories} />
6
5
 
7
6
  # PasswordField
8
7
 
9
- Le composant `PasswordField` est utilisé pour afficher un champ de saisie de mot de passe et gérer sa validation.
10
- Il permet également d’afficher ou de masquer le contenu du champ à l’aide d’une icône.
8
+ Le composant `PasswordField` est un champ de saisie sécurisé conçu pour la gestion des mots de passe. Il hérite des fonctionnalités du composant `SyTextField` tout en ajoutant des fonctionnalités spécifiques à la saisie de mots de passe.
11
9
 
12
- <Canvas story={{height: '150px'}} of={PasswordFieldStories.Default}/>
10
+ ## Utilisation basique
13
11
 
14
- # API
12
+ La version de base du composant avec le style outlined par défaut.
15
13
 
16
- <Controls of={PasswordFieldStories.Default}/>
14
+ <Canvas of={PasswordFieldStories.Default} />
17
15
 
18
- ## Utilisation de base
16
+ ## Fonctionnalités principales
17
+
18
+ - **Masquage/affichage du mot de passe** : Une icône permet de basculer entre l'affichage en clair et masqué
19
+ - **Validation personnalisable** : Support des messages d'erreur, d'avertissement et de succès
20
+ - **Styles configurables** : Choix entre les styles `outlined` et `underlined`
21
+ - **États spéciaux** : Support des états désactivé et lecture seule
22
+ - **Validation automatique** : Validation à la perte de focus configurable
23
+
24
+ ## API
25
+
26
+ <Controls of={PasswordFieldStories.Default} />
27
+
28
+ <Source
29
+ dark code={`
30
+ <template>
31
+ <PasswordField
32
+ v-model="password"
33
+ label="Mot de passe"
34
+ />
35
+ </template>
19
36
 
20
- <Source
21
- dark
22
- code={`
23
37
  <script setup lang="ts">
24
- import { ref } from 'vue'
25
- import { PasswordField } from '@cnamts/synapse'
26
-
27
- const password = ref('')
28
- const passwordFieldRef = ref() // Référence Vue pour accéder au composant enfant
29
-
30
- function handleSubmit() {
31
- // Appeler la méthode exposée validateOnSubmit via la référence
32
- const isValid = passwordFieldRef.value?.validateOnSubmit()
33
- if (!isValid) {
34
- alert('Veuillez corriger les erreurs avant de soumettre.')
35
- } else {
36
- alert('Formulaire soumis avec succès !')
37
- }
38
- }
39
- </script>
38
+ import { ref } from 'vue'
39
+ import { PasswordField } from '@cnamts/synapse'
40
40
 
41
- <template>
42
- <form @submit.prevent="handleSubmit">
43
- <PasswordField
44
- ref="passwordFieldRef"
45
- v-model="password"
46
- outlined
47
- :is-validate-on-blur="true"
48
- />
49
- <button type="submit">Soumettre</button>
50
- </form>
51
- </template>
41
+ const password = ref('')
42
+ </script>
52
43
  `}
53
44
  />
54
45
 
55
- ## Gestion de la validation
46
+ ## Validation
47
+
48
+ ### Validation simple
49
+
50
+ Le composant peut être requis et afficher un message d'erreur si le champ est vide.
51
+
52
+ <Canvas of={PasswordFieldStories.Required} />
53
+
54
+ ### Validation avancée
55
+
56
+ Exemple complet montrant les différents types de validation (erreurs, avertissements, succès).
57
+
58
+ <Canvas of={PasswordFieldStories.WithValidation} />
59
+
60
+ ### Exemples d'états de validation
61
+
62
+ <div className="sb-grid">
63
+ <div>
64
+ <h4>Avec erreur</h4>
65
+ <Canvas of={PasswordFieldStories.WithError} />
66
+ </div>
67
+ <div>
68
+ <h4>Avec avertissement</h4>
69
+ <Canvas of={PasswordFieldStories.WithWarning} />
70
+ </div>
71
+ <div>
72
+ <h4>Avec succès</h4>
73
+ <Canvas of={PasswordFieldStories.WithSuccess} />
74
+ </div>
75
+ </div>
76
+
77
+ ### Validation de formulaire
78
+
79
+ Le composant expose une méthode `validateOnSubmit` pour valider le champ lors de la soumission d'un formulaire.
80
+
81
+ <Canvas of={PasswordFieldStories.WithFormValidation} />
82
+
83
+ <Source
84
+ dark code={`
85
+ <template>
86
+ <form @submit.prevent="handleSubmit">
87
+ <PasswordField
88
+ ref="passwordFieldRef"
89
+ v-model="password"
90
+ required
91
+ :custom-rules="customRules"
92
+ />
93
+ <button type="submit">Valider</button>
94
+ </form>
95
+ </template>
96
+
97
+ <script setup lang="ts">
98
+ import { ref } from 'vue'
99
+ import { PasswordField } from '@cnamts/synapse'
100
+
101
+ const password = ref('')
102
+ const passwordFieldRef = ref()
103
+
104
+ const customRules = [{
105
+ type: 'custom',
106
+ options: {
107
+ message: 'Le mot de passe doit contenir au moins 8 caractères',
108
+ validate: (value: string) => value.length >= 8
109
+ }
110
+ }]
111
+
112
+ function handleSubmit() {
113
+ const isValid = passwordFieldRef.value?.validateOnSubmit()
114
+ if (!isValid) {
115
+ // Gérer l'erreur
116
+ return
117
+ }
118
+ // Continuer avec la soumission
119
+ }
120
+ </script>
121
+ `}
122
+ />
56
123
 
57
- ### Validation par défaut
124
+ ### Méthodes exposées
58
125
 
59
- - **required** : Si `true`, le champ est obligatoire et affiche une erreur si le champ est vide.
60
- - **isValidateOnBlur** : Si `true`, la validation se déclenche automatiquement lors du blur (perte de focus).
126
+ Le composant expose les méthodes et propriétés suivantes via `defineExpose` :
61
127
 
62
- ### Règles de validation personnalisées (props `customRules`)
128
+ - **showEyeIcon** : (ref) Contrôle l'affichage du mot de passe
129
+ - **errors** : (ref) Liste des erreurs de validation actuelles
130
+ - **warnings** : (ref) Liste des avertissements actuels
131
+ - **successes** : (ref) Liste des messages de succès actuels
132
+ - **validateOnSubmit** : () => boolean - Méthode pour valider le champ, retourne true si valide
63
133
 
64
- Vous pouvez définir des règles de validation personnalisées sous forme de tableau d’objets.
134
+ ## Bonnes pratiques
65
135
 
66
- Pour savoir comment utiliser les règles personnalisées, veuillez consulter la section [Comment utiliser les rules](/docs/guide-du-dev-comment-utiliser-les-rules--docs).
136
+ 1. **Validation progressive** :
137
+ - Utilisez `isValidateOnBlur` pour une validation en temps réel
138
+ - Combinez erreurs, avertissements et succès pour guider l'utilisateur
67
139
 
140
+ 2. **Messages clairs** :
141
+ - Utilisez des messages d'erreur explicites
142
+ - Fournissez des suggestions d'amélioration via les warnings
143
+ - Confirmez les bonnes pratiques avec les messages de succès
68
144
 
145
+ 3. **Accessibilité** :
146
+ - Toujours fournir un label explicite
147
+ - Utiliser la prop `required` quand nécessaire
148
+ - Considérer l'utilisation de `displayAsterisk` pour les champs requis
69
149
 
150
+ ## En savoir plus
70
151
 
152
+ Pour plus d'informations sur l'utilisation des règles de validation, consultez la section [Comment utiliser les rules](/docs/guide-du-dev-comment-utiliser-les-rules--docs).