daisy-ui-kit 5.0.0-pre.3 → 5.0.0-pre.31

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 (151) hide show
  1. package/app/components/Accordion.vue +29 -0
  2. package/app/components/Alert.vue +36 -0
  3. package/app/components/Avatar.vue +131 -0
  4. package/app/components/AvatarGroup.vue +22 -0
  5. package/app/components/Badge.vue +72 -0
  6. package/app/components/Breadcrumbs.vue +7 -0
  7. package/app/components/Button.vue +140 -0
  8. package/app/components/Calendar.vue +175 -0
  9. package/app/components/CalendarInput.vue +275 -0
  10. package/app/components/CalendarSkeleton.vue +87 -0
  11. package/app/components/Card.vue +51 -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 +24 -0
  16. package/app/components/CarouselItem.vue +5 -0
  17. package/app/components/Chat.vue +26 -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 +51 -0
  23. package/app/components/Collapse.vue +76 -0
  24. package/app/components/CollapseContent.vue +5 -0
  25. package/app/components/CollapseTitle.vue +15 -0
  26. package/app/components/Countdown.vue +15 -0
  27. package/app/components/CountdownTimers.vue +69 -0
  28. package/app/components/Counter.vue +21 -0
  29. package/app/components/Crumb.vue +5 -0
  30. package/app/components/DaisyLink.vue +56 -0
  31. package/app/components/Diff.vue +11 -0
  32. package/app/components/Divider.vue +43 -0
  33. package/app/components/Dock.vue +57 -0
  34. package/app/components/DockItem.vue +27 -0
  35. package/app/components/DockLabel.vue +5 -0
  36. package/app/components/Drawer.vue +50 -0
  37. package/app/components/DrawerContent.vue +20 -0
  38. package/app/components/DrawerSide.vue +21 -0
  39. package/app/components/Dropdown.vue +106 -0
  40. package/app/components/DropdownButton.vue +23 -0
  41. package/app/components/DropdownContent.vue +127 -0
  42. package/app/components/DropdownTarget.vue +21 -0
  43. package/app/components/Fab.vue +16 -0
  44. package/app/components/FabClose.vue +18 -0
  45. package/app/components/FabMainAction.vue +5 -0
  46. package/app/components/FabTrigger.vue +117 -0
  47. package/app/components/Fieldset.vue +20 -0
  48. package/app/components/FileInput.vue +53 -0
  49. package/app/components/Filter.vue +129 -0
  50. package/app/components/Flex.vue +89 -0
  51. package/app/components/FlexItem.vue +62 -0
  52. package/app/components/Footer.vue +31 -0
  53. package/app/components/FooterTitle.vue +18 -0
  54. package/app/components/FormControl.vue +5 -0
  55. package/app/components/Hero.vue +18 -0
  56. package/app/components/HeroContent.vue +18 -0
  57. package/app/components/HeroOverlay.vue +5 -0
  58. package/app/components/Hover3D.vue +22 -0
  59. package/app/components/HoverGallery.vue +11 -0
  60. package/app/components/Indicator.vue +20 -0
  61. package/app/components/IndicatorItem.vue +43 -0
  62. package/app/components/Input.vue +116 -0
  63. package/app/components/Join.vue +5 -0
  64. package/app/components/Kbd.vue +25 -0
  65. package/app/components/Label.vue +100 -0
  66. package/app/components/List.vue +5 -0
  67. package/app/components/ListColGrow.vue +5 -0
  68. package/app/components/ListColWrap.vue +5 -0
  69. package/app/components/ListRow.vue +5 -0
  70. package/app/components/LoadingBall.vue +42 -0
  71. package/app/components/LoadingBars.vue +42 -0
  72. package/app/components/LoadingDots.vue +42 -0
  73. package/app/components/LoadingInfinity.vue +42 -0
  74. package/app/components/LoadingRing.vue +42 -0
  75. package/app/components/LoadingSpinner.vue +42 -0
  76. package/app/components/Mask.vue +49 -0
  77. package/app/components/Menu.vue +30 -0
  78. package/app/components/MenuExpand.vue +92 -0
  79. package/app/components/MenuExpandToggle.vue +20 -0
  80. package/app/components/MenuItem.vue +39 -0
  81. package/app/components/MenuTitle.vue +5 -0
  82. package/app/components/MockupBrowser.vue +5 -0
  83. package/app/components/MockupBrowserToolbar.vue +5 -0
  84. package/app/components/MockupCode.vue +4 -0
  85. package/app/components/MockupPhone.vue +14 -0
  86. package/app/components/MockupWindow.vue +5 -0
  87. package/app/components/Modal.vue +63 -0
  88. package/app/components/ModalAction.vue +5 -0
  89. package/app/components/ModalBox.vue +5 -0
  90. package/app/components/NavButton.vue +12 -0
  91. package/app/components/Navbar.vue +12 -0
  92. package/app/components/NavbarCenter.vue +11 -0
  93. package/app/components/NavbarEnd.vue +11 -0
  94. package/app/components/NavbarStart.vue +11 -0
  95. package/app/components/Progress.vue +46 -0
  96. package/app/components/Prose.vue +37 -0
  97. package/app/components/RadialProgress.vue +36 -0
  98. package/app/components/Radio.vue +69 -0
  99. package/app/components/RadioGroup.vue +47 -0
  100. package/app/components/Range.vue +201 -0
  101. package/app/components/RangeMeasure.vue +87 -0
  102. package/app/components/RangeMeasureTick.vue +69 -0
  103. package/app/components/Rating.vue +197 -0
  104. package/app/components/Select.vue +101 -0
  105. package/app/components/Skeleton.vue +5 -0
  106. package/app/components/SkeletonText.vue +11 -0
  107. package/app/components/Stack.vue +30 -0
  108. package/app/components/Stat.vue +19 -0
  109. package/app/components/StatActions.vue +5 -0
  110. package/app/components/StatDesc.vue +5 -0
  111. package/app/components/StatFigure.vue +5 -0
  112. package/app/components/StatTitle.vue +5 -0
  113. package/app/components/StatValue.vue +5 -0
  114. package/app/components/Stats.vue +5 -0
  115. package/app/components/Status.vue +43 -0
  116. package/app/components/Step.vue +34 -0
  117. package/app/components/StepIcon.vue +5 -0
  118. package/app/components/Steps.vue +23 -0
  119. package/app/components/Swap.vue +56 -0
  120. package/app/components/Tab.vue +56 -0
  121. package/app/components/TabContent.vue +29 -0
  122. package/app/components/Table.vue +32 -0
  123. package/app/components/Tabs.vue +53 -0
  124. package/app/components/Text.vue +166 -0
  125. package/app/components/TextArea.vue +106 -0
  126. package/app/components/TextRotate.vue +24 -0
  127. package/app/components/ThemeController.vue +45 -0
  128. package/app/components/ThemeProvider.vue +302 -0
  129. package/app/components/ThemeTile.vue +50 -0
  130. package/app/components/Timeline.vue +22 -0
  131. package/app/components/TimelineEnd.vue +14 -0
  132. package/app/components/TimelineItem.vue +5 -0
  133. package/app/components/TimelineLine.vue +29 -0
  134. package/app/components/TimelineMiddle.vue +5 -0
  135. package/app/components/TimelineStart.vue +14 -0
  136. package/app/components/Toast.vue +67 -0
  137. package/app/components/Toggle.vue +60 -0
  138. package/app/components/Tooltip.vue +137 -0
  139. package/app/components/TooltipContent.vue +283 -0
  140. package/app/components/TooltipTarget.vue +20 -0
  141. package/app/components/ValidatorHint.vue +5 -0
  142. package/app/composables/__tests__/use-calendar.test.ts +239 -0
  143. package/app/composables/use-calendar.ts +288 -0
  144. package/app/composables/use-daisy-theme.ts +140 -0
  145. package/app/composables/use-toast.ts +345 -0
  146. package/app/composables/useSearch.ts +22 -0
  147. package/app/utils/drawer-utils.ts +34 -0
  148. package/app/utils/position-area.ts +40 -0
  149. package/nuxt.d.ts +13 -0
  150. package/nuxt.js +31 -0
  151. package/package.json +50 -22
