@cnamts/synapse 0.0.7-alpha → 0.0.9-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 (198) hide show
  1. package/dist/design-system-v3.d.ts +785 -372
  2. package/dist/design-system-v3.js +4993 -3357
  3. package/dist/design-system-v3.umd.cjs +1 -10
  4. package/dist/style.css +1 -1
  5. package/package.json +10 -2
  6. package/src/assets/settings.scss +2 -2
  7. package/src/assets/tokens.scss +107 -112
  8. package/src/components/BackBtn/BackBtn.vue +4 -4
  9. package/src/components/BackToTopBtn/BackToTopBtn.vue +1 -0
  10. package/src/components/CollapsibleList/CollapsibleList.mdx +1 -1
  11. package/src/components/CollapsibleList/CollapsibleList.vue +43 -44
  12. package/src/components/ContextualMenu/Accessibilite.mdx +14 -0
  13. package/src/components/ContextualMenu/Accessibilite.stories.ts +191 -0
  14. package/src/components/ContextualMenu/AccessibiliteItems.ts +89 -0
  15. package/src/components/ContextualMenu/ContextualMenu.mdx +118 -0
  16. package/src/components/ContextualMenu/ContextualMenu.stories.ts +430 -0
  17. package/src/components/ContextualMenu/ContextualMenu.vue +101 -0
  18. package/src/components/ContextualMenu/constants/ExpertiseLevelEnum.ts +4 -0
  19. package/src/components/ContextualMenu/tests/ContextualMenu.spec.ts +115 -0
  20. package/src/components/ContextualMenu/tests/__snapshots__/ContextualMenu.spec.ts.snap +10 -0
  21. package/src/components/ContextualMenu/types.ts +5 -0
  22. package/src/components/CookieBanner/CookieBanner.stories.ts +1 -2
  23. package/src/components/CookieBanner/CookieBanner.vue +13 -10
  24. package/src/components/CookieBanner/tests/__snapshots__/CookieBanner.spec.ts.snap +17 -15
  25. package/src/components/CookiesSelection/CookiesInformation/CookiesInformation.vue +6 -1
  26. package/src/components/CookiesSelection/CookiesInformation/locales.ts +1 -0
  27. package/src/components/CookiesSelection/CookiesTable/CookiesTable.vue +1 -0
  28. package/src/components/CookiesSelection/tests/__snapshots__/CookiesSelection.spec.ts.snap +17 -15
  29. package/src/components/CopyBtn/CopyBtn.vue +7 -7
  30. package/src/components/Customs/SyBtnSelect/SyBtnSelect.vue +26 -26
  31. package/src/components/Customs/SyInputSelect/SyInputSelect.vue +24 -24
  32. package/src/components/Customs/SySelect/SySelect.stories.ts +7 -7
  33. package/src/components/Customs/SySelect/SySelect.vue +36 -30
  34. package/src/components/Customs/SySelect/tests/SySelect.spec.ts +2 -2
  35. package/src/components/Customs/SyTextField/SyTextField.stories.ts +187 -2
  36. package/src/components/Customs/SyTextField/SyTextField.vue +185 -16
  37. package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +2 -4
  38. package/src/components/Customs/SyTextField/tests/__snapshots__/SyTextField.spec.ts.snap +18 -16
  39. package/src/components/Customs/SyTextField/types.d.ts +2 -2
  40. package/src/components/DataList/DataList.stories.ts +3 -2
  41. package/src/components/DataList/DataList.vue +1 -1
  42. package/src/components/DataListGroup/DataListGroup.stories.ts +3 -2
  43. package/src/components/DataListItem/DataListItem.vue +12 -12
  44. package/src/components/DatePicker/DatePicker.mdx +191 -0
  45. package/src/components/DatePicker/DatePicker.stories.ts +787 -0
  46. package/src/components/DatePicker/DatePicker.vue +560 -0
  47. package/src/components/DatePicker/DateTextInput.vue +409 -0
  48. package/src/components/DatePicker/tests/DatePicker.spec.ts +266 -0
  49. package/src/components/DialogBox/DialogBox.mdx +28 -2
  50. package/src/components/DialogBox/DialogBox.stories.ts +2 -2
  51. package/src/components/DialogBox/DialogBox.vue +3 -2
  52. package/src/components/DownloadBtn/DownloadBtn.vue +2 -1
  53. package/src/components/ExternalLinks/Accessibilite.mdx +14 -0
  54. package/src/components/ExternalLinks/Accessibilite.stories.ts +191 -0
  55. package/src/components/ExternalLinks/AccessibiliteItems.ts +197 -0
  56. package/src/components/ExternalLinks/ExternalLinks.mdx +86 -0
  57. package/src/components/ExternalLinks/ExternalLinks.stories.ts +553 -0
  58. package/src/components/ExternalLinks/ExternalLinks.vue +200 -0
  59. package/src/components/ExternalLinks/config.ts +34 -0
  60. package/src/components/ExternalLinks/constants/ExpertiseLevelEnum.ts +4 -0
  61. package/src/components/ExternalLinks/locales.ts +4 -0
  62. package/src/components/ExternalLinks/tests/ExternalLinks.spec.ts +154 -0
  63. package/src/components/ExternalLinks/tests/__snapshots__/ExternalLinks.spec.ts.snap +159 -0
  64. package/src/components/FileUpload/FileUpload.mdx +165 -0
  65. package/src/components/FileUpload/FileUpload.stories.ts +429 -0
  66. package/src/components/FileUpload/FileUpload.vue +195 -0
  67. package/src/components/FileUpload/FileUploadContent.vue +109 -0
  68. package/src/components/FileUpload/locales.ts +10 -0
  69. package/src/components/FileUpload/tests/FileUpload.spec.ts +332 -0
  70. package/src/components/FileUpload/tests/__snapshots__/FileUpload.spec.ts.snap +7 -0
  71. package/src/components/FileUpload/useFileDrop.ts +23 -0
  72. package/src/components/FileUpload/validateFiles.ts +39 -0
  73. package/src/components/FooterBar/FooterBar.vue +105 -80
  74. package/src/components/FranceConnectBtn/FranceConnectBtn.vue +14 -13
  75. package/src/components/HeaderBar/HeaderBar.vue +3 -3
  76. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.vue +11 -7
  77. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +5 -5
  78. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.vue +2 -2
  79. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +10 -8
  80. package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +2 -2
  81. package/src/components/HeaderBar/HeaderLogo/logos/Logo-mobile.vue +2 -1
  82. package/src/components/HeaderBar/HeaderLogo/logos/Logo.vue +2 -1
  83. package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +10 -10
  84. package/src/components/HeaderBar/consts.scss +1 -1
  85. package/src/components/HeaderLoading/HeaderLoading.vue +12 -11
  86. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +2 -1
  87. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +9 -9
  88. package/src/components/HeaderToolbar/HeaderToolbar.vue +215 -202
  89. package/src/components/LangBtn/LangBtn.vue +8 -6
  90. package/src/components/LogoBrandSection/LogoBrandSection.stories.ts +2 -2
  91. package/src/components/NirField/NirField.stories.ts +8 -8
  92. package/src/components/NirField/NirField.vue +46 -48
  93. package/src/components/NotFoundPage/NotFoundPage.stories.ts +33 -2
  94. package/src/components/NotFoundPage/NotFoundPage.vue +17 -0
  95. package/src/components/NotificationBar/NotificationBar.mdx +5 -5
  96. package/src/components/NotificationBar/NotificationBar.stories.ts +410 -314
  97. package/src/components/NotificationBar/NotificationBar.vue +43 -41
  98. package/src/components/PageContainer/PageContainer.vue +4 -4
  99. package/src/components/PasswordField/Accessibilite.mdx +14 -0
  100. package/src/components/PasswordField/Accessibilite.stories.ts +191 -0
  101. package/src/components/PasswordField/AccessibiliteItems.ts +184 -0
  102. package/src/components/PasswordField/PasswordField.mdx +70 -0
  103. package/src/components/PasswordField/PasswordField.stories.ts +213 -0
  104. package/src/components/PasswordField/PasswordField.vue +189 -0
  105. package/src/components/PasswordField/config.ts +11 -0
  106. package/src/components/PasswordField/constants/ExpertiseLevelEnum.ts +4 -0
  107. package/src/components/PasswordField/locales.ts +4 -0
  108. package/src/components/PasswordField/tests/PasswordField.spec.ts +96 -0
  109. package/src/components/PhoneField/PhoneField.mdx +0 -2
  110. package/src/components/PhoneField/PhoneField.stories.ts +10 -50
  111. package/src/components/PhoneField/PhoneField.vue +77 -93
  112. package/src/components/PhoneField/tests/PhoneField.spec.ts +0 -15
  113. package/src/components/RangeField/RangeField.mdx +54 -0
  114. package/src/components/RangeField/RangeField.stories.ts +189 -0
  115. package/src/components/RangeField/RangeField.vue +157 -0
  116. package/src/components/RangeField/RangeSlider/RangeSlider.vue +387 -0
  117. package/src/components/RangeField/RangeSlider/Tooltip/Tooltip.vue +64 -0
  118. package/src/components/RangeField/RangeSlider/tests/__snapshots__/rangeSlider.spec.ts.snap +27 -0
  119. package/src/components/RangeField/RangeSlider/tests/rangeSlider.spec.ts +100 -0
  120. package/src/components/RangeField/RangeSlider/tests/useDoubleSlider.spec.ts +246 -0
  121. package/src/components/RangeField/RangeSlider/tests/useMouseSlide.spec.ts +204 -0
  122. package/src/components/RangeField/RangeSlider/tests/useThumb.spec.ts +22 -0
  123. package/src/components/RangeField/RangeSlider/tests/useThumbKeyboard.spec.ts +233 -0
  124. package/src/components/RangeField/RangeSlider/tests/useTooltipsNudge.spec.ts +150 -0
  125. package/src/components/RangeField/RangeSlider/tests/useTrack.spec.ts +314 -0
  126. package/src/components/RangeField/RangeSlider/tests/vAnimateClick.spec.ts +32 -0
  127. package/src/components/RangeField/RangeSlider/types.ts +15 -0
  128. package/src/components/RangeField/RangeSlider/useMouseSlide.ts +109 -0
  129. package/src/components/RangeField/RangeSlider/useRangeSlider.ts +126 -0
  130. package/src/components/RangeField/RangeSlider/useThumb.ts +18 -0
  131. package/src/components/RangeField/RangeSlider/useThumbKeyboard.ts +84 -0
  132. package/src/components/RangeField/RangeSlider/useTooltipsNudge.ts +92 -0
  133. package/src/components/RangeField/RangeSlider/useTrack.ts +116 -0
  134. package/src/components/RangeField/RangeSlider/vAnimateClick.ts +19 -0
  135. package/src/components/RangeField/config.ts +7 -0
  136. package/src/components/RangeField/locales.ts +4 -0
  137. package/src/components/RangeField/tests/RangeField.spec.ts +224 -0
  138. package/src/components/RangeField/tests/__snapshots__/RangeField.spec.ts.snap +379 -0
  139. package/src/components/RatingPicker/EmotionPicker/EmotionPicker.vue +205 -0
  140. package/src/components/RatingPicker/EmotionPicker/locales.ts +3 -0
  141. package/src/components/RatingPicker/EmotionPicker/tests/EmotionPicker.spec.ts +104 -0
  142. package/src/components/RatingPicker/EmotionPicker/tests/__snapshots__/EmotionPicker.spec.ts.snap +66 -0
  143. package/src/components/RatingPicker/NumberPicker/NumberPicker.vue +159 -0
  144. package/src/components/RatingPicker/NumberPicker/locales.ts +4 -0
  145. package/src/components/RatingPicker/NumberPicker/tests/NumberPicker.spec.ts +73 -0
  146. package/src/components/RatingPicker/NumberPicker/tests/__snapshots__/NumberPicker.spec.ts.snap +105 -0
  147. package/src/components/RatingPicker/Rating.ts +45 -0
  148. package/src/components/RatingPicker/RatingPicker.mdx +56 -0
  149. package/src/components/RatingPicker/RatingPicker.stories.ts +515 -0
  150. package/src/components/RatingPicker/RatingPicker.vue +122 -0
  151. package/src/components/RatingPicker/StarsPicker/StarsPicker.vue +116 -0
  152. package/src/components/RatingPicker/StarsPicker/tests/StarsPicker.spec.ts +95 -0
  153. package/src/components/RatingPicker/StarsPicker/tests/__snapshots__/StarsPicker.spec.ts.snap +36 -0
  154. package/src/components/RatingPicker/locales.ts +3 -0
  155. package/src/components/RatingPicker/tests/Rating.spec.ts +104 -0
  156. package/src/components/RatingPicker/tests/RatingPicker.spec.ts +187 -0
  157. package/src/components/RatingPicker/tests/__snapshots__/RatingPicker.spec.ts.snap +108 -0
  158. package/src/components/SearchListField/SearchListField.mdx +74 -0
  159. package/src/components/SearchListField/SearchListField.stories.ts +126 -0
  160. package/src/components/SearchListField/SearchListField.vue +194 -0
  161. package/src/components/SearchListField/locales.ts +5 -0
  162. package/src/components/SearchListField/tests/SearchListField.spec.ts +323 -0
  163. package/src/components/SearchListField/types.d.ts +4 -0
  164. package/src/components/SelectBtnField/SelectBtnField.mdx +50 -0
  165. package/src/components/SelectBtnField/SelectBtnField.stories.ts +763 -0
  166. package/src/components/SelectBtnField/SelectBtnField.vue +283 -0
  167. package/src/components/SelectBtnField/config.ts +11 -0
  168. package/src/components/SelectBtnField/tests/SelectBtnField.spec.ts +327 -0
  169. package/src/components/SelectBtnField/tests/__snapshots__/SelectBtnField.spec.ts.snap +125 -0
  170. package/src/components/SelectBtnField/types.d.ts +11 -0
  171. package/src/components/SkipLink/SkipLink.vue +10 -10
  172. package/src/components/SocialMediaLinks/SocialMediaLinks.vue +28 -26
  173. package/src/components/SubHeader/SubHeader.vue +32 -31
  174. package/src/components/SyAlert/SyAlert.vue +12 -12
  175. package/src/components/UserMenuBtn/UserMenuBtn.vue +1 -1
  176. package/src/components/UserMenuBtn/config.ts +1 -1
  177. package/src/components/index.ts +17 -7
  178. package/src/composables/rules/useFieldValidation.ts +172 -44
  179. package/src/designTokens/index.ts +6 -4
  180. package/src/designTokens/{bootstrapColors.md → paColors.md} +1 -1
  181. package/src/designTokens/tokens/cnam/cnamLightTheme.ts +2 -0
  182. package/src/designTokens/tokens/pa/paColors.ts +171 -0
  183. package/src/designTokens/tokens/pa/paContextual.ts +58 -0
  184. package/src/designTokens/tokens/pa/paDarkTheme.ts +5 -0
  185. package/src/designTokens/tokens/pa/paLightTheme.ts +123 -0
  186. package/src/designTokens/tokens/pa/paSemantic.ts +87 -0
  187. package/src/stories/Fondamentaux/CustomisationEtThemes.mdx +52 -2
  188. package/src/stories/GuideDuDev/CreerUneIssue.mdx +64 -0
  189. package/src/stories/GuideDuDev/{CommentUtiliserLesRules.mdx → UtiliserLesRules.mdx} +2 -2
  190. package/src/stories/GuideDuDev/components.stories.ts +9 -7
  191. package/src/stories/Guidelines/Vuetify/Vuetify.stories.ts +163 -88
  192. package/src/stories/Guidelines/Vuetify/VuetifyItems.ts +250 -23
  193. package/src/temp/TestDTComponent.vue +5 -6
  194. package/src/utils/calcHumanFileSize/index.ts +12 -0
  195. package/src/utils/calcHumanFileSize/tests/calcHumanFileSize.spec.ts +21 -0
  196. package/src/designTokens/tokens/bootstrap/bootstrapColors.ts +0 -158
  197. package/src/designTokens/tokens/bootstrap/bootstrapLightTheme.ts +0 -22
  198. package/src/stories/GuideDuDev/CommentContribuer.mdx +0 -22
