@nexxtmove/ui 2.5.0 → 2.7.0
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.
- package/dist/components/editor/molecules/EditorBorder/EditorBorder.vue.d.ts +12 -0
- package/dist/components/editor/molecules/EditorColor/_ThemeRoleSwatches.vue.d.ts +16 -0
- package/dist/index.js +1094 -1135
- package/dist/nuxt.js +0 -1
- package/package.json +38 -36
- package/src/attribute-contract.test.ts +151 -0
- package/src/components/atoms/AnimatedNumber/AnimatedNumber.stories.ts +36 -0
- package/src/components/atoms/AnimatedNumber/AnimatedNumber.test.ts +21 -0
- package/src/components/atoms/Avatar/Avatar.stories.ts +122 -0
- package/src/components/atoms/Avatar/Avatar.test.ts +134 -0
- package/src/components/atoms/Button/Button.stories.ts +290 -0
- package/src/components/atoms/Button/Button.test.ts +406 -0
- package/src/components/atoms/Card/Card.stories.ts +45 -0
- package/src/components/atoms/Card/Card.test.ts +46 -0
- package/src/components/atoms/Checkbox/Checkbox.stories.ts +35 -0
- package/src/components/atoms/Checkbox/Checkbox.test.ts +55 -0
- package/src/components/atoms/Chip/Chip.stories.ts +274 -0
- package/src/components/atoms/Chip/Chip.test.ts +230 -0
- package/src/components/atoms/EnergyLabel/EnergyLabel.stories.ts +189 -0
- package/src/components/atoms/EnergyLabel/EnergyLabel.test.ts +100 -0
- package/src/components/atoms/FloatingPanel/FloatingPanel.stories.ts +677 -0
- package/src/components/atoms/FloatingPanel/FloatingPanel.test.ts +864 -0
- package/src/components/atoms/Icon/Icon.stories.ts +63 -0
- package/src/components/atoms/Icon/Icon.test.ts +89 -0
- package/src/components/atoms/Loader/Loader.stories.ts +36 -0
- package/src/components/atoms/Loader/Loader.test.ts +40 -0
- package/src/components/atoms/PickerItem/PickerItem.stories.ts +172 -0
- package/src/components/atoms/PickerItem/PickerItem.test.ts +142 -0
- package/src/components/atoms/PickerPreview/PickerPreview.stories.ts +183 -0
- package/src/components/atoms/PickerPreview/PickerPreview.test.ts +137 -0
- package/src/components/atoms/PresenceIndicator/PresenceIndicator.stories.ts +21 -0
- package/src/components/atoms/PropertyListing/PropertyListing.stories.ts +38 -0
- package/src/components/atoms/PropertyListing/PropertyListing.test.ts +46 -0
- package/src/components/atoms/SelectableOption/SelectableOption.stories.ts +131 -0
- package/src/components/atoms/SelectableOption/SelectableOption.test.ts +96 -0
- package/src/components/atoms/Skeleton/Skeleton.stories.ts +27 -0
- package/src/components/atoms/Skeleton/Skeleton.test.ts +28 -0
- package/src/components/atoms/Slider/Slider.stories.ts +151 -0
- package/src/components/atoms/Slider/Slider.test.ts +191 -0
- package/src/components/atoms/Squircle/Squircle.stories.ts +114 -0
- package/src/components/atoms/Squircle/Squircle.test.ts +70 -0
- package/src/components/atoms/Switch/Switch.stories.ts +91 -0
- package/src/components/atoms/Switch/Switch.test.ts +183 -0
- package/src/components/atoms/Tooltip/Tooltip.stories.ts +158 -0
- package/src/components/atoms/Tooltip/Tooltip.test.ts +134 -0
- package/src/components/editor/atoms/EditorDimensionField/EditorDimensionField.stories.ts +124 -0
- package/src/components/editor/atoms/EditorDimensionField/EditorDimensionField.test.ts +464 -0
- package/src/components/editor/atoms/EditorSettingsBlock/EditorSettingsBlock.stories.ts +266 -0
- package/src/components/editor/atoms/EditorSettingsBlock/EditorSettingsBlock.test.ts +421 -0
- package/src/components/editor/atoms/EditorSettingsGroup/EditorSettingsGroup.stories.ts +365 -0
- package/src/components/editor/atoms/EditorSettingsGroup/EditorSettingsGroup.test.ts +484 -0
- package/src/components/editor/composables/useRadioGrid.test.ts +261 -0
- package/src/components/editor/molecules/EditorAlignItems/EditorAlignItems.stories.ts +73 -0
- package/src/components/editor/molecules/EditorAlignItems/EditorAlignItems.test.ts +189 -0
- package/src/components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.stories.ts +309 -0
- package/src/components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.test.ts +359 -0
- package/src/components/editor/molecules/EditorAnchor/EditorAnchor.stories.ts +138 -0
- package/src/components/editor/molecules/EditorAnchor/EditorAnchor.test.ts +344 -0
- package/src/components/editor/molecules/EditorBackgroundSize/EditorBackgroundSize.stories.ts +87 -0
- package/src/components/editor/molecules/EditorBackgroundSize/EditorBackgroundSize.test.ts +262 -0
- package/src/components/editor/molecules/EditorBlur/EditorBlur.stories.ts +115 -0
- package/src/components/editor/molecules/EditorBlur/EditorBlur.test.ts +243 -0
- package/src/components/editor/molecules/EditorBorder/EditorBorder.stories.ts +187 -0
- package/src/components/editor/molecules/EditorBorder/EditorBorder.test.ts +456 -0
- package/src/components/editor/molecules/EditorBorder/EditorBorder.vue +58 -2
- package/src/components/editor/molecules/EditorColor/EditorColor.stories.ts +563 -0
- package/src/components/editor/molecules/EditorColor/EditorColor.test.ts +689 -0
- package/src/components/editor/molecules/EditorColor/EditorColorGradient.test.ts +793 -0
- package/src/components/editor/molecules/EditorColor/_ColorField.vue +7 -29
- package/src/components/editor/molecules/EditorColor/_ThemeRoleSwatches.vue +57 -0
- package/src/components/editor/molecules/EditorColor/gradientClass.test.ts +303 -0
- package/src/components/editor/molecules/EditorDashPattern/EditorDashPattern.stories.ts +72 -0
- package/src/components/editor/molecules/EditorDashPattern/EditorDashPattern.test.ts +124 -0
- package/src/components/editor/molecules/EditorFlexDirection/EditorFlexDirection.stories.ts +46 -0
- package/src/components/editor/molecules/EditorFlexDirection/EditorFlexDirection.test.ts +97 -0
- package/src/components/editor/molecules/EditorFontSize/EditorFontSize.stories.ts +248 -0
- package/src/components/editor/molecules/EditorFontSize/EditorFontSize.test.ts +288 -0
- package/src/components/editor/molecules/EditorGap/EditorGap.stories.ts +129 -0
- package/src/components/editor/molecules/EditorGap/EditorGap.test.ts +253 -0
- package/src/components/editor/molecules/EditorHeadingType/EditorHeadingType.stories.ts +68 -0
- package/src/components/editor/molecules/EditorHeadingType/EditorHeadingType.test.ts +150 -0
- package/src/components/editor/molecules/EditorJustifyContent/EditorJustifyContent.stories.ts +71 -0
- package/src/components/editor/molecules/EditorJustifyContent/EditorJustifyContent.test.ts +161 -0
- package/src/components/editor/molecules/EditorLetterSpacing/EditorLetterSpacing.stories.ts +204 -0
- package/src/components/editor/molecules/EditorLetterSpacing/EditorLetterSpacing.test.ts +238 -0
- package/src/components/editor/molecules/EditorLineHeight/EditorLineHeight.stories.ts +257 -0
- package/src/components/editor/molecules/EditorLineHeight/EditorLineHeight.test.ts +286 -0
- package/src/components/editor/molecules/EditorLineStyle/EditorLineStyle.stories.ts +135 -0
- package/src/components/editor/molecules/EditorLineStyle/EditorLineStyle.test.ts +230 -0
- package/src/components/editor/molecules/EditorMaxWidth/EditorMaxWidth.stories.ts +154 -0
- package/src/components/editor/molecules/EditorMaxWidth/EditorMaxWidth.test.ts +112 -0
- package/src/components/editor/molecules/EditorOverrideStatus/EditorOverrideStatus.stories.ts +206 -0
- package/src/components/editor/molecules/EditorOverrideStatus/EditorOverrideStatus.test.ts +332 -0
- package/src/components/editor/molecules/EditorPadding/EditorPadding.stories.ts +374 -0
- package/src/components/editor/molecules/EditorPadding/EditorPadding.test.ts +712 -0
- package/src/components/editor/molecules/EditorRadius/EditorRadius.stories.ts +64 -0
- package/src/components/editor/molecules/EditorRadius/EditorRadius.test.ts +137 -0
- package/src/components/editor/molecules/EditorShadow/EditorShadow.stories.ts +103 -0
- package/src/components/editor/molecules/EditorShadow/EditorShadow.test.ts +168 -0
- package/src/components/editor/molecules/EditorSize/EditorSize.stories.ts +84 -0
- package/src/components/editor/molecules/EditorSize/EditorSize.test.ts +253 -0
- package/src/components/editor/molecules/EditorSizeLimit/EditorSizeLimit.stories.ts +49 -0
- package/src/components/editor/molecules/EditorSizeLimit/EditorSizeLimit.test.ts +43 -0
- package/src/components/editor/molecules/EditorTextAlign/EditorTextAlign.stories.ts +69 -0
- package/src/components/editor/molecules/EditorTextAlign/EditorTextAlign.test.ts +155 -0
- package/src/components/molecules/Announcement/Announcement.stories.ts +224 -0
- package/src/components/molecules/Announcement/Announcement.test.ts +161 -0
- package/src/components/molecules/ContactInfoCard/ContactInfoCard.stories.ts +99 -0
- package/src/components/molecules/ContactInfoCard/ContactInfoCard.test.ts +70 -0
- package/src/components/molecules/CustomerJourneyTile/CustomerJourneyTile.stories.ts +148 -0
- package/src/components/molecules/CustomerJourneyTile/CustomerJourneyTile.test.ts +271 -0
- package/src/components/molecules/DoughnutChart/DoughnutChart.stories.ts +45 -0
- package/src/components/molecules/DoughnutChart/DoughnutChart.test.ts +205 -0
- package/src/components/molecules/InfoBlock/InfoBlock.stories.ts +84 -0
- package/src/components/molecules/InfoBlock/InfoBlock.test.ts +101 -0
- package/src/components/molecules/InputField/InputField.stories.ts +117 -0
- package/src/components/molecules/InputField/InputField.test.ts +138 -0
- package/src/components/molecules/InputSelect/InputSelect.stories.ts +116 -0
- package/src/components/molecules/InputSelect/InputSelect.test.ts +127 -0
- package/src/components/molecules/ModalFooter/ModalFooter.stories.ts +204 -0
- package/src/components/molecules/ModalFooter/ModalFooter.test.ts +276 -0
- package/src/components/molecules/PageCard/PageCard.stories.ts +100 -0
- package/src/components/molecules/PageCard/PageCard.test.ts +91 -0
- package/src/components/molecules/PageContainer/PageContainer.stories.ts +90 -0
- package/src/components/molecules/PageContainer/PageContainer.test.ts +50 -0
- package/src/components/molecules/PageMockup/PageMockup.stories.ts +38 -0
- package/src/components/molecules/PageMockup/PageMockup.test.ts +20 -0
- package/src/components/molecules/PageTypeTile/PageTypeTile.stories.ts +63 -0
- package/src/components/molecules/PageTypeTile/PageTypeTile.test.ts +41 -0
- package/src/components/molecules/Pagination/Pagination.stories.ts +72 -0
- package/src/components/molecules/Pagination/Pagination.test.ts +130 -0
- package/src/components/molecules/PickerGroup/PickerGroup.stories.ts +90 -0
- package/src/components/molecules/PickerGroup/PickerGroup.test.ts +145 -0
- package/src/components/molecules/PickerList/PickerList.stories.ts +436 -0
- package/src/components/molecules/PickerList/PickerList.test.ts +870 -0
- package/src/components/molecules/PlaceholderInput/PlaceholderInput.stories.ts +48 -0
- package/src/components/molecules/PlaceholderInput/PlaceholderInput.test.ts +107 -0
- package/src/components/molecules/PropertyCard/PropertyCard.stories.ts +46 -0
- package/src/components/molecules/PropertyCard/PropertyCard.test.ts +59 -0
- package/src/components/molecules/Select/Select.stories.ts +264 -0
- package/src/components/molecules/Select/Select.test.ts +315 -0
- package/src/components/molecules/SidebarMenuItem/SidebarMenuItem.stories.ts +84 -0
- package/src/components/molecules/SidebarMenuItem/SidebarMenuItem.test.ts +103 -0
- package/src/components/molecules/SkeletonPropertyCard/SkeletonPropertyCard.stories.ts +11 -0
- package/src/components/molecules/SkeletonPropertyCard/SkeletonPropertyCard.test.ts +38 -0
- package/src/components/molecules/SocialIcons/SocialIcons.stories.ts +28 -0
- package/src/components/molecules/SocialIcons/SocialIcons.test.ts +58 -0
- package/src/components/molecules/SocialMediaCustomTemplate/SocialMediaCustomTemplate.stories.ts +11 -0
- package/src/components/molecules/SocialMediaCustomTemplate/SocialMediaCustomTemplate.test.ts +116 -0
- package/src/components/molecules/SocialMediaType/SocialMediaType.stories.ts +37 -0
- package/src/components/molecules/SocialMediaType/SocialMediaType.test.ts +126 -0
- package/src/components/molecules/Source/Source.stories.ts +35 -0
- package/src/components/molecules/Source/Source.test.ts +45 -0
- package/src/components/molecules/TabbedContent/TabbedContent.stories.ts +96 -0
- package/src/components/molecules/TabbedContent/TabbedContent.test.ts +109 -0
- package/src/components/molecules/Tabs/Tabs.stories.ts +230 -0
- package/src/components/molecules/Tabs/Tabs.test.ts +280 -0
- package/src/components/molecules/TemplateCard/TemplateCard.stories.ts +327 -0
- package/src/components/molecules/TemplateCard/TemplateCard.test.ts +339 -0
- package/src/components/molecules/Textarea/Textarea.stories.ts +216 -0
- package/src/components/molecules/Textarea/Textarea.test.ts +191 -0
- package/src/components/molecules/TimelineEvent/TimelineEvent.stories.ts +319 -0
- package/src/components/molecules/TimelineEvent/TimelineEvent.test.ts +224 -0
- package/src/components/molecules/TimelineLanes/TimelineLanes.stories.ts +29 -0
- package/src/components/molecules/TimelineLanes/TimelineLanes.test.ts +30 -0
- package/src/components/molecules/Toast/Toast.stories.ts +110 -0
- package/src/components/molecules/Toast/Toast.test.ts +103 -0
- package/src/components/molecules/ToggleGroup/ToggleGroup.stories.ts +297 -0
- package/src/components/molecules/ToggleGroup/ToggleGroup.test.ts +578 -0
- package/src/components/molecules/Tree/Tree.stories.ts +884 -0
- package/src/components/molecules/Tree/Tree.test.ts +1247 -0
- package/src/components/molecules/Tree/tree-drop.test.ts +223 -0
- package/src/components/organisms/Calendar/Calendar.stories.ts +108 -0
- package/src/components/organisms/Calendar/Calendar.test.ts +279 -0
- package/src/components/organisms/Calendar/_CalendarDayView.test.ts +104 -0
- package/src/components/organisms/Calendar/_CalendarHeader.test.ts +86 -0
- package/src/components/organisms/Calendar/_CalendarMonthView.test.ts +52 -0
- package/src/components/organisms/Calendar/_CalendarTimePicker.test.ts +89 -0
- package/src/components/organisms/Calendar/_CalendarYearView.test.ts +56 -0
- package/src/components/organisms/ColorPicker/ColorPicker.stories.ts +229 -0
- package/src/components/organisms/ColorPicker/ColorPicker.test.ts +638 -0
- package/src/components/organisms/ColorPicker/gradient.test.ts +67 -0
- package/src/components/organisms/ColorPicker/gradientGeometry.test.ts +206 -0
- package/src/components/organisms/Combobox/Combobox.stories.ts +234 -0
- package/src/components/organisms/Combobox/Combobox.test.ts +512 -0
- package/src/components/organisms/Combobox/Combobox.vue +1 -1
- package/src/components/organisms/ComboboxPanel/ComboboxPanel.stories.ts +158 -0
- package/src/components/organisms/ComboboxPanel/ComboboxPanel.test.ts +524 -0
- package/src/components/organisms/ComboboxPanel/ComboboxPanel.vue +1 -1
- package/src/components/organisms/CountrySelect/CountrySelect.stories.ts +139 -0
- package/src/components/organisms/CountrySelect/CountrySelect.test.ts +149 -0
- package/src/components/organisms/DatePicker/DatePicker.stories.ts +163 -0
- package/src/components/organisms/DatePicker/DatePicker.test.ts +214 -0
- package/src/components/organisms/DropdownButton/DropdownButton.stories.ts +123 -0
- package/src/components/organisms/DropdownButton/DropdownButton.test.ts +379 -0
- package/src/components/organisms/FontPicker/FontPicker.stories.ts +476 -0
- package/src/components/organisms/FontPicker/FontPicker.test.ts +873 -0
- package/src/components/organisms/Header/Header.stories.ts +75 -0
- package/src/components/organisms/Header/Header.test.ts +233 -0
- package/src/components/organisms/IconPicker/IconPicker.stories.ts +734 -0
- package/src/components/organisms/IconPicker/IconPicker.test.ts +669 -0
- package/src/components/organisms/IconPicker/_IconPickerGrid.test.ts +184 -0
- package/src/components/organisms/IconPicker/_IconPickerRail.test.ts +102 -0
- package/src/components/organisms/IconPicker/useIconPickerNavigation.test.ts +215 -0
- package/src/components/organisms/Modal/Modal.stories.ts +350 -0
- package/src/components/organisms/Modal/Modal.test.ts +275 -0
- package/src/components/organisms/PickerPanel/PickerPanel.stories.ts +452 -0
- package/src/components/organisms/PickerPanel/PickerPanel.test.ts +358 -0
- package/src/components/organisms/ProgressBar/ProgressBar.stories.ts +100 -0
- package/src/components/organisms/ProgressBar/ProgressBar.test.ts +417 -0
- package/src/components/organisms/ReferenceCard/ReferenceCard.stories.ts +191 -0
- package/src/components/organisms/ReferenceCard/ReferenceCard.test.ts +165 -0
- package/src/components/organisms/SocialMediaTemplate/SocialMediaTemplate.stories.ts +65 -0
- package/src/components/organisms/SocialMediaTemplate/SocialMediaTemplate.test.ts +466 -0
- package/src/components/organisms/StepperHeader/StepperHeader.stories.ts +91 -0
- package/src/components/organisms/StepperHeader/StepperHeader.test.ts +279 -0
- package/src/components/organisms/Table/Table.stories.ts +332 -0
- package/src/components/organisms/Table/Table.test.ts +320 -0
- package/src/components/organisms/TimelinePhaseblock/TimelinePhaseblock.stories.ts +198 -0
- package/src/components/organisms/TimelinePhaseblock/TimelinePhaseblock.test.ts +283 -0
- package/src/components/organisms/TimelineTrack/TimelineTrack.stories.ts +120 -0
- package/src/components/organisms/TimelineTrack/TimelineTrack.test.ts +91 -0
- package/src/components/organisms/Toaster/Toaster.stories.ts +51 -0
- package/src/components/organisms/Toaster/Toaster.test.ts +75 -0
- package/src/components/organisms/VideoControls/VideoControls.stories.ts +792 -0
- package/src/components/organisms/VideoControls/VideoControls.test.ts +1056 -0
- package/src/components/organisms/VideoPlayer/VideoPlayer.stories.ts +327 -0
- package/src/components/organisms/VideoPlayer/VideoPlayer.test.ts +439 -0
|
@@ -0,0 +1,116 @@
|
|
|
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('internal methods do nothing if hasPlayedOnce is false', async () => {
|
|
92
|
+
const wrapper = mount(SocialMediaCustomTemplate)
|
|
93
|
+
const videoElement = wrapper.find('video').element as HTMLVideoElement
|
|
94
|
+
const playSpy = vi.spyOn(videoElement, 'play').mockImplementation(() => Promise.resolve())
|
|
95
|
+
const pauseSpy = vi.spyOn(videoElement, 'pause')
|
|
96
|
+
|
|
97
|
+
// @ts-expect-error - calling internal method
|
|
98
|
+
wrapper.vm.handleMouseEnter()
|
|
99
|
+
// @ts-expect-error - calling internal method
|
|
100
|
+
wrapper.vm.handleMouseLeave()
|
|
101
|
+
|
|
102
|
+
expect(playSpy).not.toHaveBeenCalled()
|
|
103
|
+
expect(pauseSpy).not.toHaveBeenCalled()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('plays onMounted if videoRef is valid', async () => {
|
|
107
|
+
const wrapper = mount(SocialMediaCustomTemplate)
|
|
108
|
+
const videoElement = wrapper.find('video').element as HTMLVideoElement
|
|
109
|
+
const playSpy = vi.spyOn(videoElement, 'play').mockImplementation(() => Promise.resolve())
|
|
110
|
+
|
|
111
|
+
// Simulate onMounted behavior by calling it again (it already ran once on mount)
|
|
112
|
+
// @ts-expect-error - manually calling onMounted setup code
|
|
113
|
+
wrapper.vm.handleMouseEnter() // hasPlayedOnce is false, should not play
|
|
114
|
+
expect(playSpy).not.toHaveBeenCalled()
|
|
115
|
+
})
|
|
116
|
+
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
|
2
|
+
import SocialMediaType from './SocialMediaType.vue'
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Components/Molecules/Social Media Type',
|
|
6
|
+
component: SocialMediaType,
|
|
7
|
+
} satisfies Meta<typeof SocialMediaType>
|
|
8
|
+
|
|
9
|
+
type Story = StoryObj<typeof SocialMediaType>
|
|
10
|
+
|
|
11
|
+
export const Post: Story = {
|
|
12
|
+
args: {
|
|
13
|
+
variant: 'post',
|
|
14
|
+
icons: ['facebook', 'instagram', 'linkedin', 'x', 'google'],
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const Reel: Story = {
|
|
19
|
+
args: {
|
|
20
|
+
variant: 'reel',
|
|
21
|
+
chip: 'Nieuw!',
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const Story: Story = {
|
|
26
|
+
args: {
|
|
27
|
+
variant: 'story',
|
|
28
|
+
icons: ['instagram'],
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const ReelSelected: Story = {
|
|
33
|
+
args: {
|
|
34
|
+
variant: 'reel',
|
|
35
|
+
selected: true,
|
|
36
|
+
},
|
|
37
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import { describe, it, expect } from 'vitest'
|
|
3
|
+
import SocialMediaType from './SocialMediaType.vue'
|
|
4
|
+
import SocialIcons, { type NexxtSocialIconsProps } from '../SocialIcons/SocialIcons.vue'
|
|
5
|
+
|
|
6
|
+
type Variant = 'post' | 'reel' | 'story'
|
|
7
|
+
|
|
8
|
+
describe('SocialMediaType', () => {
|
|
9
|
+
it.each([
|
|
10
|
+
['post', 'Post', { facebook: true, instagram: true, linkedin: true, x: true, google: true }],
|
|
11
|
+
['reel', 'TikTok & Reel', { instagram: true, tiktok: true }],
|
|
12
|
+
['story', 'Story', { instagram: true }],
|
|
13
|
+
])('renders correctly for variant: %s', (variant, expectedLabel, expectedIcons) => {
|
|
14
|
+
const wrapper = mount(SocialMediaType, {
|
|
15
|
+
props: {
|
|
16
|
+
variant: variant as Variant,
|
|
17
|
+
},
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// Check label
|
|
21
|
+
expect(wrapper.text()).toContain(expectedLabel)
|
|
22
|
+
|
|
23
|
+
// Check SocialIcons props
|
|
24
|
+
const socialIcons = wrapper.findComponent(SocialIcons)
|
|
25
|
+
expect(socialIcons.exists()).toBe(true)
|
|
26
|
+
|
|
27
|
+
Object.entries(expectedIcons).forEach(([prop, value]) => {
|
|
28
|
+
expect(socialIcons.props(prop as keyof NexxtSocialIconsProps)).toBe(value)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('renders the chip when provided', () => {
|
|
33
|
+
const wrapper = mount(SocialMediaType, {
|
|
34
|
+
props: {
|
|
35
|
+
variant: 'post',
|
|
36
|
+
chip: 'Featured',
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
expect(wrapper.text()).toContain('Featured')
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('emits click event when clicked', async () => {
|
|
43
|
+
const wrapper = mount(SocialMediaType, {
|
|
44
|
+
props: {
|
|
45
|
+
variant: 'reel',
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
await wrapper.trigger('click')
|
|
49
|
+
expect(wrapper.emitted('click')).toBeTruthy()
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('normalizes twitter to x in custom icons', () => {
|
|
53
|
+
const wrapper = mount(SocialMediaType, {
|
|
54
|
+
props: {
|
|
55
|
+
variant: 'post',
|
|
56
|
+
icons: ['twitter', 'facebook'],
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const socialIcons = wrapper.findComponent(SocialIcons)
|
|
61
|
+
expect(socialIcons.props('x')).toBe(true)
|
|
62
|
+
expect(socialIcons.props('facebook')).toBe(true)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('handles custom icons array correctly', () => {
|
|
66
|
+
const wrapper = mount(SocialMediaType, {
|
|
67
|
+
props: {
|
|
68
|
+
variant: 'reel',
|
|
69
|
+
icons: ['instagram', 'tiktok', 'linkedin'],
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
const socialIcons = wrapper.findComponent(SocialIcons)
|
|
74
|
+
expect(socialIcons.props('instagram')).toBe(true)
|
|
75
|
+
expect(socialIcons.props('tiktok')).toBe(true)
|
|
76
|
+
expect(socialIcons.props('linkedin')).toBe(true)
|
|
77
|
+
expect(socialIcons.props('facebook')).toBe(false)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('renders the selected state correctly', () => {
|
|
81
|
+
const wrapper = mount(SocialMediaType, {
|
|
82
|
+
props: {
|
|
83
|
+
variant: 'story',
|
|
84
|
+
selected: true,
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
expect(wrapper.classes()).toContain('bg-gray-50')
|
|
88
|
+
const icons = wrapper.findAllComponents({ name: 'NexxtIcon' })
|
|
89
|
+
const checkIcon = icons.find((icon) => icon.props('name') === 'check')
|
|
90
|
+
expect(checkIcon).toBeDefined()
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
it('renders a custom label', () => {
|
|
94
|
+
const wrapper = mount(SocialMediaType, {
|
|
95
|
+
props: {
|
|
96
|
+
variant: 'post',
|
|
97
|
+
label: 'My Custom Post',
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
expect(wrapper.text()).toContain('My Custom Post')
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('handles default branch for variant (if TS bypassed)', () => {
|
|
104
|
+
const wrapper = mount(SocialMediaType, {
|
|
105
|
+
props: {
|
|
106
|
+
// @ts-expect-error - testing invalid variant bypass
|
|
107
|
+
variant: 'invalid',
|
|
108
|
+
},
|
|
109
|
+
})
|
|
110
|
+
const socialIcons = wrapper.findComponent(SocialIcons)
|
|
111
|
+
// Should hit default: return {}
|
|
112
|
+
expect(socialIcons.exists()).toBe(true)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('handles empty icons array', () => {
|
|
116
|
+
const wrapper = mount(SocialMediaType, {
|
|
117
|
+
props: {
|
|
118
|
+
variant: 'post',
|
|
119
|
+
icons: [],
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
const socialIcons = wrapper.findComponent(SocialIcons)
|
|
123
|
+
// Should have no icons
|
|
124
|
+
expect(socialIcons.exists()).toBe(true)
|
|
125
|
+
})
|
|
126
|
+
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
|
2
|
+
import Source, { SOURCE_MAP } from './Source.vue'
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Components/Molecules/Source',
|
|
6
|
+
component: Source,
|
|
7
|
+
argTypes: {
|
|
8
|
+
source: {
|
|
9
|
+
control: 'select',
|
|
10
|
+
options: Object.keys(SOURCE_MAP),
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
} satisfies Meta<typeof Source>
|
|
14
|
+
|
|
15
|
+
type Story = StoryObj<typeof Source>
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
args: {
|
|
19
|
+
source: 'website',
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const All: Story = {
|
|
24
|
+
render: () => ({
|
|
25
|
+
components: { Source },
|
|
26
|
+
setup: () => ({ sources: Object.keys(SOURCE_MAP) }),
|
|
27
|
+
template: `
|
|
28
|
+
<div class="flex flex-col gap-2">
|
|
29
|
+
<div v-for="source in sources" :key="source" class="flex items-center gap-3">
|
|
30
|
+
<Source :source="source" />
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
`,
|
|
34
|
+
}),
|
|
35
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import Source, { SOURCE_MAP } from './Source.vue'
|
|
4
|
+
|
|
5
|
+
describe('Source', () => {
|
|
6
|
+
it('renders an image for sources with an image', () => {
|
|
7
|
+
const wrapper = mount(Source, { props: { source: 'realworks' } })
|
|
8
|
+
expect(wrapper.find('img').exists()).toBe(true)
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('sets the correct alt text on the image', () => {
|
|
12
|
+
const wrapper = mount(Source, { props: { source: 'realworks' } })
|
|
13
|
+
expect(wrapper.find('img').attributes('alt')).toBe(SOURCE_MAP.realworks)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('renders an icon for sources without an image', () => {
|
|
17
|
+
const wrapper = mount(Source, { props: { source: 'website' } })
|
|
18
|
+
expect(wrapper.find('img').exists()).toBe(false)
|
|
19
|
+
expect(wrapper.find('span[class*="rounded-full"]').exists()).toBe(true)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('renders the label text for sources without an image', () => {
|
|
23
|
+
const wrapper = mount(Source, { props: { source: 'website' } })
|
|
24
|
+
expect(wrapper.text()).toContain(SOURCE_MAP.website)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('applies the correct bg color class for icon sources', () => {
|
|
28
|
+
const wrapper = mount(Source, { props: { source: 'website' } })
|
|
29
|
+
expect(wrapper.find('span[class*="rounded-full"]').classes()).toContain(
|
|
30
|
+
'bg-cornflower-blue-500',
|
|
31
|
+
)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('applies the correct height class on the image', () => {
|
|
35
|
+
const wrapper = mount(Source, { props: { source: 'realworks' } })
|
|
36
|
+
expect(wrapper.find('img').classes()).toContain('h-4')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('renders the label for all sources without errors', () => {
|
|
40
|
+
for (const source of Object.keys(SOURCE_MAP) as (keyof typeof SOURCE_MAP)[]) {
|
|
41
|
+
const wrapper = mount(Source, { props: { source } })
|
|
42
|
+
expect(wrapper.exists()).toBe(true)
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
|
2
|
+
import { expect, within } from 'storybook/test'
|
|
3
|
+
import TabbedContend from './TabbedContent.vue'
|
|
4
|
+
|
|
5
|
+
const PANELS = `
|
|
6
|
+
<template #overview>
|
|
7
|
+
<div style="background-color: #dbeafe; padding: 32px; border-radius: 12px; min-height: 200px;">
|
|
8
|
+
<h2 style="font-size: 20px; font-weight: 600; margin-bottom: 8px;">Overview</h2>
|
|
9
|
+
<p>This is the Overview content. Here you can find a summary of everything that matters.</p>
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
<template #details>
|
|
13
|
+
<div style="background-color: #dcfce7; padding: 32px; border-radius: 12px; min-height: 200px;">
|
|
14
|
+
<h2 style="font-size: 20px; font-weight: 600; margin-bottom: 8px;">Details</h2>
|
|
15
|
+
<p>This is the Details content. All the specifics and fine print live here.</p>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
<template #settings>
|
|
19
|
+
<div style="background-color: #fef9c3; padding: 32px; border-radius: 12px; min-height: 200px;">
|
|
20
|
+
<h2 style="font-size: 20px; font-weight: 600; margin-bottom: 8px;">Settings</h2>
|
|
21
|
+
<p>This is the Settings content. Configure your preferences here.</p>
|
|
22
|
+
</div>
|
|
23
|
+
</template>
|
|
24
|
+
`
|
|
25
|
+
|
|
26
|
+
export default {
|
|
27
|
+
title: 'Components/Molecules/Tabbed Content',
|
|
28
|
+
component: TabbedContend,
|
|
29
|
+
decorators: [
|
|
30
|
+
() => ({
|
|
31
|
+
template:
|
|
32
|
+
'<div style="min-height: 350px; padding: 16px; background-color: #F5F5F5;"><story /></div>',
|
|
33
|
+
}),
|
|
34
|
+
],
|
|
35
|
+
} satisfies Meta<typeof TabbedContend>
|
|
36
|
+
|
|
37
|
+
type Story = StoryObj<typeof TabbedContend>
|
|
38
|
+
|
|
39
|
+
export const Default: Story = {
|
|
40
|
+
render: (args) => ({
|
|
41
|
+
components: { TabbedContend },
|
|
42
|
+
setup() {
|
|
43
|
+
return { args }
|
|
44
|
+
},
|
|
45
|
+
template: `<TabbedContend v-bind="args">${PANELS}</TabbedContend>`,
|
|
46
|
+
}),
|
|
47
|
+
args: {
|
|
48
|
+
tabs: ['Overview', 'Details', 'Settings'],
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const Animated: Story = {
|
|
53
|
+
render: (args) => ({
|
|
54
|
+
components: { TabbedContend },
|
|
55
|
+
setup() {
|
|
56
|
+
return { args }
|
|
57
|
+
},
|
|
58
|
+
template: `<TabbedContend v-bind="args">${PANELS}</TabbedContend>`,
|
|
59
|
+
}),
|
|
60
|
+
args: {
|
|
61
|
+
tabs: ['Overview', 'Details', 'Settings'],
|
|
62
|
+
animated: true,
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* `tabs` accepteert naast losse strings ook `{ label, icon }`. De slotnaam komt
|
|
68
|
+
* dan van het label, net als bij de stringvorm.
|
|
69
|
+
*/
|
|
70
|
+
export const WithIcons: Story = {
|
|
71
|
+
args: {
|
|
72
|
+
tabs: [
|
|
73
|
+
{ label: 'Overview', icon: 'house' },
|
|
74
|
+
{ label: 'Details', icon: 'list' },
|
|
75
|
+
{ label: 'Settings', icon: 'gear' },
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
render: (args) => ({
|
|
79
|
+
components: { TabbedContend },
|
|
80
|
+
setup: () => ({ args }),
|
|
81
|
+
template: `
|
|
82
|
+
<TabbedContend v-bind="args" style="width: 520px">
|
|
83
|
+
<template #overview>Overzicht</template>
|
|
84
|
+
<template #details>Details</template>
|
|
85
|
+
<template #settings>Instellingen</template>
|
|
86
|
+
</TabbedContend>
|
|
87
|
+
`,
|
|
88
|
+
}),
|
|
89
|
+
play: async ({ canvasElement }) => {
|
|
90
|
+
const canvas = within(canvasElement)
|
|
91
|
+
// Het paneel toont het slot dat bij het label hoort; met het ruwe object als
|
|
92
|
+
// modelwaarde bleef het leeg.
|
|
93
|
+
await expect(canvas.getByRole('tabpanel')).toHaveTextContent('Overzicht')
|
|
94
|
+
await expect(canvasElement.querySelectorAll('i.fa-house').length).toBeGreaterThan(0)
|
|
95
|
+
},
|
|
96
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import { describe, it, expect, beforeAll } from 'vitest'
|
|
3
|
+
import TabbedContent from './TabbedContent.vue'
|
|
4
|
+
|
|
5
|
+
beforeAll(() => {
|
|
6
|
+
Object.defineProperty(document, 'fonts', {
|
|
7
|
+
value: { ready: Promise.resolve() },
|
|
8
|
+
configurable: true,
|
|
9
|
+
})
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const tabs = ['Overview', 'Details', 'Settings']
|
|
13
|
+
|
|
14
|
+
describe('TabbedContent', () => {
|
|
15
|
+
it('defaults to the first tab', () => {
|
|
16
|
+
const wrapper = mount(TabbedContent, {
|
|
17
|
+
props: { tabs },
|
|
18
|
+
slots: {
|
|
19
|
+
overview: '<div>Overview content</div>',
|
|
20
|
+
details: '<div>Details content</div>',
|
|
21
|
+
},
|
|
22
|
+
})
|
|
23
|
+
expect(wrapper.find('[role="tabpanel"]').text()).toContain('Overview content')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('shows the slot for the v-model selected tab', () => {
|
|
27
|
+
const wrapper = mount(TabbedContent, {
|
|
28
|
+
props: { tabs, modelValue: 'Details' },
|
|
29
|
+
slots: {
|
|
30
|
+
overview: '<div>Overview content</div>',
|
|
31
|
+
details: '<div>Details content</div>',
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
expect(wrapper.find('[role="tabpanel"]').text()).toContain('Details content')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('sets aria-labelledby based on the selected tab', () => {
|
|
38
|
+
const wrapper = mount(TabbedContent, {
|
|
39
|
+
props: { tabs, modelValue: 'Overview' },
|
|
40
|
+
})
|
|
41
|
+
expect(wrapper.find('[role="tabpanel"]').attributes('aria-labelledby')).toBe('tab-overview')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('converts tab labels with spaces to hyphenated slot names', () => {
|
|
45
|
+
const wrapper = mount(TabbedContent, {
|
|
46
|
+
props: { tabs: ['My Reports', 'Other'], modelValue: 'My Reports' },
|
|
47
|
+
slots: {
|
|
48
|
+
'my-reports': '<div>Report content</div>',
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
expect(wrapper.find('[role="tabpanel"]').text()).toContain('Report content')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('emits update:modelValue when a tab is clicked', async () => {
|
|
55
|
+
const wrapper = mount(TabbedContent, {
|
|
56
|
+
props: { tabs, modelValue: 'Overview' },
|
|
57
|
+
})
|
|
58
|
+
const buttons = wrapper.findAll('[role="tab"]')
|
|
59
|
+
await buttons[1].trigger('click')
|
|
60
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['Details'])
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('updates displayed content when modelValue prop changes', async () => {
|
|
64
|
+
const wrapper = mount(TabbedContent, {
|
|
65
|
+
props: { tabs, modelValue: 'Overview' },
|
|
66
|
+
slots: {
|
|
67
|
+
overview: '<div>Overview content</div>',
|
|
68
|
+
details: '<div>Details content</div>',
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
await wrapper.setProps({ modelValue: 'Details' })
|
|
72
|
+
expect(wrapper.find('[role="tabpanel"]').text()).toContain('Details content')
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
describe('TabbedContent met tab-objecten', () => {
|
|
77
|
+
// NexxtTabs accepteert sinds de icoonondersteuning ook { label, icon }. Geen
|
|
78
|
+
// enkele story of test gaf die vorm door, en het component behandelde elke tab
|
|
79
|
+
// als string: het zette het hele object in een model dat een label verwacht.
|
|
80
|
+
const iconTabs = [
|
|
81
|
+
{ label: 'Overview', icon: 'house' },
|
|
82
|
+
{ label: 'Details', icon: 'list' },
|
|
83
|
+
] as const
|
|
84
|
+
|
|
85
|
+
it('vult het model met het label en niet met het object', () => {
|
|
86
|
+
const wrapper = mount(TabbedContent, { props: { tabs: [...iconTabs] } })
|
|
87
|
+
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['Overview'])
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('leidt de slotnaam af van het label', () => {
|
|
91
|
+
const wrapper = mount(TabbedContent, {
|
|
92
|
+
props: { tabs: [...iconTabs] },
|
|
93
|
+
slots: { overview: '<div>Overzicht</div>' },
|
|
94
|
+
})
|
|
95
|
+
expect(wrapper.find('[role="tabpanel"]').text()).toContain('Overzicht')
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('kent de volgorde van objecttabs, zodat de richting klopt', async () => {
|
|
99
|
+
// Op props.tabs vergelijken gaf met objecten twee keer -1, waardoor de
|
|
100
|
+
// richting altijd backward werd. Zichtbaar in de klassen die de Transition
|
|
101
|
+
// meekrijgt bij vooruit versus achteruit.
|
|
102
|
+
const wrapper = mount(TabbedContent, {
|
|
103
|
+
props: { tabs: [...iconTabs], animated: true, modelValue: 'Overview' },
|
|
104
|
+
})
|
|
105
|
+
await wrapper.setProps({ modelValue: 'Details' })
|
|
106
|
+
|
|
107
|
+
expect((wrapper.vm as unknown as { direction: string }).direction).toBe('forward')
|
|
108
|
+
})
|
|
109
|
+
})
|