@cnamts/synapse 0.0.2-alpha → 0.0.4-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 (193) hide show
  1. package/README.md +1 -1
  2. package/dist/design-system-v3.d.ts +712 -27
  3. package/dist/design-system-v3.js +2745 -5384
  4. package/dist/design-system-v3.umd.cjs +10 -2
  5. package/dist/style.css +1 -1
  6. package/package.json +32 -29
  7. package/src/components/Alert/Alert.mdx +1 -1
  8. package/src/components/Alert/Alert.stories.ts +91 -1
  9. package/src/components/Alert/Alert.vue +8 -8
  10. package/src/components/BackBtn/BackBtn.mdx +1 -1
  11. package/src/components/BackBtn/BackBtn.stories.ts +84 -1
  12. package/src/components/BackToTopBtn/BackToTopBtn.mdx +3 -3
  13. package/src/components/BackToTopBtn/BackToTopBtn.stories.ts +172 -11
  14. package/src/components/CollapsibleList/CollapsibleList.mdx +2 -2
  15. package/src/components/CollapsibleList/CollapsibleList.stories.ts +37 -1
  16. package/src/components/CopyBtn/CopyBtn.mdx +1 -1
  17. package/src/components/CopyBtn/CopyBtn.stories.ts +120 -1
  18. package/src/components/CopyBtn/CopyBtn.vue +1 -1
  19. package/src/components/Customs/CustomInputSelect/CustomInputSelect.mdx +6 -8
  20. package/src/components/Customs/CustomInputSelect/CustomInputSelect.stories.ts +270 -4
  21. package/src/components/Customs/CustomInputSelect/CustomInputSelect.vue +80 -53
  22. package/src/components/Customs/CustomInputSelect/config.ts +10 -0
  23. package/src/components/Customs/CustomSelect/CustomSelect.mdx +3 -3
  24. package/src/components/Customs/CustomSelect/CustomSelect.stories.ts +158 -2
  25. package/src/components/Customs/CustomSelect/CustomSelect.vue +25 -6
  26. package/src/components/Customs/CustomTextField/CustomTextField.mdx +44 -0
  27. package/src/components/Customs/CustomTextField/CustomTextField.stories.ts +403 -0
  28. package/src/components/Customs/CustomTextField/CustomTextField.vue +110 -0
  29. package/src/components/Customs/CustomTextField/tests/CustomTextField.spec.ts +93 -0
  30. package/src/components/Customs/CustomTextField/tests/__snapshots__/CustomTextField.spec.ts.snap +59 -0
  31. package/src/components/Customs/CustomTextField/types.d.ts +3 -0
  32. package/src/components/DataList/DataList.mdx +77 -0
  33. package/src/components/DataList/DataList.stories.ts +960 -0
  34. package/src/components/DataList/DataList.vue +140 -0
  35. package/src/components/DataList/DataListLoading/DataListLoading.vue +56 -0
  36. package/src/components/DataList/DataListLoading/tests/DataListLoading.spec.ts +23 -0
  37. package/src/components/DataList/locales.ts +3 -0
  38. package/src/components/DataList/tests/DataList.spec.ts +194 -0
  39. package/src/components/DataList/types.d.ts +23 -0
  40. package/src/components/DataListGroup/DataListGroup.mdx +77 -0
  41. package/src/components/DataListGroup/DataListGroup.stories.ts +987 -0
  42. package/src/components/DataListGroup/DataListGroup.vue +59 -0
  43. package/src/components/DataListGroup/tests/DataListGroup.spec.ts +54 -0
  44. package/src/components/DataListGroup/tests/data/dataListGroupItems.ts +41 -0
  45. package/src/components/DataListGroup/types.d.ts +15 -0
  46. package/src/components/DataListItem/DataListItem.vue +135 -0
  47. package/src/components/DataListItem/config.ts +17 -0
  48. package/src/components/DataListItem/locales.ts +3 -0
  49. package/src/components/DataListItem/tests/DataListItem.spec.ts +156 -0
  50. package/src/components/DataListItem/types.d.ts +23 -0
  51. package/src/components/DownloadBtn/Accessibilite.mdx +14 -0
  52. package/src/components/DownloadBtn/Accessibilite.stories.ts +166 -0
  53. package/src/components/DownloadBtn/AccessibiliteItems.ts +129 -0
  54. package/src/components/DownloadBtn/DownloadBtn.mdx +5 -6
  55. package/src/components/DownloadBtn/DownloadBtn.stories.ts +207 -2
  56. package/src/components/DownloadBtn/constants/ExpertiseLevelEnum.ts +4 -0
  57. package/src/components/FooterBar/FooterBar.mdx +2 -2
  58. package/src/components/FooterBar/FooterBar.stories.ts +1 -1
  59. package/src/components/FranceConnectBtn/FranceConnectBtn.mdx +1 -1
  60. package/src/components/FranceConnectBtn/FranceConnectBtn.stories.ts +58 -1
  61. package/src/components/FranceConnectBtn/FranceConnectBtn.vue +2 -2
  62. package/src/components/HeaderBar/HeaderBar.mdx +256 -0
  63. package/src/components/HeaderBar/HeaderBar.stories.ts +703 -0
  64. package/src/components/HeaderBar/HeaderBar.vue +276 -0
  65. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.mdx +433 -0
  66. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.stories.ts +1089 -0
  67. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.vue +234 -0
  68. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.mdx +38 -0
  69. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.stories.ts +89 -0
  70. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +51 -0
  71. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/tests/HeaderMenuItem.spec.ts +16 -0
  72. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/tests/__snapshots__/HeaderMenuItem.spec.ts.snap +3 -0
  73. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.mdx +17 -0
  74. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.stories.ts +121 -0
  75. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.vue +51 -0
  76. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/tests/HeaderMenuSection.spec.ts +31 -0
  77. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.mdx +43 -0
  78. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.stories.ts +261 -0
  79. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +194 -0
  80. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/tests/HeaderSubMenu.spec.ts +63 -0
  81. package/src/components/HeaderBar/HeaderBurgerMenu/conts.ts +1 -0
  82. package/src/components/HeaderBar/HeaderBurgerMenu/locals.ts +4 -0
  83. package/src/components/HeaderBar/HeaderBurgerMenu/tests/HeaderBurgerMenu.spec.ts +180 -0
  84. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/HeaderBurgerMenu.spec.ts.snap +13 -0
  85. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/HeaderComplexMenu.spec.ts.snap +13 -0
  86. package/src/components/HeaderBar/HeaderBurgerMenu/tests/useHandleSubMenus.spec.ts +158 -0
  87. package/src/components/HeaderBar/HeaderBurgerMenu/useHandleSubMenus.ts +49 -0
  88. package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +143 -0
  89. package/src/components/HeaderBar/HeaderLogo/locales.ts +3 -0
  90. package/src/components/HeaderBar/HeaderLogo/logos/Logo-mobile.vue +117 -0
  91. package/src/components/HeaderBar/HeaderLogo/logos/Logo.vue +279 -0
  92. package/src/components/HeaderBar/HeaderLogo/tests/HeaderLogo.spec.ts +119 -0
  93. package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +84 -0
  94. package/src/components/HeaderBar/HeaderMenuBtn/locals.ts +4 -0
  95. package/src/components/HeaderBar/HeaderMenuBtn/tests/HeaderMenuBtn.spec.ts +70 -0
  96. package/src/components/HeaderBar/Usages.mdx +85 -0
  97. package/src/components/HeaderBar/consts.scss +6 -0
  98. package/src/components/HeaderBar/consts.ts +2 -0
  99. package/src/components/HeaderBar/locales.ts +3 -0
  100. package/src/components/HeaderBar/tests/HeaderBar.spec.ts +216 -0
  101. package/src/components/HeaderBar/tests/__snapshots__/HeaderBar.spec.ts.snap +45 -0
  102. package/src/components/HeaderBar/tests/useHeaderResponsiveMode.spec.ts +26 -0
  103. package/src/components/HeaderBar/tests/useScrollDirection.spec.ts +34 -0
  104. package/src/components/HeaderBar/useHeaderResponsiveMode.ts +25 -0
  105. package/src/components/HeaderBar/useScrollDirection.ts +26 -0
  106. package/src/components/HeaderLoading/HeaderLoading.mdx +28 -0
  107. package/src/components/HeaderLoading/HeaderLoading.stories.ts +62 -0
  108. package/src/components/HeaderLoading/HeaderLoading.vue +45 -0
  109. package/src/components/HeaderLoading/tests/HeaderLoading.spec.ts +22 -0
  110. package/src/components/HeaderNavigationBar/HeaderNavigationBar.mdx +128 -0
  111. package/src/components/HeaderNavigationBar/HeaderNavigationBar.stories.ts +784 -0
  112. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +194 -0
  113. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +74 -0
  114. package/src/components/HeaderNavigationBar/HorizontalNavbar/config.ts +18 -0
  115. package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.spec.ts +127 -0
  116. package/src/components/HeaderNavigationBar/types.ts +7 -0
  117. package/src/components/HeaderToolbar/HeaderToolbar.mdx +31 -0
  118. package/src/components/HeaderToolbar/HeaderToolbar.stories.ts +343 -0
  119. package/src/components/HeaderToolbar/HeaderToolbar.vue +487 -0
  120. package/src/components/HeaderToolbar/tests/HeaderToolbar.spec.ts +196 -0
  121. package/src/components/HeaderToolbar/types.d.ts +20 -0
  122. package/src/components/LangBtn/LangBtn.mdx +1 -1
  123. package/src/components/LangBtn/LangBtn.stories.ts +125 -8
  124. package/src/components/Logo/Logo.mdx +2 -2
  125. package/src/components/Logo/Logo.stories.ts +147 -1
  126. package/src/components/LogoBrandSection/LogoBrandSection.mdx +14 -0
  127. package/src/components/LogoBrandSection/LogoBrandSection.stories.ts +158 -0
  128. package/src/components/LogoBrandSection/LogoBrandSection.vue +312 -0
  129. package/src/components/LogoBrandSection/assets/ameli-pro.svg +1 -0
  130. package/src/components/LogoBrandSection/assets/ameli.svg +1 -0
  131. package/src/components/LogoBrandSection/assets/cnam.svg +1 -0
  132. package/src/components/LogoBrandSection/assets/compte-ameli.svg +1 -0
  133. package/src/components/LogoBrandSection/dividerDimensionsMapping.ts +14 -0
  134. package/src/components/LogoBrandSection/locales.ts +14 -0
  135. package/src/components/LogoBrandSection/secondaryLogoMapping.ts +24 -0
  136. package/src/components/LogoBrandSection/tests/LogoBrandSection.spec.ts +365 -0
  137. package/src/components/LogoBrandSection/tests/__snapshots__/LogoBrandSection.spec.ts.snap +14 -0
  138. package/src/components/LogoBrandSection/types.ts +8 -0
  139. package/src/components/NotificationBar/NotificationBar.mdx +6 -6
  140. package/src/components/NotificationBar/NotificationBar.stories.ts +1 -1
  141. package/src/components/NotificationBar/NotificationBar.vue +7 -9
  142. package/src/components/NotificationBar/tests/NotificationBar.spec.ts +1 -1
  143. package/src/components/PageContainer/PageContainer.mdx +1 -1
  144. package/src/components/PageContainer/PageContainer.stories.ts +86 -1
  145. package/src/components/PageContainer/PageContainer.vue +0 -1
  146. package/src/components/PhoneField/PhoneField.mdx +49 -0
  147. package/src/components/PhoneField/PhoneField.stories.ts +869 -0
  148. package/src/components/PhoneField/PhoneField.vue +230 -0
  149. package/src/components/PhoneField/indicatifs.ts +104 -0
  150. package/src/components/PhoneField/locales.ts +4 -0
  151. package/src/components/PhoneField/tests/PhoneField.spec.ts +179 -0
  152. package/src/components/SkipLink/SkipLink.stories.ts +50 -1
  153. package/src/components/SocialMediaLinks/SocialMediaLinks.mdx +28 -1
  154. package/src/components/SocialMediaLinks/SocialMediaLinks.stories.ts +37 -1
  155. package/src/components/SubHeader/SubHeader.mdx +31 -0
  156. package/src/components/SubHeader/SubHeader.stories.ts +1032 -0
  157. package/src/components/SubHeader/SubHeader.vue +185 -0
  158. package/src/components/SubHeader/config.ts +12 -0
  159. package/src/components/SubHeader/locales.ts +3 -0
  160. package/src/components/SubHeader/tests/SubHeader.spec.ts +144 -0
  161. package/src/components/index.ts +24 -7
  162. package/src/composables/widthable/index.ts +29 -0
  163. package/src/composables/widthable/tests/widthable.spec.ts +52 -0
  164. package/src/designTokens/tokens/cnam/cnamLightTheme.ts +2 -2
  165. package/src/main.ts +1 -0
  166. package/src/modules.d.ts +4 -0
  167. package/src/services/index.ts +1 -0
  168. package/src/stories/Demarrer/Accueil.mdx +10 -0
  169. package/src/stories/Demarrer/Accueil.stories.ts +76 -0
  170. package/src/stories/Demarrer/PolitiqueDeConfidentialite.mdx +9 -0
  171. package/src/stories/Demarrer/PolitiqueDeConfidentialite.stories.ts +20 -0
  172. package/src/stories/Fondamentaux/Accessibilite/Accessibilite.mdx +1 -2
  173. package/src/stories/Fondamentaux/Accessibilite/Accessibilite.stories.ts +1 -1
  174. package/src/stories/Fondamentaux/EcoConception/Econception.stories.ts +1 -1
  175. package/src/stories/GuideDuDev/moduleDeNotification.mdx +52 -48
  176. package/src/stories/GuideDuDev/vuetifyOptions.mdx +31 -28
  177. package/src/stories/Guidelines/CustomisationEtThemes.mdx +1 -1
  178. package/src/utils/functions/throttleDisplayFn/tests/throttleDisplayFn.spec.ts +47 -0
  179. package/src/utils/functions/throttleDisplayFn/throttleDisplayFn.ts +26 -0
  180. package/src/utils/rules/exactLength/index.ts +33 -0
  181. package/src/utils/rules/exactLength/locales.ts +6 -0
  182. package/src/utils/rules/required/index.ts +25 -0
  183. package/src/utils/rules/required/locales.ts +5 -0
  184. package/src/utils/rules/required/ruleMessageHelper.ts +14 -0
  185. package/src/utils/rules/required/tests/index.spec.ts +47 -0
  186. package/src/utils/rules/required/tests/rulesMessageHelper.spec.ts +22 -0
  187. package/src/utils/rules/types.d.ts +15 -0
  188. package/src/components/Beta/beta.mdx +0 -5
  189. package/src/components/Deprecated/deprecated.mdx +0 -5
  190. package/src/stories/Home/Accueil.mdx +0 -7
  191. package/src/stories/Home/PolitiqueDeConfidentialite.mdx +0 -4
  192. package/src/stories/Home/synapse.webp +0 -0
  193. /package/src/components/Logo/{types.d.ts → types.ts} +0 -0
