@cnamts/synapse 0.0.3-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 (185) hide show
  1. package/dist/design-system-v3.d.ts +712 -27
  2. package/dist/design-system-v3.js +2715 -1485
  3. package/dist/design-system-v3.umd.cjs +10 -1
  4. package/dist/style.css +1 -1
  5. package/package.json +5 -2
  6. package/src/components/Alert/Alert.mdx +1 -1
  7. package/src/components/Alert/Alert.stories.ts +91 -1
  8. package/src/components/BackBtn/BackBtn.mdx +1 -1
  9. package/src/components/BackBtn/BackBtn.stories.ts +84 -1
  10. package/src/components/BackToTopBtn/BackToTopBtn.mdx +3 -3
  11. package/src/components/BackToTopBtn/BackToTopBtn.stories.ts +172 -11
  12. package/src/components/CollapsibleList/CollapsibleList.mdx +2 -2
  13. package/src/components/CollapsibleList/CollapsibleList.stories.ts +37 -1
  14. package/src/components/CopyBtn/CopyBtn.mdx +1 -1
  15. package/src/components/CopyBtn/CopyBtn.stories.ts +120 -1
  16. package/src/components/CopyBtn/CopyBtn.vue +1 -1
  17. package/src/components/Customs/CustomInputSelect/CustomInputSelect.mdx +6 -8
  18. package/src/components/Customs/CustomInputSelect/CustomInputSelect.stories.ts +270 -4
  19. package/src/components/Customs/CustomInputSelect/CustomInputSelect.vue +80 -53
  20. package/src/components/Customs/CustomInputSelect/config.ts +10 -0
  21. package/src/components/Customs/CustomSelect/CustomSelect.mdx +3 -3
  22. package/src/components/Customs/CustomSelect/CustomSelect.stories.ts +158 -2
  23. package/src/components/Customs/CustomSelect/CustomSelect.vue +25 -6
  24. package/src/components/Customs/CustomTextField/CustomTextField.mdx +44 -0
  25. package/src/components/Customs/CustomTextField/CustomTextField.stories.ts +403 -0
  26. package/src/components/Customs/CustomTextField/CustomTextField.vue +110 -0
  27. package/src/components/Customs/CustomTextField/tests/CustomTextField.spec.ts +93 -0
  28. package/src/components/Customs/CustomTextField/tests/__snapshots__/CustomTextField.spec.ts.snap +59 -0
  29. package/src/components/Customs/CustomTextField/types.d.ts +3 -0
  30. package/src/components/DataList/DataList.mdx +77 -0
  31. package/src/components/DataList/DataList.stories.ts +960 -0
  32. package/src/components/DataList/DataList.vue +140 -0
  33. package/src/components/DataList/DataListLoading/DataListLoading.vue +56 -0
  34. package/src/components/DataList/DataListLoading/tests/DataListLoading.spec.ts +23 -0
  35. package/src/components/DataList/locales.ts +3 -0
  36. package/src/components/DataList/tests/DataList.spec.ts +194 -0
  37. package/src/components/DataList/types.d.ts +23 -0
  38. package/src/components/DataListGroup/DataListGroup.mdx +77 -0
  39. package/src/components/DataListGroup/DataListGroup.stories.ts +987 -0
  40. package/src/components/DataListGroup/DataListGroup.vue +59 -0
  41. package/src/components/DataListGroup/tests/DataListGroup.spec.ts +54 -0
  42. package/src/components/DataListGroup/tests/data/dataListGroupItems.ts +41 -0
  43. package/src/components/DataListGroup/types.d.ts +15 -0
  44. package/src/components/DataListItem/DataListItem.vue +135 -0
  45. package/src/components/DataListItem/config.ts +17 -0
  46. package/src/components/DataListItem/locales.ts +3 -0
  47. package/src/components/DataListItem/tests/DataListItem.spec.ts +156 -0
  48. package/src/components/DataListItem/types.d.ts +23 -0
  49. package/src/components/DownloadBtn/Accessibilite.mdx +14 -0
  50. package/src/components/DownloadBtn/Accessibilite.stories.ts +166 -0
  51. package/src/components/DownloadBtn/AccessibiliteItems.ts +129 -0
  52. package/src/components/DownloadBtn/DownloadBtn.mdx +5 -6
  53. package/src/components/DownloadBtn/DownloadBtn.stories.ts +207 -2
  54. package/src/components/DownloadBtn/constants/ExpertiseLevelEnum.ts +4 -0
  55. package/src/components/FooterBar/FooterBar.mdx +2 -2
  56. package/src/components/FooterBar/FooterBar.stories.ts +1 -1
  57. package/src/components/FranceConnectBtn/FranceConnectBtn.mdx +1 -1
  58. package/src/components/FranceConnectBtn/FranceConnectBtn.stories.ts +58 -1
  59. package/src/components/HeaderBar/HeaderBar.mdx +164 -45
  60. package/src/components/HeaderBar/HeaderBar.stories.ts +559 -15
  61. package/src/components/HeaderBar/HeaderBar.vue +60 -22
  62. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.mdx +433 -0
  63. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.stories.ts +1089 -0
  64. package/src/components/HeaderBar/{HeaderComplexMenu/HeaderComplexMenu.vue → HeaderBurgerMenu/HeaderBurgerMenu.vue} +74 -45
  65. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.mdx +38 -0
  66. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.stories.ts +89 -0
  67. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuItem/tests/__snapshots__/HeaderMenuItem.spec.ts.snap +1 -1
  68. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.mdx +17 -0
  69. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.stories.ts +121 -0
  70. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuSection/HeaderMenuSection.vue +2 -2
  71. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuSection/tests/HeaderMenuSection.spec.ts +1 -3
  72. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.mdx +43 -0
  73. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.stories.ts +261 -0
  74. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderSubMenu/HeaderSubMenu.vue +17 -3
  75. package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderSubMenu/tests/HeaderSubMenu.spec.ts +1 -1
  76. package/src/components/HeaderBar/HeaderBurgerMenu/tests/HeaderBurgerMenu.spec.ts +180 -0
  77. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/HeaderBurgerMenu.spec.ts.snap +13 -0
  78. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/HeaderComplexMenu.spec.ts.snap +13 -0
  79. package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +62 -25
  80. package/src/components/HeaderBar/HeaderLogo/tests/HeaderLogo.spec.ts +49 -1
  81. package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +19 -23
  82. package/src/components/HeaderBar/HeaderMenuBtn/tests/HeaderMenuBtn.spec.ts +70 -0
  83. package/src/components/HeaderBar/Usages.mdx +85 -0
  84. package/src/components/HeaderBar/consts.scss +0 -1
  85. package/src/components/HeaderBar/tests/HeaderBar.spec.ts +8 -2
  86. package/src/components/HeaderBar/tests/__snapshots__/HeaderBar.spec.ts.snap +5 -10
  87. package/src/components/HeaderLoading/HeaderLoading.mdx +28 -0
  88. package/src/components/HeaderLoading/HeaderLoading.stories.ts +62 -0
  89. package/src/components/HeaderLoading/HeaderLoading.vue +45 -0
  90. package/src/components/HeaderLoading/tests/HeaderLoading.spec.ts +22 -0
  91. package/src/components/HeaderNavigationBar/HeaderNavigationBar.mdx +128 -0
  92. package/src/components/HeaderNavigationBar/HeaderNavigationBar.stories.ts +784 -0
  93. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +194 -0
  94. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +74 -0
  95. package/src/components/HeaderNavigationBar/HorizontalNavbar/config.ts +18 -0
  96. package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.spec.ts +127 -0
  97. package/src/components/HeaderNavigationBar/types.ts +7 -0
  98. package/src/components/HeaderToolbar/HeaderToolbar.mdx +31 -0
  99. package/src/components/HeaderToolbar/HeaderToolbar.stories.ts +343 -0
  100. package/src/components/HeaderToolbar/HeaderToolbar.vue +487 -0
  101. package/src/components/HeaderToolbar/tests/HeaderToolbar.spec.ts +196 -0
  102. package/src/components/HeaderToolbar/types.d.ts +20 -0
  103. package/src/components/LangBtn/LangBtn.mdx +1 -1
  104. package/src/components/LangBtn/LangBtn.stories.ts +125 -8
  105. package/src/components/Logo/Logo.mdx +2 -2
  106. package/src/components/Logo/Logo.stories.ts +147 -1
  107. package/src/components/LogoBrandSection/LogoBrandSection.mdx +14 -0
  108. package/src/components/LogoBrandSection/LogoBrandSection.stories.ts +158 -0
  109. package/src/components/LogoBrandSection/LogoBrandSection.vue +312 -0
  110. package/src/components/LogoBrandSection/assets/ameli-pro.svg +1 -0
  111. package/src/components/LogoBrandSection/assets/ameli.svg +1 -0
  112. package/src/components/LogoBrandSection/assets/cnam.svg +1 -0
  113. package/src/components/LogoBrandSection/assets/compte-ameli.svg +1 -0
  114. package/src/components/LogoBrandSection/dividerDimensionsMapping.ts +14 -0
  115. package/src/components/LogoBrandSection/locales.ts +14 -0
  116. package/src/components/LogoBrandSection/secondaryLogoMapping.ts +24 -0
  117. package/src/components/LogoBrandSection/tests/LogoBrandSection.spec.ts +365 -0
  118. package/src/components/LogoBrandSection/tests/__snapshots__/LogoBrandSection.spec.ts.snap +14 -0
  119. package/src/components/LogoBrandSection/types.ts +8 -0
  120. package/src/components/NotificationBar/NotificationBar.mdx +6 -6
  121. package/src/components/NotificationBar/NotificationBar.stories.ts +1 -1
  122. package/src/components/NotificationBar/NotificationBar.vue +2 -2
  123. package/src/components/NotificationBar/tests/NotificationBar.spec.ts +1 -1
  124. package/src/components/PageContainer/PageContainer.mdx +1 -1
  125. package/src/components/PageContainer/PageContainer.stories.ts +86 -1
  126. package/src/components/PhoneField/PhoneField.mdx +49 -0
  127. package/src/components/PhoneField/PhoneField.stories.ts +869 -0
  128. package/src/components/PhoneField/PhoneField.vue +230 -0
  129. package/src/components/PhoneField/indicatifs.ts +104 -0
  130. package/src/components/PhoneField/locales.ts +4 -0
  131. package/src/components/PhoneField/tests/PhoneField.spec.ts +179 -0
  132. package/src/components/SkipLink/SkipLink.stories.ts +50 -1
  133. package/src/components/SocialMediaLinks/SocialMediaLinks.mdx +28 -1
  134. package/src/components/SocialMediaLinks/SocialMediaLinks.stories.ts +37 -1
  135. package/src/components/SubHeader/SubHeader.mdx +31 -0
  136. package/src/components/SubHeader/SubHeader.stories.ts +1032 -0
  137. package/src/components/SubHeader/SubHeader.vue +185 -0
  138. package/src/components/SubHeader/config.ts +12 -0
  139. package/src/components/SubHeader/locales.ts +3 -0
  140. package/src/components/SubHeader/tests/SubHeader.spec.ts +144 -0
  141. package/src/components/index.ts +24 -7
  142. package/src/composables/widthable/index.ts +29 -0
  143. package/src/composables/widthable/tests/widthable.spec.ts +52 -0
  144. package/src/designTokens/tokens/cnam/cnamLightTheme.ts +2 -2
  145. package/src/main.ts +1 -0
  146. package/src/modules.d.ts +4 -0
  147. package/src/services/index.ts +1 -0
  148. package/src/stories/Demarrer/Accueil.mdx +10 -0
  149. package/src/stories/Demarrer/Accueil.stories.ts +76 -0
  150. package/src/stories/Demarrer/PolitiqueDeConfidentialite.mdx +9 -0
  151. package/src/stories/Demarrer/PolitiqueDeConfidentialite.stories.ts +20 -0
  152. package/src/stories/Fondamentaux/Accessibilite/Accessibilite.mdx +1 -2
  153. package/src/stories/Fondamentaux/Accessibilite/Accessibilite.stories.ts +1 -1
  154. package/src/stories/Fondamentaux/EcoConception/Econception.stories.ts +1 -1
  155. package/src/stories/GuideDuDev/moduleDeNotification.mdx +52 -48
  156. package/src/stories/GuideDuDev/vuetifyOptions.mdx +31 -28
  157. package/src/stories/Guidelines/CustomisationEtThemes.mdx +1 -1
  158. package/src/utils/functions/throttleDisplayFn/tests/throttleDisplayFn.spec.ts +47 -0
  159. package/src/utils/functions/throttleDisplayFn/throttleDisplayFn.ts +26 -0
  160. package/src/utils/rules/exactLength/index.ts +33 -0
  161. package/src/utils/rules/exactLength/locales.ts +6 -0
  162. package/src/utils/rules/required/index.ts +25 -0
  163. package/src/utils/rules/required/locales.ts +5 -0
  164. package/src/utils/rules/required/ruleMessageHelper.ts +14 -0
  165. package/src/utils/rules/required/tests/index.spec.ts +47 -0
  166. package/src/utils/rules/required/tests/rulesMessageHelper.spec.ts +22 -0
  167. package/src/utils/rules/types.d.ts +15 -0
  168. package/src/components/Beta/beta.mdx +0 -5
  169. package/src/components/Deprecated/deprecated.mdx +0 -5
  170. package/src/components/HeaderBar/HeaderComplexMenu/HeaderComplexMenu.stories.ts +0 -272
  171. package/src/components/HeaderBar/HeaderComplexMenu/HeaderMenuItem/HeaderMenuItem.stories.ts +0 -49
  172. package/src/components/HeaderBar/HeaderComplexMenu/HeaderMenuSection/HeaderMenuSection.stories.ts +0 -56
  173. package/src/components/HeaderBar/HeaderComplexMenu/HeaderSubMenu/HeaderSubMenu.stories.ts +0 -137
  174. package/src/components/HeaderBar/HeaderComplexMenu/tests/HeaderComplexMenu.spec.ts +0 -129
  175. package/src/components/HeaderBar/HeaderComplexMenu/tests/__snapshots__/HeaderComplexMenu.spec.ts.snap +0 -18
  176. package/src/stories/Home/Accueil.mdx +0 -7
  177. package/src/stories/Home/PolitiqueDeConfidentialite.mdx +0 -4
  178. package/src/stories/Home/synapse.webp +0 -0
  179. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuItem/HeaderMenuItem.vue +0 -0
  180. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/HeaderMenuItem/tests/HeaderMenuItem.spec.ts +0 -0
  181. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/conts.ts +0 -0
  182. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/locals.ts +0 -0
  183. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/tests/useHandleSubMenus.spec.ts +0 -0
  184. /package/src/components/HeaderBar/{HeaderComplexMenu → HeaderBurgerMenu}/useHandleSubMenus.ts +0 -0
  185. /package/src/components/Logo/{types.d.ts → types.ts} +0 -0
