@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
@@ -3,6 +3,7 @@ import SySelect from '@/components/Customs/SySelect/SySelect.vue'
3
3
  import SyAlert from '@/components/SyAlert/SyAlert.vue'
4
4
  import { VBtn, VMenu, VList, VListItem, VListItemTitle } from 'vuetify/components'
5
5
  import { ref } from 'vue'
6
+ import { fn } from '@storybook/test'
6
7
 
7
8
  const meta: Meta<typeof SySelect> = {
8
9
  title: 'Composants/Formulaires/SySelect',
@@ -16,6 +17,19 @@ const meta: Meta<typeof SySelect> = {
16
17
  items: { control: 'object' },
17
18
  errorMessages: { control: 'object' },
18
19
  required: { control: 'boolean' },
20
+ displayAsterisk: { control: 'boolean' },
21
+ textKey: {
22
+ control: 'text',
23
+ description: 'Nom de la propriété qui contient le texte à afficher',
24
+ },
25
+ valueKey: {
26
+ control: 'text',
27
+ description: 'Nom de la propriété qui contient la valeur à retourner',
28
+ },
29
+ returnObject: {
30
+ control: 'boolean',
31
+ description: 'Retourne l\'objet complet sélectionné',
32
+ },
19
33
  },
20
34
  } as Meta<typeof SySelect>
21
35
 
@@ -52,10 +66,11 @@ export const Default: Story = {
52
66
  ],
53
67
  },