@@ -5,7 +5,7 @@ import { ref } from 'vue'
5
5
  import Alert from '../../Alert/Alert.vue'
6
6
 
7
7
  const meta = {
8
- title: 'Components/CustomInputSelect',
8
+ title: 'Composants/Formulaires/CustomInputSelect',
9
9
  component: CustomInputSelect,
10
10
  parameters: {
11
11
  layout: 'fullscreen',
@@ -15,6 +15,10 @@ const meta = {
15
15
  selectedValue: { control: 'text' },
16
16
  items: { control: 'object' },
17
17
  errorMessages: { control: 'object' },
18
+ required: { control: 'boolean' },
19
+ textKey: { control: 'text' },
20
+ valueKey: { control: 'text' },
21
+ vuetifyOptions: { control: 'object' },
18
22
  },
19
23
  } as Meta<typeof CustomInputSelect>
20
24
 
@@ -22,11 +26,47 @@ export default meta
22
26
 
23
27
  type Story = StoryObj<typeof meta>
24
28
  export const Default: Story = {
29
+ parameters: {
30
+ sourceCode: [
31
+ {
32
+ name: 'Template',
33
+ code: `
34
+ <template>
35
+ <CustomInputSelect
36
+ v-model="value"
37
+ :items="items"
38
+ />
39
+ </template>
40
+ `,
41
+ },
42
+ {
43
+ name: 'Script',
44
+ code: `
45
+ <script setup lang="ts">
46
+ import CustomInputSelect from '@cnamts/CustomInputSelect'
47
+
48
+ const items = [
49
+ { text: 'Option 1', value: '1' },
50
+ { text: 'Option 2', value: '2' },
51
+ ],
52
+ </script>
53
+ `,
54
+ },
55
+ ],
56
+ },
25
57
  args: {
26
58
  items: [
27
59
  { text: 'Option 1', value: '1' },
28
60
  { text: 'Option 2', value: '2' },
29
61
  ],
62
+ vuetifyOptions: {
63
+ menu: {
64
+ color: 'primary',
65
+ },
66
+ option: {
67
+ color: 'primary',
68
+ },
69
+ },
30
70
  },
31
71
  render: (args) => {
32
72
  return {
@@ -38,6 +78,7 @@ export const Default: Story = {
38
78
  <div class="d-flex flex-wrap align-center pa-4">
39
79
  <CustomInputSelect
40
80
  v-bind="args"
81
+ :vuetify-options="args.vuetifyOptions"
41
82
  />
42
83
  </div>
43
84
  <br/><br/><br/><br/>
@@ -47,6 +88,35 @@ export const Default: Story = {
47
88
  }
48
89
 
49
90
  export const Outlined: Story = {
91
+ parameters: {
92
+ sourceCode: [
93
+ {
94
+ name: 'Template',
95
+ code: `
96
+ <template>
97
+ <CustomInputSelect
98
+ v-model="value"
99
+ :items="items"
100
+ outlined
101
+ />
102
+ </template>
103
+ `,
104
+ },
105
+ {
106
+ name: 'Script',
107
+ code: `
108
+ <script setup lang="ts">
109
+ import CustomInputSelect from '@cnamts/CustomInputSelect'
110
+
111
+ const items = [
112
+ { text: 'Option 1', value: '1' },
113
+ { text: 'Option 2', value: '2' },
114
+ ],
115
+ </script>
116
+ `,
117
+ },
118
+ ],
119
+ },
50
120
  args: {
51
121
  items: [
52
122
  { text: 'Option 1', value: '1' },
@@ -71,7 +141,101 @@ export const Outlined: Story = {
71
141
  },
72
142
  }
73
143
 
74
- export const withError: Story = {
144
+ export const Required: Story = {
145
+ parameters: {
146
+ sourceCode: [
147
+ {
148
+ name: 'Template',
149
+ code: `
150
+ <template>
151
+ <CustomInputSelect
152
+ v-model="value"
153
+ :items="items"
154
+ required
155
+ />
156
+ </template>
157
+ `,
158
+ },
159
+ {
160
+ name: 'Script',
161
+ code: `
162
+ <script setup lang="ts">
163
+ import CustomInputSelect from '@cnamts/CustomInputSelect'
164
+
165
+ const items = [
166
+ { text: 'Option 1', value: '1' },
167
+ { text: 'Option 2', value: '2' },
168
+ ],
169
+ </script>
170
+ `,
171
+ },
172
+ ],
173
+ },
174
+ args: {
175
+ items: [
176
+ { text: 'Option 1', value: '1' },
177
+ { text: 'Option 2', value: '2' },
178
+ ],
179
+ required: true,
180
+ },
181
+ render: (args) => {
182
+ return {
183
+ components: { CustomInputSelect, VBtn, VMenu, VList, VListItem, VListItemTitle },
184
+ setup() {
185
+ return { args }
186
+ },
187
+ template: `
188
+ <div class="d-flex flex-wrap align-center pa-4">
189
+ <CustomInputSelect
190
+ v-bind="args"
191
+ :required="args.required"
192
+ />
193
+ </div>
194
+ `,
195
+ }
196
+ },
197
+ }
198
+
199
+ export const withCustomError: Story = {
200
+ parameters: {
201
+ sourceCode: [
202
+ {
203
+ name: 'Template',
204
+ code: `
205
+ <template>
206
+ <CustomInputSelect
207
+ v-model="value"
208
+ :items="items"
209
+ :error-messages="errorMessages"
210
+ />
211
+ <VBtn @click="triggerError">
212
+ Trigger Error
213
+ </VBtn>
214
+ </template>
215
+ `,
216
+ },
217
+ {
218
+ name: 'Script',
219
+ code: `
220
+ <script setup lang="ts">
221
+ import CustomInputSelect from '@cnamts/CustomInputSelect'
222
+ import { ref } from 'vue'
223
+
224
+ const items = [
225
+ { text: 'Option 1', value: '1' },
226
+ { text: 'Option 2', value: '2' },
227
+ ]
228
+
229
+ const errorMessages = ref([])
230
+
231
+ const triggerError = () => {
232
+ errorMessages.value = ['This is a test error message']
233
+ }
234
+ </script>
235
+ `,
236
+ },
237
+ ],
238
+ },
75
239
  args: {
76
240
  items: [
77
241
  { text: 'Option 1', value: '1' },
@@ -105,10 +269,40 @@ export const withError: Story = {
105
269
  }
106
270
 
107
271
  export const withCustomKey: Story = {
272
+ parameters: {
273
+ sourceCode: [
274
+ {
275
+ name: 'Template',
276
+ code: `
277
+ <template>
278
+ <CustomInputSelect
279
+ v-model="value"
280
+ :items="items"
281
+ text-key="customKey"
282
+ outlined
283
+ />
284
+ </template>
285
+ `,
286
+ },
287
+ {
288
+ name: 'Script',
289
+ code: `
290
+ <script setup lang="ts">
291
+ import CustomInputSelect from '@cnamts/CustomInputSelect'
292
+
293
+ const items = [
294
+ { customKey: 'Choix 1', value: '1' },
295
+ { customKey: 'Choix 2', value: '2' }
296
+ ]
297
+ </script>
298
+ `,
299
+ },
300
+ ],
301
+ },
108
302
  args: {
109
303
  items: [
110
- { customKey: 'Option 1', value: '1' },
111
- { customKey: 'Option 2', value: '2' },
304
+ { customKey: 'Choix 1', value: '1' },
305
+ { customKey: 'Choix 2', value: '2' },
112
306
  ],
113
307
  },
114
308
  render: (args) => {
@@ -130,6 +324,78 @@ export const withCustomKey: Story = {
130
324
  },
131
325
  }
132
326
 
327
+ export const withCustomStyles: Story = {
328
+ parameters: {
329
+ sourceCode: [
330
+ {
331
+ name: 'Template',
332
+ code: `
333
+ <template>
334
+ <CustomInputSelect
335
+ v-model="value"
336
+ :items="items"
337
+ :vuetify-options="vuetifyOptions
338
+ />
339
+ </template>
340
+ `,
341
+ },
342
+ {
343
+ name: 'Script',
344
+ code: `
345
+ <script setup lang="ts">
346
+ import CustomInputSelect from '@cnamts/CustomInputSelect'
347
+
348
+ const items = [
349
+ { text: 'Option 1', value: '1' },
350
+ { text: 'Option 2', value: '2' },
351
+ ]
352
+
353
+ const vuetifyOptions = {
354
+ menu: {
355
+ color: 'secondary',
356
+ },
357
+ option: {
358
+ color: 'secondary',
359
+ },
360
+ }
361
+ </script>
362
+ `,
363
+ },
364
+ ],
365
+ },
366
+ args: {
367
+ items: [
368
+ { text: 'Option 1', value: '1' },
369
+ { text: 'Option 2', value: '2' },
370
+ ],
371
+ vuetifyOptions: {
372
+ menu: {
373
+ color: 'secondary',
374
+ },
375
+ option: {
376
+ color: 'secondary',
377
+ },
378
+ },
379
+ },
380
+ render: (args) => {
381
+ return {
382
+ components: { CustomInputSelect, VBtn, VMenu, VList, VListItem, VListItemTitle },
383
+ setup() {
384
+ return { args }
385
+ },
386
+ template: `
387
+ <div class="d-flex flex-wrap align-center pa-4">
388
+ <CustomInputSelect
389
+ v-bind="args"
390
+ :items="args.items"
391
+ :vuetify-options="args.vuetifyOptions"
392
+ />
393
+ </div>
394
+ `,
395
+ }
396
+ },
397
+ }
398
+
133
399
  export const Info: Story = {
134
400
  render: (args) => {
135
401
  return {
@@ -1,51 +1,39 @@
1
- <script setup lang="ts">
2
- import { mdiMenuDown } from '@mdi/js'
3
- import { ref, watch, computed, type PropType } from 'vue'
1
+ <script lang="ts" setup>
2
+ import { mdiChevronDown } from '@mdi/js'
3
+ import { computed, onMounted, ref, watch } from 'vue'
4
4
  import { VIcon, VList, VListItem, VListItemTitle } from 'vuetify/components'
5
5
 
6
- const props = defineProps({
7
- modelValue: {
8
- type: [Object, String],
9
- default: null,
10
- },
11
- items: {
12
- type: Array,
13
- default: () => [],
14
- },
15
- label: {
16
- type: String,
17
- default: 'Sélectionnez une option',
18
- },
19
- errorMessages: {
20
- type: [String, Array] as PropType<string | readonly string[]>,
21
- default: () => [],
22
- },
23
- required: {
24
- type: Boolean,
25
- default: false,
26
- },
27
- menuId: {
28
- type: String,
29
- default: 'custom-select-menu',
30
- },
31
- outlined: {
32
- type: Boolean,
33
- default: false,
34
- },
35
- textKey: {
36
- type: String,
37
- default: 'text',
38
- },
39
- valueKey: {
40
- type: String,
41
- default: 'value',
42
- },
6
+ import useCustomizableOptions, { type CustomizableOptions } from '@/composables/useCustomizableOptions'
7
+ import defaultOptions from './config'
8
+
9
+ const props = withDefaults(defineProps<CustomizableOptions & {
10
+ modelValue?: Record<string, unknown> | string | null
11
+ items?: Record<string, unknown>[] | string[]
12
+ textKey?: string
13
+ valueKey?: string
14
+ label?: string
15
+ outlined?: boolean
16
+ required?: boolean
17
+ errorMessages?: string | string[]
18
+ isHeaderToolbar?: boolean
19
+ }>(), {
20
+ modelValue: null,
21
+ items: () => [],
22
+ textKey: 'text',
23
+ valueKey: 'value',
24
+ label: 'Sélectionnez une option',
25
+ outlined: false,
26
+ required: false,
27
+ errorMessages: () => [],
28
+ isHeaderToolbar: false,
43
29
  })
44
30
 
31
+ const options = useCustomizableOptions(defaultOptions, props)
32
+
45
33
  const emit = defineEmits(['update:modelValue'])
46
34
 
47
35
  const isOpen = ref(false)
48
- const selectedItem = ref<Record<string, unknown > | string | null>(props.modelValue)
36
+ const selectedItem = ref<Record<string, unknown> | string | null>(props.modelValue)
49
37
 
50
38
  const toggleMenu = () => {
51
39
  isOpen.value = !isOpen.value
@@ -81,6 +69,24 @@
81
69
  selectedItem.value = newValue
82
70
  })
83
71
 
72
+ watch(() => props.errorMessages, (newValue) => {
73
+ localErrorMessages.value = newValue
74
+ })
75
+
76
+ const menu = ref<HTMLElement | null>(null)
77
+ const menuWidth = ref('')
78
+ onMounted(() => {
79
+ watch(
80
+ [() => isOpen.value, () => menu.value?.getBoundingClientRect().width],
81
+ ([newValue, newWidth]) => {
82
+ if (newValue && newWidth) {
83
+ const totalWidth = newWidth + (props.isHeaderToolbar ? 32 : 0)
84
+ menuWidth.value = `${totalWidth}`
85
+ }
86
+ },
87
+ )
88
+ })
89
+
84
90
  const buttonClass = computed(() => {
85
91
  return props.outlined ? 'v-btn v-btn--density-default v-btn--size-default v-btn--variant-outlined' : 'text-color'
86
92
  })
@@ -93,22 +99,36 @@
93
99
  return item
94
100
  })
95
101
  })
102
+
103
+ const localErrorMessages = ref<string | string[]>(props.errorMessages as string | string[])
104
+ const checkForErrors = () => {
105
+ if (props.required && !selectedItem.value) {
106
+ localErrorMessages.value = ['Le champ est requis.']
107
+ return false
108
+ }
109
+ if (props.errorMessages.length > 0) {
110
+ localErrorMessages.value = props.errorMessages
111
+ return false
112
+ }
113
+ localErrorMessages.value = []
114
+ return true
115
+ }
96
116
  </script>
97
117
 
98
118
  <template>
99
119
  <v-input
100
120
  :id="inputId"
101
121
  v-model="selectedItem"
122
+ :error-messages="localErrorMessages"
102
123
  :label="props.label"
103
124
  :title="props.label"
104
125
  role="menu"
105
- :error-messages="errorMessages"
106
- :required="required"
126
+ @click="checkForErrors"
107
127
  >
108
128
  <div
109
129
  ref="menu"
110
130
  v-click-outside="closeList"
111
- :class="['custom-select', buttonClass, 'primary']"
131
+ :class="['custom-select', buttonClass, 'text-'+options.menu.color]"
112
132
  role="menu"
113
133
  tabindex="0"
114
134
  @click="toggleMenu"
@@ -116,24 +136,28 @@
116
136
  @keydown.space.prevent="toggleMenu"
117
137
  >
118
138
  <span>{{ selectedItemText }}</span>
119
- <VIcon> {{ mdiMenuDown }}</VIcon>
139
+ <VIcon> {{ mdiChevronDown }}</VIcon>
120
140
  </div>
121
141
  <VList
122
142
  v-if="isOpen"
123
- class="v-list"
124
- :style="`max-width: ${$refs.menu ? $refs.menu.getBoundingClientRect().width : 0}px;`"
125
143
  :aria-label="props.label"
144
+ :is-header-toolbar="props.isHeaderToolbar"
145
+ :style="`min-width:${menuWidth}px; ${props.outlined ? 'top: 36px;' : 'top: 30px;'}`"
126
146
  :title="props.label"
147
+ class="v-list"
148
+ v-bind="options.list"
127
149
  @keydown.esc.prevent="isOpen = false"
128
150
  >
129
151
  <VListItem
130
152
  v-for="(item, index) in formattedItems"
131
153
  :key="index"
132
154
  :ref="'options-' + index"
133
- role="option"
134
- class="v-list-item"
135
155
  :aria-selected="selectedItem === item"
156
+ :base-color="options.option.color"
136
157
  :tabindex="index + 1"
158
+ class="v-list-item"
159
+ role="option"
160
+ v-bind="options.option"
137
161
  @click="selectItem(item)"
138
162
  >
139
163
  <VListItemTitle>
@@ -144,7 +168,7 @@
144
168
  </v-input>
145
169
  </template>
146
170
 
147
- <style scoped lang="scss">
171
+ <style lang="scss" scoped>
148
172
  @use '@/assets/tokens.scss';
149
173
 
150
174
  .v-input {
@@ -154,12 +178,11 @@
154
178
 
155
179
  .v-list {
156
180
  position: absolute;
157
- top: 36px;
158
181
  width: 100%;
159
182
  z-index: 1;
160
183
  background-color: white;
161
184
  min-width: fit-content;
162
- max-width: 150px;
185
+ max-width: 100px;
163
186
  padding: 0;
164
187
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.12), 0 2px 10px rgba(0, 0, 0, 0.08);
165
188
  border-radius: 4px;
@@ -171,8 +194,12 @@
171
194
  background-color: rgba(0, 0, 0, 0.04);
172
195
  }
173
196
 
174
- .v-list-item[aria-selected='true'] {
197
+ :deep(.v-list-item[aria-selected='true']) {
175
198
  background-color: rgba(0, 0, 0, 0.08);
199
+
200
+ .v-list-item-title {
201
+ font-weight: bold;
202
+ }
176
203
  }
177
204
 
178
205
  .v-btn {
@@ -0,0 +1,10 @@
1
+ const defaultOptions = {
2
+ menu: {
3
+ color: 'primary',
4
+ },
5
+ option: {
6
+ color: 'primary',
7
+ },
8
+ }
9
+
10
+ export default defaultOptions
@@ -20,14 +20,14 @@ Le composant `CustomSelect` est utilisé pour proposer une alternative au `v-sel
20
20
  <Source dark code={`
21
21
  <script setup lang="ts">
22
22
  import { ref } from 'vue'
23
- import CustomSelect from '@/components/Customs/CustomSelect/CustomSelect.vue'
23
+ import CustomSelect from '@cnamts/synapse'
24
24
 
25
25
  const selectedValue = ref(undefined)
26
26
 
27
- const items = ref([
27
+ const items = [
28
28
  { text: 'Option 1', value: '1' },
29
29
  { text: 'Option 2', value: '2' },
30
- ])
30
+ ]
31
31
  </script>
32
32
 
33
33
  <template>