daisy-ui-kit 3.0.12 → 5.0.0-pre.11

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 (213) hide show
  1. package/README.md +62 -14
  2. package/app/components/Accordion.vue +29 -0
  3. package/app/components/Alert.vue +36 -0
  4. package/app/components/Avatar.vue +131 -0
  5. package/app/components/AvatarGroup.vue +22 -0
  6. package/app/components/Badge.vue +67 -0
  7. package/app/components/Button.vue +135 -0
  8. package/app/components/Calendar.vue +89 -0
  9. package/app/components/CalendarInput.vue +174 -0
  10. package/app/components/CalendarSkeleton.vue +87 -0
  11. package/app/components/Card.vue +46 -0
  12. package/{components → app/components}/CardActions.vue +2 -5
  13. package/{components → app/components}/CardBody.vue +2 -5
  14. package/{components → app/components}/CardTitle.vue +1 -6
  15. package/app/components/Carousel.vue +24 -0
  16. package/app/components/Chat.vue +26 -0
  17. package/app/components/ChatBubble.vue +31 -0
  18. package/app/components/Checkbox.vue +51 -0
  19. package/app/components/Collapse.vue +75 -0
  20. package/app/components/CollapseTitle.vue +15 -0
  21. package/{components → app/components}/Countdown.vue +1 -1
  22. package/app/components/CountdownTimers.vue +69 -0
  23. package/app/components/Counter.vue +21 -0
  24. package/app/components/DaisyLink.vue +52 -0
  25. package/app/components/Diff.vue +11 -0
  26. package/app/components/Divider.vue +43 -0
  27. package/app/components/Dock.vue +60 -0
  28. package/app/components/DockItem.vue +26 -0
  29. package/app/components/DockLabel.vue +5 -0
  30. package/{components → app/components}/Drawer.vue +17 -12
  31. package/{components → app/components}/DrawerContent.vue +8 -5
  32. package/{components → app/components}/DrawerSide.vue +8 -5
  33. package/app/components/Dropdown.vue +106 -0
  34. package/app/components/DropdownButton.vue +23 -0
  35. package/app/components/DropdownContent.vue +127 -0
  36. package/{components → app/components}/DropdownTarget.vue +9 -2
  37. package/app/components/Fab.vue +16 -0
  38. package/app/components/FabClose.vue +18 -0
  39. package/app/components/FabMainAction.vue +5 -0
  40. package/app/components/FabTrigger.vue +117 -0
  41. package/app/components/Fieldset.vue +16 -0
  42. package/app/components/FileInput.vue +53 -0
  43. package/app/components/Filter.vue +125 -0
  44. package/app/components/Flex.vue +84 -0
  45. package/{components → app/components}/FlexItem.vue +30 -27
  46. package/app/components/Footer.vue +31 -0
  47. package/{components → app/components}/FooterTitle.vue +8 -5
  48. package/app/components/FormControl.vue +5 -0
  49. package/{components → app/components}/Hero.vue +8 -5
  50. package/{components → app/components}/HeroContent.vue +8 -5
  51. package/app/components/Hover3D.vue +22 -0
  52. package/app/components/HoverGallery.vue +11 -0
  53. package/{components → app/components}/Indicator.vue +8 -5
  54. package/{components → app/components}/IndicatorItem.vue +16 -13
  55. package/app/components/Input.vue +126 -0
  56. package/app/components/Kbd.vue +25 -0
  57. package/app/components/Label.vue +100 -0
  58. package/{components/CollapseTitle.vue → app/components/List.vue} +1 -1
  59. package/{components/FormControl.vue → app/components/ListColGrow.vue} +1 -1
  60. package/app/components/ListColWrap.vue +5 -0
  61. package/{components/Stat.vue → app/components/ListRow.vue} +1 -1
  62. package/app/components/LoadingBall.vue +42 -0
  63. package/app/components/LoadingBars.vue +42 -0
  64. package/app/components/LoadingDots.vue +42 -0
  65. package/app/components/LoadingInfinity.vue +42 -0
  66. package/app/components/LoadingRing.vue +42 -0
  67. package/app/components/LoadingSpinner.vue +42 -0
  68. package/app/components/Mask.vue +49 -0
  69. package/app/components/Menu.vue +30 -0
  70. package/app/components/MenuExpand.vue +94 -0
  71. package/app/components/MenuExpandToggle.vue +20 -0
  72. package/{components → app/components}/MenuItem.vue +7 -6
  73. package/app/components/MockupPhone.vue +14 -0
  74. package/{components → app/components}/Modal.vue +28 -13
  75. package/app/components/NavButton.vue +12 -0
  76. package/{components → app/components}/Navbar.vue +3 -5
  77. package/{components → app/components}/NavbarCenter.vue +3 -5
  78. package/{components → app/components}/NavbarEnd.vue +3 -5
  79. package/{components → app/components}/NavbarStart.vue +3 -5
  80. package/app/components/Progress.vue +46 -0
  81. package/{components → app/components}/Prose.vue +8 -3
  82. package/app/components/RadialProgress.vue +36 -0
  83. package/app/components/Radio.vue +69 -0
  84. package/{components → app/components}/RadioGroup.vue +2 -1
  85. package/app/components/Range.vue +61 -0
  86. package/app/components/RangeMeasure.vue +87 -0
  87. package/{components → app/components}/RangeMeasureTick.vue +9 -14
  88. package/app/components/Rating.vue +197 -0
  89. package/app/components/Select.vue +101 -0
  90. package/app/components/Skeleton.vue +5 -0
  91. package/app/components/SkeletonText.vue +11 -0
  92. package/app/components/Stack.vue +25 -0
  93. package/app/components/Stat.vue +19 -0
  94. package/app/components/Status.vue +43 -0
  95. package/app/components/Step.vue +34 -0
  96. package/app/components/StepIcon.vue +5 -0
  97. package/app/components/Steps.vue +23 -0
  98. package/app/components/Swap.vue +56 -0
  99. package/app/components/Tab.vue +51 -0
  100. package/{components → app/components}/TabContent.vue +10 -10
  101. package/app/components/Table.vue +32 -0
  102. package/app/components/Tabs.vue +53 -0
  103. package/app/components/Text.vue +162 -0
  104. package/app/components/TextArea.vue +64 -0
  105. package/app/components/TextRotate.vue +24 -0
  106. package/app/components/ThemeController.vue +45 -0
  107. package/app/components/ThemeProvider.vue +302 -0
  108. package/app/components/ThemeTile.vue +50 -0
  109. package/app/components/Timeline.vue +22 -0
  110. package/app/components/TimelineEnd.vue +14 -0
  111. package/app/components/TimelineItem.vue +5 -0
  112. package/app/components/TimelineLine.vue +29 -0
  113. package/app/components/TimelineMiddle.vue +5 -0
  114. package/app/components/TimelineStart.vue +14 -0
  115. package/app/components/Toast.vue +67 -0
  116. package/app/components/Toggle.vue +60 -0
  117. package/app/components/Tooltip.vue +48 -0
  118. package/app/components/TooltipContent.vue +5 -0
  119. package/app/components/ValidatorHint.vue +5 -0
  120. package/{utils → app/utils}/drawer-utils.ts +15 -13
  121. package/app/utils/position-area.ts +41 -0
  122. package/nuxt.js +7 -1
  123. package/package.json +60 -61
  124. package/components/Accordion.vue +0 -29
  125. package/components/Alert.vue +0 -25
  126. package/components/Artboard.vue +0 -33
  127. package/components/Avatar.vue +0 -70
  128. package/components/AvatarGroup.vue +0 -19
  129. package/components/Badge.vue +0 -50
  130. package/components/BottomNav.vue +0 -25
  131. package/components/Button.vue +0 -111
  132. package/components/Card.vue +0 -30
  133. package/components/Carousel.vue +0 -25
  134. package/components/Chat.vue +0 -27
  135. package/components/ChatBubble.vue +0 -34
  136. package/components/Checkbox.vue +0 -55
  137. package/components/Code.vue +0 -92
  138. package/components/Collapse.vue +0 -54
  139. package/components/CountdownTimers.vue +0 -70
  140. package/components/Counter.vue +0 -14
  141. package/components/Divider.vue +0 -24
  142. package/components/Dropdown.vue +0 -95
  143. package/components/DropdownButton.vue +0 -16
  144. package/components/DropdownContent.vue +0 -56
  145. package/components/FileInput.vue +0 -59
  146. package/components/Flex.vue +0 -59
  147. package/components/Footer.vue +0 -24
  148. package/components/Kbd.vue +0 -25
  149. package/components/Label.vue +0 -15
  150. package/components/LabelText.vue +0 -15
  151. package/components/LabelTextAlt.vue +0 -15
  152. package/components/Link.vue +0 -40
  153. package/components/LoadingBall.vue +0 -43
  154. package/components/LoadingBars.vue +0 -43
  155. package/components/LoadingDots.vue +0 -43
  156. package/components/LoadingInfinity.vue +0 -43
  157. package/components/LoadingRing.vue +0 -43
  158. package/components/LoadingSpinner.vue +0 -43
  159. package/components/Mask.config.ts +0 -77
  160. package/components/Mask.vue +0 -14
  161. package/components/Menu.vue +0 -35
  162. package/components/MenuExpand.vue +0 -79
  163. package/components/MenuExpandToggle.vue +0 -13
  164. package/components/MockupPhone.vue +0 -8
  165. package/components/NavButton.vue +0 -20
  166. package/components/Progress.vue +0 -42
  167. package/components/RadialProgress.vue +0 -41
  168. package/components/Radio.vue +0 -76
  169. package/components/Range.vue +0 -60
  170. package/components/RangeMeasure.vue +0 -83
  171. package/components/Rating.vue +0 -167
  172. package/components/Select.vue +0 -100
  173. package/components/Stack.vue +0 -13
  174. package/components/Step.vue +0 -36
  175. package/components/Steps.vue +0 -21
  176. package/components/Swap.vue +0 -58
  177. package/components/Tab.vue +0 -48
  178. package/components/Tabs.vue +0 -77
  179. package/components/TabsManager.vue +0 -38
  180. package/components/Text.vue +0 -142
  181. package/components/TextArea.vue +0 -64
  182. package/components/TextInput.vue +0 -66
  183. package/components/Toast.vue +0 -31
  184. package/components/Toggle.vue +0 -59
  185. package/components/Tooltip.vue +0 -47
  186. package/index.ts +0 -108
  187. package/utils/-utils.ts +0 -41
  188. package/utils/Button.config.ts +0 -26
  189. package/utils/fixtures.ts +0 -62
  190. package/utils/types.ts +0 -7
  191. /package/{components → app/components}/Breadcrumbs.vue +0 -0
  192. /package/{components → app/components}/CarouselItem.vue +0 -0
  193. /package/{components → app/components}/ChatFooter.vue +0 -0
  194. /package/{components → app/components}/ChatHeader.vue +0 -0
  195. /package/{components → app/components}/ChatImage.vue +0 -0
  196. /package/{components → app/components}/CollapseContent.vue +0 -0
  197. /package/{components → app/components}/Crumb.vue +0 -0
  198. /package/{components → app/components}/HeroOverlay.vue +0 -0
  199. /package/{components → app/components}/Join.vue +0 -0
  200. /package/{components → app/components}/MenuTitle.vue +0 -0
  201. /package/{components → app/components}/MockupBrowser.vue +0 -0
  202. /package/{components → app/components}/MockupBrowserToolbar.vue +0 -0
  203. /package/{components → app/components}/MockupCode.vue +0 -0
  204. /package/{components → app/components}/MockupWindow.vue +0 -0
  205. /package/{components → app/components}/ModalAction.vue +0 -0
  206. /package/{components → app/components}/ModalBox.vue +0 -0
  207. /package/{components → app/components}/StatActions.vue +0 -0
  208. /package/{components → app/components}/StatDesc.vue +0 -0
  209. /package/{components → app/components}/StatFigure.vue +0 -0
  210. /package/{components → app/components}/StatTitle.vue +0 -0
  211. /package/{components → app/components}/StatValue.vue +0 -0
  212. /package/{components → app/components}/Stats.vue +0 -0
  213. /package/{utils → app/utils}/random-string.ts +0 -0
