@nexxtmove/ui 0.1.30 → 0.1.32

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 (56) hide show
  1. package/dist/index.d.ts +113 -17
  2. package/dist/index.js +146 -111
  3. package/dist/nuxt.js +26 -25
  4. package/package.json +1 -1
  5. package/src/components/Avatar/Avatar.vue +49 -0
  6. package/src/components/Calendar/_CalendarDayView.vue +1 -1
  7. package/src/components/Chip/Chip.vue +9 -4
  8. package/src/components/Table/Table.vue +2 -2
  9. package/src/components.json +1 -0
  10. package/src/index.ts +1 -0
  11. package/src/components/AnimatedNumber/AnimatedNumber.stories.ts +0 -15
  12. package/src/components/AnimatedNumber/AnimatedNumber.test.ts +0 -56
  13. package/src/components/Button/Button.stories.ts +0 -212
  14. package/src/components/Button/Button.test.ts +0 -318
  15. package/src/components/Calendar/Calendar.stories.ts +0 -91
  16. package/src/components/Calendar/Calendar.test.ts +0 -279
  17. package/src/components/Calendar/_CalendarDayView.test.ts +0 -104
  18. package/src/components/Calendar/_CalendarHeader.test.ts +0 -86
  19. package/src/components/Calendar/_CalendarMonthView.test.ts +0 -52
  20. package/src/components/Calendar/_CalendarYearView.test.ts +0 -56
  21. package/src/components/Checkbox/Checkbox.stories.ts +0 -35
  22. package/src/components/Checkbox/Checkbox.test.ts +0 -55
  23. package/src/components/Chip/Chip.stories.ts +0 -42
  24. package/src/components/Chip/Chip.test.ts +0 -51
  25. package/src/components/CustomerJourneyTile/CustomerJourneyTile.stories.ts +0 -86
  26. package/src/components/CustomerJourneyTile/CustomerJourneyTile.test.ts +0 -178
  27. package/src/components/DatePicker/DatePicker.stories.ts +0 -149
  28. package/src/components/DatePicker/DatePicker.test.ts +0 -191
  29. package/src/components/DropdownButton/DropdownButton.stories.ts +0 -68
  30. package/src/components/DropdownButton/DropdownButton.test.ts +0 -124
  31. package/src/components/Header/Header.stories.ts +0 -54
  32. package/src/components/Header/Header.test.ts +0 -183
  33. package/src/components/Icon/Icon.stories.ts +0 -50
  34. package/src/components/Icon/Icon.test.ts +0 -73
  35. package/src/components/InfoBlock/InfoBlock.stories.ts +0 -90
  36. package/src/components/InfoBlock/InfoBlock.test.ts +0 -101
  37. package/src/components/ProgressBar/ProgressBar.stories.ts +0 -30
  38. package/src/components/ProgressBar/ProgressBar.test.ts +0 -314
  39. package/src/components/SocialIcons/SocialIcons.stories.ts +0 -34
  40. package/src/components/SocialIcons/SocialIcons.test.ts +0 -58
  41. package/src/components/SocialMediaCustomTemplate/SocialMediaCustomTemplate.stories.ts +0 -11
  42. package/src/components/SocialMediaCustomTemplate/SocialMediaCustomTemplate.test.ts +0 -131
  43. package/src/components/SocialMediaTemplate/SocialMediaTemplate.stories.ts +0 -71
  44. package/src/components/SocialMediaTemplate/SocialMediaTemplate.test.ts +0 -466
  45. package/src/components/SocialMediaType/SocialMediaType.stories.ts +0 -43
  46. package/src/components/SocialMediaType/SocialMediaType.test.ts +0 -126
  47. package/src/components/StepperHeader/StepperHeader.stories.ts +0 -47
  48. package/src/components/StepperHeader/StepperHeader.test.ts +0 -244
  49. package/src/components/Table/Table.stories.ts +0 -283
  50. package/src/components/Table/Table.test.ts +0 -220
  51. package/src/components/TimelineEvent/TimelineEvent.stories.ts +0 -291
  52. package/src/components/TimelineEvent/TimelineEvent.test.ts +0 -166
  53. package/src/components/TimelinePhaseblock/TimelinePhaseblock.stories.ts +0 -198
  54. package/src/components/TimelinePhaseblock/TimelinePhaseblock.test.ts +0 -283
  55. package/src/components/Tooltip/Tooltip.stories.ts +0 -146
  56. package/src/components/Tooltip/Tooltip.test.ts +0 -122
