daisy-ui-kit 5.0.0-pre.5 → 5.0.0-pre.6

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 (132) hide show
  1. package/app/components/Accordion.vue +26 -0
  2. package/app/components/Alert.vue +35 -0
  3. package/app/components/Avatar.vue +128 -0
  4. package/app/components/AvatarGroup.vue +18 -0
  5. package/app/components/Badge.vue +54 -0
  6. package/app/components/Breadcrumbs.vue +7 -0
  7. package/app/components/Button.vue +113 -0
  8. package/app/components/Calendar.vue +66 -0
  9. package/app/components/CalendarInput.vue +176 -0
  10. package/app/components/CalendarSkeleton.vue +46 -0
  11. package/app/components/Card.vue +33 -0
  12. package/app/components/CardActions.vue +13 -0
  13. package/app/components/CardBody.vue +13 -0
  14. package/app/components/CardTitle.vue +11 -0
  15. package/app/components/Carousel.vue +23 -0
  16. package/app/components/CarouselItem.vue +5 -0
  17. package/app/components/Chat.vue +21 -0
  18. package/app/components/ChatBubble.vue +31 -0
  19. package/app/components/ChatFooter.vue +5 -0
  20. package/app/components/ChatHeader.vue +5 -0
  21. package/app/components/ChatImage.vue +5 -0
  22. package/app/components/Checkbox.vue +49 -0
  23. package/app/components/Collapse.vue +43 -0
  24. package/app/components/CollapseContent.vue +5 -0
  25. package/app/components/CollapseTitle.vue +5 -0
  26. package/app/components/Countdown.vue +15 -0
  27. package/app/components/CountdownTimers.vue +72 -0
  28. package/app/components/Counter.vue +10 -0
  29. package/app/components/Crumb.vue +5 -0
  30. package/app/components/DaisyLink.vue +38 -0
  31. package/app/components/Diff.vue +11 -0
  32. package/app/components/Divider.vue +43 -0
  33. package/app/components/Dock.vue +58 -0
  34. package/app/components/DockItem.vue +25 -0
  35. package/app/components/DockLabel.vue +5 -0
  36. package/app/components/Drawer.vue +47 -0
  37. package/app/components/DrawerContent.vue +17 -0
  38. package/app/components/DrawerSide.vue +18 -0
  39. package/app/components/Dropdown.vue +95 -0
  40. package/app/components/DropdownButton.vue +16 -0
  41. package/app/components/DropdownContent.vue +57 -0
  42. package/app/components/DropdownTarget.vue +14 -0
  43. package/app/components/Fieldset.vue +19 -0
  44. package/app/components/FileInput.vue +53 -0
  45. package/app/components/Filter.vue +122 -0
  46. package/app/components/Flex.vue +82 -0
  47. package/app/components/FlexItem.vue +59 -0
  48. package/app/components/Footer.vue +27 -0
  49. package/app/components/FooterTitle.vue +15 -0
  50. package/app/components/FormControl.vue +5 -0
  51. package/app/components/Hero.vue +15 -0
  52. package/app/components/HeroContent.vue +15 -0
  53. package/app/components/HeroOverlay.vue +5 -0
  54. package/app/components/Indicator.vue +13 -0
  55. package/app/components/IndicatorItem.vue +36 -0
  56. package/app/components/Input.vue +102 -0
  57. package/app/components/Join.vue +5 -0
  58. package/app/components/Kbd.vue +24 -0
  59. package/app/components/Label.vue +61 -0
  60. package/app/components/List.vue +5 -0
  61. package/app/components/ListColGrow.vue +5 -0
  62. package/app/components/ListColWrap.vue +5 -0
  63. package/app/components/ListRow.vue +5 -0
  64. package/app/components/LoadingBall.vue +42 -0
  65. package/app/components/LoadingBars.vue +42 -0
  66. package/app/components/LoadingDots.vue +42 -0
  67. package/app/components/LoadingInfinity.vue +42 -0
  68. package/app/components/LoadingRing.vue +42 -0
  69. package/app/components/LoadingSpinner.vue +42 -0
  70. package/app/components/Mask.vue +49 -0
  71. package/app/components/Menu.vue +30 -0
  72. package/app/components/MenuExpand.vue +100 -0
  73. package/app/components/MenuExpandToggle.vue +14 -0
  74. package/app/components/MenuItem.vue +37 -0
  75. package/app/components/MenuTitle.vue +5 -0
  76. package/app/components/MockupBrowser.vue +5 -0
  77. package/app/components/MockupBrowserToolbar.vue +5 -0
  78. package/app/components/MockupCode.vue +4 -0
  79. package/app/components/MockupPhone.vue +8 -0
  80. package/app/components/MockupWindow.vue +5 -0
  81. package/app/components/Modal.vue +57 -0
  82. package/app/components/ModalAction.vue +5 -0
  83. package/app/components/ModalBox.vue +5 -0
  84. package/app/components/NavButton.vue +12 -0
  85. package/app/components/Navbar.vue +12 -0
  86. package/app/components/NavbarCenter.vue +11 -0
  87. package/app/components/NavbarEnd.vue +11 -0
  88. package/app/components/NavbarStart.vue +11 -0
  89. package/app/components/Progress.vue +34 -0
  90. package/app/components/Prose.vue +32 -0
  91. package/app/components/RadialProgress.vue +36 -0
  92. package/app/components/Radio.vue +67 -0
  93. package/app/components/RadioGroup.vue +47 -0
  94. package/app/components/Range.vue +61 -0
  95. package/app/components/RangeMeasure.vue +84 -0
  96. package/app/components/RangeMeasureTick.vue +70 -0
  97. package/app/components/Rating.vue +180 -0
  98. package/app/components/Select.vue +104 -0
  99. package/app/components/Skeleton.vue +5 -0
  100. package/app/components/Stack.vue +25 -0
  101. package/app/components/Stat.vue +19 -0
  102. package/app/components/StatActions.vue +5 -0
  103. package/app/components/StatDesc.vue +5 -0
  104. package/app/components/StatFigure.vue +5 -0
  105. package/app/components/StatTitle.vue +5 -0
  106. package/app/components/StatValue.vue +5 -0
  107. package/app/components/Stats.vue +5 -0
  108. package/app/components/Status.vue +43 -0
  109. package/app/components/Step.vue +34 -0
  110. package/app/components/StepIcon.vue +5 -0
  111. package/app/components/Steps.vue +18 -0
  112. package/app/components/Swap.vue +62 -0
  113. package/app/components/Tab.vue +38 -0
  114. package/app/components/TabContent.vue +29 -0
  115. package/app/components/Table.vue +32 -0
  116. package/app/components/Tabs.vue +53 -0
  117. package/app/components/Text.vue +142 -0
  118. package/app/components/TextArea.vue +61 -0
  119. package/app/components/Timeline.vue +22 -0
  120. package/app/components/TimelineEnd.vue +14 -0
  121. package/app/components/TimelineItem.vue +5 -0
  122. package/app/components/TimelineLine.vue +29 -0
  123. package/app/components/TimelineMiddle.vue +5 -0
  124. package/app/components/TimelineStart.vue +13 -0
  125. package/app/components/Toast.vue +29 -0
  126. package/app/components/Toggle.vue +58 -0
  127. package/app/components/Tooltip.vue +47 -0
  128. package/app/components/TooltipContent.vue +5 -0
  129. package/app/components/ValidatorHint.vue +5 -0
  130. package/app/utils/drawer-utils.ts +32 -0
  131. package/app/utils/random-string.ts +19 -0
  132. package/package.json +4 -4