@@ -0,0 +1,174 @@
1
+ <script setup lang="ts">
2
+ import type { PikadayOptions } from 'pikaday'
3
+ import type { ComponentPublicInstance } from 'vue'
4
+ import { onMounted, ref, watch } from 'vue'
5
+
6
+ import { usePikaday } from '~/composables/use-pikaday'
7
+
8
+ const props = defineProps<{
9
+ /** Bound value: Date object or ISO string or null */
10
+ modelValue: Date | string | number | null
11
+ /** All Pikaday options (except `field`) */
12
+ options?: Omit<PikadayOptions, 'field'>
13
+ /** If true, default to today when no value provided */
14
+ autoDefault?: boolean
15
+ placeholder?: string
16
+ disabled?: boolean
17
+ validator?: boolean
18
+ join?: boolean
19
+ color?: string
20
+ primary?: boolean
21
+ secondary?: boolean
22
+ accent?: boolean
23
+ info?: boolean
24
+ success?: boolean
25
+ warning?: boolean
26
+ error?: boolean
27
+ ghost?: boolean
28
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
29
+ xl?: boolean
30
+ lg?: boolean
31
+ md?: boolean
32
+ sm?: boolean
33
+ xs?: boolean
34
+ }>()
35
+ const emit = defineEmits<{
36
+ (e: 'update:modelValue', v: Date | null): void
37
+ (e: 'update:inputValue', v: string | null): void
38
+ }>()
39
+ const inputRef = ref<ComponentPublicInstance | null>(null)
40
+ const inputValue = ref<string | null>(null)
41
+ const visible = ref(false)
42
+
43
+ const defaultOptions: Partial<PikadayOptions> = {
44
+ format: 'D MMM YYYY',
45
+ }
46
+
47
+ const { picker, createPicker } = usePikaday(
48
+ {
49
+ ...defaultOptions,
50
+ ...props.options,
51
+ bound: true,
52
+ field: undefined, // will be set below
53
+ },
54
+ handleSelect,
55
+ handleOpen,
56
+ handleClose,
57
+ )
58
+
59
+ function handleSelect(date: Date) {
60
+ emit('update:modelValue', date)
61
+ inputValue.value = picker.value?.toString() ?? ''
62
+ emit('update:inputValue', inputValue.value)
63
+ }
64
+ function handleOpen() {
65
+ visible.value = true
66
+ }
67
+ function handleClose() {
68
+ visible.value = false
69
+ }
70
+
71
+ onMounted(async () => {
72
+ const inputEl = inputRef.value as HTMLInputElement | null
73
+ // Format and set the initial input value BEFORE initializing Pikaday
74
+ if (props.modelValue) {
75
+ let d: Date | null = null
76
+ if (props.modelValue instanceof Date) {
77
+ d = props.modelValue
78
+ } else if (typeof props.modelValue === 'string') {
79
+ const tmp = new Date(props.modelValue)
80
+ if (!Number.isNaN(tmp.getTime())) {
81
+ d = tmp
82
+ }
83
+ }
84
+ if (d) {
85
+ const day = d.getDate()
86
+ const month = d.toLocaleString('en-US', { month: 'short' })
87
+ const year = d.getFullYear()
88
+ inputValue.value = `${day} ${month} ${year}`
89
+ }
90
+ }
91
+ if (inputEl) {
92
+ picker.value = await createPicker(inputEl)
93
+ // Do not call setDate here
94
+ if (picker.value && (picker.value as any).config?.bound === false) {
95
+ picker.value.hide()
96
+ }
97
+ }
98
+ })
99
+
100
+ function onFocus() {
101
+ if (picker.value) {
102
+ let d: Date | null = null
103
+ if (props.modelValue instanceof Date) {
104
+ d = props.modelValue
105
+ } else if (typeof props.modelValue === 'string') {
106
+ const tmp = new Date(props.modelValue)
107
+ if (!Number.isNaN(tmp.getTime())) {
108
+ d = tmp
109
+ }
110
+ }
111
+ picker.value.setDate(d, true)
112
+ }
113
+ }
114
+
115
+ watch(
116
+ () => props.modelValue,
117
+ val => {
118
+ if (!picker.value) {
119
+ return
120
+ }
121
+ if (!visible.value) {
122
+ if (val instanceof Date) {
123
+ picker.value.setDate(val, true)
124
+ inputValue.value = picker.value.toString()
125
+ } else if (typeof val === 'string') {
126
+ const d = new Date(val)
127
+ if (!Number.isNaN(d.getTime())) {
128
+ picker.value.setDate(d, true)
129
+ inputValue.value = picker.value.toString()
130
+ }
131
+ } else {
132
+ picker.value.setDate(null, true)
133
+ inputValue.value = ''
134
+ }
135
+ }
136
+ },
137
+ )
138
+ </script>
139
+
140
+ <template>
141
+ <input
142
+ ref="inputRef"
143
+ type="text"
144
+ :value="inputValue"
145
+ :placeholder="props.placeholder"
146
+ :disabled="props.disabled"
147
+ class="input"
148
+ :class="[
149
+ { validator: props.validator },
150
+ { 'input-primary': props.primary || props.color === 'primary' },
151
+ { 'input-secondary': props.secondary || props.color === 'secondary' },
152
+ { 'input-accent': props.accent || props.color === 'accent' },
153
+ { 'input-info': props.info || props.color === 'info' },
154
+ { 'input-success': props.success || props.color === 'success' },
155
+ { 'input-warning': props.warning || props.color === 'warning' },
156
+ { 'input-error': props.error || props.color === 'error' },
157
+ { 'input-ghost': props.ghost },
158
+ { 'input-xl': props.xl || props.size === 'xl' },
159
+ { 'input-lg': props.lg || props.size === 'lg' },
160
+ { 'input-md': props.md || props.size === 'md' },
161
+ { 'input-sm': props.sm || props.size === 'sm' },
162
+ { 'input-xs': props.xs || props.size === 'xs' },
163
+ { 'join-item': props.join },
164
+ ]"
165
+ v-bind="$attrs"
166
+ @focus="onFocus"
167
+ @input="
168
+ e => {
169
+ const val = (e.target as HTMLInputElement).value
170
+ emit('update:inputValue', val)
171
+ }
172
+ "
173
+ />
174
+ </template>
@@ -0,0 +1,87 @@
1
+ <script setup lang="ts">
2
+ import Skeleton from './Skeleton.vue'
3
+
4
+ const props = defineProps<{
5
+ numberOfMonths?: number
6
+ date?: Date
7
+ firstDay?: number // 0 = Sunday, 1 = Monday, etc. (matches Pikaday's firstDay option)
8
+ }>()
9
+
10
+ // Calculate the number of weeks needed for a given month
11
+ function getWeeksInMonth(date: Date, weekStartDay: number = 0): number {
12
+ const year = date.getFullYear()
13
+ const month = date.getMonth()
14
+
15
+ // Get first day of month
16
+ const firstDay = new Date(year, month, 1)
17
+ const firstDayOfWeek = firstDay.getDay()
18
+
19
+ // Get last day of month
20
+ const lastDay = new Date(year, month + 1, 0)
21
+ const daysInMonth = lastDay.getDate()
22
+
23
+ // Calculate offset based on what day the week starts on
24
+ // If week starts on Monday (1) and month starts on Sunday (0), offset is 6
25
+ // If week starts on Sunday (0) and month starts on Sunday (0), offset is 0
26
+ const offset = (firstDayOfWeek - weekStartDay + 7) % 7
27
+
28
+ // Calculate total cells needed (days in month + offset from first day)
29
+ const totalCells = daysInMonth + offset
30
+
31
+ // Return number of weeks (rows) needed
32
+ return Math.ceil(totalCells / 7)
33
+ }
34
+
35
+ // Calculate weeks for each month being displayed
36
+ const weeksPerMonth = computed(() => {
37
+ const baseDate = props.date || new Date()
38
+ const weekStartDay = props.firstDay ?? 0
39
+ const weeks: number[] = []
40
+
41
+ for (let i = 0; i < (props.numberOfMonths || 1); i++) {
42
+ const monthDate = new Date(baseDate.getFullYear(), baseDate.getMonth() + i, 1)
43
+ weeks.push(getWeeksInMonth(monthDate, weekStartDay))
44
+ }
45
+
46
+ return weeks
47
+ })
48
+ </script>
49
+
50
+ <template>
51
+ <Skeleton col class="bg-base-200 rounded-box">
52
+ <div
53
+ v-for="(weeks, idx) in weeksPerMonth"
54
+ :key="`calendar-${idx}`"
55
+ class="w-[270px] px-3 py-[14px] mx-auto flex flex-col gap-2"
56
+ :class="{
57
+ '-mt-3.5': idx > 0,
58
+ }"
59
+ >
60
+ <Flex justify-between items-center class="mb-3 px-2">
61
+ <span
62
+ class="size-4 rounded-full bg-base-300 inline-block"
63
+ :class="{
64
+ 'bg-base-300': idx === 0,
65
+ 'bg-transparent': idx !== 0,
66
+ }"
67
+ />
68
+ <span class="h-5 w-20 rounded-full bg-base-300 inline-block" />
69
+ <span
70
+ class="size-4 rounded-full bg-base-300 inline-block"
71
+ :class="{
72
+ 'bg-base-300': idx === weeksPerMonth.length - 1,
73
+ 'bg-transparent': idx !== weeksPerMonth.length - 1,
74
+ }"
75
+ />
76
+ </Flex>
77
+ <Flex col class="h-full">
78
+ <div class="grid grid-cols-7 gap-[4px] mb-3 flex-shrink-0">
79
+ <span v-for="d in 7" :key="`dow-${d}`" class="size-4 rounded-full bg-base-300 mx-auto block" />
80
+ </div>
81
+ <div class="grid grid-cols-7 gap-y-[8px] gap-x-[4px]">
82
+ <span v-for="i in weeks * 7" :key="`day-${i}`" class="size-7 rounded-full bg-base-300 block mx-auto" />
83
+ </div>
84
+ </Flex>
85
+ </div>
86
+ </Skeleton>
87
+ </template>
@@ -0,0 +1,46 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ const { is = 'div', ...props } = defineProps<{
5
+ is?: string
6
+ border?: boolean
7
+ dash?: boolean
8
+ side?: boolean
9
+ imageFull?: boolean
10
+ size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
11
+ xl?: boolean
12
+ lg?: boolean
13
+ md?: boolean
14
+ sm?: boolean
15
+ xs?: boolean
16
+ }>()
17
+
18
+ const NuxtLink = resolveComponent('NuxtLink')
19
+ const RouterLink = resolveComponent('RouterLink')
20
+
21
+ const resolvedComponent = computed(() => {
22
+ if (is === 'NuxtLink') return NuxtLink
23
+ if (is === 'RouterLink') return RouterLink
24
+ return is
25
+ })
26
+ </script>
27
+
28
+ <template>
29
+ <component
30
+ :is="resolvedComponent"
31
+ class="card"
32
+ :class="{
33
+ 'card-border': props.border,
34
+ 'card-side': props.side,
35
+ 'image-full': props.imageFull,
36
+
37
+ 'card-xl': props.xl || props.size === 'xl',
38
+ 'card-lg': props.lg || props.size === 'lg',
39
+ 'card-md': props.md || props.size === 'md',
40
+ 'card-sm': props.sm || props.size === 'sm',
41
+ 'card-xs': props.xs || props.size === 'xs',
42
+ }"
43
+ >
44
+ <slot />
45
+ </component>
46
+ </template>
@@ -1,12 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import Text from './Text.vue'
3
3
 