@@ -1,314 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest'
2
- import { mount } from '@vue/test-utils'
3
- import ProgressBar from './ProgressBar.vue'
4
-
5
- describe('ProgressBar', () => {
6
- beforeEach(() => {
7
- vi.clearAllMocks()
8
- vi.stubGlobal('console', { warn: vi.fn() })
9
- })
10
-
11
- it('renders correct percentage for first step', () => {
12
- const wrapper = mount(ProgressBar, {
13
- props: {
14
- steps: 5,
15
- currentStep: 0,
16
- },
17
- })
18
-
19
- const progressbar = wrapper.find('[role="progressbar"]')
20
- expect(progressbar.attributes('aria-valuenow')).toBe('0')
21
-
22
- const innerBar = progressbar.find('div')
23
- expect(innerBar.attributes('style')).toContain('width: 0%')
24
- })
25
-
26
- it('renders correct percentage for middle step', () => {
27
- const wrapper = mount(ProgressBar, {
28
- props: {
29
- steps: 5,
30
- currentStep: 2,
31
- },
32
- })
33
-
34
- const progressbar = wrapper.find('[role="progressbar"]')
35
- expect(progressbar.attributes('aria-valuenow')).toBe('50')
36
- expect(progressbar.find('div').attributes('style')).toContain('width: 50%')
37
- })
38
-
39
- it('renders correct percentage for last step', () => {
40
- const wrapper = mount(ProgressBar, {
41
- props: {
42
- steps: 5,
43
- currentStep: 4,
44
- },
45
- })
46
-
47
- const progressbar = wrapper.find('[role="progressbar"]')
48
- expect(progressbar.attributes('aria-valuenow')).toBe('100')
49
- expect(progressbar.find('div').attributes('style')).toContain('width: 100%')
50
- })
51
-
52
- it('clamps currentStep within range', () => {
53
- const wrapperLow = mount(ProgressBar, {
54
- props: { steps: 5, currentStep: -1 },
55
- })
56
- expect(wrapperLow.find('[role="progressbar"]').attributes('aria-valuenow')).toBe('0')
57
-
58
- const wrapperHigh = mount(ProgressBar, {
59
- props: { steps: 5, currentStep: 10 },
60
- })
61
- expect(wrapperHigh.find('[role="progressbar"]').attributes('aria-valuenow')).toBe('100')
62
- })
63
-
64
- it('handles edge case of 0 or 1 steps', () => {
65
- const wrapperZero = mount(ProgressBar, {
66
- props: { steps: 0, currentStep: 0 },
67
- })
68
- expect(wrapperZero.find('[role="progressbar"]').attributes('aria-valuenow')).toBe('0')
69
-
70
- const wrapperOne = mount(ProgressBar, {
71
- props: { steps: 1, currentStep: 0 },
72
- })
73
- expect(wrapperOne.find('[role="progressbar"]').attributes('aria-valuenow')).toBe('100')
74
- })
75
-
76
- it('handles empty stepTitles array', () => {
77
- const wrapper = mount(ProgressBar, {
78
- props: { steps: 5, currentStep: 0, stepTitles: [] },
79
- })
80
- expect(wrapper.find('ol').exists()).toBe(false)
81
- expect(wrapper.find('.tabular-nums').exists()).toBe(false)
82
- })
83
-
84
- it('displays correct step text without titles', () => {
85
- const wrapper = mount(ProgressBar, {
86
- props: { steps: 5, currentStep: 2 },
87
- })
88
-
89
- expect(wrapper.find('[role="progressbar"]').attributes('aria-valuetext')).toBe('Step 3 of 5')
90
- })
91
-
92
- it('displays correct step text with titles', () => {
93
- const stepTitles = ['Start', 'Middle', 'End']
94
- const wrapper = mount(ProgressBar, {
95
- props: {
96
- steps: 3,
97
- currentStep: 1,
98
- stepTitles,
99
- },
100
- })
101
-
102
- expect(wrapper.find('[role="progressbar"]').attributes('aria-valuetext')).toBe(
103
- 'Step 2 of 3: Middle',
104
- )
105
- })
106
-
107
- it('renders step titles and marks current step', () => {
108
- const stepTitles = ['Step 1', 'Step 2', 'Step 3']
109
- const wrapper = mount(ProgressBar, {
110
- props: {
111
- steps: 3,
112
- currentStep: 1,
113
- stepTitles,
114
- },
115
- })
116
-
117
- const items = wrapper.findAll('li')
118
- expect(items).toHaveLength(3)
119
- expect(items[1]!.attributes('aria-current')).toBe('step')
120
- expect(items[1]!.classes()).toContain('text-sapphire-500')
121
- expect(items[0]!.attributes('aria-current')).toBeUndefined()
122
- })
123
-
124
- it('uses default progress label', () => {
125
- const wrapper = mount(ProgressBar, {
126
- props: {
127
- steps: 5,
128
- currentStep: 0,
129
- },
130
- })
131
- expect(wrapper.find('[role="progressbar"]').attributes('aria-label')).toBe('Voortgang')
132
- })
133
-
134
- it('uses custom progress label', () => {
135
- const wrapper = mount(ProgressBar, {
136
- props: {
137
- steps: 5,
138
- currentStep: 0,
139
- progressLabel: 'My Progress',
140
- },
141
- })
142
- expect(wrapper.find('[role="progressbar"]').attributes('aria-label')).toBe('My Progress')
143
- })
144
-
145
- it('warns when stepTitles length mismatch', () => {
146
- const spy = vi.spyOn(console, 'warn')
147
- mount(ProgressBar, {
148
- props: {
149
- steps: 5,
150
- currentStep: 0,
151
- stepTitles: ['Only one'],
152
- },
153
- })
154
- expect(spy).toHaveBeenCalledWith(expect.stringContaining('[NexxtProgressBar]'))
155
- })
156
-
157
- it('handles missing title in titles array gracefully', () => {
158
- const wrapper = mount(ProgressBar, {
159
- props: {
160
- steps: 3,
161
- currentStep: 2, // Last step
162
- stepTitles: ['Only First'], // Only index 0 exists
163
- },
164
- })
165
- // clampedStep is 2, stepTitles[2] is undefined
166
- expect(wrapper.find('[role="progressbar"]').attributes('aria-valuetext')).toBe('Step 3 of 3')
167
- })
168
-
169
- it('has responsive container query classes', () => {
170
- const wrapper = mount(ProgressBar, {
171
- props: {
172
- steps: 5,
173
- currentStep: 0,
174
- stepTitles: ['Step 1', 'Step 2', 'Step 3', 'Step 4', 'Step 5'],
175
- },
176
- })
177
-
178
- // Verify the root is a container
179
- expect(wrapper.classes()).toContain('@container')
180
-
181
- // Verify the digit counter hides when the container is large
182
- const counter = wrapper.find('.tabular-nums')
183
- expect(counter.classes()).toContain('@md:hidden')
184
-
185
- // Verify list items hide titles when the container is small
186
- const firstTitle = wrapper.find('li')
187
- expect(firstTitle.classes()).toContain('@max-md:hidden')
188
- })
189
-
190
- it('updates animation direction correctly based on step change', async () => {
191
- const wrapper = mount(ProgressBar, {
192
- props: {
193
- steps: 5,
194
- currentStep: 2,
195
- stepTitles: ['1', '2', '3', '4', '5'],
196
- },
197
- global: {
198
- stubs: {
199
- // Stubbing Transition lets us inspect the dynamic classes passed to it
200
- Transition: {
201
- template: '<slot />',
202
- props: ['enterFromClass', 'leaveToClass'],
203
- },
204
- },
205
- },
206
- })
207
-
208
- // Increment: Step 3 -> 4
209
- await wrapper.setProps({ currentStep: 3 })
210
- let transition = wrapper.findComponent({ name: 'Transition' })
211
- expect(transition.props('enterFromClass')).toBe('translate-y-full')
212
- expect(transition.props('leaveToClass')).toBe('-translate-y-full')
213
-
214
- // Decrement: Step 4 -> 2
215
- await wrapper.setProps({ currentStep: 1 })
216
- transition = wrapper.findComponent({ name: 'Transition' })
217
- expect(transition.props('enterFromClass')).toBe('-translate-y-full')
218
- expect(transition.props('leaveToClass')).toBe('translate-y-full')
219
- })
220
-
221
- it('emits update:currentStep when a previous step is clicked', async () => {
222
- const stepTitles = ['Step 1', 'Step 2', 'Step 3']
223
- const wrapper = mount(ProgressBar, {
224
- props: {
225
- steps: 3,
226
- currentStep: 2,
227
- stepTitles,
228
- },
229
- })
230
-
231
- const items = wrapper.findAll('li')
232
-
233
- // Click first step (index 0, previous)
234
- await items[0]!.trigger('click')
235
- expect(wrapper.emitted('update:currentStep')).toBeTruthy()
236
- expect(wrapper.emitted('update:currentStep')![0]).toEqual([0])
237
-
238
- // Click second step (index 1, previous)
239
- await items[1]!.trigger('click')
240
- expect(wrapper.emitted('update:currentStep')![1]).toEqual([1])
241
- })
242
-
243
- it('does not emit update:currentStep when the current or a future step is clicked', async () => {
244
- const stepTitles = ['Step 1', 'Step 2', 'Step 3']
245
- const wrapper = mount(ProgressBar, {
246
- props: {
247
- steps: 3,
248
- currentStep: 1,
249
- stepTitles,
250
- },
251
- })
252
-
253
- const items = wrapper.findAll('li')
254
-
255
- // Click current step (index 1)
256
- await items[1]!.trigger('click')
257
- expect(wrapper.emitted('update:currentStep')).toBeFalsy()
258
-
259
- // Click future step (index 2)
260
- await items[2]!.trigger('click')
261
- expect(wrapper.emitted('update:currentStep')).toBeFalsy()
262
- })
263
-
264
- it('applies interactive classes only to previous steps', () => {
265
- const stepTitles = ['Step 1', 'Step 2', 'Step 3']
266
- const wrapper = mount(ProgressBar, {
267
- props: {
268
- steps: 3,
269
- currentStep: 1,
270
- stepTitles,
271
- },
272
- })
273
-
274
- const items = wrapper.findAll('li')
275
-
276
- // Previous step
277
- expect(items[0]!.classes()).toContain('cursor-pointer')
278
- expect(items[0]!.classes()).toContain('hover:text-sapphire-400')
279
- expect(items[0]!.attributes('role')).toBe('button')
280
- expect(items[0]!.attributes('tabindex')).toBe('0')
281
- expect(items[0]!.attributes('aria-label')).toBe('Ga naar Step 1')
282
-
283
- // Current step
284
- expect(items[1]!.classes()).not.toContain('cursor-pointer')
285
- expect(items[1]!.attributes('role')).toBeUndefined()
286
- expect(items[1]!.attributes('tabindex')).toBeUndefined()
287
-
288
- // Future step
289
- expect(items[2]!.classes()).not.toContain('cursor-pointer')
290
- expect(items[2]!.attributes('role')).toBeUndefined()
291
- expect(items[2]!.attributes('tabindex')).toBeUndefined()
292
- })
293
-
294
- it('emits update:currentStep when Enter or Space is pressed on a previous step', async () => {
295
- const stepTitles = ['Step 1', 'Step 2', 'Step 3']
296
- const wrapper = mount(ProgressBar, {
297
- props: {
298
- steps: 3,
299
- currentStep: 2,
300
- stepTitles,
301
- },
302
- })
303
-
304
- const items = wrapper.findAll('li')
305
-
306
- // Press Enter on first step
307
- await items[0]!.trigger('keydown.enter')
308
- expect(wrapper.emitted('update:currentStep')![0]).toEqual([0])
309
-
310
- // Press Space on second step
311
- await items[1]!.trigger('keydown.space')
312
- expect(wrapper.emitted('update:currentStep')![1]).toEqual([1])
313
- })
314
- })
@@ -1,34 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
- import SocialIcons from './SocialIcons.vue'
3
-
4
- export default {
5
- title: 'Components/Molecules/Social Icons',
6
- component: SocialIcons,
7
- parameters: {
8
- design: {
9
- type: 'figma',
10
- url: 'https://www.figma.com/design/CdbFJ7qUga6mtjagcPDvYK/Design-System?node-id=524-17&t=CbHvOQfEMIr7M5mO-11',
11
- },
12
- },
13
- } satisfies Meta<typeof SocialIcons>
14
-
15
- type Story = StoryObj<typeof SocialIcons>
16
-
17
- export const Default: Story = {
18
- args: {
19
- facebook: true,
20
- instagram: true,
21
- linkedin: true,
22
- x: true,
23
- google: true,
24
- tiktok: true,
25
- },
26
- }
27
-
28
- export const Selective: Story = {
29
- args: {
30
- facebook: true,
31
- linkedin: true,
32
- instagram: true,
33
- },
34
- }
@@ -1,58 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { mount } from '@vue/test-utils'
3
- import SocialIcons from './SocialIcons.vue'
4
-
5
- describe('SocialIcons', () => {
6
- it('renders nothing when no props are set', () => {
7
- const wrapper = mount(SocialIcons)
8
- expect(wrapper.findAll('.rounded-full')).toHaveLength(0)
9
- })
10
-
11
- it('renders only the requested icons', () => {
12
- const wrapper = mount(SocialIcons, {
13
- props: {
14
- facebook: true,
15
- instagram: true,
16
- },
17
- })
18
-
19
- const icons = wrapper.findAll('.rounded-full')
20
- expect(icons).toHaveLength(2)
21
-
22
- // Check for specific background colors to verify which icons are rendered
23
- expect(icons[0]!.classes()).toContain('bg-brands-facebook')
24
- expect(icons[1]!.classes()).toContain('bg-brands-instagram')
25
- })
26
-
27
- it('has correct accessibility attributes', () => {
28
- const wrapper = mount(SocialIcons, {
29
- props: {
30
- facebook: true,
31
- },
32
- })
33
-
34
- const list = wrapper.find('ul')
35
- expect(list.exists()).toBe(true)
36
- expect(list.attributes('aria-label')).toBe('Sociale media kanalen')
37
-
38
- const item = wrapper.find('li')
39
- expect(item.exists()).toBe(true)
40
- expect(item.attributes('aria-label')).toBe('Facebook')
41
- expect(item.findComponent({ name: 'NexxtIcon' }).attributes('aria-hidden')).toBe('true')
42
- })
43
-
44
- it('renders all icons when all props are true', () => {
45
- const wrapper = mount(SocialIcons, {
46
- props: {
47
- facebook: true,
48
- instagram: true,
49
- linkedin: true,
50
- x: true,
51
- google: true,
52
- tiktok: true,
53
- },
54
- })
55
-
56
- expect(wrapper.findAll('.rounded-full')).toHaveLength(6)
57
- })
58
- })
@@ -1,11 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
- import SocialMediaCustomTemplate from './SocialMediaCustomTemplate.vue'
3
-
4
- export default {
5
- title: 'Components/Molecules/Social Media Custom Template',
6
- component: SocialMediaCustomTemplate,
7
- } satisfies Meta<typeof SocialMediaCustomTemplate>
8
-
9
- type Story = StoryObj<typeof SocialMediaCustomTemplate>
10
-
11
- export const Default: Story = {}
@@ -1,131 +0,0 @@
1
- import { mount } from '@vue/test-utils'
2
- import { describe, it, expect, vi } from 'vitest'
3
- import SocialMediaCustomTemplate from './SocialMediaCustomTemplate.vue'
4
-
5
- describe('SocialMediaCustomTemplate', () => {
6
- it('renders correctly with video and poster', () => {
7
- const wrapper = mount(SocialMediaCustomTemplate)
8
- const video = wrapper.find('video')
9
-
10
- expect(wrapper.element.tagName).toBe('BUTTON')
11
- expect(video.exists()).toBe(true)
12
- // Check video properties directly
13
- const videoElement = video.element as HTMLVideoElement
14
- expect(videoElement.muted).toBe(true)
15
- expect(video.attributes('poster')).toContain('Template_aanvragen.jpg')
16
- })
17
-
18
- it('handles video ended event correctly', async () => {
19
- const wrapper = mount(SocialMediaCustomTemplate)
20
- const videoElement = wrapper.find('video').element as HTMLVideoElement
21
- const loadSpy = vi.spyOn(videoElement, 'load').mockImplementation(() => {})
22
-
23
- // Simulate video ending
24
- await wrapper.find('video').trigger('ended')
25
-
26
- expect(videoElement.currentTime).toBe(0)
27
- expect(loadSpy).toHaveBeenCalled()
28
- })
29
-
30
- it('plays video on mouseenter after first play', async () => {
31
- const wrapper = mount(SocialMediaCustomTemplate)
32
- const videoElement = wrapper.find('video').element as HTMLVideoElement
33
- const playSpy = vi.spyOn(videoElement, 'play').mockImplementation(() => Promise.resolve())
34
-
35
- // Set state to hasPlayedOnce
36
- await wrapper.find('video').trigger('ended')
37
-
38
- // Trigger mouseenter
39
- await wrapper.trigger('mouseenter')
40
-
41
- expect(playSpy).toHaveBeenCalled()
42
- })
43
-
44
- it('pauses video on mouseleave after first play', async () => {
45
- const wrapper = mount(SocialMediaCustomTemplate)
46
- const videoElement = wrapper.find('video').element as HTMLVideoElement
47
- const pauseSpy = vi.spyOn(videoElement, 'pause')
48
-
49
- // Set state to hasPlayedOnce
50
- await wrapper.find('video').trigger('ended')
51
-
52
- // Trigger mouseleave
53
- await wrapper.trigger('mouseleave')
54
-
55
- expect(pauseSpy).toHaveBeenCalled()
56
- })
57
-
58
- it('sets loop to true after first play', async () => {
59
- const wrapper = mount(SocialMediaCustomTemplate)
60
- const video = wrapper.find('video')
61
- const videoElement = video.element as HTMLVideoElement
62
-
63
- expect(videoElement.loop).toBe(false)
64
-
65
- // Simulate video ending
66
- await video.trigger('ended')
67
-
68
- expect(videoElement.loop).toBe(true)
69
- })
70
-
71
- it('does not play on mouseenter before first play has ended', async () => {
72
- const wrapper = mount(SocialMediaCustomTemplate)
73
- const videoElement = wrapper.find('video').element as HTMLVideoElement
74
- const playSpy = vi.spyOn(videoElement, 'play')
75
-
76
- await wrapper.trigger('mouseenter')
77
-
78
- expect(playSpy).not.toHaveBeenCalled()
79
- })
80
-
81
- it('does not pause on mouseleave before first play has ended', async () => {
82
- const wrapper = mount(SocialMediaCustomTemplate)
83
- const videoElement = wrapper.find('video').element as HTMLVideoElement
84
- const pauseSpy = vi.spyOn(videoElement, 'pause')
85
-
86
- await wrapper.trigger('mouseleave')
87
-
88
- expect(pauseSpy).not.toHaveBeenCalled()
89
- })
90
-
91
- it('does not call handleEnded if videoRef is null', async () => {
92
- const wrapper = mount(SocialMediaCustomTemplate)
93
- // @ts-expect-error - manually setting ref to null for test
94
- wrapper.vm.videoRef = null
95
-
96
- // Trigger handleEnded directly (internally)
97
- // @ts-expect-error - calling internal method
98
- wrapper.vm.handleEnded()
99
-
100
- // @ts-expect-error - checking internal state
101
- expect(wrapper.vm.hasPlayedOnce).toBe(false)
102
- })
103
-
104
- it('internal methods do nothing if videoRef is null', async () => {
105
- const wrapper = mount(SocialMediaCustomTemplate)
106
- // @ts-expect-error - manually setting ref to null for test
107
- wrapper.vm.videoRef = null
108
- // @ts-expect-error - manually setting hasPlayedOnce for branch test
109
- wrapper.vm.hasPlayedOnce = true
110
-
111
- // Trigger handleMouseEnter directly (internally)
112
- // @ts-expect-error - calling internal method
113
- wrapper.vm.handleMouseEnter()
114
- // Trigger handleMouseLeave directly (internally)
115
- // @ts-expect-error - calling internal method
116
- wrapper.vm.handleMouseLeave()
117
-
118
- // No errors should occur
119
- })
120
-
121
- it('plays onMounted if videoRef is valid', async () => {
122
- const wrapper = mount(SocialMediaCustomTemplate)
123
- const videoElement = wrapper.find('video').element as HTMLVideoElement
124
- const playSpy = vi.spyOn(videoElement, 'play').mockImplementation(() => Promise.resolve())
125
-
126
- // Simulate onMounted behavior by calling it again (it already ran once on mount)
127
- // @ts-expect-error - manually calling onMounted setup code
128
- wrapper.vm.handleMouseEnter() // hasPlayedOnce is false, should not play
129
- expect(playSpy).not.toHaveBeenCalled()
130
- })
131
- })
@@ -1,71 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
- import SocialMediaTemplate from './SocialMediaTemplate.vue'
3
-
4
- export default {
5
- title: 'Components/Organisms/Social Media Template',
6
- component: SocialMediaTemplate,
7
- argTypes: {
8
- variant: {
9
- control: 'select',
10
- options: ['post', 'video', 'slideshow'],
11
- },
12
- selected: {
13
- control: 'boolean',
14
- },
15
- muted: {
16
- control: 'boolean',
17
- },
18
- },
19
- parameters: {
20
- design: {
21
- type: 'figma',
22
- url: 'https://www.figma.com/design/CdbFJ7qUga6mtjagcPDvYK/Design-System?node-id=578-340&t=CbHvOQfEMIr7M5mO-11',
23
- },
24
- },
25
- } satisfies Meta<typeof SocialMediaTemplate>
26
-
27
- type Story = StoryObj<typeof SocialMediaTemplate>
28
-
29
- export const Post: Story = {
30
- args: {
31
- variant: 'post',
32
- media: 'https://loremflickr.com/400/600/house',
33
- mediaType: 'image',
34
- name: 'Amsterdam',
35
- type: 'Woning',
36
- selected: false,
37
- },
38
- }
39
-
40
- export const Video: Story = {
41
- args: {
42
- variant: 'video',
43
- media: '/barcelona.mp4',
44
- mediaType: 'video',
45
- muted: true,
46
- name: 'Barcelona',
47
- type: 'Woning',
48
- selected: false,
49
- },
50
- }
51
-
52
- export const Slideshow: Story = {
53
- args: {
54
- variant: 'slideshow',
55
- media: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e',
56
- mediaType: 'image',
57
- name: 'Stockholm',
58
- type: 'Bedrijfsunit',
59
- },
60
- }
61
-
62
- export const Selected: Story = {
63
- args: {
64
- variant: 'post',
65
- media: 'https://images.unsplash.com/photo-1551963831-b3b1ca40c98e',
66
- mediaType: 'image',
67
- name: 'Amsterdam',
68
- type: 'Woning',
69
- selected: true,
70
- },
71
- }