@@ -0,0 +1,403 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import CustomTextField from '@/components/Customs/CustomTextField/CustomTextField.vue'
3
+ import { VIcon } from 'vuetify/components'
4
+ import { ref } from 'vue'
5
+ import { mdiAccountBox } from '@mdi/js'
6
+
7
+ const meta = {
8
+ title: 'Composants/Formulaires/CustomTextField',
9
+ component: CustomTextField,
10
+ parameters: {
11
+ layout: 'fullscreen',
12
+ controls: { exclude: ['modelValue', 'appendInnerIconColor'] },
13
+ },
14
+ argTypes: {
15
+ modelValue: { control: 'text' },
16
+ label: { control: 'text' },
17
+ prependIcon: {
18
+ control: 'select',
19
+ options: ['info', 'success', 'warning', 'error', 'close'],
20
+ },
21
+ appendIcon: {
22
+ control: 'select',
23
+ options: ['info', 'success', 'warning', 'error', 'close'],
24
+ },
25
+ prependInnerIcon: {
26
+ control: 'select',
27
+ options: ['info', 'success', 'warning', 'error', 'close'],
28
+ },
29
+ appendInnerIcon: {
30
+ control: 'select',
31
+ options: ['info', 'success', 'warning', 'error', 'close'],
32
+ },
33
+ variantStyle: {
34
+ control: 'select',
35
+ options: ['outlined', 'plain', 'underlined', 'filled', 'solo', 'solo-inverted', 'solo-filled'],
36
+ },
37
+ color: {
38
+ control: 'select',
39
+ options: ['primary', 'secondary', 'success', 'error', 'warning'],
40
+ },
41
+ },
42
+ } as Meta<typeof CustomTextField>
43
+
44
+ export default meta
45
+
46
+ type Story = StoryObj<typeof meta>
47
+ export const Default: Story = {
48
+ parameters: {
49
+ sourceCode: [
50
+ {
51
+ name: 'Template',
52
+ code: `
53
+ <template>
54
+ <CustomTextField v-model="value" />
55
+ </template>
56
+ `,
57
+ },
58
+ {
59
+ name: 'Script',
60
+ code: `
61
+ <script setup lang="ts">
62
+ import CustomTextField from '@cnamts/synapse'
63
+ </script>
64
+ `,
65
+ },
66
+ ],
67
+ },
68
+ args: {
69
+ showDivider: false,
70
+ variantStyle: 'outlined',
71
+ color: 'primary',
72
+ isClearable: true,
73
+ label: 'Label',
74
+ },
75
+ render: (args) => {
76
+ return {
77
+ components: { CustomTextField, VIcon },
78
+ setup() {
79
+ return { args }
80
+ },
81
+ template: `
82
+ <div class="d-flex flex-wrap align-center pa-4">
83
+ <CustomTextField v-bind="args" />
84
+ </div>
85
+ `,
86
+ }
87
+ },
88
+ }
89
+
90
+ export const SlotPrepend: Story = {
91
+ parameters: {
92
+ sourceCode: [
93
+ {
94
+ name: 'Template',
95
+ code: `
96
+ <template>
97
+ <CustomTextField
98
+ v-model="value"
99
+ prepend-icon="info"
100
+ />
101
+ </template>
102
+ `,
103
+ },
104
+ {
105
+ name: 'Script',
106
+ code: `
107
+ <script setup lang="ts">
108
+ import CustomTextField from '@cnamts/synapse'
109
+ </script>
110
+ `,
111
+ },
112
+ ],
113
+ },
114
+ args: {
115
+ variantStyle: 'outlined',
116
+ isClearable: true,
117
+ showDivider: false,
118
+ label: 'Label',
119
+ color: 'primary',
120
+ prependIcon: 'info',
121
+ },
122
+ render: (args) => {
123
+ return {
124
+ components: { CustomTextField, VIcon },
125
+ setup() {
126
+ return { args }
127
+ },
128
+ template: `
129
+ <div class="d-flex flex-wrap align-center pa-4">
130
+ <CustomTextField
131
+ v-bind="args"
132
+ :label="args.label"
133
+ :prepend-icon="args.prependIcon"
134
+ />
135
+ </div>
136
+ `,
137
+ }
138
+ },
139
+ }
140
+
141
+ export const SlotAppend: Story = {
142
+ parameters: {
143
+ sourceCode: [
144
+ {
145
+ name: 'Template',
146
+ code: `
147
+ <template>
148
+ <CustomTextField
149
+ v-model="value"
150
+ append-icon="success"
151
+ />
152
+ </template>
153
+ `,
154
+ },
155
+ {
156
+ name: 'Script',
157
+ code: `
158
+ <script setup lang="ts">
159
+ import CustomTextField from '@cnamts/synapse'
160
+ </script>
161
+ `,
162
+ },
163
+ ],
164
+ },
165
+ args: {
166
+ variantStyle: 'outlined',
167
+ isClearable: true,
168
+ showDivider: false,
169
+ label: 'champs de text',
170
+ color: 'primary',
171
+ appendIcon: 'success',
172
+ },
173
+ render: (args) => {
174
+ return {
175
+ components: { CustomTextField, VIcon },
176
+ setup() {
177
+ return { args }
178
+ },
179
+ template: `
180
+ <div class="d-flex flex-wrap align-center pa-4">
181
+ <CustomTextField
182
+ v-bind="args"
183
+ :append-icon="args.appendIcon"
184
+ />
185
+ </div>
186
+ `,
187
+ }
188
+ },
189
+ }
190
+
191
+ export const SlotPrependInner: Story = {
192
+ parameters: {
193
+ sourceCode: [
194
+ {
195
+ name: 'Template',
196
+ code: `
197
+ <template>
198
+ <CustomTextField
199
+ v-model="value"
200
+ prepend-inner-icon="info"
201
+ />
202
+ </template>
203
+ `,
204
+ },
205
+ {
206
+ name: 'Script',
207
+ code: `
208
+ <script setup lang="ts">
209
+ import CustomTextField from '@cnamts/synapse'
210
+ </script>
211
+ `,
212
+ },
213
+ ],
214
+ },
215
+ args: {
216
+ variantStyle: 'outlined',
217
+ isClearable: true,
218
+ showDivider: false,
219
+ label: 'Label',
220
+ color: 'primary',
221
+ prependInnerIcon: 'info',
222
+ },
223
+ render: (args) => {
224
+ return {
225
+ components: { CustomTextField, VIcon },
226
+ setup() {
227
+ return { args }
228
+ },
229
+ template: `
230
+ <div class="d-flex flex-wrap align-center pa-4">
231
+ <CustomTextField
232
+ v-bind="args"
233
+ :prepend-inner-icon="args.prependInnerIcon"
234
+ />
235
+ </div>
236
+ `,
237
+ }
238
+ },
239
+ }
240
+
241
+ export const SlotPrependInnerDivider: Story = {
242
+ parameters: {
243
+ sourceCode: [
244
+ {
245
+ name: 'Template',
246
+ code: `
247
+ <template>
248
+ <CustomTextField
249
+ v-model="value"
250
+ prepend-inner-icon="info"
251
+ show-divider
252
+ />
253
+ </template>
254
+ `,
255
+ },
256
+ {
257
+ name: 'Script',
258
+ code: `
259
+ <script setup lang="ts">
260
+ import CustomTextField from '@cnamts/synapse'
261
+ </script>
262
+ `,
263
+ },
264
+ ],
265
+ },
266
+ args: {
267
+ variantStyle: 'outlined',
268
+ isClearable: true,
269
+ showDivider: true,
270
+ label: 'Label',
271
+ color: 'primary',
272
+ prependInnerIcon: 'info',
273
+ },
274
+ render: (args) => {
275
+ return {
276
+ components: { CustomTextField, VIcon },
277
+ setup() {
278
+ return { args }
279
+ },
280
+ template: `
281
+ <div class="d-flex flex-wrap align-center pa-4">
282
+ <CustomTextField
283
+ v-bind="args"
284
+ :prepend-inner-icon="args.prependInnerIcon"
285
+ :show-divider="args.showDivider"
286
+ />
287
+ </div>
288
+ `,
289
+ }
290
+ },
291
+ }
292
+
293
+ export const SlotAppendInner: Story = {
294
+ parameters: {
295
+ sourceCode: [
296
+ {
297
+ name: 'Template',
298
+ code: `
299
+ <template>
300
+ <CustomTextField
301
+ v-model="value"
302
+ append-inner-icon="success"
303
+ />
304
+ </template>
305
+ `,
306
+ },
307
+ {
308
+ name: 'Script',
309
+ code: `
310
+ <script setup lang="ts">
311
+ import CustomTextField from '@cnamts/synapse'
312
+ </script>
313
+ `,
314
+ },
315
+ ],
316
+ },
317
+ args: {
318
+ variantStyle: 'outlined',
319
+ isClearable: true,
320
+ showDivider: false,
321
+ label: 'Label',
322
+ color: 'primary',
323
+ appendInnerIcon: 'success',
324
+ },
325
+ render: (args) => {
326
+ return {
327
+ components: { CustomTextField, VIcon },
328
+ setup() {
329
+ return { args }
330
+ },
331
+ template: `
332
+ <div class="d-flex flex-wrap align-center pa-4">
333
+ <CustomTextField
334
+ v-bind="args"
335
+ :append-inner-icon="args.appendInnerIcon"
336
+ />
337
+ </div>
338
+ `,
339
+ }
340
+ },
341
+ }
342
+
343
+ export const SlotCustomIcon: Story = {
344
+ parameters: {
345
+ sourceCode: [
346
+ {
347
+ name: 'Template',
348
+ code: `
349
+ <template>
350
+ <CustomTextField v-model="value">
351
+ <template #append-inner>
352
+ <VIcon>
353
+ {{ iconName }}
354
+ </VIcon>
355
+ </template>
356
+ </CustomTextField>
357
+ </template>
358
+ `,
359
+ },
360
+ {
361
+ name: 'Script',
362
+ code: `
363
+ <script setup lang="ts">
364
+ import CustomTextField from '@cnamts/synapse'
365
+ import { mdiAccountBox } from '@mdi/js'
366
+
367
+ const iconName = mdiAccountBox
368
+ </script>
369
+ `,
370
+ },
371
+ ],
372
+ },
373
+ args: {
374
+ variantStyle: 'outlined',
375
+ isClearable: true,
376
+ showDivider: false,
377
+ label: 'Label',
378
+ color: 'primary',
379
+ },
380
+ render: (args) => {
381
+ return {
382
+ components: { CustomTextField, VIcon },
383
+ setup() {
384
+ const iconName = ref(mdiAccountBox)
385
+
386
+ return { args, iconName }
387
+ },
388
+ template: `
389
+ <div class="d-flex flex-wrap align-center pa-4">
390
+ <CustomTextField
391
+ v-bind="args"
392
+ >
393
+ <template #append-inner>
394
+ <VIcon>
395
+ {{ iconName }}
396
+ </VIcon>
397
+ </template>
398
+ </CustomTextField>
399
+ </div>
400
+ `,
401
+ }
402
+ },
403
+ }
@@ -0,0 +1,110 @@
1
+ <script setup lang="ts">
2
+ import { computed, ref } from 'vue'
3
+ import type { IconType, VariantStyle, ColorType } from './types'
4
+ import {
5
+ mdiAlertOutline,
6
+ mdiCheck,
7
+ mdiInformationOutline,
8
+ mdiClose,
9
+ mdiInformation,
10
+ } from '@mdi/js'
11
+
12
+ // only variantStyle need a default value
13
+ /* eslint-disable vue/require-default-prop */
14
+ const props = withDefaults(
15
+ defineProps<{
16
+ prependIcon?: IconType
17
+ appendIcon?: IconType
18
+ prependInnerIcon?: IconType
19
+ appendInnerIcon?: IconType
20
+ variantStyle?: VariantStyle
21
+ color?: ColorType
22
+ isClearable?: boolean
23
+ showDivider?: boolean
24
+ label?: string
25
+ }>(),
26
+ {
27
+ variantStyle: 'outlined', // Remplacez par la valeur par défaut souhaitée
28
+ },
29
+ )
30
+
31
+ const ICONS: Record<IconType, string> = {
32
+ info: mdiInformationOutline,
33
+ success: mdiCheck,
34
+ warning: mdiAlertOutline,
35
+ error: mdiInformation,
36
+ close: mdiClose,
37
+ }
38
+
39
+ const model = ref('')
40
+
41
+ const appendInnerIconColor = computed(() => {
42
+ return props.appendInnerIcon === 'error' || props.appendInnerIcon === 'success'
43
+ ? props.appendInnerIcon
44
+ : 'black'
45
+ })
46
+
47
+ const dividerProps = {
48
+ thickness: 2,
49
+ length: '25px',
50
+ color: 'primary',
51
+ opacity: '1',
52
+ }
53
+
54
+ defineExpose({
55
+ appendInnerIconColor,
56
+ })
57
+ </script>
58
+
59
+ <template>
60
+ <VTextField
61
+ v-model="model"
62
+ :variant="props.variantStyle"
63
+ :color="props.color"
64
+ :clearable="props.isClearable"
65
+ :clear-icon="ICONS.close"
66
+ :aria-label="props.label"
67
+ :label="props.label"
68
+ >
69
+ <template #prepend>
70
+ <slot name="prepend">
71
+ <VIcon
72
+ v-if="props.prependIcon"
73
+ :icon="ICONS[props.prependIcon]"
74
+ />
75
+ </slot>
76
+ </template>
77
+ <template #append>
78
+ <slot name="append">
79
+ <VIcon
80
+ v-if="props.appendIcon"
81
+ :icon="ICONS[props.appendIcon]"
82
+ />
83
+ </slot>
84
+ </template>
85
+ <template #prepend-inner>
86
+ <slot name="prepend-inner">
87
+ <VIcon
88
+ v-if="props.prependInnerIcon"
89
+ :icon="ICONS[props.prependInnerIcon]"
90
+ />
91
+ </slot>
92
+ <VDivider
93
+ v-if="props.showDivider"
94
+ v-bind="dividerProps"
95
+ class="mt-4 pa-1"
96
+ vertical
97
+ />
98
+ </template>
99
+ <template #append-inner>
100
+ <slot name="append-inner">
101
+ <VIcon
102
+ v-if="props.appendInnerIcon"
103
+ :icon="ICONS[props.appendInnerIcon]"
104
+ :class="{ 'error-icon': props.appendInnerIcon === 'error' }"
105
+ :color="appendInnerIconColor"
106
+ />
107
+ </slot>
108
+ </template>
109
+ </VTextField>
110
+ </template>
@@ -0,0 +1,93 @@
1
+ import { mount } from '@vue/test-utils'
2
+ import CustomTextField from '../CustomTextField.vue'
3
+ import { expect, describe, it } from 'vitest'
4
+ import { VIcon } from 'vuetify/components'
5
+ import { vuetify } from '@tests/unit/setup'
6
+
7
+ describe('CustomTextField', () => {
8
+ const factory = (props = {}, slots = {}) => {
9
+ return mount(CustomTextField, {
10
+ props,
11
+ slots,
12
+ global: {
13
+ plugins: [vuetify],
14
+ },
15
+ })
16
+ }
17
+
18
+ it('renders correctly with default props', () => {
19
+ const wrapper = factory()
20
+ expect(wrapper.exists()).toBe(true)
21
+ expect(wrapper.findComponent(VIcon).exists()).toBe(false) // No icons by default
22
+ })
23
+
24
+ it('applies the correct variant style', () => {
25
+ const wrapper = factory({ variantStyle: 'filled' })
26
+ const textField = wrapper.findComponent({ name: 'VTextField' })
27
+ expect(textField.props('variant')).toBe('filled')
28
+ })
29
+
30
+ it('renders default slots correctly', () => {
31
+ const wrapper = factory({}, {
32
+ prepend: '<div data-testid="prepend-slot">Prepend Slot Content</div>',
33
+ append: '<div data-testid="append-slot">Append Slot Content</div>',
34
+ })
35
+
36
+ const prependSlot = wrapper.find('[data-testid="prepend-slot"]')
37
+ const appendSlot = wrapper.find('[data-testid="append-slot"]')
38
+
39
+ expect(prependSlot.exists()).toBe(true)
40
+ expect(prependSlot.text()).toBe('Prepend Slot Content')
41
+ expect(appendSlot.exists()).toBe(true)
42
+ expect(appendSlot.text()).toBe('Append Slot Content')
43
+ })
44
+
45
+ it('renders inner slots correctly', () => {
46
+ const wrapper = factory({}, {
47
+ 'prepend-inner': '<div data-testid="prepend-inner-slot">Prepend Inner Slot Content</div>',
48
+ 'append-inner': '<div data-testid="append-inner-slot">Append Inner Slot Content</div>',
49
+ })
50
+
51
+ const prependInnerSlot = wrapper.find('[data-testid="prepend-inner-slot"]')
52
+ const appendInnerSlot = wrapper.find('[data-testid="append-inner-slot"]')
53
+
54
+ expect(prependInnerSlot.exists()).toBe(true)
55
+ expect(prependInnerSlot.text()).toBe('Prepend Inner Slot Content')
56
+ expect(appendInnerSlot.exists()).toBe(true)
57
+ expect(appendInnerSlot.text()).toBe('Append Inner Slot Content')
58
+ })
59
+
60
+ it('matches snapshot', () => {
61
+ const wrapper = factory({
62
+ prependIcon: 'info',
63
+ appendIcon: 'success',
64
+ prependInnerIcon: 'warning',
65
+ appendInnerIcon: 'error',
66
+ variantStyle: 'filled',
67
+ isClearable: true,
68
+ showDivider: true,
69
+ })
70
+
71
+ expect(wrapper.html()).toMatchSnapshot()
72
+ })
73
+
74
+ it('returns error color for appendInnerIcon when value is error', () => {
75
+ const wrapper = factory({ appendInnerIcon: 'error' })
76
+ expect(wrapper.vm.appendInnerIconColor).toBe('error')
77
+ })
78
+
79
+ it('returns success color for appendInnerIcon when value is success', () => {
80
+ const wrapper = factory({ appendInnerIcon: 'success' })
81
+ expect(wrapper.vm.appendInnerIconColor).toBe('success')
82
+ })
83
+
84
+ it('returns default color for appendInnerIcon when value is info', () => {
85
+ const wrapper = factory({ appendInnerIcon: 'info' })
86
+ expect(wrapper.vm.appendInnerIconColor).toBe('black')
87
+ })
88
+
89
+ it('returns default color for appendInnerIcon when value is undefined', () => {
90
+ const wrapper = factory({ appendInnerIcon: undefined })
91
+ expect(wrapper.vm.appendInnerIconColor).toBe('black')
92
+ })
93
+ })
@@ -0,0 +1,59 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`CustomTextField > matches snapshot 1`] = `
4
+ "<div class="v-input v-input--horizontal v-input--center-affix v-input--density-default v-theme--light v-locale--is-ltr v-text-field">
5
+ <div class="v-input__prepend"><i class="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z mdi v-icon notranslate v-theme--light v-icon--size-default" aria-hidden="true"></i>
6
+ <!---->
7
+ </div>
8
+ <div class="v-input__control">
9
+ <div class="v-field v-field--appended v-field--center-affix v-field--prepended v-field--no-label v-field--variant-filled v-theme--light v-locale--is-ltr">
10
+ <div class="v-field__overlay"></div>
11
+ <div class="v-field__loader">
12
+ <div class="v-progress-linear v-theme--light v-locale--is-ltr" style="top: 0px; height: 0px; --v-progress-linear-height: 2px;" role="progressbar" aria-hidden="true" aria-valuemin="0" aria-valuemax="100">
13
+ <!---->
14
+ <div class="v-progress-linear__background" style="opacity: NaN;"></div>
15
+ <div class="v-progress-linear__buffer" style="opacity: NaN; width: 0%;"></div>
16
+ <transition-stub name="fade-transition" appear="false" persisted="false" css="true">
17
+ <div class="v-progress-linear__indeterminate">
18
+ <div class="v-progress-linear__indeterminate long"></div>
19
+ <div class="v-progress-linear__indeterminate short"></div>
20
+ </div>
21
+ </transition-stub>
22
+ <!---->
23
+ </div>
24
+ </div>
25
+ <div class="v-field__prepend-inner">
26
+ <!----><i class="M12,2L1,21H23M12,6L19.53,19H4.47M11,10V14H13V10M11,16V18H13V16 mdi v-icon notranslate v-theme--light v-icon--size-default" aria-hidden="true"></i>
27
+ <hr class="v-divider v-divider--vertical v-theme--light text-primary mt-4 pa-1" style="height: 25px; border-right-width: 2px; --v-border-opacity: 1;" aria-orientation="vertical" role="separator">
28
+ </div>
29
+ <div class="v-field__field" data-no-activator="">
30
+ <!----><label class="v-label v-field-label" for="input-0">
31
+ <!---->
32
+ <!---->
33
+ </label>
34
+ <!----><input size="1" type="text" id="input-0" aria-describedby="input-0-messages" class="v-field__input" value="">
35
+ <!---->
36
+ </div>
37
+ <transition-stub name="expand-x-transition" appear="false" persisted="false" css="true">
38
+ <div class="v-field__clearable" style="display: none;"><i class="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z mdi v-icon notranslate v-theme--light v-icon--size-default v-icon--clickable" role="button" aria-hidden="false" tabindex="0" aria-label="Clear "></i></div>
39
+ </transition-stub>
40
+ <div class="v-field__append-inner"><i class="M13,9H11V7H13M13,17H11V11H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z mdi v-icon notranslate v-theme--light v-icon--size-default text-error error-icon" aria-hidden="true"></i>
41
+ <!---->
42
+ </div>
43
+ <div class="v-field__outline">
44
+ <!---->
45
+ <!---->
46
+ </div>
47
+ </div>
48
+ </div>
49
+ <div class="v-input__append">
50
+ <!----><i class="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z mdi v-icon notranslate v-theme--light v-icon--size-default" aria-hidden="true"></i>
51
+ </div>
52
+ <div class="v-input__details">
53
+ <transition-group-stub name="slide-y-transition" tag="div" appear="false" persisted="false" css="true" class="v-messages" role="alert" aria-live="polite" id="input-0-messages">
54
+ <!---->
55
+ </transition-group-stub>
56
+ <!---->
57
+ </div>
58
+ </div>"
59
+ `;
@@ -0,0 +1,3 @@
1
+ export type IconType = 'info' | 'success' | 'warning' | 'error' | 'close'
2
+ export type VariantStyle = 'outlined' | 'filled' | 'solo' | 'solo-inverted' | 'solo-filled'
3
+ export type ColorType = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error'