4
- interface Props {
4
+ const { is = 'div' } = defineProps<{
5
5
  is?: string
6
- }
7
- withDefaults(defineProps<Props>(), {
8
- is: 'div',
9
- })
6
+ }>()
10
7
  </script>
11
8
 
12
9
  <template>
@@ -1,12 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import Text from './Text.vue'
3
3
 
4
- interface Props {
4
+ const { is = 'div' } = defineProps<{
5
5
  is?: string
6
- }
7
- withDefaults(defineProps<Props>(), {
8
- is: 'div',
9
- })
6
+ }>()
10
7
  </script>
11
8
 
12
9
  <template>
@@ -1,12 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import Text from './Text.vue'
3
3
 
4
- interface Props {
5
- is?: string
6
- }
7
- withDefaults(defineProps<Props>(), {
8
- is: 'div',
9
- })
4
+ const { is = 'div' } = defineProps<{ is?: string }>()
10
5
  </script>
11
6
 
12
7
  <template>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ const { snapTo, center, end, vertical } = defineProps<{
3
+ snapTo?: 'center' | 'end'
4
+ center?: boolean
5
+ end?: boolean
6
+ orientation?: 'horizontal' | 'vertical'
7
+ horizontal?: boolean
8
+ vertical?: boolean
9
+ }>()
10
+ </script>
11
+
12
+ <template>
13
+ <div
14
+ class="carousel"
15
+ :class="{
16
+ 'carousel-center': center || snapTo === 'center',
17
+ 'carousel-end': end || snapTo === 'end',
18
+ 'carousel-horizontal': horizontal || orientation === 'horizontal',
19
+ 'carousel-vertical': vertical || orientation === 'vertical',
20
+ }"
21
+ >
22
+ <slot />
23
+ </div>
24
+ </template>
@@ -0,0 +1,26 @@
1
+ <script setup lang="ts">
2
+ const {
3
+ pre,
4
+ align = 'start',
5
+ start,
6
+ end,
7
+ } = defineProps<{
8
+ pre?: boolean
9
+ align?: string
10
+ start?: boolean
11
+ end?: boolean
12
+ }>()
13
+ </script>
14
+
15
+ <template>
16
+ <div
17
+ class="chat"
18
+ :class="{
19
+ 'chat-start': start || (!end && align === 'start'),
20
+ 'chat-end': end || align === 'end',
21
+ 'whitespace-pre': pre,
22
+ }"
23
+ >
24
+ <slot />
25
+ </div>
26
+ </template>
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ const { color, neutral, primary, secondary, accent, info, success, warning, error } = 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
+ </script>
14
+
15
+ <template>
16
+ <div
17
+ class="chat-bubble"
18
+ :class="{
19
+ 'chat-bubble-neutral': neutral || color === 'neutral',
20
+ 'chat-bubble-primary': primary || color === 'primary',
21
+ 'chat-bubble-secondary': secondary || color === 'secondary',
22
+ 'chat-bubble-accent': accent || color === 'accent',
23
+ 'chat-bubble-info': info || color === 'info',
24
+ 'chat-bubble-success': success || color === 'success',
25
+ 'chat-bubble-warning': warning || color === 'warning',
26
+ 'chat-bubble-error': error || color === 'error',
27
+ }"
28
+ >
29
+ <slot />
30
+ </div>
31
+ </template>
@@ -0,0 +1,51 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ const props = defineProps<{
5
+ modelValue?: any
6
+ themeController?: boolean
7
+
8
+ color?: string
9
+ primary?: boolean
10
+ secondary?: boolean
11
+ accent?: boolean
12
+ success?: boolean
13
+ warning?: boolean
14
+ info?: boolean
15
+ error?: boolean
16
+
17
+ size?: string
18
+ lg?: boolean
19
+ md?: boolean
20
+ sm?: boolean
21
+ xs?: boolean
22
+ }>()
23
+ const emit = defineEmits(['update:modelValue'])
24
+
25
+ const currentValue = computed({
26
+ get: () => props.modelValue,
27
+ set: (val: string) => emit('update:modelValue', val),
28
+ })
29
+ </script>
30
+
31
+ <template>
32
+ <input
33
+ v-model="currentValue"
34
+ type="checkbox"
35
+ class="checkbox"
36
+ :class="{
37
+ 'checkbox-primary': primary || color === 'primary',
38
+ 'checkbox-secondary': secondary || color === 'secondary',
39
+ 'checkbox-accent': accent || color === 'accent',
40
+ 'checkbox-success': success || color === 'success',
41
+ 'checkbox-warning': warning || color === 'warning',
42
+ 'checkbox-info': info || color === 'info',
43
+ 'checkbox-error': error || color === 'error',
44
+ 'checkbox-xs': xs || size === 'xs',
45
+ 'checkbox-sm': sm || size === 'sm',
46
+ 'checkbox-md': md || size === 'md',
47
+ 'checkbox-lg': lg || size === 'lg',
48
+ 'theme-controller': themeController,
49
+ }"
50
+ />
51
+ </template>
@@ -0,0 +1,75 @@
1
+ <script setup lang="ts">
2
+ import { inject, provide, ref, watch } from 'vue'
3
+
4
+ const props = defineProps<{
5
+ variant?: 'arrow' | 'plus'
6
+ arrow?: boolean
7
+ plus?: boolean
8
+ open?: boolean
9
+ close?: boolean
10
+ toggle?: boolean
11
+ value?: any
12
+ }>()
13
+
14
+ const isOpen = defineModel('open', { default: false })
15
+
16
+ const accordionValue = inject('accordion-value', ref(null))
17
+ const useAccordion = accordionValue.value !== null
18
+
19
+ // Internal state for toggle mode
20
+ const internalChecked = ref(props.open || false)
21
+
22
+ // Generate unique ID for checkbox
23
+ const checkboxId = `collapse-${Math.random().toString(36).substr(2, 9)}`
24
+ provide('collapseCheckboxId', checkboxId)
25
+ provide('collapseToggle', props.toggle || useAccordion)
26
+
27
+ // Sync internal state with modelValue
28
+ watch(
29
+ () => isOpen.value,
30
+ newVal => {
31
+ internalChecked.value = newVal
32
+ },
33
+ )
34
+
35
+ watch(internalChecked, newVal => {
36
+ isOpen.value = newVal
37
+ })
38
+
39
+ function handleClick() {
40
+ // Only handle clicks for accordion mode
41
+ if (useAccordion) {
42
+ accordionValue.value = props.value
43
+ }
44
+ }
45
+
46
+ const isChecked = computed(() => {
47
+ if (useAccordion) {
48
+ return accordionValue.value === props.value
49
+ }
50
+ return internalChecked.value
51
+ })
52
+ </script>
53
+
54
+ <template>
55
+ <div
56
+ :tabindex="props.toggle || useAccordion ? undefined : 0"
57
+ class="collapse"
58
+ :class="[
59
+ { 'collapse-arrow': props.arrow || props.variant === 'arrow' },
60
+ { 'collapse-plus': props.plus || props.variant === 'plus' },
61
+ { 'collapse-open': (props.open && !props.close) || (useAccordion && accordionValue === props.value) },
62
+ { 'collapse-close': props.close },
63
+ ]"
64
+ @click="useAccordion ? handleClick : undefined"
65
+ >
66
+ <input
67
+ v-if="props.toggle || useAccordion"
68
+ :id="checkboxId"
69
+ v-model="internalChecked"
70
+ :type="useAccordion ? 'radio' : 'checkbox'"
71
+ :checked="useAccordion ? isChecked : undefined"
72
+ />
73
+ <slot />
74
+ </div>
75
+ </template>
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ import { inject } from 'vue'
3
+
4
+ const checkboxId = inject('collapseCheckboxId', null)
5
+ const hasToggle = inject('collapseToggle', false)
6
+ </script>
7
+
8
+ <template>
9
+ <label v-if="hasToggle && checkboxId" :for="checkboxId" class="collapse-title">
10
+ <slot />
11
+ </label>
12
+ <div v-else class="collapse-title">
13
+ <slot />
14
+ </div>
15
+ </template>
@@ -2,7 +2,7 @@
2
2
  import { computed } from 'vue'
