@nexxtmove/ui 0.1.22 → 0.1.23

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 (66) hide show
  1. package/dist/index.d.ts +75 -8
  2. package/dist/index.js +2408 -252
  3. package/dist/nuxt.d.ts +1 -0
  4. package/dist/nuxt.js +49 -0
  5. package/package.json +23 -13
  6. package/src/assets/images/Template_aanvragen.jpg +0 -0
  7. package/src/assets/svg/type_post.svg +1 -0
  8. package/src/assets/svg/type_reel.svg +54 -0
  9. package/src/assets/svg/type_story.svg +46 -0
  10. package/src/assets/svg/type_tiktok.svg +1 -0
  11. package/src/assets/video/Template_aanvragen.mp4 +0 -0
  12. package/src/components/AnimatedNumber/AnimatedNumber.stories.ts +15 -0
  13. package/src/components/AnimatedNumber/AnimatedNumber.test.ts +56 -0
  14. package/src/components/AnimatedNumber/AnimatedNumber.vue +61 -0
  15. package/src/components/Button/Button.stories.ts +212 -0
  16. package/src/components/Button/Button.test.ts +318 -0
  17. package/src/components/Button/Button.vue +67 -0
  18. package/src/components/Calendar/Calendar.stories.ts +91 -0
  19. package/src/components/Calendar/Calendar.test.ts +269 -0
  20. package/src/components/Calendar/Calendar.vue +221 -0
  21. package/src/components/Calendar/_CalendarDayView.test.ts +145 -0
  22. package/src/components/Calendar/_CalendarDayView.vue +156 -0
  23. package/src/components/Calendar/_CalendarHeader.test.ts +86 -0
  24. package/src/components/Calendar/_CalendarHeader.vue +123 -0
  25. package/src/components/Calendar/_CalendarMonthView.test.ts +68 -0
  26. package/src/components/Calendar/_CalendarMonthView.vue +70 -0
  27. package/src/components/Calendar/_CalendarYearView.vue +77 -0
  28. package/src/components/Calendar/calendar.types.ts +10 -0
  29. package/src/components/Chip/Chip.stories.ts +42 -0
  30. package/src/components/Chip/Chip.test.ts +51 -0
  31. package/src/components/Chip/Chip.vue +37 -0
  32. package/src/components/DatePicker/DatePicker.stories.ts +149 -0
  33. package/src/components/DatePicker/DatePicker.test.ts +191 -0
  34. package/src/components/DatePicker/DatePicker.vue +142 -0
  35. package/src/components/Header/Header.stories.ts +48 -0
  36. package/src/components/Header/Header.test.ts +169 -0
  37. package/src/components/Header/Header.vue +42 -0
  38. package/src/components/Icon/Icon.stories.ts +50 -0
  39. package/src/components/Icon/Icon.test.ts +73 -0
  40. package/src/components/Icon/Icon.vue +20 -0
  41. package/src/components/InfoBlock/InfoBlock.stories.ts +90 -0
  42. package/src/components/InfoBlock/InfoBlock.test.ts +101 -0
  43. package/src/components/InfoBlock/InfoBlock.vue +70 -0
  44. package/src/components/ProgressBar/ProgressBar.stories.ts +30 -0
  45. package/src/components/ProgressBar/ProgressBar.test.ts +314 -0
  46. package/src/components/ProgressBar/ProgressBar.vue +102 -0
  47. package/src/components/SocialIcons/SocialIcons.stories.ts +34 -0
  48. package/src/components/SocialIcons/SocialIcons.test.ts +58 -0
  49. package/src/components/SocialIcons/SocialIcons.vue +58 -0
  50. package/src/components/SocialMediaCustomTemplate/SocialMediaCustomTemplate.stories.ts +11 -0
  51. package/src/components/SocialMediaCustomTemplate/SocialMediaCustomTemplate.test.ts +131 -0
  52. package/src/components/SocialMediaCustomTemplate/SocialMediaCustomTemplate.vue +55 -0
  53. package/src/components/SocialMediaTemplate/SocialMediaTemplate.stories.ts +71 -0
  54. package/src/components/SocialMediaTemplate/SocialMediaTemplate.test.ts +466 -0
  55. package/src/components/SocialMediaTemplate/SocialMediaTemplate.vue +130 -0
  56. package/src/components/SocialMediaType/SocialMediaType.stories.ts +43 -0
  57. package/src/components/SocialMediaType/SocialMediaType.test.ts +126 -0
  58. package/src/components/SocialMediaType/SocialMediaType.vue +117 -0
  59. package/src/components/StepperHeader/StepperHeader.stories.ts +47 -0
  60. package/src/components/StepperHeader/StepperHeader.test.ts +244 -0
  61. package/src/components/StepperHeader/StepperHeader.vue +37 -0
  62. package/src/components.json +16 -0
  63. package/src/env.d.ts +23 -0
  64. package/src/index.css +2 -0
  65. package/src/index.ts +15 -0
  66. package/src/nuxt.ts +50 -0