@@ -0,0 +1,201 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ const props = withDefaults(
5
+ defineProps<{
6
+ modelValue?: number | [number, number]
7
+ min?: number
8
+ max?: number
9
+ step?: number
10
+ disabled?: boolean
11
+
12
+ color?: string
13
+ neutral?: boolean
14
+ primary?: boolean
15
+ secondary?: boolean
16
+ accent?: boolean
17
+ success?: boolean
18
+ warning?: boolean
19
+ info?: boolean
20
+ error?: boolean
21
+
22
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
23
+ xl?: boolean
24
+ lg?: boolean
25
+ md?: boolean
26
+ sm?: boolean
27
+ xs?: boolean
28
+ }>(),
29
+ {
30
+ min: 0,
31
+ max: 100,
32
+ step: 1,
33
+ },
34
+ )
35
+ const emit = defineEmits(['update:modelValue'])
36
+
37
+ const isRange = computed(() => {
38
+ return Array.isArray(props.modelValue)
39
+ })
40
+
41
+ const singleValue = computed({
42
+ get: () => (isRange.value ? 0 : (props.modelValue as number)),
43
+ set: val => emit('update:modelValue', Number(val)),
44
+ })
45
+
46
+ const lowValue = computed({
47
+ get: () => (isRange.value ? (props.modelValue as [number, number])[0] : 0),
48
+ set: val => {
49
+ const v = Number(val)
50
+ const high = (props.modelValue as [number, number])[1]
51
+ emit('update:modelValue', [Math.min(v, high), high])
52
+ },
53
+ })
54
+
55
+ const highValue = computed({
56
+ get: () => (isRange.value ? (props.modelValue as [number, number])[1] : 100),
57
+ set: val => {
58
+ const v = Number(val)
59
+ const low = (props.modelValue as [number, number])[0]
60
+ emit('update:modelValue', [low, Math.max(v, low)])
61
+ },
62
+ })
63
+
64
+ const rangeClasses = computed(() => ({
65
+ 'range-neutral': props.neutral || props.color === 'neutral',
66
+ 'range-primary': props.primary || props.color === 'primary',
67
+ 'range-secondary': props.secondary || props.color === 'secondary',
68
+ 'range-accent': props.accent || props.color === 'accent',
69
+ 'range-success': props.success || props.color === 'success',
70
+ 'range-info': props.info || props.color === 'info',
71
+ 'range-warning': props.warning || props.color === 'warning',
72
+ 'range-error': props.error || props.color === 'error',
73
+ 'range-xl': props.xl || props.size === 'xl',
74
+ 'range-lg': props.lg || props.size === 'lg',
75
+ 'range-md': props.md || props.size === 'md',
76
+ 'range-sm': props.sm || props.size === 'sm',
77
+ 'range-xs': props.xs || props.size === 'xs',
78
+ }))
79
+
80
+ // Calculate percentage positions for the filled track
81
+ const lowPercent = computed(() => {
82
+ const range = props.max - props.min
83
+ return ((lowValue.value - props.min) / range) * 100
84
+ })
85
+
86
+ const highPercent = computed(() => {
87
+ const range = props.max - props.min
88
+ return ((highValue.value - props.min) / range) * 100
89
+ })
90
+ </script>
91
+
92
+ <template>
93
+ <!-- Single value mode -->
94
+ <input
95
+ v-if="!isRange"
96
+ v-model="singleValue"
97
+ type="range"
98
+ class="range"
99
+ :class="rangeClasses"
100
+ :min="min"
101
+ :max="max"
102
+ :step="step"
103
+ :disabled="disabled"
104
+ />
105
+
106
+ <!-- Dual handle range mode -->
107
+ <div v-else class="range range-slider-wrapper" :class="rangeClasses">
108
+ <div class="range-slider-track" />
109
+ <div
110
+ class="range-slider-fill"
111
+ :style="{
112
+ left: `calc(${lowPercent}% + (var(--range-thumb-size, 1.5rem) / 2) - (${lowPercent} * var(--range-thumb-size, 1.5rem) / 100))`,
113
+ width: `calc(${highPercent - lowPercent}% - (${highPercent - lowPercent} * var(--range-thumb-size, 1.5rem) / 100))`,
114
+ }"
115
+ />
116
+ <input
117
+ v-model="lowValue"
118
+ type="range"
119
+ class="range range-slider-input"
120
+ :class="rangeClasses"
121
+ :min="min"
122
+ :max="max"
123
+ :step="step"
124
+ :disabled="disabled"
125
+ />
126
+ <input
127
+ v-model="highValue"
128
+ type="range"
129
+ class="range range-slider-input"
130
+ :class="rangeClasses"
131
+ :min="min"
132
+ :max="max"
133
+ :step="step"
134
+ :disabled="disabled"
135
+ />
136
+ </div>
137
+ </template>
138
+
139
+ <style>
140
+ .range-slider-wrapper {
141
+ position: relative;
142
+ width: 100%;
143
+ height: var(--range-thumb-size, 1.5rem);
144
+ }
145
+
146
+ .range-slider-track {
147
+ position: absolute;
148
+ top: 50%;
149
+ left: 0;
150
+ right: 0;
151
+ height: calc(var(--range-thumb-size, 1.5rem) / 3);
152
+ transform: translateY(-50%);
153
+ background: color-mix(in oklab, currentColor 10%, transparent);
154
+ border-radius: var(--radius-selector, 1rem);
155
+ }
156
+
157
+ .range-slider-fill {
158
+ position: absolute;
159
+ top: 50%;
160
+ height: var(--range-thumb-size, 1.5rem);
161
+ transform: translateY(-50%);
162
+ background: currentColor;
163
+ border-radius: 0;
164
+ z-index: 1;
165
+ }
166
+
167
+ .range-slider-input {
168
+ position: absolute;
169
+ top: 0;
170
+ left: 0;
171
+ width: 100%;
172
+ height: 100%;
173
+ pointer-events: none;
174
+ background: transparent;
175
+ --range-fill: 0 !important;
176
+ }
177
+
178
+ /* Hide both tracks - we draw our own */
179
+ .range-slider-input::-webkit-slider-runnable-track {
180
+ background: transparent !important;
181
+ box-shadow: none !important;
182
+ }
183
+
184
+ .range-slider-input::-moz-range-track {
185
+ background: transparent !important;
186
+ box-shadow: none !important;
187
+ }
188
+
189
+ /* Enable pointer events only on thumbs */
190
+ .range-slider-input::-webkit-slider-thumb {
191
+ pointer-events: auto;
192
+ position: relative;
193
+ z-index: 3;
194
+ }
195
+
196
+ .range-slider-input::-moz-range-thumb {
197
+ pointer-events: auto;
198
+ position: relative;
199
+ z-index: 3;
200
+ }
201
+ </style>
@@ -0,0 +1,87 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ const props = withDefaults(
5
+ defineProps<{
6
+ modelValue?: number | string
7
+ min?: number | string
8
+ max?: number | string
9
+ step?: number | string
10
+
11
+ numbered?: boolean
12
+ asButtons?: boolean
13
+ disabled?: boolean
14
+
15
+ color?: string
16
+ neutral?: boolean
17
+ primary?: boolean
18
+ secondary?: boolean
19
+ accent?: boolean
20
+ success?: boolean
21
+ warning?: boolean
22
+ info?: boolean
23
+ error?: boolean
24
+
25
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
26
+ xl?: boolean
27
+ lg?: boolean
28
+ md?: boolean
29
+ sm?: boolean
30
+ xs?: boolean
31
+ }>(),
32
+ {
33
+ min: 0,
34
+ max: 100,
35
+ step: 1,
36
+ },
37
+ )
38
+ defineEmits(['update:modelValue'])
39
+
40
+ const values = computed(() => {
41
+ const vals = []
42
+ for (let index = Number.parseInt(props.min as string); index < Number.parseInt(props.max as string) + 1; index++) {
43
+ vals.push({
44
+ value: index,
45
+ isVisible: index % Number.parseInt(props.step as string) === 0,
46
+ })
47
+ }
48
+ return vals
49
+ })
50
+ // const count = computed(() => Number.parseInt(props.max as string) - Number.parseInt(props.min as string))
51
+ </script>
52
+
53
+ <template>
54
+ <div
55
+ class="flex justify-between select-none"
56
+ :class="{
57
+ 'text-neutral': neutral || color === 'neutral',
58
+ 'text-primary': primary || color === 'primary',
59
+ 'text-secondary': secondary || color === 'secondary',
60
+ 'text-accent': accent || color === 'accent',
61
+ 'text-success': success || color === 'success',
62
+ 'text-info': info || color === 'info',
63
+ 'text-warning': warning || color === 'warning',
64
+ 'text-error': error || color === 'error',
65
+ 'text-xl': xl || size === 'xl',
66
+ 'text-lg': lg || size === 'lg',
67
+ 'text-md': md || size === 'md',
68
+ 'text-sm': sm || size === 'sm',
69
+ 'text-xs': xs || size === 'xs',
70
+ 'opacity-50': disabled,
71
+ }"
72
+ >
73
+ <RangeMeasureTick
74
+ v-for="tick in values"
75
+ :key="tick.value"
76
+ :tick="tick.value"
77
+ :model-value="modelValue"
78
+ :numbered="numbered"
79
+ :as-button="asButtons"
80
+ :is-hidden="!tick.isVisible"
81
+ :disabled="disabled"
82
+ @update:model-value="val => !disabled && $emit('update:modelValue', val)"
83
+ >
84
+ {{ numbered ? tick : '|' }}
85
+ </RangeMeasureTick>
86
+ </div>
87
+ </template>
@@ -0,0 +1,69 @@
1
+ <script setup lang="ts">
2
+ import { useTimeoutFn } from '@vueuse/core'
3
+ import { computed, ref, watch } from 'vue'
4
+
5
+ const props = defineProps<{
6
+ tick: number
7
+ modelValue?: number | string
8
+ numbered?: boolean
9
+ asButton?: boolean
10
+ isHidden?: boolean
11
+ disabled?: boolean
12
+ }>()
13
+ defineEmits(['update:modelValue'])
14
+
15
+ const hasChanged = ref(false)
16
+ const { isPending, start, stop } = useTimeoutFn(() => {
17
+ hasChanged.value = false
18
+ }, 1000)
19
+ watch(
20
+ () => props.modelValue,
21
+ val => {
22
+ if (val) {
23
+ start()
24
+ hasChanged.value = true
25
+ } else if (!isPending.value) {
26
+ stop()
27
+ }
28
+ },
29
+ )
30
+
31
+ // eslint-disable-next-line eqeqeq
32
+ const isCurrent = computed(() => props.modelValue == props.tick)
33
+ </script>
34
+
35
+ <template>
36
+ <Button
37
+ v-if="asButton && !isHidden"
38
+ xs
39
+ :ghost="!isCurrent"
40
+ circle
41
+ :class="{
42
+ 'font-bold': isCurrent,
43
+ 'opacity-50': props.disabled,
44
+ 'cursor-pointer': !props.disabled,
45
+ 'cursor-not-allowed': props.disabled,
46
+ }"
47
+ :disabled="disabled"
48
+ @click="$emit('update:modelValue', tick)"
49
+ >
50
+ {{ numbered ? tick : '|' }}
51
+ </Button>
52
+ <Tooltip
53
+ v-else
54
+ :tip="tick"
55
+ :open="hasChanged && isCurrent && !disabled"
56
+ position="bottom"
57
+ :class="{
58
+ 'px-[2px]': !asButton,
59
+ 'opacity-50': disabled,
60
+ 'cursor-pointer': !disabled,
61
+ 'cursor-not-allowed': disabled,
62
+ }"
63
+ @click="$emit('update:modelValue', tick)"
64
+ >
65
+ <Text v-if="!isHidden" :black="isCurrent">
66
+ {{ numbered ? tick : '|' }}
67
+ </Text>
68
+ </Tooltip>
69
+ </template>
@@ -0,0 +1,197 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ const props = withDefaults(
5
+ defineProps<{
6
+ modelValue?: number | string
7
+ count?: number | string
8
+ half?: boolean
9
+
10
+ disabled?: boolean
11
+
12
+ color?: string
13
+ neutral?: boolean
14
+ primary?: boolean
15
+ secondary?: boolean
16
+ accent?: boolean
17
+ info?: boolean
18
+ success?: boolean
19
+ warning?: boolean
20
+ error?: boolean
21
+
22
+ bg?: string
23
+
24
+ shape?: string
25
+ squircle?: boolean
26
+ heart?: boolean
27
+ hexagon?: boolean
28
+ hexagon2?: boolean
29
+ decagon?: boolean
30
+ pentagon?: boolean
31
+ diamond?: boolean
32
+ square?: boolean
33
+ circle?: boolean
34
+
35
+ star?: boolean
36
+ star2?: boolean
37
+ triangle?: boolean
38
+ triangle2?: boolean
39
+ triangle3?: boolean
40
+ triangle4?: boolean
41
+
42
+ size?: 'lg' | 'md' | 'sm' | 'xs' | 'xl'
43
+ xl?: boolean
44
+ lg?: boolean
45
+ md?: boolean
46
+ sm?: boolean
47
+ xs?: boolean
48
+ }>(),
49
+ {
50
+ count: 5,
51
+ },
52
+ )
53
+ const emit = defineEmits(['update:modelValue'])
54
+
55
+ const max = computed(() => Number.parseInt(props.count as string))
56
+
57
+ function handleValue(digit: number, half = false) {
58
+ if (props.disabled) {
59
+ return
60
+ }
61
+
62
+ if (props.half) {
63
+ emit('update:modelValue', half ? digit - 0.5 : digit)
64
+ return
65
+ }
66
+
67
+ emit('update:modelValue', digit)
68
+ }
69
+
70
+ // Check if any shape prop is set
71
+ const hasShape = computed(() => {
72
+ return (
73
+ props.shape ||
74
+ props.squircle ||
75
+ props.heart ||
76
+ props.hexagon ||
77
+ props.hexagon2 ||
78
+ props.decagon ||
79
+ props.pentagon ||
80
+ props.diamond ||
81
+ props.square ||
82
+ props.circle ||
83
+ props.star ||
84
+ props.star2 ||
85
+ props.triangle ||
86
+ props.triangle2 ||
87
+ props.triangle3 ||
88
+ props.triangle4
89
+ )
90
+ })
91
+ </script>
92
+
93
+ <template>
94
+ <div
95
+ class="rating"
96
+ :class="{
97
+ 'rating-half': half,
98
+ 'rating-xl': xl || size === 'xl',
99
+ 'rating-lg': lg || size === 'lg',
100
+ 'rating-md': md || size === 'md',
101
+ 'rating-sm': sm || size === 'sm',
102
+ 'rating-xs': xs || size === 'xs',
103
+ 'opacity-60': disabled,
104
+ 'cursor-not-allowed': disabled,
105
+ }"
106
+ >
107
+ <input
108
+ type="radio"
109
+ :value="0"
110
+ class="rating-hidden"
111
+ :checked="modelValue === 0"
112
+ @change="$emit('update:modelValue', 0)"
113
+ />
114
+ <template v-for="digit in max" :key="digit">
115
+ <input
116
+ type="radio"
117
+ :value="half ? digit - 0.5 : digit"
118
+ :disabled="disabled"
119
+ class="mask"
120
+ :class="[
121
+ bg,
122
+ { 'mask-half-1': half },
123
+ { 'cursor-not-allowed opacity-50': disabled },
124
+
125
+ // Color classes
126
+ { 'bg-neutral': neutral || color === 'neutral' },
127
+ { 'bg-primary': primary || color === 'primary' },
128
+ { 'bg-secondary': secondary || color === 'secondary' },
129
+ { 'bg-accent': accent || color === 'accent' },
130
+ { 'bg-info': info || color === 'info' },
131
+ { 'bg-success': success || color === 'success' },
132
+ { 'bg-warning': warning || color === 'warning' },
133
+ { 'bg-error': error || color === 'error' },
134
+
135
+ // Shape classes
136
+ { 'mask-squircle': squircle || shape === 'squircle' },
137
+ { 'mask-heart': heart || shape === 'heart' },
138
+ { 'mask-hexagon': hexagon || shape === 'hexagon' },
139
+ { 'mask-hexagon-2': hexagon2 || shape === 'hexagon-2' },
140
+ { 'mask-decagon': decagon || shape === 'decagon' },
141
+ { 'mask-pentagon': pentagon || shape === 'pentagon' },
142
+ { 'mask-diamond': diamond || shape === 'diamond' },
143
+ { 'mask-square': square || shape === 'square' },
144
+ { 'mask-circle': circle || shape === 'circle' },
145
+ { 'mask-star': star || shape === 'star' },
146
+ { 'mask-star-2': star2 || shape === 'star-2' || !hasShape },
147
+ { 'mask-triangle': triangle || shape === 'triangle' },
148
+ { 'mask-triangle-2': triangle2 || shape === 'triangle-2' },
149
+ { 'mask-triangle-3': triangle3 || shape === 'triangle-3' },
150
+ { 'mask-triangle-4': triangle4 || shape === 'triangle-4' },
151
+ ]"
152
+ :checked="half ? modelValue === digit - 0.5 : modelValue === digit"
153
+ @change="() => handleValue(digit, true)"
154
+ />
155
+ <input
156
+ v-if="half"
157
+ type="radio"
158
+ :value="digit"
159
+ class="mask mask-half-2"
160
+ :disabled="disabled"
161
+ :class="[
162
+ bg,
163
+ { 'cursor-not-allowed opacity-50': disabled },
164
+
165
+ // Color classes
166
+ { 'bg-neutral': neutral || color === 'neutral' },
167
+ { 'bg-primary': primary || color === 'primary' },
168
+ { 'bg-secondary': secondary || color === 'secondary' },
169
+ { 'bg-accent': accent || color === 'accent' },
170
+ { 'bg-info': info || color === 'info' },
171
+ { 'bg-success': success || color === 'success' },
172
+ { 'bg-warning': warning || color === 'warning' },
173
+ { 'bg-error': error || color === 'error' },
174
+
175
+ // Shape classes
176
+ { 'mask-squircle': squircle || shape === 'squircle' },
177
+ { 'mask-heart': heart || shape === 'heart' },
178
+ { 'mask-hexagon': hexagon || shape === 'hexagon' },
179
+ { 'mask-hexagon-2': hexagon2 || shape === 'hexagon-2' },
180
+ { 'mask-decagon': decagon || shape === 'decagon' },
181
+ { 'mask-pentagon': pentagon || shape === 'pentagon' },
182
+ { 'mask-diamond': diamond || shape === 'diamond' },
183
+ { 'mask-square': square || shape === 'square' },
184
+ { 'mask-circle': circle || shape === 'circle' },
185
+ { 'mask-star': star || shape === 'star' },
186
+ { 'mask-star-2': star2 || shape === 'star-2' || !hasShape },
187
+ { 'mask-triangle': triangle || shape === 'triangle' },
188
+ { 'mask-triangle-2': triangle2 || shape === 'triangle-2' },
189
+ { 'mask-triangle-3': triangle3 || shape === 'triangle-3' },
190
+ { 'mask-triangle-4': triangle4 || shape === 'triangle-4' },
191
+ ]"
192
+ :checked="modelValue === digit"
193
+ @change="() => handleValue(digit)"
194
+ />
195
+ </template>
196
+ </div>
197
+ </template>
@@ -0,0 +1,101 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ type Color = 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'
5
+
6
+ const props = withDefaults(
7
+ defineProps<{
8
+ modelValue: any
9
+ options: Record<string, any>[] | any[]
10
+ value?: (val: any) => any
11
+ label?: (val: any) => any
12
+ resultAsObject?: boolean
13
+ join?: boolean
14
+
15
+ ghost?: boolean
16
+ disabled?: boolean
17
+ validator?: boolean
18
+ native?: boolean
19
+
20
+ color?: Color
21
+ neutral?: boolean
22
+ primary?: boolean
23
+ secondary?: boolean
24
+ accent?: boolean
25
+ info?: boolean
26
+ success?: boolean
27
+ warning?: boolean
28
+ error?: boolean
29
+
30
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
31
+ xl?: boolean
32
+ lg?: boolean
33
+ md?: boolean
34
+ sm?: boolean
35
+ xs?: boolean
36
+ }>(),
37
+ {
38
+ value: (val: any) => {
39
+ if (val == null) {
40
+ return null
41
+ }
42
+
43
+ return typeof val === 'string' ? (val as string) : (val?.value ?? val?.id ?? val?._id ?? val)
44
+ },
45
+ label: (val: any) => (typeof val === 'string' ? (val as string) : val.label || val.name || val.title),
46
+ resultAsObject: false,
47
+ },
48
+ )
49
+ const emit = defineEmits(['update:modelValue'])
50
+
51
+ const computedVModel = computed({
52
+ get: () => {
53
+ if (props.resultAsObject && props.modelValue != null) {
54
+ return props.value(props.modelValue)
55
+ }
56
+
57
+ return props.modelValue
58
+ },
59
+ set: val => {
60
+ if (val === undefined) {
61
+ val = null
62
+ }
63
+ if (props.resultAsObject && val != null) {
64
+ val = props.options.find(o => props.value(o) === val)
65
+ }
66
+
67
+ emit('update:modelValue', val)
68
+ },
69
+ })
70
+ </script>
71
+
72
+ <template>
73
+ <select
74
+ v-model="computedVModel"
75
+ class="select"
76
+ :class="{
77
+ 'join-item': props.join,
78
+ validator: props.validator,
79
+ 'select-ghost': props.ghost,
80
+ 'appearance-none': props.native,
81
+ 'select-neutral': props.neutral || props.color === 'neutral',
82
+ 'select-primary': props.primary || props.color === 'primary',
83
+ 'select-secondary': props.secondary || props.color === 'secondary',
84
+ 'select-accent': props.accent || props.color === 'accent',
85
+ 'select-info': props.info || props.color === 'info',
86
+ 'select-success': props.success || props.color === 'success',
87
+ 'select-warning': props.warning || props.color === 'warning',
88
+ 'select-error': props.error || props.color === 'error',
89
+ 'select-xl': props.xl || props.size === 'xl',
90
+ 'select-lg': props.lg || props.size === 'lg',
91
+ 'select-md': props.md || props.size === 'md',
92
+ 'select-sm': props.sm || props.size === 'sm',
93
+ 'select-xs': props.xs || props.size === 'xs',
94
+ }"
95
+ :disabled="disabled"
96
+ >
97
+ <option v-for="option in options" :key="value(option)" :value="value(option)" :disabled="option.disabled">
98
+ {{ label(option) }}
99
+ </option>
100
+ </select>
101
+ </template>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div class="skeleton">
3
+ <slot />
4
+ </div>
5
+ </template>
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ is?: any
4
+ }>()
5
+ </script>
6
+
7
+ <template>
8
+ <component :is="props.is || 'span'" class="skeleton skeleton-text">
9
+ <slot />
10
+ </component>
11
+ </template>
@@ -0,0 +1,30 @@
1
+ <script setup lang="ts">
2
+ defineOptions({
3
+ inheritAttrs: false,
4
+ })
5
+
6
+ const { is = 'div' } = defineProps<{
7
+ is?: string
8
+ direction?: 'top' | 'end' | 'bottom' | 'start'
9
+ top?: boolean
10
+ end?: boolean
11
+ bottom?: boolean
12
+ start?: boolean
13
+ }>()
14
+ </script>
15
+
16
+ <template>
17
+ <component
18
+ :is="is"
19
+ v-bind="$attrs"
20
+ class="stack"
21
+ :class="{
22
+ 'stack-top': top || direction === 'top',
23
+ 'stack-end': end || direction === 'end',
24
+ 'stack-bottom': bottom || direction === 'bottom',
25
+ 'stack-start': start || direction === 'start',
26
+ }"
27
+ >
28
+ <slot />
29
+ </component>
30
+ </template>