@@ -0,0 +1,233 @@
1
+ import { defineComponent, ref, type Ref } from 'vue'
2
+ import useThumbKeyboard from '../useThumbKeyboard'
3
+ import { describe, expect, it, vi, afterEach } from 'vitest'
4
+ import { mount } from '@vue/test-utils'
5
+ import { vuetify } from '@tests/unit/setup'
6
+
7
+ describe('useThumbKeyboard', () => {
8
+ let setValue = vi.fn()
9
+
10
+ const TestComponent = defineComponent({
11
+ props: {
12
+ step: {
13
+ type: Number,
14
+ default: 1,
15
+ },
16
+ },
17
+ setup(props) {
18
+ const thumb = ref<HTMLElement | null>(null)
19
+ useThumbKeyboard(
20
+ thumb as Ref<HTMLElement>,
21
+ ref(50),
22
+ 0,
23
+ 100,
24
+ props.step,
25
+ setValue,
26
+ )
27
+
28
+ return { thumb }
29
+ },
30
+ template: `<div ref="thumb" class="thumb"></div>`,
31
+ })
32
+
33
+ afterEach(() => {
34
+ setValue = vi.fn()
35
+ })
36
+
37
+ it('should handle ArrowLeft key', async () => {
38
+ const wrapper = mount(TestComponent, {
39
+ global: {
40
+ plugins: [vuetify],
41
+ },
42
+ props: {
43
+ step: 5,
44
+ },
45
+ })
46
+
47
+ await wrapper.find('div.thumb').trigger('keydown', {
48
+ key: 'ArrowLeft',
49
+ })
50
+
51
+ expect(setValue).toHaveBeenCalledTimes(1)
52
+ expect(setValue).toHaveBeenCalledWith(45)
53
+ })
54
+
55
+ it('should handle ArrowDown key', async () => {
56
+ const wrapper = mount(TestComponent, {
57
+ global: {
58
+ plugins: [vuetify],
59
+ },
60
+ props: {
61
+ step: 5,
62
+ },
63
+ })
64
+
65
+ await wrapper.find('div.thumb').trigger('keydown', {
66
+ key: 'ArrowDown',
67
+ })
68
+
69
+ expect(setValue).toHaveBeenCalledTimes(1)
70
+ expect(setValue).toHaveBeenCalledWith(45)
71
+ })
72
+
73
+ it('should handle ArrowRight key', async () => {
74
+ const wrapper = mount(TestComponent, {
75
+ global: {
76
+ plugins: [vuetify],
77
+ },
78
+ props: {
79
+ step: 5,
80
+ },
81
+ })
82
+
83
+ await wrapper.find('div.thumb').trigger('keydown', {
84
+ key: 'ArrowRight',
85
+ })
86
+
87
+ expect(setValue).toHaveBeenCalledTimes(1)
88
+ expect(setValue).toHaveBeenCalledWith(55)
89
+ })
90
+
91
+ it('should handle ArrowUp key', async () => {
92
+ const wrapper = mount(TestComponent, {
93
+ global: {
94
+ plugins: [vuetify],
95
+ },
96
+ props: {
97
+ step: 5,
98
+ },
99
+ })
100
+
101
+ await wrapper.find('div.thumb').trigger('keydown', {
102
+ key: 'ArrowUp',
103
+ })
104
+
105
+ expect(setValue).toHaveBeenCalledTimes(1)
106
+ expect(setValue).toHaveBeenCalledWith(55)
107
+ })
108
+
109
+ it('should set a value that is a multiple of the step', async () => {
110
+ const wrapper = mount(TestComponent, {
111
+ global: {
112
+ plugins: [vuetify],
113
+ },
114
+ props: {
115
+ step: 6,
116
+ },
117
+ })
118
+
119
+ await wrapper.find('div.thumb').trigger('keydown', {
120
+ key: 'ArrowRight',
121
+ })
122
+
123
+ expect(setValue).toHaveBeenCalledWith(54)
124
+ })
125
+
126
+ it('should handle Home key', async () => {
127
+ const wrapper = mount(TestComponent, {
128
+ global: {
129
+ plugins: [vuetify],
130
+ },
131
+ props: {
132
+ step: 9,
133
+ },
134
+ })
135
+
136
+ await wrapper.find('div.thumb').trigger('keydown', {
137
+ key: 'Home',
138
+ })
139
+
140
+ expect(setValue).toHaveBeenCalledTimes(1)
141
+ expect(setValue).toHaveBeenCalledWith(0)
142
+ })
143
+
144
+ it('should handle End key', async () => {
145
+ const wrapper = mount(TestComponent, {
146
+ global: {
147
+ plugins: [vuetify],
148
+ },
149
+ props: {
150
+ step: 9,
151
+ },
152
+ })
153
+
154
+ await wrapper.find('div.thumb').trigger('keydown', {
155
+ key: 'End',
156
+ })
157
+
158
+ expect(setValue).toHaveBeenCalledTimes(1)
159
+ expect(setValue).toHaveBeenCalledWith(100)
160
+ })
161
+
162
+ it('should handle PageDown key', async () => {
163
+ const wrapper = mount(TestComponent, {
164
+ global: {
165
+ plugins: [vuetify],
166
+ },
167
+ props: {
168
+ step: 2,
169
+ },
170
+ })
171
+
172
+ await wrapper.find('div.thumb').trigger('keydown', {
173
+ key: 'PageDown',
174
+ })
175
+
176
+ expect(setValue).toHaveBeenCalledTimes(1)
177
+ expect(setValue).toHaveBeenCalledWith(30)
178
+ })
179
+
180
+ it('should handle PageUp key', async () => {
181
+ const wrapper = mount(TestComponent, {
182
+ global: {
183
+ plugins: [vuetify],
184
+ },
185
+ props: {
186
+ step: 2,
187
+ },
188
+ })
189
+
190
+ await wrapper.find('div.thumb').trigger('keydown', {
191
+ key: 'PageUp',
192
+ })
193
+
194
+ expect(setValue).toHaveBeenCalledTimes(1)
195
+ expect(setValue).toHaveBeenCalledWith(70)
196
+ })
197
+
198
+ it('should handle PageDown key with overflow', async () => {
199
+ const wrapper = mount(TestComponent, {
200
+ global: {
201
+ plugins: [vuetify],
202
+ },
203
+ props: {
204
+ step: 9,
205
+ },
206
+ })
207
+
208
+ await wrapper.find('div.thumb').trigger('keydown', {
209
+ key: 'PageDown',
210
+ })
211
+
212
+ expect(setValue).toHaveBeenCalledTimes(1)
213
+ expect(setValue).toHaveBeenCalledWith(0)
214
+ })
215
+
216
+ it('should handle PageUp key with overflow', async () => {
217
+ const wrapper = mount(TestComponent, {
218
+ global: {
219
+ plugins: [vuetify],
220
+ },
221
+ props: {
222
+ step: 9,
223
+ },
224
+ })
225
+
226
+ await wrapper.find('div.thumb').trigger('keydown', {
227
+ key: 'PageUp',
228
+ })
229
+
230
+ expect(setValue).toHaveBeenCalledTimes(1)
231
+ expect(setValue).toHaveBeenCalledWith(100)
232
+ })
233
+ })
@@ -0,0 +1,150 @@
1
+ /* eslint-disable vue/one-component-per-file */
2
+ import { mount } from '@vue/test-utils'
3
+ import { describe, expect, it, vi } from 'vitest'
4
+ import { defineComponent, nextTick, onMounted, ref, type Ref } from 'vue'
5
+ import type Tooltip from '../Tooltip/Tooltip.vue'
6
+ import type { Range } from '../types'
7
+ import useTooltipsNudge from '../useTooltipsNudge'
8
+
9
+ describe('useTooltipsNudge', () => {
10
+ function getTestTooltip(left: number, right: number, width: number) {
11
+ return defineComponent({
12
+ setup() {
13
+ const element = ref<HTMLElement | null>(null)
14
+ onMounted(() => {
15
+ vi.spyOn(
16
+ element.value as HTMLElement,
17
+ 'getBoundingClientRect',
18
+ ).mockReturnValue({
19
+ left,
20
+ right,
21
+ width,
22
+ } as DOMRect)
23
+ })
24
+ return { element }
25
+ },
26
+ template: `<div ref="element"></div>`,
27
+ })
28
+ }
29
+
30
+ function getTestComponent(minThumb, maxThumb) {
31
+ return defineComponent({
32
+ components: {
33
+ minThumb,
34
+ maxThumb,
35
+ },
36
+ setup() {
37
+ const minThumb = ref()
38
+ const maxThumb = ref()
39
+ const placeholderMinThumb = ref()
40
+ const placeholderMaxThumb = ref()
41
+
42
+ const range = {
43
+ min: 0,
44
+ max: 100,
45
+ step: 1,
46
+ }
47
+
48
+ const { nudgeMinThumb, nudgeMaxThumb } = useTooltipsNudge(
49
+ minThumb as Ref<typeof Tooltip>,
50
+ maxThumb as Ref<typeof Tooltip>,
51
+ placeholderMinThumb as Ref<typeof Tooltip>,
52
+ placeholderMaxThumb as Ref<typeof Tooltip>,
53
+ range as unknown as Range,
54
+ )
55
+
56
+ return {
57
+ minThumb,
58
+ maxThumb,
59
+ placeholderMinThumb,
60
+ placeholderMaxThumb,
61
+ nudgeMinThumb,
62
+ nudgeMaxThumb,
63
+ }
64
+ },
65
+ template: `
66
+ <div>
67
+ <minThumb ref="minThumb"></minThumb>
68
+ <maxThumb ref="maxThumb"></maxThumb>
69
+ <minThumb ref="placeholderMinThumb"></minThumb>
70
+ <maxThumb ref="placeholderMaxThumb"></maxThumb>
71
+ </div>
72
+ `,
73
+ })
74
+ }
75
+
76
+ it('does not nudge the tooltips when they do not overlap', async () => {
77
+ const TestMin = getTestTooltip(0, 100, 100)
78
+ const TestMax = getTestTooltip(200, 300, 100)
79
+ const TestComponent = getTestComponent(TestMin, TestMax)
80
+
81
+ const wrapper = mount(TestComponent, {
82
+ attachTo: document.body,
83
+ })
84
+
85
+ await nextTick()
86
+
87
+ expect(wrapper.vm.nudgeMinThumb).toBe(0)
88
+ expect(wrapper.vm.nudgeMaxThumb).toBe(0)
89
+
90
+ wrapper.unmount()
91
+ })
92
+
93
+ it('nudges the tooltips when they overlap', async () => {
94
+ const right = 100
95
+ const left = 90
96
+ const TestMin = getTestTooltip(0, right, 100)
97
+ const TestMax = getTestTooltip(left, 190, 100)
98
+ const TestComponent = getTestComponent(TestMin, TestMax)
99
+
100
+ const wrapper = mount(TestComponent, {
101
+ attachTo: document.body,
102
+ })
103
+
104
+ await nextTick()
105
+
106
+ expect(wrapper.vm.nudgeMinThumb + wrapper.vm.nudgeMaxThumb).toBeGreaterThan(right - left)
107
+
108
+ wrapper.unmount()
109
+ })
110
+
111
+ it('nudge the bigger tooltip in priority to avoid the smaller to fly away (max)', async () => {
112
+ const right = 150
113
+ const left = 140
114
+ const TestMin = getTestTooltip(140, right, 10)
115
+ const TestMax = getTestTooltip(left, 10140, 10000)
116
+ const TestComponent = getTestComponent(TestMin, TestMax)
117
+
118
+ const wrapper = mount(TestComponent, {
119
+ attachTo: document.body,
120
+ })
121
+
122
+ await nextTick()
123
+
124
+ expect(wrapper.vm.nudgeMinThumb).toBe(1)
125
+ expect(wrapper.vm.nudgeMaxThumb).toBeGreaterThan(right - left)
126
+ expect(wrapper.vm.nudgeMaxThumb).toBeLessThan(right - left + 5)
127
+
128
+ wrapper.unmount()
129
+ })
130
+
131
+ it('nudge the bigger tooltip in priority to avoid the smaller to fly away (min)', async () => {
132
+ const right = 1250
133
+ const left = 800
134
+ const TestMin = getTestTooltip(230, right, 1020)
135
+ const TestMax = getTestTooltip(left, 900, 100)
136
+ const TestComponent = getTestComponent(TestMin, TestMax)
137
+
138
+ const wrapper = mount(TestComponent, {
139
+ attachTo: document.body,
140
+ })
141
+
142
+ await nextTick()
143
+
144
+ expect(wrapper.vm.nudgeMinThumb).toBeGreaterThan(right - left)
145
+ expect(wrapper.vm.nudgeMinThumb).toBeLessThan(right - left + 5)
146
+ expect(wrapper.vm.nudgeMaxThumb).toBe(1)
147
+
148
+ wrapper.unmount()
149
+ })
150
+ })
@@ -0,0 +1,314 @@
1
+ /* eslint-disable vue/one-component-per-file */
2
+ import { defineComponent, onMounted, ref, toRef, type Ref } from 'vue'
3
+ import useTrack from '../useTrack'
4
+ import { describe, expect, it, vi } from 'vitest'
5
+ import { mount } from '@vue/test-utils'
6
+ import { vuetify } from '@tests/unit/setup'
7
+
8
+ describe('useTrack', () => {
9
+ it('should return the track object', async () => {
10
+ const setMin = vi.fn()
11
+ const setMax = vi.fn()
12
+ const TestElement = defineComponent({
13
+ setup() {
14
+ const track = ref<HTMLElement | null>(null)
15
+ onMounted(() => {
16
+ const mockRect = vi.spyOn((track.value as HTMLElement), 'getBoundingClientRect')
17
+ mockRect.mockReturnValue({
18
+ left: 0,
19
+ width: 200,
20
+ } as DOMRect)
21
+ })
22
+
23
+ useTrack(
24
+ track as Ref<HTMLElement>,
25
+ {
26
+ rangeMin: 0,
27
+ rangeMax: 100,
28
+ selectedMin: 0,
29
+ selectedMax: 100,
30
+ step: 1,
31
+ },
32
+ setMin,
33
+ setMax,
34
+ )
35
+
36
+ return { track }
37
+ },
38
+ template: `<div>
39
+ <div ref="track" class="track"></div>
40
+ </div>`,
41
+ })
42
+
43
+ const wrapper = mount(TestElement, {
44
+ global: {
45
+ plugins: [vuetify],
46
+ },
47
+ })
48
+
49
+ await wrapper.find('div.track').trigger('click', {
50
+ clientX: 30,
51
+ })
52
+
53
+ expect(setMin).toHaveBeenCalledTimes(1)
54
+ expect(setMin).toHaveBeenCalledWith(15)
55
+ expect(setMax).toHaveBeenCalledTimes(0)
56
+
57
+ await wrapper.find('div.track').trigger('click', {
58
+ clientX: 170,
59
+ })
60
+
61
+ expect(setMax).toHaveBeenCalledTimes(1)
62
+ expect(setMax).toHaveBeenCalledWith(85)
63
+ expect(setMin).toHaveBeenCalledTimes(1)
64
+
65
+ await wrapper.find('div.track').trigger('click', {
66
+ clientX: 200,
67
+ })
68
+
69
+ expect(setMax).toHaveBeenCalledTimes(2)
70
+ expect(setMax).toHaveBeenCalledWith(100)
71
+ expect(setMin).toHaveBeenCalledTimes(1)
72
+ })
73
+
74
+ it('call the function with the closest step', async () => {
75
+ const setMin = vi.fn()
76
+ const setMax = vi.fn()
77
+ const TestElement = defineComponent({
78
+ setup() {
79
+ const track = ref<HTMLElement | null>(null)
80
+ onMounted(() => {
81
+ const mockRect = vi.spyOn((track.value as HTMLElement), 'getBoundingClientRect')
82
+ mockRect.mockReturnValue({
83
+ left: 0,
84
+ width: 200,
85
+ } as DOMRect)
86
+ })
87
+
88
+ useTrack(
89
+ track as Ref<HTMLElement>,
90
+ {
91
+ rangeMin: 0,
92
+ rangeMax: 100,
93
+ selectedMin: 0,
94
+ selectedMax: 100,
95
+ step: 5,
96
+ },
97
+ setMin,
98
+ setMax,
99
+ )
100
+
101
+ return { track }
102
+ },
103
+ template: `<div>
104
+ <div ref="track" class="track"></div>
105
+ </div>`,
106
+ })
107
+
108
+ const wrapper = mount(TestElement, {
109
+ global: {
110
+ plugins: [vuetify],
111
+ },
112
+ })
113
+
114
+ await wrapper.find('div.track').trigger('click', {
115
+ clientX: 33,
116
+ })
117
+
118
+ expect(setMin).toHaveBeenCalledTimes(1)
119
+ expect(setMin).toHaveBeenCalledWith(15)
120
+
121
+ await wrapper.find('div.track').trigger('click', {
122
+ clientX: 188,
123
+ })
124
+
125
+ expect(setMax).toHaveBeenCalledTimes(1)
126
+ expect(setMax).toHaveBeenCalledWith(95)
127
+ })
128
+
129
+ it('return the good value when the track contains negative values', async () => {
130
+ const setMin = vi.fn()
131
+ const setMax = vi.fn()
132
+ const TestElement = defineComponent({
133
+ setup() {
134
+ const track = ref<HTMLElement | null>(null)
135
+ onMounted(() => {
136
+ const mockRect = vi.spyOn((track.value as HTMLElement), 'getBoundingClientRect')
137
+ mockRect.mockReturnValue({
138
+ left: 0,
139
+ width: 200,
140
+ } as DOMRect)
141
+ })
142
+
143
+ useTrack(
144
+ track as Ref<HTMLElement>,
145
+ {
146
+ rangeMin: -50,
147
+ rangeMax: 50,
148
+ selectedMin: -50,
149
+ selectedMax: 10,
150
+ step: 5,
151
+ },
152
+ setMin,
153
+ setMax,
154
+ )
155
+
156
+ return { track }
157
+ },
158
+ template: `<div>
159
+ <div ref="track" class="track"></div>
160
+ </div>`,
161
+ })
162
+
163
+ const wrapper = mount(TestElement, {
164
+ global: {
165
+ plugins: [vuetify],
166
+ },
167
+ })
168
+
169
+ await wrapper.find('div.track').trigger('click', {
170
+ clientX: 121,
171
+ })
172
+
173
+ expect(setMax).toHaveBeenCalledTimes(1)
174
+ expect(setMax).toHaveBeenCalledWith(10)
175
+
176
+ await wrapper.find('div.track').trigger('click', {
177
+ clientX: 17,
178
+ })
179
+
180
+ expect(setMin).toHaveBeenCalledTimes(1)
181
+ expect(setMin).toHaveBeenCalledWith(-40)
182
+ })
183
+
184
+ it('do not call any function if the disabled prop is true', async () => {
185
+ const setMin = vi.fn()
186
+ const setMax = vi.fn()
187
+ const TestElement = defineComponent({
188
+ props: {
189
+ disable: {
190
+ type: Boolean,
191
+ default: false,
192
+ },
193
+ },
194
+ setup(props) {
195
+ const track = ref<HTMLElement | null>(null)
196
+ const disable = toRef(props, 'disable')
197
+ onMounted(() => {
198
+ const mockRect = vi.spyOn((track.value as HTMLElement), 'getBoundingClientRect')
199
+ mockRect.mockReturnValue({
200
+ left: 0,
201
+ width: 200,
202
+ } as DOMRect)
203
+ })
204
+
205
+ useTrack(
206
+ track as Ref<HTMLElement>,
207
+ {
208
+ rangeMin: 0,
209
+ rangeMax: 100,
210
+ selectedMin: 0,
211
+ selectedMax: 100,
212
+ step: 5,
213
+ },
214
+ setMin,
215
+ setMax,
216
+ disable,
217
+ )
218
+
219
+ return { track }
220
+ },
221
+ template: `<div>
222
+ <div ref="track" class="track"></div>
223
+ </div>`,
224
+ })
225
+
226
+ const wrapper = mount(TestElement, {
227
+ global: {
228
+ plugins: [vuetify],
229
+ },
230
+ props: {
231
+ disable: true,
232
+ },
233
+ })
234
+
235
+ await wrapper.find('div.track').trigger('click', {
236
+ clientX: 33,
237
+ })
238
+
239
+ expect(setMin).toHaveBeenCalledTimes(0)
240
+ expect(setMax).toHaveBeenCalledTimes(0)
241
+
242
+ await wrapper.setProps({ disable: false })
243
+
244
+ await wrapper.find('div.track').trigger('click', {
245
+ clientX: 33,
246
+ })
247
+
248
+ expect(setMin).toHaveBeenCalledTimes(1)
249
+
250
+ await wrapper.setProps({ disable: true })
251
+
252
+ await wrapper.find('div.track').trigger('click', {
253
+ clientX: 33,
254
+ })
255
+
256
+ expect(setMin).toHaveBeenCalledTimes(1)
257
+ expect(setMax).toHaveBeenCalledTimes(0)
258
+ })
259
+
260
+ it('when min and max are equal, call the function for right thumb', async () => {
261
+ const setMin = vi.fn()
262
+ const setMax = vi.fn()
263
+ const TestElement = defineComponent({
264
+ setup() {
265
+ const track = ref<HTMLElement | null>(null)
266
+ onMounted(() => {
267
+ const mockRect = vi.spyOn((track.value as HTMLElement), 'getBoundingClientRect')
268
+ mockRect.mockReturnValue({
269
+ left: 0,
270
+ width: 200,
271
+ } as DOMRect)
272
+ })
273
+
274
+ useTrack(
275
+ track as Ref<HTMLElement>,
276
+ {
277
+ rangeMin: 0,
278
+ rangeMax: 100,
279
+ selectedMin: 50,
280
+ selectedMax: 50,
281
+ step: 5,
282
+ },
283
+ setMin,
284
+ setMax,
285
+ )
286
+
287
+ return { track }
288
+ },
289
+ template: `<div>
290
+ <div ref="track" class="track"></div>
291
+ </div>`,
292
+ })
293
+
294
+ const wrapper = mount(TestElement, {
295
+ global: {
296
+ plugins: [vuetify],
297
+ },
298
+ })
299
+
300
+ await wrapper.find('div.track').trigger('click', {
301
+ clientX: 90,
302
+ })
303
+
304
+ expect(setMin).toHaveBeenCalledTimes(1)
305
+ expect(setMax).toHaveBeenCalledTimes(0)
306
+
307
+ await wrapper.find('div.track').trigger('click', {
308
+ clientX: 160,
309
+ })
310
+
311
+ expect(setMin).toHaveBeenCalledTimes(1)
312
+ expect(setMax).toHaveBeenCalledTimes(1)
313
+ })
314
+ })
@@ -0,0 +1,32 @@
1
+ import { mount } from '@vue/test-utils'
2
+ import { describe, expect, it } from 'vitest'
3
+ import { defineComponent } from 'vue'
4
+ import { vAnimateClick } from '../vAnimateClick'
5
+
6
+ describe('vAnimateClick', () => {
7
+ const TestComponent = defineComponent({
8
+ directives: {
9
+ animateClick: vAnimateClick,
10
+ },
11
+ template: `<div v-animate-click></div>`,
12
+ })
13
+
14
+ it('should add the animate-click class on mousedown', async () => {
15
+ const wrapper = mount(TestComponent)
16
+
17
+ const el = wrapper.find('div')
18
+
19
+ await el.trigger('mousedown')
20
+ expect(el.classes()).toContain('animate-click')
21
+ })
22
+
23
+ it('should remove the animate-click class on mouseup', async () => {
24
+ const wrapper = mount(TestComponent)
25
+
26
+ const el = wrapper.find('div')
27
+
28
+ await el.trigger('mousedown')
29
+ await el.trigger('mouseup')
30
+ expect(el.classes()).not.toContain('animate-click')
31
+ })
32
+ })