3
3
 
4
4
  const props = defineProps<{
5
- is?: string | Function | Object
5
+ is?: any
6
6
  }>()
7
7
 
8
8
  const tag = computed(() => props.is || 'span')
@@ -0,0 +1,69 @@
1
+ <script setup lang="ts">
2
+ import { useIntervalFn } from '@vueuse/core'
3
+ import { computed, ref, watch } from 'vue'
4
+
5
+ const { durationInSeconds = 0, untilDate } = defineProps<{
6
+ durationInSeconds?: number
7
+ untilDate?: Date
8
+ }>()
9
+ const emit = defineEmits(['done'])
10
+
11
+ function getTargetDate() {
12
+ return untilDate || new Date(Date.now() + durationInSeconds * 1000)
13
+ }
14
+
15
+ const targetDate = ref(getTargetDate())
16
+
17
+ watch(
18
+ () => [durationInSeconds, untilDate],
19
+ () => {
20
+ targetDate.value = getTargetDate()
21
+ },
22
+ { immediate: true },
23
+ )
24
+
25
+ const timeLeft = ref(0)
26
+ const calcTimeLeft = () => Math.max(0, targetDate.value.getTime() - Date.now())
27
+
28
+ useIntervalFn(() => {
29
+ timeLeft.value = calcTimeLeft()
30
+ }, 1000)
31
+
32
+ watch(timeLeft, val => {
33
+ if (val === 0) {
34
+ emit('done')
35
+ }
36
+ })
37
+
38
+ const totalSeconds = computed(() => Math.round(timeLeft.value / 1000))
39
+ const totalMinutes = computed(() => Math.floor(totalSeconds.value / 60))
40
+ const totalHours = computed(() => Math.floor(totalMinutes.value / 60))
41
+ const totalDays = computed(() => Math.floor(totalHours.value / 24))
42
+ const totalWeeks = computed(() => Math.floor(totalDays.value / 7))
43
+ const totalMonths = computed(() => {
44
+ const now = new Date()
45
+ return (targetDate.value.getFullYear() - now.getFullYear()) * 12 + (targetDate.value.getMonth() - now.getMonth())
46
+ })
47
+ const split = computed(() => {
48
+ const days = totalDays.value
49
+ const hours = totalHours.value - days * 24
50
+ const minutes = totalMinutes.value - totalHours.value * 60
51
+ const seconds = totalSeconds.value - totalMinutes.value * 60
52
+ return { days, hours, minutes, seconds }
53
+ })
54
+ </script>
55
+
56
+ <template>
57
+ <slot
58
+ v-bind="{
59
+ totalSeconds,
60
+ totalMinutes,
61
+ totalHours,
62
+ totalDays,
63
+ totalWeeks,
64
+ totalMonths,
65
+ targetDate,
66
+ split,
67
+ }"
68
+ />
69
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ const props = defineProps<{
5
+ value: number
6
+ is?: any
7
+ digits?: 2 | 3
8
+ }>()
9
+
10
+ const style = computed(() => {
11
+ let css = `--value:${props.value};`
12
+ if (props.digits) {
13
+ css += `--digits:${props.digits};`
14
+ }
15
+ return css
16
+ })
17
+ </script>
18
+
19
+ <template>
20
+ <component :is="props.is || 'span'" v-bind="$attrs" :style="style" />
21
+ </template>