@@ -0,0 +1,102 @@
1
+ <script setup lang="ts">
2
+ import { computed, inject } from 'vue'
3
+
4
+ // Map input type to value type
5
+ type InputType =
6
+ | 'text' | 'password' | 'email' | 'number' | 'date' | 'datetime-local' | 'week' | 'month' | 'tel' | 'url' | 'search' | 'time'
7
+
8
+ const props = withDefaults(defineProps<{
9
+ modelValue?: string | number | null
10
+ type?: InputType
11
+ placeholder?: string
12
+ disabled?: boolean
13
+ validator?: boolean
14
+ join?: boolean
15
+ color?: string
16
+ primary?: boolean
17
+ secondary?: boolean
18
+ accent?: boolean
19
+ info?: boolean
20
+ success?: boolean
21
+ warning?: boolean
22
+ error?: boolean
23
+ ghost?: boolean
24
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
25
+ xl?: boolean
26
+ lg?: boolean
27
+ md?: boolean
28
+ sm?: boolean
29
+ xs?: boolean
30
+ }>(), {
31
+ type: 'text',
32
+ })
33
+ const emit = defineEmits(['update:modelValue'])
34
+
35
+ // For slot context
36
+ function setValue(val: string | number | null) {
37
+ emit('update:modelValue', val)
38
+ }
39
+
40
+ const labelCtx = inject('labelCtx', false)
41
+
42
+ const inputAttrs = computed(() => {
43
+ if (labelCtx) {
44
+ return {
45
+ type: props.type,
46
+ placeholder: props.placeholder,
47
+ disabled: props.disabled,
48
+ }
49
+ }
50
+ return {
51
+ type: props.type,
52
+ placeholder: props.placeholder,
53
+ disabled: props.disabled,
54
+ class: [
55
+ 'input',
56
+ { validator: props.validator },
57
+ { 'input-primary': props.primary || props.color === 'primary' },
58
+ { 'input-secondary': props.secondary || props.color === 'secondary' },
59
+ { 'input-accent': props.accent || props.color === 'accent' },
60
+ { 'input-info': props.info || props.color === 'info' },
61
+ { 'input-success': props.success || props.color === 'success' },
62
+ { 'input-warning': props.warning || props.color === 'warning' },
63
+ { 'input-error': props.error || props.color === 'error' },
64
+ { 'input-ghost': props.ghost },
65
+ { 'input-xl': props.xl || props.size === 'xl' },
66
+ { 'input-lg': props.lg || props.size === 'lg' },
67
+ { 'input-md': props.md || props.size === 'md' },
68
+ { 'input-sm': props.sm || props.size === 'sm' },
69
+ { 'input-xs': props.xs || props.size === 'xs' },
70
+ { 'join-item': props.join },
71
+ ],
72
+ }
73
+ })
74
+ const inputModel = computed({
75
+ get: () => props.modelValue,
76
+ set: setValue,
77
+ })
78
+ </script>
79
+
80
+ <template>
81
+ <div v-if="$slots.default">
82
+ <slot
83
+ :value="inputModel"
84
+ :set-value="setValue"
85
+ :input-attrs="inputAttrs"
86
+ :props="props"
87
+ :input-model="inputModel"
88
+ />
89
+ </div>
90
+ <input
91
+ v-else
92
+ v-bind="inputAttrs"
93
+ :value="inputModel"
94
+ @input="
95
+ $emit('update:modelValue',
96
+ props.type === 'number'
97
+ ? ($event.target as HTMLInputElement).value === '' ? null : Number(($event.target as HTMLInputElement).value)
98
+ : ($event.target as HTMLInputElement).value,
99
+ )
100
+ "
101
+ >
102
+ </template>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div class="join">
3
+ <slot />
4
+ </div>
5
+ </template>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ defineProps<{
3
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
4
+ xl?: boolean
5
+ lg?: boolean
6
+ md?: boolean
7
+ sm?: boolean
8
+ xs?: boolean
9
+ }>()
10
+ </script>
11
+
12
+ <template>
13
+ <kbd
14
+ class="kbd" :class="{
15
+ 'kbd-xl': xl || size === 'xl',
16
+ 'kbd-lg': lg || size === 'lg',
17
+ 'kbd-md': md || size === 'md',
18
+ 'kbd-sm': sm || size === 'sm',
19
+ 'kbd-xs': xs || size === 'xs',
20
+ }"
21
+ >
22
+ <slot />
23
+ </kbd>
24
+ </template>
@@ -0,0 +1,61 @@
1
+ <script setup lang="ts">
2
+ import { provide } from 'vue'
3
+ import Text from './Text.vue'
4
+
5
+ withDefaults(defineProps<{
6
+ is?: string
7
+ floating?: boolean
8
+ input?: boolean
9
+
10
+ join?: boolean
11
+ color?: string
12
+ primary?: boolean
13
+ secondary?: boolean
14
+ accent?: boolean
15
+ info?: boolean
16
+ success?: boolean
17
+ warning?: boolean
18
+ error?: boolean
19
+ ghost?: boolean
20
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
21
+ xl?: boolean
22
+ lg?: boolean
23
+ md?: boolean
24
+ sm?: boolean
25
+ xs?: boolean
26
+ }>(), {
27
+ is: 'label',
28
+ })
29
+
30
+ // Provide label context for child inputs
31
+ provide('labelCtx', true)
32
+ </script>
33
+
34
+ <template>
35
+ <Text
36
+ :is="is"
37
+ :class="[
38
+ {
39
+ 'input': input,
40
+ 'join-item': input && join,
41
+ 'input-primary': input && (primary || color === 'primary'),
42
+ 'input-secondary': input && (secondary || color === 'secondary'),
43
+ 'input-accent': input && (accent || color === 'accent'),
44
+ 'input-info': input && (info || color === 'info'),
45
+ 'input-success': input && (success || color === 'success'),
46
+ 'input-warning': input && (warning || color === 'warning'),
47
+ 'input-error': input && (error || color === 'error'),
48
+ 'input-ghost': input && ghost,
49
+ 'input-xl': input && (size === 'xl' || xl),
50
+ 'input-lg': input && (size === 'lg' || lg),
51
+ 'input-md': input && (size === 'md' || md),
52
+ 'input-sm': input && (size === 'sm' || sm),
53
+ 'input-xs': input && (size === 'xs' || xs),
54
+ },
55
+ { label: !floating && !input },
56
+ { 'floating-label': floating },
57
+ ]"
58
+ >
59
+ <slot />
60
+ </Text>
61
+ </template>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div class="list list-none">
3
+ <slot />
4
+ </div>
5
+ </template>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div class="list-col-grow">
3
+ <slot />
4
+ </div>
5
+ </template>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div class="list-col-wrap">
3
+ <slot />
4
+ </div>
5
+ </template>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div class="list-row">
3
+ <slot />
4
+ </div>
5
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ color?: string
4
+ neutral?: boolean
5
+ primary?: boolean
6
+ secondary?: boolean
7
+ accent?: boolean
8
+ info?: boolean
9
+ success?: boolean
10
+ warning?: boolean
11
+ error?: boolean
12
+
13
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
14
+ xl?: boolean
15
+ lg?: boolean
16
+ md?: boolean
17
+ sm?: boolean
18
+ xs?: boolean
19
+ }>()
20
+ </script>
21
+
22
+ <template>
23
+ <span
24
+ class="loading loading-ball"
25
+ :class="{
26
+ 'text-primary': props.primary || props.color === 'primary',
27
+ 'text-secondary': props.secondary || props.color === 'secondary',
28
+ 'text-neutral': props.neutral || props.color === 'neutral',
29
+ 'text-accent': props.accent || props.color === 'accent',
30
+ 'text-info': props.info || props.color === 'info',
31
+ 'text-success': props.success || props.color === 'success',
32
+ 'text-warning': props.warning || props.color === 'warning',
33
+ 'text-error': props.error || props.color === 'error',
34
+
35
+ 'loading-xl': props.xl || props.size === 'xl',
36
+ 'loading-lg': props.lg || props.size === 'lg',
37
+ 'loading-md': props.md || props.size === 'md',
38
+ 'loading-sm': props.sm || props.size === 'sm',
39
+ 'loading-xs': props.xs || props.size === 'xs',
40
+ }"
41
+ />
42
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ color?: string
4
+ neutral?: boolean
5
+ primary?: boolean
6
+ secondary?: boolean
7
+ accent?: boolean
8
+ info?: boolean
9
+ success?: boolean
10
+ warning?: boolean
11
+ error?: boolean
12
+
13
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
14
+ xl?: boolean
15
+ lg?: boolean
16
+ md?: boolean
17
+ sm?: boolean
18
+ xs?: boolean
19
+ }>()
20
+ </script>
21
+
22
+ <template>
23
+ <span
24
+ class="loading loading-bars"
25
+ :class="{
26
+ 'text-primary': props.primary || props.color === 'primary',
27
+ 'text-secondary': props.secondary || props.color === 'secondary',
28
+ 'text-neutral': props.neutral || props.color === 'neutral',
29
+ 'text-accent': props.accent || props.color === 'accent',
30
+ 'text-info': props.info || props.color === 'info',
31
+ 'text-success': props.success || props.color === 'success',
32
+ 'text-warning': props.warning || props.color === 'warning',
33
+ 'text-error': props.error || props.color === 'error',
34
+
35
+ 'loading-xl': props.xl || props.size === 'xl',
36
+ 'loading-lg': props.lg || props.size === 'lg',
37
+ 'loading-md': props.md || props.size === 'md',
38
+ 'loading-sm': props.sm || props.size === 'sm',
39
+ 'loading-xs': props.xs || props.size === 'xs',
40
+ }"
41
+ />
42
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ color?: string
4
+ neutral?: boolean
5
+ primary?: boolean
6
+ secondary?: boolean
7
+ accent?: boolean
8
+ info?: boolean
9
+ success?: boolean
10
+ warning?: boolean
11
+ error?: boolean
12
+
13
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
14
+ xl?: boolean
15
+ lg?: boolean
16
+ md?: boolean
17
+ sm?: boolean
18
+ xs?: boolean
19
+ }>()
20
+ </script>
21
+
22
+ <template>
23
+ <span
24
+ class="loading loading-dots"
25
+ :class="{
26
+ 'text-primary': props.primary || props.color === 'primary',
27
+ 'text-secondary': props.secondary || props.color === 'secondary',
28
+ 'text-neutral': props.neutral || props.color === 'neutral',
29
+ 'text-accent': props.accent || props.color === 'accent',
30
+ 'text-info': props.info || props.color === 'info',
31
+ 'text-success': props.success || props.color === 'success',
32
+ 'text-warning': props.warning || props.color === 'warning',
33
+ 'text-error': props.error || props.color === 'error',
34
+
35
+ 'loading-xl': props.xl || props.size === 'xl',
36
+ 'loading-lg': props.lg || props.size === 'lg',
37
+ 'loading-md': props.md || props.size === 'md',
38
+ 'loading-sm': props.sm || props.size === 'sm',
39
+ 'loading-xs': props.xs || props.size === 'xs',
40
+ }"
41
+ />
42
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ color?: string
4
+ neutral?: boolean
5
+ primary?: boolean
6
+ secondary?: boolean
7
+ accent?: boolean
8
+ info?: boolean
9
+ success?: boolean
10
+ warning?: boolean
11
+ error?: boolean
12
+
13
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
14
+ xl?: boolean
15
+ lg?: boolean
16
+ md?: boolean
17
+ sm?: boolean
18
+ xs?: boolean
19
+ }>()
20
+ </script>
21
+
22
+ <template>
23
+ <span
24
+ class="loading loading-infinity"
25
+ :class="{
26
+ 'text-primary': props.primary || props.color === 'primary',
27
+ 'text-secondary': props.secondary || props.color === 'secondary',
28
+ 'text-neutral': props.neutral || props.color === 'neutral',
29
+ 'text-accent': props.accent || props.color === 'accent',
30
+ 'text-info': props.info || props.color === 'info',
31
+ 'text-success': props.success || props.color === 'success',
32
+ 'text-warning': props.warning || props.color === 'warning',
33
+ 'text-error': props.error || props.color === 'error',
34
+
35
+ 'loading-xl': props.xl || props.size === 'xl',
36
+ 'loading-lg': props.lg || props.size === 'lg',
37
+ 'loading-md': props.md || props.size === 'md',
38
+ 'loading-sm': props.sm || props.size === 'sm',
39
+ 'loading-xs': props.xs || props.size === 'xs',
40
+ }"
41
+ />
42
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ color?: string
4
+ neutral?: boolean
5
+ primary?: boolean
6
+ secondary?: boolean
7
+ accent?: boolean
8
+ info?: boolean
9
+ success?: boolean
10
+ warning?: boolean
11
+ error?: boolean
12
+
13
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
14
+ xl?: boolean
15
+ lg?: boolean
16
+ md?: boolean
17
+ sm?: boolean
18
+ xs?: boolean
19
+ }>()
20
+ </script>
21
+
22
+ <template>
23
+ <span
24
+ class="loading loading-ring"
25
+ :class="{
26
+ 'text-primary': props.primary || props.color === 'primary',
27
+ 'text-secondary': props.secondary || props.color === 'secondary',
28
+ 'text-neutral': props.neutral || props.color === 'neutral',
29
+ 'text-accent': props.accent || props.color === 'accent',
30
+ 'text-info': props.info || props.color === 'info',
31
+ 'text-success': props.success || props.color === 'success',
32
+ 'text-warning': props.warning || props.color === 'warning',
33
+ 'text-error': props.error || props.color === 'error',
34
+
35
+ 'loading-xl': props.xl || props.size === 'xl',
36
+ 'loading-lg': props.lg || props.size === 'lg',
37
+ 'loading-md': props.md || props.size === 'md',
38
+ 'loading-sm': props.sm || props.size === 'sm',
39
+ 'loading-xs': props.xs || props.size === 'xs',
40
+ }"
41
+ />
42
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ color?: string
4
+ neutral?: boolean
5
+ primary?: boolean
6
+ secondary?: boolean
7
+ accent?: boolean
8
+ info?: boolean
9
+ success?: boolean
10
+ warning?: boolean
11
+ error?: boolean
12
+
13
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
14
+ xl?: boolean
15
+ lg?: boolean
16
+ md?: boolean
17
+ sm?: boolean
18
+ xs?: boolean
19
+ }>()
20
+ </script>
21
+
22
+ <template>
23
+ <span
24
+ class="loading loading-spinner"
25
+ :class="{
26
+ 'text-primary': props.primary || props.color === 'primary',
27
+ 'text-secondary': props.secondary || props.color === 'secondary',
28
+ 'text-neutral': props.neutral || props.color === 'neutral',
29
+ 'text-accent': props.accent || props.color === 'accent',
30
+ 'text-info': props.info || props.color === 'info',
31
+ 'text-success': props.success || props.color === 'success',
32
+ 'text-warning': props.warning || props.color === 'warning',
33
+ 'text-error': props.error || props.color === 'error',
34
+
35
+ 'loading-xl': props.xl || props.size === 'xl',
36
+ 'loading-lg': props.lg || props.size === 'lg',
37
+ 'loading-md': props.md || props.size === 'md',
38
+ 'loading-sm': props.sm || props.size === 'sm',
39
+ 'loading-xs': props.xs || props.size === 'xs',
40
+ }"
41
+ />
42
+ </template>
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ shape?: string
4
+ squircle?: boolean
5
+ heart?: boolean
6
+ hexagon?: boolean
7
+ hexagon2?: boolean
8
+ decagon?: boolean
9
+ pentagon?: boolean
10
+ diamond?: boolean
11
+ square?: boolean
12
+ circle?: boolean
13
+ star?: boolean
14
+ star2?: boolean
15
+ triangle?: boolean
16
+ triangle2?: boolean
17
+ triangle3?: boolean
18
+ triangle4?: boolean
19
+ half1?: boolean
20
+ half2?: boolean
21
+ }>()
22
+ </script>
23
+
24
+ <template>
25
+ <div
26
+ class="mask"
27
+ :class="{
28
+ 'mask-squircle': props.squircle || props.shape === 'squircle',
29
+ 'mask-heart': props.heart || props.shape === 'heart',
30
+ 'mask-hexagon': props.hexagon || props.shape === 'hexagon',
31
+ 'mask-hexagon-2': props.hexagon2 || props.shape === 'hexagon-2',
32
+ 'mask-decagon': props.decagon || props.shape === 'decagon',
33
+ 'mask-pentagon': props.pentagon || props.shape === 'pentagon',
34
+ 'mask-diamond': props.diamond || props.shape === 'diamond',
35
+ 'mask-square': props.square || props.shape === 'square',
36
+ 'mask-circle': props.circle || props.shape === 'circle',
37
+ 'mask-star': props.star || props.shape === 'star',
38
+ 'mask-star-2': props.star2 || props.shape === 'star-2',
39
+ 'mask-triangle': props.triangle || props.shape === 'triangle',
40
+ 'mask-triangle-2': props.triangle2 || props.shape === 'triangle-2',
41
+ 'mask-triangle-3': props.triangle3 || props.shape === 'triangle-3',
42
+ 'mask-triangle-4': props.triangle4 || props.shape === 'triangle-4',
43
+ 'mask-half-1': props.half1 || props.shape === 'half-1',
44
+ 'mask-half-2': props.half2 || props.shape === 'half-2',
45
+ }"
46
+ >
47
+ <slot />
48
+ </div>
49
+ </template>
@@ -0,0 +1,30 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ align?: 'vertical' | 'horizontal'
4
+ vertical?: boolean
5
+ horizontal?: boolean
6
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
7
+ xl?: boolean
8
+ lg?: boolean
9
+ md?: boolean
10
+ sm?: boolean
11
+ xs?: boolean
12
+ }>()
13
+ </script>
14
+
15
+ <template>
16
+ <ul
17
+ class="menu"
18
+ :class="{
19
+ 'menu-vertical': props.vertical || props.align === 'vertical',
20
+ 'menu-horizontal': props.horizontal || props.align === 'horizontal',
21
+ 'menu-xl': props.xl || props.size === 'xl',
22
+ 'menu-lg': props.lg || props.size === 'lg',
23
+ 'menu-md': props.md || props.size === 'md',
24
+ 'menu-sm': props.sm || props.size === 'sm',
25
+ 'menu-xs': props.xs || props.size === 'xs',
26
+ }"
27
+ >
28
+ <slot />
29
+ </ul>
30
+ </template>
@@ -0,0 +1,100 @@
1
+ <script setup lang="ts">
2
+ import type { Ref } from 'vue'
3
+
4
+ import { onClickOutside, useElementHover } from '@vueuse/core'
5
+ import { onMounted, provide, ref } from 'vue'
6
+ import { randomString } from '../utils/random-string'
7
+
8
+ // Define the MenuExpandState interface
9
+ export interface MenuExpandState {
10
+ id: string
11
+ isOpen: Ref<boolean>
12
+ toggle: () => void
13
+ open: () => void
14
+ close: () => void
15
+ }
16
+
17
+ // Props with defaults
18
+ const {
19
+ randomId = randomString(12),
20
+ hover = false,
21
+ delayLeave = 300,
22
+ closeOnClickOutside = false,
23
+ } = defineProps<{
24
+ randomId?: string
25
+ hover?: boolean
26
+ delayLeave?: number
27
+ closeOnClickOutside?: boolean
28
+ }>()
29
+
30
+ // v-model for open state
31
+ const isOpen = defineModel('open', { default: false, type: Boolean })
32
+
33
+ // Generate IDs for accessibility and targeting
34
+ const wrapperId = `expand-wrapper-${randomId}`
35
+ const id = `expand-${randomId}`
36
+
37
+ // Element reference for click outside detection
38
+ const expandEl = ref()
39
+
40
+ // Control functions
41
+ function toggle() {
42
+ setTimeout(() => {
43
+ isOpen.value = !isOpen.value
44
+ }, 50)
45
+ }
46
+
47
+ function open() {
48
+ isOpen.value = true
49
+ }
50
+
51
+ function close() {
52
+ isOpen.value = false
53
+ }
54
+
55
+ // Create and provide the menu expand state object
56
+ const menuExpandState: MenuExpandState = {
57
+ id,
58
+ isOpen,
59
+ toggle,
60
+ open,
61
+ close,
62
+ }
63
+
64
+ // Provide the state to child components
65
+ provide('menuExpandState', menuExpandState)
66
+
67
+ // Setup event handlers
68
+ onMounted(() => {
69
+ // Handle clicks outside the component
70
+ onClickOutside(expandEl, () => {
71
+ if (closeOnClickOutside) {
72
+ setTimeout(() => {
73
+ isOpen.value = false
74
+ }, 500)
75
+ }
76
+ })
77
+
78
+ // Setup hover behavior if enabled
79
+ if (hover) {
80
+ useElementHover(expandEl, {
81
+ delayLeave,
82
+ })
83
+ }
84
+ })
85
+
86
+ // Empty click handler for internal use
87
+ function handleClick(_ev: MouseEvent) {}
88
+ </script>
89
+
90
+ <template>
91
+ <details
92
+ :id="wrapperId"
93
+ ref="expandEl"
94
+ class="dropdown menu-expand"
95
+ :open="isOpen"
96
+ @click="handleClick"
97
+ >
98
+ <slot v-bind="{ toggle, open, close }" />
99
+ </details>
100
+ </template>
@@ -0,0 +1,14 @@
1
+ <script setup lang="ts">
2
+ import type { MenuExpandState } from './MenuExpand.vue'
3
+
4
+ import { inject } from 'vue'
5
+
6
+ const menuExpandState = inject<MenuExpandState>('menuExpandState')
7
+ const { id, isOpen, toggle } = menuExpandState || {}
8
+ </script>
9
+
10
+ <template>
11
+ <summary :id="id" :aria-expanded="isOpen" aria-haspopup="menu" class="menu-expand-toggle" @click.prevent.stop="toggle">
12
+ <slot />
13
+ </summary>
14
+ </template>