54
68
  args: {
55
- items: [
69
+ 'items': [
56
70
  { text: 'Option 1', value: '1' },
57
71
  { text: 'Option 2', value: '2' },
58
72
  ],
73
+ 'onUpdate:modelValue': fn(),
59
74
  },
60
75
  render: (args) => {
61
76
  return {
@@ -106,11 +121,12 @@ export const Required: Story = {
106
121
  ],
107
122
  },
108
123
  args: {
109
- items: [
124
+ 'items': [
110
125
  { text: 'Option 1', value: '1' },
111
126
  { text: 'Option 2', value: '2' },
112
127
  ],
113
- required: true,
128
+ 'required': true,
129
+ 'onUpdate:modelValue': fn(),
114
130
  },
115
131
  render: (args) => {
116
132
  return {
@@ -130,6 +146,71 @@ export const Required: Story = {
130
146
  },
131
147
  }
132
148
 
149
+ export const RequiredWithAsterisk: Story = {
150
+ parameters: {
151
+ docs: {
152
+ description: {
153
+ story: 'Version du champ de sélection requis avec un astérisque visuel.',
154
+ },
155
+ },
156
+ sourceCode: [
157
+ {
158
+ name: 'Template',
159
+ code: `
160
+ <template>
161
+ <SySelect
162
+ v-model="value"
163
+ :items="items"
164
+ label="Sélectionnez une option"
165
+ required
166
+ display-asterisk
167
+ />
168
+ </template>
169
+ `,
170
+ },
171
+ {
172
+ name: 'Script',
173
+ code: `
174
+ <script setup lang="ts">
175
+ import { ref } from 'vue'
176
+ import SySelect from '@cnamts/synapse'
177
+
178
+ const value = ref('')
179
+ const items = [
180
+ { text: 'Option 1', value: '1' },
181
+ { text: 'Option 2', value: '2' },
182
+ ]
183
+ </script>
184
+ `,
185
+ },
186
+ ],
187
+ },
188
+ args: {
189
+ ...Default.args,
190
+ 'label': 'Sélectionnez une option',
191
+ 'required': true,
192
+ 'displayAsterisk': true,
193
+ 'onUpdate:modelValue': fn(),
194
+ },
195
+ render: (args) => {
196
+ return {
197
+ components: { SySelect },
198
+ setup() {
199
+ return { args }
200
+ },
201
+ template: `
202
+ <div class="pa-4">
203
+ <SySelect
204
+ v-bind="args"
205
+ :required="args.required"
206
+ :display-asterisk="args.displayAsterisk"
207
+ />
208
+ </div>
209
+ `,
210
+ }
211
+ },
212
+ }
213
+
133
214
  export const withCustomError: Story = {
134
215
  parameters: {
135
216
  sourceCode: [
@@ -171,10 +252,11 @@ export const withCustomError: Story = {
171
252
  ],
172
253
  },
173
254
  args: {
174
- items: [
255
+ 'items': [
175
256
  { text: 'Option 1', value: '1' },
176
257
  { text: 'Option 2', value: '2' },
177
258
  ],
259
+ 'onUpdate:modelValue': fn(),
178
260
  },
179
261
  render: (args) => {
180
262
  return {
@@ -235,10 +317,11 @@ export const withCustomKey: Story = {
235
317
  ],
236
318
  },
237
319
  args: {
238
- items: [
320
+ 'items': [
239
321
  { customKey: 'Choix 1', value: '1' },
240
322
  { customKey: 'Choix 2', value: '2' },
241
323
  ],
324
+ 'onUpdate:modelValue': fn(),
242
325
  },
243
326
  render: (args) => {
244
327
  return {
@@ -14,7 +14,7 @@
14
14
  },
15
15
  label: {
16
16
  type: String,
17
- default: '',
17
+ default: 'Sélectionnez une option',
18
18
  },
19
19
  errorMessages: {
20
20
  type: [String, Array] as PropType<string | readonly string[]>,
@@ -44,6 +44,14 @@
44
44
  type: String,
45
45
  default: 'value',
46
46
  },
47
+ displayAsterisk: {
48
+ type: Boolean,
49
+ default: false,
50
+ },
51
+ returnObject: {
52
+ type: Boolean,
53
+ default: false,
54
+ },
47
55
  })
48
56
 
49
57
  const emit = defineEmits(['update:modelValue'])
@@ -65,8 +73,14 @@
65
73
 
66
74
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
67
75
  const selectItem = (item: any) => {
68
- selectedItem.value = item
69
- emit('update:modelValue', item)
76
+ if (props.returnObject) {
77
+ selectedItem.value = item
78
+ emit('update:modelValue', item)
79
+ }
80
+ else {
81
+ selectedItem.value = item[props.valueKey]
82
+ emit('update:modelValue', item[props.valueKey])
83
+ }
70
84
  isOpen.value = false
71
85
  }
72
86
 
@@ -76,11 +90,22 @@
76
90
  }
77
91
 
78
92
  const selectedItemText = computed(() => {
79
- if (selectedItem.value && typeof selectedItem.value === 'object') {
80
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
81
- return (selectedItem.value as Record<string, any>)[props.textKey]
93
+ if (selectedItem.value) {
94
+ if (props.returnObject) {
95
+ return (selectedItem.value as Record<string, unknown>)[props.textKey]
96
+ }
97
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
+ return props.items.find((item: any) => item[props.valueKey] === selectedItem.value)?.[props.textKey]
82
99
  }
83
- return props.label
100
+ return ''
101
+ })
102
+
103
+ const isShouldDisplayAsterisk = computed(() => {
104
+ return props.displayAsterisk && props.required
105
+ })
106
+
107
+ const labelWithAsterisk = computed(() => {
108
+ return isShouldDisplayAsterisk.value ? `${props.label} *` : props.label
84
109
  })
85
110
 
86
111
  const formattedItems = computed(() => {
@@ -134,16 +159,17 @@
134
159
  ref="input"
135
160
  v-model="selectedItemText"
136
161
  v-click-outside="closeList"
137
- title="Sélectionnez une option"
162
+ :title="labelWithAsterisk"
138
163
  color="primary"
139
164
  tabindex="0"
140
165
  readonly
141
166
  :disabled="disabled"
142
- :label="selectedItem ? label : 'Sélectionnez une option'"
143
- :aria-label="selectedItem ? label : 'Sélectionnez une option'"
167
+ :label="labelWithAsterisk"
168
+ :aria-label="labelWithAsterisk"
144
169
  :error-messages="errorMessages"
145
170
  :variant="outlined ? 'outlined' : 'underlined'"
146
171
  :rules="isRequired ? ['Le champ est requis.'] : []"
172
+ :display-asterisk="displayAsterisk"
147
173
  class="sy-select"
148
174
  :style="hasError ? { minWidth: `${labelWidth + 18}px`} : {minWidth: `${labelWidth}px`}"
149
175
  @click="toggleMenu"
@@ -89,7 +89,11 @@ describe('SySelect.vue', () => {
89
89
 
90
90
  it('returns the correct text when selectedItem is an object', async () => {
91
91
  const wrapper = mount(SySelect, {
92
- props: { modelValue: { text: 'Option 1', value: '1' }, textKey: 'text' },
92
+ props: {
93
+ modelValue: { text: 'Option 1', value: '1' },
94
+ textKey: 'text',
95
+ returnObject: true,
96
+ },
93
97
  global: {
94
98
  plugins: [vuetify],
95
99
  },
@@ -100,6 +104,24 @@ describe('SySelect.vue', () => {
100
104
  expect(instance.selectedItemText).toBe('Option 1')
101
105
  })
102
106
 
107
+ it('returns the correct text when selectedItem is a value', async () => {
108
+ const wrapper = mount(SySelect, {
109
+ props: {
110
+ items: [{ text: 'Option 1', value: '1' }, { text: 'Option 2', value: '2' }],
111
+ modelValue: '1',
112
+ textKey: 'text',
113
+ },
114
+ global: {
115
+ plugins: [vuetify],
116
+ },
117
+ })
118
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
119
+ const instance = wrapper.vm as any
120
+ await wrapper.setProps({ modelValue: '2' })
121
+ await wrapper.vm.$nextTick()
122
+ expect(instance.selectedItemText).toBe('Option 2')
123
+ })
124
+
103
125
  it('formats items correctly', () => {
104
126
  const items = ['Option 1', 'Option 2']
105
127
  const wrapper = mount(SySelect, {
@@ -163,7 +185,7 @@ describe('SySelect.vue', () => {
163
185
  const instance = wrapper.vm as any
164
186
  instance.selectItem({ text: 'Option 1', value: '1' })
165
187
  await wrapper.vm.$nextTick()
166
- expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ text: 'Option 1', value: '1' }])
188
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['1'])
167
189
  })
168
190
 
169
191
  it('closes the menu when v-click-outside directive is called', async () => {
@@ -190,4 +212,115 @@ describe('SySelect.vue', () => {
190
212
  await wrapper.vm.closeList()
191
213
  expect(wrapper.vm.isOpen).toBe(false)
192
214
  })
215
+
216
+ it('emit the value when returnObject is false', async () => {
217
+ const wrapper = mount(SySelect, {
218
+ props: {
219
+ returnObject: false,
220
+ items: [{ text: 'Option 1', value: '1' }, { text: 'Option 2', value: '2' }],
221
+ },
222
+ global: {
223
+ plugins: [vuetify],
224
+ },
225
+ })
226
+ await wrapper.find('.sy-select').trigger('click')
227
+ const firstItem = wrapper.findAll('.v-list-item').at(0)
228
+ await firstItem!.trigger('click')
229
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['1'])
230
+
231
+ await wrapper.find('.sy-select').trigger('click')
232
+ const secondItem = wrapper.findAll('.v-list-item').at(1)
233
+ await secondItem!.trigger('click')
234
+ expect(wrapper.emitted()['update:modelValue'][1]).toEqual(['2'])
235
+ })
236
+
237
+ it('emit the object when returnObject is true', async () => {
238
+ const wrapper = mount(SySelect, {
239
+ props: {
240
+ returnObject: true,
241
+ items: [{ text: 'Option 1', value: '1' }, { text: 'Option 2', value: '2' }],
242
+ },
243
+ global: {
244
+ plugins: [vuetify],
245
+ },
246
+ })
247
+
248
+ await wrapper.find('.sy-select').trigger('click')
249
+ const firstItem = wrapper.findAll('.v-list-item').at(0)
250
+ await firstItem!.trigger('click')
251
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ text: 'Option 1', value: '1' }])
252
+
253
+ await wrapper.find('.sy-select').trigger('click')
254
+ const secondItem = wrapper.findAll('.v-list-item').at(1)
255
+ await secondItem!.trigger('click')
256
+ expect(wrapper.emitted()['update:modelValue'][1]).toEqual([{ text: 'Option 2', value: '2' }])
257
+ })
258
+
259
+ it('emit the value when returnObject is false with textKey and keyValue set', async () => {
260
+ const wrapper = mount(SySelect, {
261
+ props: {
262
+ returnObject: false,
263
+ textKey: 'theText',
264
+ valueKey: 'theValue',
265
+ items: [{ theText: 'Option 1', theValue: '1' }, { theText: 'Option 2', theValue: '2' }],
266
+ },
267
+ global: {
268
+ plugins: [vuetify],
269
+ },
270
+ })
271
+ await wrapper.find('.sy-select').trigger('click')
272
+ const firstItem = wrapper.findAll('.v-list-item').at(0)
273
+ await firstItem!.trigger('click')
274
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['1'])
275
+
276
+ await wrapper.find('.sy-select').trigger('click')
277
+ const secondItem = wrapper.findAll('.v-list-item').at(1)
278
+ await secondItem!.trigger('click')
279
+ expect(wrapper.emitted()['update:modelValue'][1]).toEqual(['2'])
280
+ })
281
+
282
+ it('emit the object when returnObject is true with textKey and keyValue set', async () => {
283
+ const wrapper = mount(SySelect, {
284
+ props: {
285
+ returnObject: true,
286
+ textKey: 'theText',
287
+ valueKey: 'theValue',
288
+ items: [{ theText: 'Option 1', theValue: '1' }, { theText: 'Option 2', theValue: '2' }],
289
+ },
290
+ global: {
291
+ plugins: [vuetify],
292
+ },
293
+ })
294
+
295
+ await wrapper.find('.sy-select').trigger('click')
296
+ const firstItem = wrapper.findAll('.v-list-item').at(0)
297
+ await firstItem!.trigger('click')
298
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ theText: 'Option 1', theValue: '1' }])
299
+
300
+ await wrapper.find('.sy-select').trigger('click')
301
+ const secondItem = wrapper.findAll('.v-list-item').at(1)
302
+ await secondItem!.trigger('click')
303
+ expect(wrapper.emitted()['update:modelValue'][1]).toEqual([{ theText: 'Option 2', theValue: '2' }])
304
+ })
305
+
306
+ it('emit the value when items is an array of string', async () => {
307
+ const wrapper = mount(SySelect, {
308
+ props: {
309
+ items: ['Option 1', 'Option 2'],
310
+ },
311
+ global: {
312
+ plugins: [vuetify],
313
+ },
314
+ })
315
+
316
+ await wrapper.find('.sy-select').trigger('click')
317
+ const firstItem = wrapper.findAll('.v-list-item').at(0)
318
+ await firstItem!.trigger('click')
319
+ expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['Option 1'])
320
+
321
+ await wrapper.find('.sy-select').trigger('click')
322
+ const secondItem = wrapper.findAll('.v-list-item').at(1)
323
+ await secondItem!.trigger('click')
324
+ expect(wrapper.emitted()['update:modelValue'][1]).toEqual(['Option 2'])
325
+ })
193
326
  })