@davidbirchall/core 1.0.8 → 1.0.9

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 (95) hide show
  1. package/dist/Button/types.d.ts +4 -0
  2. package/dist/Calendar/types.d.ts +22 -0
  3. package/{src/components/Card/types.ts → dist/Card/types.d.ts} +1 -1
  4. package/dist/Checkbox/types.d.ts +7 -0
  5. package/dist/DataTable/types.d.ts +11 -0
  6. package/dist/Dropdown/types.d.ts +13 -0
  7. package/dist/EmptyState/types.d.ts +8 -0
  8. package/dist/ErrorSummary/types.d.ts +4 -0
  9. package/dist/Heading/types.d.ts +6 -0
  10. package/dist/Input/types.d.ts +11 -0
  11. package/dist/Select/types.d.ts +15 -0
  12. package/dist/StatCard/types.d.ts +12 -0
  13. package/dist/Tag/types.d.ts +4 -0
  14. package/dist/TextArea/types.d.ts +11 -0
  15. package/dist/core.css +1 -0
  16. package/dist/core.js +24 -0
  17. package/dist/core.js.map +1 -0
  18. package/dist/core.umd.cjs +2 -0
  19. package/dist/core.umd.cjs.map +1 -0
  20. package/dist/index.d.ts +2 -0
  21. package/dist/package.json +27 -0
  22. package/package.json +4 -1
  23. package/.storybook/main.ts +0 -18
  24. package/.storybook/preview.ts +0 -14
  25. package/src/components/Badge/Badge.stories.ts +0 -147
  26. package/src/components/Badge/Badge.test.ts +0 -57
  27. package/src/components/Badge/Badge.vue +0 -79
  28. package/src/components/Button/Button.stories.ts +0 -80
  29. package/src/components/Button/Button.test.ts +0 -145
  30. package/src/components/Button/Button.vue +0 -108
  31. package/src/components/Button/types.ts +0 -4
  32. package/src/components/Calendar/Calendar.stories.ts +0 -261
  33. package/src/components/Calendar/Calendar.test.ts +0 -119
  34. package/src/components/Calendar/Calendar.vue +0 -528
  35. package/src/components/Calendar/types.ts +0 -20
  36. package/src/components/Card/Card.stories.ts +0 -88
  37. package/src/components/Card/Card.test.ts +0 -173
  38. package/src/components/Card/Card.vue +0 -59
  39. package/src/components/Checkbox/Checkbox.stories.ts +0 -126
  40. package/src/components/Checkbox/Checkbox.test.ts +0 -155
  41. package/src/components/Checkbox/Checkbox.vue +0 -121
  42. package/src/components/Checkbox/types.ts +0 -7
  43. package/src/components/DataTable/DataTable.stories.ts +0 -156
  44. package/src/components/DataTable/DataTable.test.ts +0 -185
  45. package/src/components/DataTable/DataTable.vue +0 -177
  46. package/src/components/DataTable/types.ts +0 -12
  47. package/src/components/DatePicker/DatePicker.stories.ts +0 -172
  48. package/src/components/DatePicker/DatePicker.test.ts +0 -87
  49. package/src/components/DatePicker/DatePicker.vue +0 -302
  50. package/src/components/Dropdown/Dropdown.stories.ts +0 -231
  51. package/src/components/Dropdown/Dropdown.vue +0 -314
  52. package/src/components/Dropdown/types.ts +0 -14
  53. package/src/components/EmptyState/EmptyState.stories.ts +0 -189
  54. package/src/components/EmptyState/EmptyState.vue +0 -215
  55. package/src/components/EmptyState/types.ts +0 -8
  56. package/src/components/ErrorSummary/ErrorSummary.vue +0 -78
  57. package/src/components/ErrorSummary/types.ts +0 -4
  58. package/src/components/FormGroup/FormGroup.stories.ts +0 -264
  59. package/src/components/FormGroup/FormGroup.test.ts +0 -63
  60. package/src/components/FormGroup/FormGroup.vue +0 -58
  61. package/src/components/Heading/Heading.stories.ts +0 -121
  62. package/src/components/Heading/Heading.test.ts +0 -184
  63. package/src/components/Heading/Heading.vue +0 -95
  64. package/src/components/Heading/types.ts +0 -6
  65. package/src/components/Input/Input.stories.ts +0 -172
  66. package/src/components/Input/Input.test.ts +0 -213
  67. package/src/components/Input/Input.vue +0 -121
  68. package/src/components/Input/types.ts +0 -11
  69. package/src/components/Modal/Modal.stories.ts +0 -341
  70. package/src/components/Modal/Modal.test.ts +0 -99
  71. package/src/components/Modal/Modal.vue +0 -278
  72. package/src/components/ProgressBar/ProgressBar.stories.ts +0 -313
  73. package/src/components/ProgressBar/ProgressBar.test.ts +0 -98
  74. package/src/components/ProgressBar/ProgressBar.vue +0 -117
  75. package/src/components/Select/Select.stories.ts +0 -177
  76. package/src/components/Select/Select.test.ts +0 -225
  77. package/src/components/Select/Select.vue +0 -147
  78. package/src/components/Select/types.ts +0 -16
  79. package/src/components/StatCard/StatCard.stories.ts +0 -274
  80. package/src/components/StatCard/StatCard.vue +0 -226
  81. package/src/components/StatCard/types.ts +0 -12
  82. package/src/components/Tag/Tag.stories.ts +0 -78
  83. package/src/components/Tag/Tag.test.ts +0 -50
  84. package/src/components/Tag/Tag.vue +0 -71
  85. package/src/components/Tag/types.ts +0 -4
  86. package/src/components/TextArea/TextArea.stories.ts +0 -171
  87. package/src/components/TextArea/TextArea.test.ts +0 -202
  88. package/src/components/TextArea/TextArea.vue +0 -122
  89. package/src/components/TextArea/types.ts +0 -11
  90. package/src/components/index.ts +0 -5
  91. package/src/test/setup.ts +0 -1
  92. package/src/vite-env.d.ts +0 -6
  93. package/tsconfig.json +0 -29
  94. package/vite.config.ts +0 -33
  95. package/vitest.config.ts +0 -28