@@ -0,0 +1,212 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
+ import Button from './Button.vue'
3
+
4
+ export default {
5
+ title: 'Components/Atoms/Button',
6
+ component: Button,
7
+ parameters: {
8
+ design: {
9
+ type: 'figma',
10
+ url: 'https://www.figma.com/design/CdbFJ7qUga6mtjagcPDvYK/Design-System?node-id=167-357&t=CbHvOQfEMIr7M5mO-4',
11
+ },
12
+ },
13
+ } satisfies Meta<typeof Button>
14
+
15
+ type Story = StoryObj<typeof Button>
16
+
17
+ export const Primary: Story = {
18
+ args: {
19
+ default: 'Button',
20
+ variant: 'primary',
21
+ iconRight: false,
22
+ disabled: false,
23
+ loading: false,
24
+ },
25
+ }
26
+
27
+ export const Secondary: Story = {
28
+ args: {
29
+ variant: 'secondary',
30
+ default: 'Secondary Button',
31
+ },
32
+ }
33
+
34
+ export const Success: Story = {
35
+ args: {
36
+ variant: 'success',
37
+ default: 'Success Button',
38
+ },
39
+ }
40
+
41
+ export const Danger: Story = {
42
+ args: {
43
+ variant: 'danger',
44
+ default: 'Danger Button',
45
+ },
46
+ }
47
+
48
+ export const Link: Story = {
49
+ args: {
50
+ variant: 'link',
51
+ default: 'Link Button',
52
+ },
53
+ }
54
+
55
+ export const WithIcon: Story = {
56
+ args: {
57
+ icon: 'star',
58
+ default: 'With Icon',
59
+ },
60
+ }
61
+
62
+ export const WithIconRight: Story = {
63
+ args: {
64
+ icon: 'arrow-right',
65
+ iconRight: true,
66
+ default: 'Next Step',
67
+ },
68
+ }
69
+
70
+ export const WithIconSecondary: Story = {
71
+ args: {
72
+ variant: 'secondary',
73
+ icon: 'download',
74
+ default: 'Download',
75
+ },
76
+ }
77
+
78
+ export const WithIconSuccess: Story = {
79
+ args: {
80
+ variant: 'success',
81
+ icon: 'check',
82
+ default: 'Success Button',
83
+ },
84
+ }
85
+
86
+ export const WithIconDanger: Story = {
87
+ args: {
88
+ variant: 'danger',
89
+ icon: 'trash',
90
+ default: 'Danger Button',
91
+ },
92
+ }
93
+
94
+ export const WithIconLink: Story = {
95
+ args: {
96
+ variant: 'link',
97
+ icon: 'download',
98
+ default: 'Download',
99
+ },
100
+ }
101
+
102
+ export const IconOnly: Story = {
103
+ args: {
104
+ icon: 'plus',
105
+ },
106
+ }
107
+
108
+ export const IconOnlySecondary: Story = {
109
+ args: {
110
+ variant: 'secondary',
111
+ icon: 'plus',
112
+ },
113
+ }
114
+
115
+ export const IconOnlySuccess: Story = {
116
+ args: {
117
+ variant: 'success',
118
+ icon: 'check',
119
+ },
120
+ }
121
+
122
+ export const IconOnlyDanger: Story = {
123
+ args: {
124
+ variant: 'danger',
125
+ icon: 'trash',
126
+ },
127
+ }
128
+
129
+ export const IconOnlyLink: Story = {
130
+ args: {
131
+ variant: 'link',
132
+ icon: 'plus',
133
+ },
134
+ }
135
+
136
+ export const Disabled: Story = {
137
+ args: {
138
+ default: 'Disabled',
139
+ disabled: true,
140
+ },
141
+ }
142
+
143
+ export const DisabledSecondary: Story = {
144
+ args: {
145
+ variant: 'secondary',
146
+ default: 'Secondary Disabled',
147
+ disabled: true,
148
+ },
149
+ }
150
+
151
+ export const DisabledSuccess: Story = {
152
+ args: {
153
+ variant: 'success',
154
+ default: 'Success Disabled',
155
+ disabled: true,
156
+ },
157
+ }
158
+
159
+ export const DisabledDanger: Story = {
160
+ args: {
161
+ variant: 'danger',
162
+ default: 'Danger Disabled',
163
+ disabled: true,
164
+ },
165
+ }
166
+
167
+ export const DisabledLink: Story = {
168
+ args: {
169
+ variant: 'link',
170
+ default: 'Link Disabled',
171
+ disabled: true,
172
+ },
173
+ }
174
+
175
+ export const Loading: Story = {
176
+ args: {
177
+ default: 'Loading',
178
+ loading: true,
179
+ },
180
+ }
181
+
182
+ export const LoadingSecondary: Story = {
183
+ args: {
184
+ variant: 'secondary',
185
+ default: 'Loading',
186
+ loading: true,
187
+ },
188
+ }
189
+
190
+ export const LoadingSuccess: Story = {
191
+ args: {
192
+ variant: 'success',
193
+ default: 'Loading',
194
+ loading: true,
195
+ },
196
+ }
197
+
198
+ export const LoadingDanger: Story = {
199
+ args: {
200
+ variant: 'danger',
201
+ default: 'Loading',
202
+ loading: true,
203
+ },
204
+ }
205
+
206
+ export const LoadingLink: Story = {
207
+ args: {
208
+ variant: 'link',
209
+ default: 'Link Button',
210
+ loading: true,
211
+ },
212
+ }
@@ -0,0 +1,318 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Button from './Button.vue'
4
+
5
+ describe('Button', () => {
6
+ it('renders slot content', () => {
7
+ const wrapper = mount(Button, {
8
+ slots: {
9
+ default: 'Click me',
10
+ },
11
+ })
12
+
13
+ expect(wrapper.text()).toBe('Click me')
14
+ })
15
+
16
+ it('renders complex slot content', () => {
17
+ const wrapper = mount(Button, {
18
+ slots: {
19
+ default: '<span>Complex</span> <span>Text</span>',
20
+ },
21
+ })
22
+
23
+ expect(wrapper.html()).toContain('<span>Complex</span>')
24
+ expect(wrapper.html()).toContain('<span>Text</span>')
25
+ })
26
+
27
+ it('applies primary variant by default', () => {
28
+ const wrapper = mount(Button, {
29
+ slots: {
30
+ default: 'Click me',
31
+ },
32
+ })
33
+
34
+ expect(wrapper.classes()).toContain('button-primary')
35
+ })
36
+
37
+ it('applies secondary variant when specified', () => {
38
+ const wrapper = mount(Button, {
39
+ props: {
40
+ variant: 'secondary',
41
+ },
42
+ slots: {
43
+ default: 'Click me',
44
+ },
45
+ })
46
+
47
+ expect(wrapper.classes()).toContain('button-secondary')
48
+ })
49
+
50
+ it('applies success variant when specified', () => {
51
+ const wrapper = mount(Button, {
52
+ props: {
53
+ variant: 'success',
54
+ },
55
+ slots: {
56
+ default: 'Click me',
57
+ },
58
+ })
59
+
60
+ expect(wrapper.classes()).toContain('button-success')
61
+ })
62
+
63
+ it('applies danger variant when specified', () => {
64
+ const wrapper = mount(Button, {
65
+ props: {
66
+ variant: 'danger',
67
+ },
68
+ slots: {
69
+ default: 'Click me',
70
+ },
71
+ })
72
+
73
+ expect(wrapper.classes()).toContain('button-danger')
74
+ })
75
+
76
+ it('applies link variant when specified', () => {
77
+ const wrapper = mount(Button, {
78
+ props: {
79
+ variant: 'link',
80
+ },
81
+ slots: {
82
+ default: 'Click me',
83
+ },
84
+ })
85
+
86
+ expect(wrapper.classes()).toContain('button-link')
87
+ })
88
+
89
+ it('applies link variant special classes', () => {
90
+ const wrapper = mount(Button, {
91
+ props: {
92
+ variant: 'link',
93
+ },
94
+ slots: {
95
+ default: 'Click me',
96
+ },
97
+ })
98
+
99
+ const span = wrapper.find('span')
100
+ expect(span.classes()).toContain('body-link')
101
+ expect(span.classes()).toContain('underline-offset-1')
102
+ expect(span.classes()).toContain('hover:underline-offset-2')
103
+ })
104
+
105
+ it('does not apply hover underline offset when link is disabled', () => {
106
+ const wrapper = mount(Button, {
107
+ props: {
108
+ variant: 'link',
109
+ disabled: true,
110
+ },
111
+ slots: {
112
+ default: 'Click me',
113
+ },
114
+ })
115
+
116
+ const span = wrapper.find('span')
117
+ expect(span.classes()).not.toContain('hover:underline-offset-2')
118
+ })
119
+
120
+ it('renders icon when icon prop is provided', () => {
121
+ const wrapper = mount(Button, {
122
+ props: {
123
+ icon: 'star',
124
+ },
125
+ slots: {
126
+ default: 'Click me',
127
+ },
128
+ })
129
+
130
+ const icon = wrapper.find('i')
131
+ expect(icon.exists()).toBe(true)
132
+ expect(icon.classes()).toContain('fa-light')
133
+ expect(icon.classes()).toContain('fa-star')
134
+ })
135
+
136
+ it('does not render icon when icon prop is not provided', () => {
137
+ const wrapper = mount(Button, {
138
+ slots: {
139
+ default: 'Click me',
140
+ },
141
+ })
142
+
143
+ const icon = wrapper.find('i')
144
+ expect(icon.exists()).toBe(false)
145
+ })
146
+
147
+ it('positions icon on the right when iconRight is true', () => {
148
+ const wrapper = mount(Button, {
149
+ props: {
150
+ icon: 'arrow-right',
151
+ iconRight: true,
152
+ },
153
+ slots: {
154
+ default: 'Next',
155
+ },
156
+ })
157
+
158
+ const icon = wrapper.find('i')
159
+ expect(icon.classes()).toContain('order-last')
160
+ })
161
+
162
+ it('positions icon on the left by default', () => {
163
+ const wrapper = mount(Button, {
164
+ props: {
165
+ icon: 'arrow-right',
166
+ },
167
+ slots: {
168
+ default: 'Back',
169
+ },
170
+ })
171
+
172
+ const icon = wrapper.find('i')
173
+ expect(icon.classes()).not.toContain('order-last')
174
+ })
175
+
176
+ it('renders as button type="button"', () => {
177
+ const wrapper = mount(Button, {
178
+ slots: {
179
+ default: 'Click me',
180
+ },
181
+ })
182
+
183
+ expect(wrapper.element.tagName).toBe('BUTTON')
184
+ expect(wrapper.attributes('type')).toBe('button')
185
+ })
186
+
187
+ it('disables button when disabled prop is true', () => {
188
+ const wrapper = mount(Button, {
189
+ props: {
190
+ disabled: true,
191
+ },
192
+ slots: {
193
+ default: 'Click me',
194
+ },
195
+ })
196
+
197
+ expect(wrapper.attributes('disabled')).toBeDefined()
198
+ expect(wrapper.classes()).toContain('disabled:cursor-not-allowed')
199
+ })
200
+
201
+ it('applies disabled styles for primary variant', () => {
202
+ const wrapper = mount(Button, {
203
+ props: {
204
+ variant: 'primary',
205
+ disabled: true,
206
+ },
207
+ slots: {
208
+ default: 'Click me',
209
+ },
210
+ })
211
+
212
+ expect(wrapper.attributes()).toHaveProperty('disabled')
213
+ })
214
+
215
+ it('hides icon and slot content when loading', () => {
216
+ const wrapper = mount(Button, {
217
+ props: {
218
+ loading: true,
219
+ icon: 'star',
220
+ },
221
+ slots: {
222
+ default: 'Submit',
223
+ },
224
+ })
225
+
226
+ const starIcon = wrapper.find('.fa-star')
227
+ expect(starIcon.classes()).toContain('opacity-0')
228
+
229
+ const label = wrapper.find('span')
230
+ expect(label.classes()).toContain('opacity-0')
231
+ })
232
+
233
+ it('removes hover effects when loading or disabled in link variant', async () => {
234
+ const wrapper = mount(Button, {
235
+ props: {
236
+ variant: 'link',
237
+ loading: true,
238
+ },
239
+ slots: {
240
+ default: 'Link',
241
+ },
242
+ })
243
+
244
+ expect(wrapper.find('span').classes()).not.toContain('hover:underline-offset-2')
245
+
246
+ await wrapper.setProps({ loading: false, disabled: true })
247
+ expect(wrapper.find('span').classes()).not.toContain('hover:underline-offset-2')
248
+
249
+ await wrapper.setProps({ disabled: false })
250
+ expect(wrapper.find('span').classes()).toContain('hover:underline-offset-2')
251
+ })
252
+
253
+ it('renders icon-only button without padding', () => {
254
+ const wrapper = mount(Button, {
255
+ props: {
256
+ icon: 'star',
257
+ },
258
+ })
259
+
260
+ expect(wrapper.classes()).toContain('w-10')
261
+ expect(wrapper.classes()).not.toContain('px-4')
262
+ })
263
+
264
+ it('displays spinner icon when loading is true', () => {
265
+ const wrapper = mount(Button, {
266
+ props: {
267
+ loading: true,
268
+ },
269
+ })
270
+
271
+ const icon = wrapper.find('i')
272
+ expect(icon.exists()).toBe(true)
273
+ expect(icon.classes()).toContain('fa-spinner-third')
274
+ expect(icon.classes()).toContain('fa-spin')
275
+ })
276
+
277
+ it('disables button when loading is true', () => {
278
+ const wrapper = mount(Button, {
279
+ props: {
280
+ loading: true,
281
+ },
282
+ })
283
+
284
+ expect(wrapper.classes()).toContain('pointer-events-none')
285
+ })
286
+
287
+ it('set the button type prop', async () => {
288
+ const wrapper = mount(Button)
289
+
290
+ expect(wrapper.attributes('type')).toBe('button')
291
+
292
+ await wrapper.setProps({ buttonType: 'submit' })
293
+ expect(wrapper.attributes('type')).toBe('submit')
294
+
295
+ await wrapper.setProps({ buttonType: 'reset' })
296
+ expect(wrapper.attributes('type')).toBe('reset')
297
+ })
298
+
299
+ it('no animated span whitout default slot', async () => {
300
+ const wrapper = mount(Button)
301
+
302
+ const slotSpanWrapper = wrapper.find('span')
303
+
304
+ expect(slotSpanWrapper.exists()).toBe(false)
305
+ })
306
+
307
+ it('has animated span with default slot', async () => {
308
+ const wrapper = mount(Button, {
309
+ slots: {
310
+ default: 'text',
311
+ },
312
+ })
313
+
314
+ const slotSpanWrapper = wrapper.find('span')
315
+
316
+ expect(slotSpanWrapper.exists()).toBe(true)
317
+ })
318
+ })
@@ -0,0 +1,67 @@
1
+ <script setup lang="ts">
2
+ import Icon from '../Icon/Icon.vue'
3
+
4
+ interface NexxtButtonProps {
5
+ variant?: 'primary' | 'secondary' | 'success' | 'danger' | 'link'
6
+ icon?: InstanceType<typeof Icon>['name']
7
+ iconRight?: boolean
8
+ disabled?: boolean
9
+ loading?: boolean
10
+ buttonType?: 'button' | 'submit' | 'reset'
11
+ }
12
+
13
+ defineOptions({
14
+ name: 'NexxtButton',
15
+ })
16
+
17
+ const {
18
+ variant = 'primary',
19
+ buttonType = 'button',
20
+ loading = false,
21
+ } = defineProps<NexxtButtonProps>()
22
+ </script>
23
+
24
+ <template>
25
+ <button
26
+ :type="buttonType"
27
+ :disabled="disabled"
28
+ :class="[
29
+ 'button relative flex h-10 cursor-pointer items-center justify-center overflow-hidden rounded-lg transition-colors duration-200 focus-visible:outline-3 disabled:cursor-not-allowed',
30
+ `button-${variant}`,
31
+ $slots.default ?? 'w-10',
32
+ !$slots.default && icon ? 'aspect-square px-0' : '',
33
+ loading ? 'pointer-events-none' : '',
34
+ ]"
35
+ :data-variant="variant"
36
+ >
37
+ <Icon
38
+ v-if="icon"
39
+ :name="icon"
40
+ class="transition-all duration-200"
41
+ :class="{ 'order-last': iconRight, 'opacity-0': loading }"
42
+ />
43
+ <span
44
+ v-if="$slots.default"
45
+ :class="[
46
+ 'inline-block transition-all duration-200',
47
+ { 'opacity-0': loading },
48
+ variant === 'link' ? 'body-link underline-offset-1' : 'body-normal',
49
+ variant === 'link' && !loading && !disabled ? 'hover:underline-offset-2' : '',
50
+ ]"
51
+ >
52
+ <slot />
53
+ </span>
54
+ <Transition
55
+ enter-active-class="transition-opacity duration-200"
56
+ enter-from-class="opacity-0"
57
+ enter-to-class="opacity-100"
58
+ leave-active-class="transition-opacity duration-200"
59
+ leave-from-class="opacity-100"
60
+ leave-to-class="opacity-0"
61
+ >
62
+ <div v-if="loading" :class="['absolute inset-0 flex items-center justify-center rounded-lg']">
63
+ <Icon name="spinner-third" type="light" class="fa-spin absolute text-sm" />
64
+ </div>
65
+ </Transition>
66
+ </button>
67
+ </template>
@@ -0,0 +1,91 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3-vite'
2
+ import { ref } from 'vue'
3
+ import { enUS } from 'date-fns/locale'
4
+ import Calendar from './Calendar.vue'
5
+ export default {
6
+ title: 'Components/Atoms/Calendar',
7
+ component: Calendar,
8
+ parameters: {
9
+ design: {
10
+ type: 'figma',
11
+ url: 'https://www.figma.com/design/CdbFJ7qUga6mtjagcPDvYK/Design-System?node-id=713-720&t=CbHvOQfEMIr7M5mO-4',
12
+ },
13
+ },
14
+ } satisfies Meta<typeof Calendar>
15
+
16
+ type Story = StoryObj<typeof Calendar>
17
+
18
+ export const Default: Story = {
19
+ args: {},
20
+ }
21
+
22
+ export const WithSelectedDate: Story = {
23
+ args: {
24
+ modelValue: new Date(),
25
+ },
26
+ }
27
+
28
+ export const WithMarkedDates: Story = {
29
+ args: {
30
+ markedDates: [
31
+ new Date(new Date().getFullYear(), new Date().getMonth(), 5),
32
+ new Date(new Date().getFullYear(), new Date().getMonth(), 12),
33
+ new Date(new Date().getFullYear(), new Date().getMonth(), 20),
34
+ ],
35
+ },
36
+ }
37
+
38
+ export const WithDisabledDates: Story = {
39
+ args: {
40
+ disabledDates: [
41
+ new Date(new Date().getFullYear(), new Date().getMonth(), 10),
42
+ new Date(new Date().getFullYear(), new Date().getMonth(), 11),
43
+ new Date(new Date().getFullYear(), new Date().getMonth(), 12),
44
+ ],
45
+ },
46
+ }
47
+
48
+ export const WithDateRange: Story = {
49
+ args: {
50
+ minDate: new Date(new Date().getFullYear(), new Date().getMonth(), 5),
51
+ maxDate: new Date(new Date().getFullYear(), new Date().getMonth() + 1, 20),
52
+ },
53
+ }
54
+
55
+ export const WithMonthYearPicker: Story = {
56
+ args: {
57
+ monthYearPicker: true,
58
+ },
59
+ }
60
+
61
+ export const EnglishLocale: Story = {
62
+ args: {
63
+ locale: enUS,
64
+ },
65
+ }
66
+
67
+ export const Playground: Story = {
68
+ render: (args) => ({
69
+ components: { Calendar },
70
+ setup() {
71
+ const selected = ref<Date | null>(null)
72
+ return { args, selected }
73
+ },
74
+ template: `
75
+ <Calendar
76
+ v-bind="args"
77
+ v-model="selected"
78
+ />
79
+ <p v-if="selected" style="margin-top: 12px; font-size: 13px; color: #555; display: block;">
80
+ Geselecteerd: {{ selected.toLocaleDateString('nl-NL') }}
81
+ </p>
82
+ `,
83
+ }),
84
+ args: {
85
+ monthYearPicker: true,
86
+ markedDates: [
87
+ new Date(new Date().getFullYear(), new Date().getMonth(), 8),
88
+ new Date(new Date().getFullYear(), new Date().getMonth(), 15),
89
+ ],
90
+ },
91
+ }