@@ -1,528 +0,0 @@
1
- <template>
2
- <div class="calendar">
3
- <div class="calendar-header">
4
- <button @click.stop="previousMonth" class="calendar-nav" type="button">
5
-
6
- </button>
7
- <div class="calendar-title">
8
- <button @click.stop="showMonthPicker" class="calendar-month-btn" type="button">
9
- {{ monthName }}
10
- </button>
11
- <button @click.stop="showYearPicker" class="calendar-year-btn" type="button">
12
- {{ currentYear }}
13
- </button>
14
- </div>
15
- <button @click.stop="nextMonth" class="calendar-nav" type="button">
16
-
17
- </button>
18
- </div>
19
-
20
- <div v-if="!pickerMode" class="calendar-body">
21
- <div class="calendar-weekdays">
22
- <div
23
- v-for="day in weekdays"
24
- :key="day"
25
- class="calendar-weekday"
26
- >
27
- {{ day }}
28
- </div>
29
- </div>
30
-
31
- <div class="calendar-days">
32
- <button
33
- v-for="day in calendarDays"
34
- :key="day.dateString"
35
- @click="selectDate(day)"
36
- type="button"
37
- :disabled="day.isDisabled"
38
- :class="[
39
- 'calendar-day',
40
- {
41
- 'calendar-day--other-month': !day.isCurrentMonth,
42
- 'calendar-day--today': day.isToday,
43
- 'calendar-day--selected': day.isSelected,
44
- 'calendar-day--disabled': day.isDisabled,
45
- 'calendar-day--in-range': day.isInRange
46
- }
47
- ]"
48
- >
49
- {{ day.date.getDate() }}
50
- </button>
51
- </div>
52
- </div>
53
-
54
- <div v-else-if="pickerMode === 'month'" class="calendar-picker">
55
- <div class="calendar-picker-grid">
56
- <button
57
- v-for="(month, index) in monthNames"
58
- :key="month"
59
- @click.stop="selectMonth(index)"
60
- type="button"
61
- :class="[
62
- 'calendar-picker-item',
63
- { 'calendar-picker-item--selected': index === currentMonth }
64
- ]"
65
- >
66
- {{ month }}
67
- </button>
68
- </div>
69
- </div>
70
-
71
- <div v-else-if="pickerMode === 'year'" class="calendar-picker">
72
- <div class="calendar-picker-nav">
73
- <button @click.stop="previousYearPage" class="calendar-nav" type="button">
74
-
75
- </button>
76
- <span class="calendar-picker-range">{{ yearRangeLabel }}</span>
77
- <button @click.stop="nextYearPage" class="calendar-nav" type="button">
78
-
79
- </button>
80
- </div>
81
- <div class="calendar-picker-grid">
82
- <button
83
- v-for="year in yearRange"
84
- :key="year"
85
- @click.stop="selectYear(year)"
86
- type="button"
87
- :class="[
88
- 'calendar-picker-item',
89
- { 'calendar-picker-item--selected': year === currentYear }
90
- ]"
91
- >
92
- {{ year }}
93
- </button>
94
- </div>
95
- </div>
96
- </div>
97
- </template>
98
-
99
- <script setup lang="ts">
100
- import { ref, computed } from 'vue'
101
- import type { CalendarProps, CalendarDay } from './types'
102
-
103
- const props = withDefaults(defineProps<CalendarProps>(), {
104
- mode: 'single',
105
- locale: 'en-US',
106
- firstDayOfWeek: 0
107
- })
108
-
109
- const emit = defineEmits<{
110
- 'update:modelValue': [value: string | string[] | { start: string; end: string }]
111
- }>()
112
-
113
- const getInitialDate = (): Date => {
114
- if (props.initialDate) {
115
- const [year, month, day] = props.initialDate.split('-').map(Number)
116
- return new Date(year, month - 1, day)
117
- }
118
-
119
- if (props.modelValue) {
120
- if (typeof props.modelValue === 'string') {
121
- const [year, month, day] = props.modelValue.split('-').map(Number)
122
- return new Date(year, month - 1, day)
123
- }
124
- if (typeof props.modelValue === 'object' && 'start' in props.modelValue && props.modelValue.start) {
125
- const [year, month, day] = props.modelValue.start.split('-').map(Number)
126
- return new Date(year, month - 1, day)
127
- }
128
- if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
129
- const [year, month, day] = props.modelValue[0].split('-').map(Number)
130
- return new Date(year, month - 1, day)
131
- }
132
- }
133
-
134
- return new Date()
135
- }
136
-
137
- const initialDate = getInitialDate()
138
- const currentMonth = ref(initialDate.getMonth())
139
- const currentYear = ref(initialDate.getFullYear())
140
- const pickerMode = ref<'month' | 'year' | null>(null)
141
- const rangeStart = ref<string | null>(null)
142
- const yearPageStart = ref(Math.floor(initialDate.getFullYear() / 12) * 12)
143
-
144
- const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
145
- const fullMonthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
146
- const weekdayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
147
-
148
- const monthName = computed(() => fullMonthNames[currentMonth.value])
149
-
150
- const weekdays = computed(() => {
151
- const days = [...weekdayNames]
152
- if (props.firstDayOfWeek > 0) {
153
- return [...days.slice(props.firstDayOfWeek), ...days.slice(0, props.firstDayOfWeek)]
154
- }
155
- return days
156
- })
157
-
158
- const yearRange = computed(() => {
159
- return Array.from({ length: 12 }, (_, i) => yearPageStart.value + i)
160
- })
161
-
162
- const yearRangeLabel = computed(() => {
163
- const start = yearPageStart.value
164
- const end = start + 11
165
- return `${start} - ${end}`
166
- })
167
-
168
- const calendarDays = computed<CalendarDay[]>(() => {
169
- const days: CalendarDay[] = []
170
- const firstDay = new Date(currentYear.value, currentMonth.value, 1)
171
- const lastDay = new Date(currentYear.value, currentMonth.value + 1, 0)
172
-
173
- let startDay = firstDay.getDay() - props.firstDayOfWeek
174
- if (startDay < 0) startDay += 7
175
-
176
- const prevMonthDays = new Date(currentYear.value, currentMonth.value, 0).getDate()
177
-
178
- // Previous month days
179
- for (let i = startDay - 1; i >= 0; i--) {
180
- const date = new Date(currentYear.value, currentMonth.value - 1, prevMonthDays - i)
181
- days.push(createCalendarDay(date, false))
182
- }
183
-
184
- // Current month days
185
- for (let i = 1; i <= lastDay.getDate(); i++) {
186
- const date = new Date(currentYear.value, currentMonth.value, i)
187
- days.push(createCalendarDay(date, true))
188
- }
189
-
190
- // Next month days
191
- const remainingDays = 42 - days.length
192
- for (let i = 1; i <= remainingDays; i++) {
193
- const date = new Date(currentYear.value, currentMonth.value + 1, i)
194
- days.push(createCalendarDay(date, false))
195
- }
196
-
197
- return days
198
- })
199
-
200
- const createCalendarDay = (date: Date, isCurrentMonth: boolean): CalendarDay => {
201
- const dateString = formatDate(date)
202
- const today = formatDate(new Date())
203
-
204
- return {
205
- date,
206
- dateString,
207
- isCurrentMonth,
208
- isToday: dateString === today,
209
- isSelected: isDateSelected(dateString),
210
- isDisabled: isDateDisabled(dateString),
211
- isInRange: isDateInRange(dateString)
212
- }
213
- }
214
-
215
- const formatDate = (date: Date): string => {
216
- const year = date.getFullYear()
217
- const month = String(date.getMonth() + 1).padStart(2, '0')
218
- const day = String(date.getDate()).padStart(2, '0')
219
- return `${year}-${month}-${day}`
220
- }
221
-
222
- const isDateSelected = (dateString: string): boolean => {
223
- if (!props.modelValue) return false
224
-
225
- if (props.mode === 'single') {
226
- return props.modelValue === dateString
227
- }
228
-
229
- if (props.mode === 'multiple' && Array.isArray(props.modelValue)) {
230
- return props.modelValue.includes(dateString)
231
- }
232
-
233
- if (props.mode === 'range' && typeof props.modelValue === 'object' && 'start' in props.modelValue) {
234
- return dateString === props.modelValue.start || dateString === props.modelValue.end
235
- }
236
-
237
- return false
238
- }
239
-
240
- const isDateDisabled = (dateString: string): boolean => {
241
- if (props.minDate && dateString < props.minDate) return true
242
- if (props.maxDate && dateString > props.maxDate) return true
243
- if (props.disabledDates?.includes(dateString)) return true
244
- return false
245
- }
246
-
247
- const isDateInRange = (dateString: string): boolean => {
248
- if (props.mode !== 'range') return false
249
- if (typeof props.modelValue !== 'object' || !('start' in props.modelValue)) return false
250
-
251
- const { start, end } = props.modelValue
252
- if (!start || !end) return false
253
-
254
- return dateString > start && dateString < end
255
- }
256
-
257
- const selectDate = (day: CalendarDay) => {
258
- if (day.isDisabled) return
259
-
260
- if (props.mode === 'single') {
261
- emit('update:modelValue', day.dateString)
262
- } else if (props.mode === 'multiple') {
263
- const current = Array.isArray(props.modelValue) ? [...props.modelValue] : []
264
- const index = current.indexOf(day.dateString)
265
-
266
- if (index > -1) {
267
- current.splice(index, 1)
268
- } else {
269
- current.push(day.dateString)
270
- }
271
-
272
- emit('update:modelValue', current)
273
- } else if (props.mode === 'range') {
274
- if (!rangeStart.value) {
275
- rangeStart.value = day.dateString
276
- emit('update:modelValue', { start: day.dateString, end: day.dateString })
277
- } else {
278
- const start = rangeStart.value < day.dateString ? rangeStart.value : day.dateString
279
- const end = rangeStart.value < day.dateString ? day.dateString : rangeStart.value
280
- emit('update:modelValue', { start, end })
281
- rangeStart.value = null
282
- }
283
- }
284
- }
285
-
286
- const previousMonth = () => {
287
- if (currentMonth.value === 0) {
288
- currentMonth.value = 11
289
- currentYear.value--
290
- } else {
291
- currentMonth.value--
292
- }
293
- }
294
-
295
- const nextMonth = () => {
296
- if (currentMonth.value === 11) {
297
- currentMonth.value = 0
298
- currentYear.value++
299
- } else {
300
- currentMonth.value++
301
- }
302
- }
303
-
304
- const showMonthPicker = () => {
305
- pickerMode.value = pickerMode.value === 'month' ? null : 'month'
306
- }
307
-
308
- const showYearPicker = () => {
309
- if (pickerMode.value !== 'year') {
310
- // Center the year page around the current year when opening
311
- yearPageStart.value = Math.floor(currentYear.value / 12) * 12
312
- }
313
- pickerMode.value = pickerMode.value === 'year' ? null : 'year'
314
- }
315
-
316
- const selectMonth = (month: number) => {
317
- currentMonth.value = month
318
- pickerMode.value = null
319
- }
320
-
321
- const selectYear = (year: number) => {
322
- currentYear.value = year
323
- pickerMode.value = null
324
- }
325
-
326
- const previousYearPage = () => {
327
- yearPageStart.value -= 12
328
- }
329
-
330
- const nextYearPage = () => {
331
- yearPageStart.value += 12
332
- }
333
- </script>
334
-
335
- <style scoped>
336
- .calendar {
337
- background: white;
338
- border: 1px solid #e5e7eb;
339
- border-radius: 0.75rem;
340
- padding: 1rem;
341
- width: 100%;
342
- max-width: 320px;
343
- user-select: none;
344
- }
345
-
346
- .calendar-header {
347
- display: flex;
348
- justify-content: space-between;
349
- align-items: center;
350
- margin-bottom: 1rem;
351
- padding-bottom: 0.75rem;
352
- border-bottom: 1px solid #f3f4f6;
353
- }
354
-
355
- .calendar-title {
356
- display: flex;
357
- gap: 0.5rem;
358
- align-items: center;
359
- }
360
-
361
- .calendar-month-btn,
362
- .calendar-year-btn {
363
- background: none;
364
- border: none;
365
- font-size: 1rem;
366
- font-weight: 600;
367
- color: #1f2937;
368
- cursor: pointer;
369
- padding: 0.25rem 0.5rem;
370
- border-radius: 0.375rem;
371
- transition: all 0.2s;
372
- }
373
-
374
- .calendar-month-btn:hover,
375
- .calendar-year-btn:hover {
376
- background: #f3f4f6;
377
- }
378
-
379
- .calendar-nav {
380
- background: none;
381
- border: none;
382
- font-size: 1.5rem;
383
- color: #6b7280;
384
- cursor: pointer;
385
- width: 2rem;
386
- height: 2rem;
387
- display: flex;
388
- align-items: center;
389
- justify-content: center;
390
- border-radius: 0.375rem;
391
- transition: all 0.2s;
392
- }
393
-
394
- .calendar-nav:hover {
395
- background: #f3f4f6;
396
- color: #1f2937;
397
- }
398
-
399
- .calendar-body {
400
- display: flex;
401
- flex-direction: column;
402
- }
403
-
404
- .calendar-weekdays {
405
- display: grid;
406
- grid-template-columns: repeat(7, 1fr);
407
- gap: 0.25rem;
408
- margin-bottom: 0.5rem;
409
- }
410
-
411
- .calendar-weekday {
412
- text-align: center;
413
- font-size: 0.75rem;
414
- font-weight: 600;
415
- color: #6b7280;
416
- padding: 0.5rem 0;
417
- }
418
-
419
- .calendar-days {
420
- display: grid;
421
- grid-template-columns: repeat(7, 1fr);
422
- gap: 0.25rem;
423
- }
424
-
425
- .calendar-day {
426
- aspect-ratio: 1;
427
- border: none;
428
- background: none;
429
- font-size: 0.875rem;
430
- color: #1f2937;
431
- cursor: pointer;
432
- border-radius: 0.375rem;
433
- transition: all 0.2s;
434
- display: flex;
435
- align-items: center;
436
- justify-content: center;
437
- }
438
-
439
- .calendar-day:hover:not(:disabled) {
440
- background: #f3f4f6;
441
- }
442
-
443
- .calendar-day--other-month {
444
- color: #d1d5db;
445
- }
446
-
447
- .calendar-day--today {
448
- font-weight: 700;
449
- color: #667eea;
450
- }
451
-
452
- .calendar-day--selected {
453
- background: #667eea;
454
- color: white;
455
- font-weight: 600;
456
- }
457
-
458
- .calendar-day--selected:hover {
459
- background: #5568d3;
460
- }
461
-
462
- .calendar-day--in-range {
463
- background: #eef2ff;
464
- color: #667eea;
465
- }
466
-
467
- .calendar-day--disabled {
468
- color: #d1d5db;
469
- cursor: not-allowed;
470
- }
471
-
472
- .calendar-day--disabled:hover {
473
- background: none;
474
- }
475
-
476
- .calendar-picker {
477
- display: flex;
478
- flex-direction: column;
479
- gap: 0.5rem;
480
- }
481
-
482
- .calendar-picker-nav {
483
- display: flex;
484
- justify-content: space-between;
485
- align-items: center;
486
- padding: 0.5rem 0;
487
- margin-bottom: 0.5rem;
488
- border-bottom: 1px solid #f3f4f6;
489
- }
490
-
491
- .calendar-picker-range {
492
- font-size: 0.875rem;
493
- font-weight: 600;
494
- color: #1f2937;
495
- }
496
-
497
- .calendar-picker-grid {
498
- display: grid;
499
- grid-template-columns: repeat(3, 1fr);
500
- gap: 0.5rem;
501
- }
502
-
503
- .calendar-picker-item {
504
- background: none;
505
- border: 1px solid #e5e7eb;
506
- padding: 0.75rem;
507
- border-radius: 0.375rem;
508
- font-size: 0.875rem;
509
- color: #1f2937;
510
- cursor: pointer;
511
- transition: all 0.2s;
512
- }
513
-
514
- .calendar-picker-item:hover {
515
- background: #f3f4f6;
516
- border-color: #667eea;
517
- }
518
-
519
- .calendar-picker-item--selected {
520
- background: #667eea;
521
- color: white;
522
- border-color: #667eea;
523
- }
524
-
525
- .calendar-picker-item--selected:hover {
526
- background: #5568d3;
527
- }
528
- </style>
@@ -1,20 +0,0 @@
1
- export interface CalendarProps {
2
- modelValue?: string | string[] | { start: string; end: string }
3
- mode?: 'single' | 'multiple' | 'range'
4
- minDate?: string
5
- maxDate?: string
6
- disabledDates?: string[]
7
- locale?: string
8
- firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6
9
- initialDate?: string
10
- }
11
-
12
- export interface CalendarDay {
13
- date: Date
14
- dateString: string
15
- isCurrentMonth: boolean
16
- isToday: boolean
17
- isSelected: boolean
18
- isDisabled: boolean
19
- isInRange: boolean
20
- }
@@ -1,88 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/vue3'
2
- import Card from './Card.vue'
3
-
4
- const meta = {
5
- title: 'Components/Card',
6
- component: Card,
7
- tags: ['autodocs'],
8
- argTypes: {
9
- hoverable: {
10
- control: 'boolean',
11
- description: 'Enable hover effect'
12
- }
13
- },
14
- args: {
15
- hoverable: false
16
- }
17
- } satisfies Meta<typeof Card>
18
-
19
- export default meta
20
- type Story = StoryObj<typeof meta>
21
-
22
- export const Default: Story = {
23
- render: (args: any) => ({
24
- components: { Card },
25
- setup() {
26
- return { args }
27
- },
28
- template: `
29
- <Card v-bind="args">
30
- <p>This is the card body content. You can put any content here.</p>
31
- </Card>
32
- `
33
- })
34
- }
35
-
36
- export const WithHeader: Story = {
37
- render: (args: any) => ({
38
- components: { Card },
39
- setup() {
40
- return { args }
41
- },
42
- template: `
43
- <Card v-bind="args">
44
- <template #header>Card Header</template>
45
- <p>This is the card body content with a header.</p>
46
- </Card>
47
- `
48
- })
49
- }
50
-
51
- export const WithHeaderAndFooter: Story = {
52
- render: (args: any) => ({
53
- components: { Card },
54
- setup() {
55
- return { args }
56
- },
57
- template: `
58
- <Card v-bind="args">
59
- <template #header>Card Title</template>
60
- <p>This card has both a header and a footer section.</p>
61
- <template #footer>
62
- <div style="display: flex; gap: 0.5rem;">
63
- <button>Cancel</button>
64
- <button>Save</button>
65
- </div>
66
- </template>
67
- </Card>
68
- `
69
- })
70
- }
71
-
72
- export const Hoverable: Story = {
73
- args: {
74
- hoverable: true
75
- },
76
- render: (args: any) => ({
77
- components: { Card },
78
- setup() {
79
- return { args }
80
- },
81
- template: `
82
- <Card v-bind="args">
83
- <template #header>Hoverable Card</template>
84
- <p>Hover over this card to see the effect!</p>
85
- </Card>
86
- `
87
- })
88
- }