daisy-ui-kit 5.0.0-pre.9 → 5.0.1

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 (94) hide show
  1. package/README.md +277 -48
  2. package/app/components/Accordion.vue +8 -5
  3. package/app/components/Alert.vue +2 -1
  4. package/app/components/Avatar.vue +10 -7
  5. package/app/components/AvatarGroup.vue +6 -2
  6. package/app/components/Badge.vue +19 -1
  7. package/app/components/Button.vue +66 -46
  8. package/app/components/Calendar.vue +151 -42
  9. package/app/components/CalendarInput.vue +229 -130
  10. package/app/components/CalendarSkeleton.vue +51 -10
  11. package/app/components/Card.vue +20 -2
  12. package/app/components/CardActions.vue +1 -1
  13. package/app/components/CardBody.vue +1 -1
  14. package/app/components/CardTitle.vue +1 -1
  15. package/app/components/Carousel.vue +2 -1
  16. package/app/components/Chat.vue +6 -1
  17. package/app/components/Checkbox.vue +1 -1
  18. package/app/components/Collapse.vue +38 -5
  19. package/app/components/CollapseTitle.vue +11 -1
  20. package/app/components/Countdown.vue +3 -3
  21. package/app/components/CountdownTimers.vue +4 -7
  22. package/app/components/Counter.vue +14 -3
  23. package/app/components/DaisyLink.vue +33 -15
  24. package/app/components/Dock.vue +5 -6
  25. package/app/components/DockItem.vue +5 -3
  26. package/app/components/Drawer.vue +15 -12
  27. package/app/components/DrawerContent.vue +9 -6
  28. package/app/components/DrawerSide.vue +9 -6
  29. package/app/components/Dropdown.vue +61 -50
  30. package/app/components/DropdownButton.vue +11 -4
  31. package/app/components/DropdownContent.vue +90 -20
  32. package/app/components/DropdownTarget.vue +10 -3
  33. package/app/components/Fab.vue +16 -0
  34. package/app/components/FabClose.vue +18 -0
  35. package/app/components/FabMainAction.vue +5 -0
  36. package/app/components/FabTrigger.vue +117 -0
  37. package/app/components/Fieldset.vue +5 -4
  38. package/app/components/FileInput.vue +1 -1
  39. package/app/components/Filter.vue +45 -38
  40. package/app/components/Flex.vue +8 -1
  41. package/app/components/FlexItem.vue +30 -27
  42. package/app/components/Footer.vue +16 -12
  43. package/app/components/FooterTitle.vue +8 -5
  44. package/app/components/Hero.vue +9 -6
  45. package/app/components/HeroContent.vue +9 -6
  46. package/app/components/Hover3D.vue +22 -0
  47. package/app/components/HoverGallery.vue +11 -0
  48. package/app/components/Indicator.vue +12 -5
  49. package/app/components/IndicatorItem.vue +21 -14
  50. package/app/components/Input.vue +44 -47
  51. package/app/components/Kbd.vue +2 -1
  52. package/app/components/Label.vue +32 -29
  53. package/app/components/MenuExpand.vue +5 -13
  54. package/app/components/MenuExpandToggle.vue +7 -1
  55. package/app/components/MenuItem.vue +6 -4
  56. package/app/components/Modal.vue +23 -17
  57. package/app/components/Progress.vue +13 -1
  58. package/app/components/Prose.vue +7 -2
  59. package/app/components/RadialProgress.vue +8 -8
  60. package/app/components/Radio.vue +1 -1
  61. package/app/components/RadioGroup.vue +2 -2
  62. package/app/components/Range.vue +186 -46
  63. package/app/components/RangeMeasure.vue +33 -30
  64. package/app/components/RangeMeasureTick.vue +4 -5
  65. package/app/components/Rating.vue +70 -53
  66. package/app/components/Select.vue +44 -47
  67. package/app/components/SkeletonText.vue +11 -0
  68. package/app/components/Stack.vue +5 -0
  69. package/app/components/Steps.vue +7 -2
  70. package/app/components/Swap.vue +4 -10
  71. package/app/components/Tab.vue +23 -5
  72. package/app/components/Text.vue +47 -23
  73. package/app/components/TextArea.vue +75 -30
  74. package/app/components/TextRotate.vue +24 -0
  75. package/app/components/ThemeController.vue +3 -4
  76. package/app/components/ThemeProvider.vue +47 -32
  77. package/app/components/TimelineLine.vue +1 -1
  78. package/app/components/TimelineStart.vue +2 -1
  79. package/app/components/Toast.vue +3 -8
  80. package/app/components/Toggle.vue +2 -2
  81. package/app/components/Tooltip.vue +111 -21
  82. package/app/components/TooltipContent.vue +279 -1
  83. package/app/components/TooltipTarget.vue +20 -0
  84. package/app/composables/__tests__/use-calendar.test.ts +239 -0
  85. package/app/composables/use-calendar.ts +288 -0
  86. package/app/composables/use-daisy-theme.ts +140 -0
  87. package/app/composables/use-toast.ts +345 -0
  88. package/app/composables/useSearch.ts +22 -0
  89. package/app/utils/drawer-utils.ts +15 -13
  90. package/app/utils/position-area.ts +40 -0
  91. package/nuxt.d.ts +13 -0
  92. package/nuxt.js +12 -9
  93. package/package.json +34 -17
  94. package/app/utils/random-string.ts +0 -19
@@ -19,7 +19,12 @@ function cssVarToCamel(str: string): string {
19
19
  function dataAttrToCamel(str: string): string {
20
20
  return str.replace(/-([a-z0-9])/g, (_, c: string) => c.toUpperCase())
21
21
  }
22
- function parseThemeString(themeString?: string): { style: Record<string, string>, dataAttrs: Record<string, string>, dataTheme: string | undefined, allAttrs: Record<string, string> } {
22
+ function parseThemeString(themeString?: string): {
23
+ style: Record<string, string>
24
+ dataAttrs: Record<string, string>
25
+ dataTheme: string | undefined
26
+ allAttrs: Record<string, string>
27
+ } {
23
28
  if (!themeString) {
24
29
  return { style: {}, dataAttrs: {}, dataTheme: undefined, allAttrs: {} }
25
30
  }
@@ -33,10 +38,14 @@ function parseThemeString(themeString?: string): { style: Record<string, string>
33
38
  const allAttrs: Record<string, string> = {}
34
39
 
35
40
  // Remove @plugin ... { and closing } if present
36
- const str = themeString.trim().replace(/^@plugin[^{}]*\{/, '').replace(/\}$/, '').trim()
41
+ const str = themeString
42
+ .trim()
43
+ .replace(/^@plugin[^{}]*\{/, '')
44
+ .replace(/\}$/, '')
45
+ .trim()
37
46
 
38
47
  // works with or without newline characters
39
- str.split(/[\n;]/).forEach((line) => {
48
+ str.split(/[\n;]/).forEach(line => {
40
49
  const trimmed = line.trim()
41
50
  if (!trimmed || trimmed.startsWith('//')) {
42
51
  return
@@ -57,12 +66,10 @@ function parseThemeString(themeString?: string): { style: Record<string, string>
57
66
  if (varNamePattern.test(key)) {
58
67
  style[key] = value
59
68
  allAttrs[cssVarToCamel(key)] = value
60
- }
61
- else if (key === 'name') {
69
+ } else if (key === 'name') {
62
70
  dataTheme = value.replace(/"/g, '')
63
71
  allAttrs.dataTheme = dataTheme
64
- }
65
- else if (attrNamePattern.test(key)) {
72
+ } else if (attrNamePattern.test(key)) {
66
73
  const attrKey = `data-${key.replace(/[^\w-]/g, '')}`
67
74
  const attrVal = value.replace(/"/g, '')
68
75
  dataAttrs[attrKey] = attrVal
@@ -78,7 +85,7 @@ const parsed = computed(() => parseThemeString(props.dataTheme ?? props.cssVars)
78
85
 
79
86
  const themeVars = ref<Record<string, string>>({})
80
87
  let observers: MutationObserver[] = []
81
- let themeControllerInputs: Array<{ el: HTMLInputElement, listener: () => void }> = []
88
+ let themeControllerInputs: Array<{ el: HTMLInputElement; listener: () => void }> = []
82
89
  let themeControllerDomObserver: MutationObserver | null = null
83
90
 
84
91
  // Converts a themeAttrs object to a DaisyUI theme string
@@ -88,15 +95,16 @@ function toThemeString(attrs: Record<string, string>, opts?: { asPlugin?: boolea
88
95
  for (const [key, value] of Object.entries(attrs)) {
89
96
  if (key === 'dataTheme') {
90
97
  lines.push(`name: "${value}";`)
91
- }
92
- else if (key.startsWith('data')) {
98
+ } else if (key.startsWith('data')) {
93
99
  // Convert dataFooBar -> foo-bar
94
- const attr = key.slice(4).replace(/([A-Z])/g, '-$1').toLowerCase()
100
+ const attr = key
101
+ .slice(4)
102
+ .replace(/([A-Z])/g, '-$1')
103
+ .toLowerCase()
95
104
  if (attr !== 'theme') {
96
105
  lines.push(`${attr}: ${value};`)
97
106
  }
98
- }
99
- else {
107
+ } else {
100
108
  // Convert camelCase to --kebab-case
101
109
  const cssVar = `--${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`
102
110
  lines.push(`${cssVar}: ${value};`)
@@ -207,8 +215,10 @@ function setupSnoop(rootEl: HTMLElement): void {
207
215
  })
208
216
  themeControllerInputs = []
209
217
  // Find all matching inputs in the document
210
- const inputs = Array.from(document.querySelectorAll('input[type="checkbox"].theme-controller, input[type="radio"].theme-controller')) as HTMLInputElement[]
211
- inputs.forEach((el) => {
218
+ const inputs = Array.from(
219
+ document.querySelectorAll('input[type="checkbox"].theme-controller, input[type="radio"].theme-controller'),
220
+ ) as HTMLInputElement[]
221
+ inputs.forEach(el => {
212
222
  const listener = () => updateVars()
213
223
  el.addEventListener('change', listener)
214
224
  themeControllerInputs.push({ el, listener })
@@ -226,9 +236,13 @@ function setupSnoop(rootEl: HTMLElement): void {
226
236
  themeControllerDomObserver.observe(document.body, { childList: true, subtree: true })
227
237
 
228
238
  // Watch for applied style changes (parsed.style)
229
- watch(() => parsed.value.style, () => {
230
- nextTick(() => updateVars())
231
- }, { immediate: false, deep: true })
239
+ watch(
240
+ () => parsed.value.style,
241
+ () => {
242
+ nextTick(() => updateVars())
243
+ },
244
+ { immediate: false, deep: true },
245
+ )
232
246
  updateVars()
233
247
  }
234
248
 
@@ -236,21 +250,22 @@ const rootEl = ref<HTMLElement | null>(null)
236
250
 
237
251
  const isClient = typeof window !== 'undefined' && typeof document !== 'undefined'
238
252
 
239
- watch([
240
- () => props.snoop,
241
- () => rootEl.value,
242
- ], ([snoop, el]) => {
243
- if (isClient) {
244
- // Clean up previous observers if any
245
- observers.forEach((o: MutationObserver) => o.disconnect())
246
- observers = []
247
- if (snoop && el) {
248
- nextTick(() => {
249
- setupSnoop(el)
250
- })
253
+ watch(
254
+ [() => props.snoop, () => rootEl.value],
255
+ ([snoop, el]) => {
256
+ if (isClient) {
257
+ // Clean up previous observers if any
258
+ observers.forEach((o: MutationObserver) => o.disconnect())
259
+ observers = []
260
+ if (snoop && el) {
261
+ nextTick(() => {
262
+ setupSnoop(el)
263
+ })
264
+ }
251
265
  }
252
- }
253
- }, { immediate: true })
266
+ },
267
+ { immediate: true },
268
+ )
254
269
 
255
270
  onUnmounted(() => {
256
271
  observers.forEach((o: MutationObserver) => o.disconnect())
@@ -25,5 +25,5 @@ defineProps<{
25
25
  'bg-warning': warning || color === 'warning',
26
26
  'bg-error': error || color === 'error',
27
27
  }"
28
- >
28
+ />
29
29
  </template>
@@ -4,7 +4,8 @@ defineProps<{ box?: boolean }>()
4
4
 
5
5
  <template>
6
6
  <div
7
- class="timeline-start" :class="{
7
+ class="timeline-start"
8
+ :class="{
8
9
  'timeline-box': box,
9
10
  }"
10
11
  >
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
- import type { Toast } from '~/composables/use-toast'
2
+ import type { Toast } from '../composables/use-toast'
3
3
  import { computed } from 'vue'
4
- import { useToast } from '~/composables/use-toast'
4
+ import { useToast } from '../composables/use-toast'
5
5
 
6
6
  // Explicit slot typing (Vue 3.4+ / Volar)
7
7
  interface ToastSlotProps {
@@ -61,12 +61,7 @@ const visibleToasts = computed(() => toasts.value ?? [])
61
61
  'toast-bottom': props.bottom || props.vAlign === 'bottom',
62
62
  }"
63
63
  >
64
- <slot
65
- v-for="toast in visibleToasts"
66
- :key="toast.id"
67
- :toast="toast"
68
- :remove-toast="removeToast"
69
- />
64
+ <slot v-for="toast in visibleToasts" :key="toast.id" :toast="toast" :remove-toast="removeToast" />
70
65
  <slot />
71
66
  </div>
72
67
  </template>
@@ -40,7 +40,7 @@ const currentValue = computed({
40
40
  class="toggle"
41
41
  :disabled="disabled"
42
42
  :class="{
43
- 'validator': validator,
43
+ validator,
44
44
  'toggle-neutral': neutral || color === 'neutral',
45
45
  'toggle-primary': primary || color === 'primary',
46
46
  'toggle-secondary': secondary || color === 'secondary',
@@ -56,5 +56,5 @@ const currentValue = computed({
56
56
  'toggle-xl': xl || size === 'xl',
57
57
  'theme-controller': themeController,
58
58
  }"
59
- >
59
+ />
60
60
  </template>
@@ -1,30 +1,115 @@
1
1
  <script setup lang="ts">
2
- const props = defineProps<{
3
- tip?: string | number
4
- open?: boolean
5
-
6
- color?: string
7
- neutral?: boolean
8
- primary?: boolean
9
- secondary?: boolean
10
- accent?: boolean
11
- info?: boolean
12
- success?: boolean
13
- warning?: boolean
14
- error?: boolean
15
-
16
- position?: 'top' | 'right' | 'bottom' | 'left'
17
- top?: boolean
18
- right?: boolean
19
- bottom?: boolean
20
- left?: boolean
21
- }>()
2
+ import { useId } from 'vue'
3
+ import { useElementHover } from '@vueuse/core'
4
+ import { computed, onMounted, provide, ref, watch } from 'vue'
5
+
6
+ const props = withDefaults(
7
+ defineProps<{
8
+ tip?: string | number
9
+ open?: boolean
10
+
11
+ color?: string
12
+ neutral?: boolean
13
+ primary?: boolean
14
+ secondary?: boolean
15
+ accent?: boolean
16
+ info?: boolean
17
+ success?: boolean
18
+ warning?: boolean
19
+ error?: boolean
20
+
21
+ position?: 'top' | 'right' | 'bottom' | 'left'
22
+ top?: boolean
23
+ right?: boolean
24
+ bottom?: boolean
25
+ left?: boolean
26
+
27
+ // Popover mode props
28
+ delayEnter?: number
29
+ delayLeave?: number
30
+ }>(),
31
+ {
32
+ delayEnter: 200,
33
+ delayLeave: 100,
34
+ },
35
+ )
36
+
37
+ // Detect if using popover mode (when TooltipTarget/TooltipContent are used)
38
+ const isPopoverMode = computed(() => {
39
+ return !props.tip
40
+ })
41
+
42
+ // Popover mode setup
43
+ const isOpen = defineModel('open', { default: false })
44
+ provide('isTooltipOpen', isOpen)
45
+
46
+ const uniqueId = useId()
47
+ const id = `tooltip-${uniqueId}`
48
+ provide('tooltipId', id)
49
+
50
+ // Compute placement for CSS anchor positioning
51
+ const placement = computed(() => {
52
+ if (props.top || props.position === 'top') return 'top'
53
+ if (props.right || props.position === 'right') return 'right'
54
+ if (props.left || props.position === 'left') return 'left'
55
+ return 'bottom' // default
56
+ })
57
+ provide('tooltipPlacement', placement)
58
+
59
+ // Provide color for TooltipContent
60
+ const color = computed(() => {
61
+ if (props.color) return props.color
62
+ if (props.neutral) return 'neutral'
63
+ if (props.primary) return 'primary'
64
+ if (props.secondary) return 'secondary'
65
+ if (props.accent) return 'accent'
66
+ if (props.info) return 'info'
67
+ if (props.success) return 'success'
68
+ if (props.warning) return 'warning'
69
+ if (props.error) return 'error'
70
+ return null
71
+ })
72
+ provide('tooltipColor', color)
73
+
74
+ // References
75
+ const targetEl = ref(null)
76
+ const contentEl = ref(null)
77
+ provide('targetEl', targetEl)
78
+ provide('contentEl', contentEl)
79
+
80
+ // Visibility utils
81
+ function open() {
82
+ isOpen.value = true
83
+ }
84
+ function close() {
85
+ isOpen.value = false
86
+ }
87
+ provide('openTooltip', open)
88
+ provide('closeTooltip', close)
89
+
90
+ const tooltipWrapper = ref(null)
91
+
92
+ onMounted(() => {
93
+ if (isPopoverMode.value) {
94
+ const hover = useElementHover(tooltipWrapper, {
95
+ delayLeave: props.delayLeave,
96
+ delayEnter: props.delayEnter,
97
+ })
98
+
99
+ watch(hover, newValue => {
100
+ isOpen.value = newValue
101
+ })
102
+ }
103
+ })
22
104
  </script>
23
105
 
24
106
  <template>
107
+ <!-- CSS-only mode (when tip prop is provided) -->
25
108
  <div
109
+ v-if="!isPopoverMode"
26
110
  :data-tip="tip"
27
- class="tooltip" :class="{
111
+ class="tooltip"
112
+ :class="{
28
113
  'tooltip-open': props.open,
29
114
 
30
115
  'tooltip-top': props.top || props.position === 'top',
@@ -44,4 +129,9 @@ const props = defineProps<{
44
129
  >
45
130
  <slot />
46
131
  </div>
132
+
133
+ <!-- Popover API mode (when using TooltipTarget/TooltipContent) -->
134
+ <div v-else ref="tooltipWrapper" class="tooltip-wrapper inline-block">
135
+ <slot />
136
+ </div>
47
137
  </template>
@@ -1,5 +1,283 @@
1
+ <script setup>
2
+ import { computed, inject, ref, watch } from 'vue'
3
+ import { getPositionArea, getPositionFallbacks } from '../utils/position-area'
4
+
5
+ const id = inject('tooltipId', null)
6
+ const isOpen = inject('isTooltipOpen', ref(false))
7
+ const contentEl = inject('contentEl', ref(null))
8
+ const placement = inject('tooltipPlacement', ref('bottom'))
9
+ const color = inject('tooltipColor', ref(null))
10
+
11
+ // Check if we're in popover mode (inside a Tooltip wrapper with context)
12
+ const isPopoverMode = computed(() => id !== null)
13
+
14
+ // Compute CSS position-area value based on placement
15
+ const positionArea = computed(() => getPositionArea(placement.value))
16
+ const positionFallbacks = computed(() => getPositionFallbacks(placement.value))
17
+
18
+ // Color classes for the tooltip
19
+ const colorClass = computed(() => {
20
+ if (!color.value) return ''
21
+ const colorMap = {
22
+ neutral: 'tooltip-neutral',
23
+ primary: 'tooltip-primary',
24
+ secondary: 'tooltip-secondary',
25
+ accent: 'tooltip-accent',
26
+ info: 'tooltip-info',
27
+ success: 'tooltip-success',
28
+ warning: 'tooltip-warning',
29
+ error: 'tooltip-error',
30
+ }
31
+ return colorMap[color.value] || ''
32
+ })
33
+
34
+ // Sync popover state with isOpen model
35
+ watch(
36
+ isOpen,
37
+ newValue => {
38
+ if (!isPopoverMode.value || !contentEl.value) return
39
+
40
+ try {
41
+ const isPopoverOpen = contentEl.value.matches(':popover-open')
42
+
43
+ if (newValue && !isPopoverOpen) {
44
+ contentEl.value.showPopover()
45
+ } else if (!newValue && isPopoverOpen) {
46
+ contentEl.value.hidePopover()
47
+ }
48
+ } catch (e) {
49
+ console.warn('Popover API not supported:', e)
50
+ }
51
+ },
52
+ { flush: 'post' },
53
+ )
54
+
55
+ // Listen to popover toggle events to sync back to isOpen model
56
+ function handleToggle(event) {
57
+ const newState = event.newState === 'open'
58
+ if (isOpen.value !== newState) {
59
+ isOpen.value = newState
60
+ }
61
+ }
62
+ </script>
63
+
1
64
  <template>
2
- <div class="tooltip-content">
65
+ <!-- Popover mode -->
66
+ <div
67
+ v-if="isPopoverMode"
68
+ :id="`${id}-content`"
69
+ ref="contentEl"
70
+ :anchor="id"
71
+ :data-placement="placement"
72
+ role="tooltip"
73
+ popover="manual"
74
+ class="tooltip-popover"
75
+ :class="colorClass"
76
+ :style="{
77
+ 'position-anchor': `--${id}`,
78
+ 'position-area': positionArea,
79
+ 'position-try-fallbacks': positionFallbacks,
80
+ }"
81
+ @toggle="handleToggle"
82
+ >
83
+ <slot />
84
+ </div>
85
+
86
+ <!-- Simple mode (no Tooltip wrapper context) -->
87
+ <div v-else class="tooltip-content">
3
88
  <slot />
4
89
  </div>
5
90
  </template>
91
+
92
+ <style>
93
+ @layer components {
94
+ .tooltip-popover[popover] {
95
+ border: none;
96
+ overflow: visible;
97
+ inset: auto;
98
+ margin: 0;
99
+ padding: 0.25rem 0.5rem;
100
+ font-size: 0.875rem;
101
+ line-height: 1.25rem;
102
+ border-radius: var(--radius-selector, 0.25rem);
103
+ background-color: var(--color-neutral);
104
+ color: var(--color-neutral-content);
105
+ max-width: 20rem;
106
+ }
107
+
108
+ .tooltip-popover[popover]:popover-open {
109
+ position: fixed;
110
+ }
111
+
112
+ /* Arrow base styles */
113
+ .tooltip-popover[popover]::before {
114
+ content: '';
115
+ position: absolute;
116
+ border: 6px solid transparent;
117
+ }
118
+
119
+ /* Bottom placement - arrow points up */
120
+ .tooltip-popover[data-placement='bottom'] {
121
+ margin-top: 6px;
122
+ }
123
+ .tooltip-popover[data-placement='bottom']::before {
124
+ bottom: 100%;
125
+ left: 50%;
126
+ transform: translateX(-50%);
127
+ border-bottom-color: var(--color-neutral);
128
+ }
129
+
130
+ /* Top placement - arrow points down */
131
+ .tooltip-popover[data-placement='top'] {
132
+ margin-bottom: 6px;
133
+ }
134
+ .tooltip-popover[data-placement='top']::before {
135
+ top: 100%;
136
+ left: 50%;
137
+ transform: translateX(-50%);
138
+ border-top-color: var(--color-neutral);
139
+ }
140
+
141
+ /* Right placement - arrow points left */
142
+ .tooltip-popover[data-placement='right'] {
143
+ margin-left: 6px;
144
+ }
145
+ .tooltip-popover[data-placement='right']::before {
146
+ right: 100%;
147
+ top: 50%;
148
+ transform: translateY(-50%);
149
+ border-right-color: var(--color-neutral);
150
+ }
151
+
152
+ /* Left placement - arrow points right */
153
+ .tooltip-popover[data-placement='left'] {
154
+ margin-right: 6px;
155
+ }
156
+ .tooltip-popover[data-placement='left']::before {
157
+ left: 100%;
158
+ top: 50%;
159
+ transform: translateY(-50%);
160
+ border-left-color: var(--color-neutral);
161
+ }
162
+
163
+ /* Color variants */
164
+ .tooltip-popover.tooltip-primary {
165
+ background-color: var(--color-primary);
166
+ color: var(--color-primary-content);
167
+ }
168
+ .tooltip-popover.tooltip-primary[data-placement='bottom']::before {
169
+ border-bottom-color: var(--color-primary);
170
+ }
171
+ .tooltip-popover.tooltip-primary[data-placement='top']::before {
172
+ border-top-color: var(--color-primary);
173
+ }
174
+ .tooltip-popover.tooltip-primary[data-placement='right']::before {
175
+ border-right-color: var(--color-primary);
176
+ }
177
+ .tooltip-popover.tooltip-primary[data-placement='left']::before {
178
+ border-left-color: var(--color-primary);
179
+ }
180
+
181
+ .tooltip-popover.tooltip-secondary {
182
+ background-color: var(--color-secondary);
183
+ color: var(--color-secondary-content);
184
+ }
185
+ .tooltip-popover.tooltip-secondary[data-placement='bottom']::before {
186
+ border-bottom-color: var(--color-secondary);
187
+ }
188
+ .tooltip-popover.tooltip-secondary[data-placement='top']::before {
189
+ border-top-color: var(--color-secondary);
190
+ }
191
+ .tooltip-popover.tooltip-secondary[data-placement='right']::before {
192
+ border-right-color: var(--color-secondary);
193
+ }
194
+ .tooltip-popover.tooltip-secondary[data-placement='left']::before {
195
+ border-left-color: var(--color-secondary);
196
+ }
197
+
198
+ .tooltip-popover.tooltip-accent {
199
+ background-color: var(--color-accent);
200
+ color: var(--color-accent-content);
201
+ }
202
+ .tooltip-popover.tooltip-accent[data-placement='bottom']::before {
203
+ border-bottom-color: var(--color-accent);
204
+ }
205
+ .tooltip-popover.tooltip-accent[data-placement='top']::before {
206
+ border-top-color: var(--color-accent);
207
+ }
208
+ .tooltip-popover.tooltip-accent[data-placement='right']::before {
209
+ border-right-color: var(--color-accent);
210
+ }
211
+ .tooltip-popover.tooltip-accent[data-placement='left']::before {
212
+ border-left-color: var(--color-accent);
213
+ }
214
+
215
+ .tooltip-popover.tooltip-info {
216
+ background-color: var(--color-info);
217
+ color: var(--color-info-content);
218
+ }
219
+ .tooltip-popover.tooltip-info[data-placement='bottom']::before {
220
+ border-bottom-color: var(--color-info);
221
+ }
222
+ .tooltip-popover.tooltip-info[data-placement='top']::before {
223
+ border-top-color: var(--color-info);
224
+ }
225
+ .tooltip-popover.tooltip-info[data-placement='right']::before {
226
+ border-right-color: var(--color-info);
227
+ }
228
+ .tooltip-popover.tooltip-info[data-placement='left']::before {
229
+ border-left-color: var(--color-info);
230
+ }
231
+
232
+ .tooltip-popover.tooltip-success {
233
+ background-color: var(--color-success);
234
+ color: var(--color-success-content);
235
+ }
236
+ .tooltip-popover.tooltip-success[data-placement='bottom']::before {
237
+ border-bottom-color: var(--color-success);
238
+ }
239
+ .tooltip-popover.tooltip-success[data-placement='top']::before {
240
+ border-top-color: var(--color-success);
241
+ }
242
+ .tooltip-popover.tooltip-success[data-placement='right']::before {
243
+ border-right-color: var(--color-success);
244
+ }
245
+ .tooltip-popover.tooltip-success[data-placement='left']::before {
246
+ border-left-color: var(--color-success);
247
+ }
248
+
249
+ .tooltip-popover.tooltip-warning {
250
+ background-color: var(--color-warning);
251
+ color: var(--color-warning-content);
252
+ }
253
+ .tooltip-popover.tooltip-warning[data-placement='bottom']::before {
254
+ border-bottom-color: var(--color-warning);
255
+ }
256
+ .tooltip-popover.tooltip-warning[data-placement='top']::before {
257
+ border-top-color: var(--color-warning);
258
+ }
259
+ .tooltip-popover.tooltip-warning[data-placement='right']::before {
260
+ border-right-color: var(--color-warning);
261
+ }
262
+ .tooltip-popover.tooltip-warning[data-placement='left']::before {
263
+ border-left-color: var(--color-warning);
264
+ }
265
+
266
+ .tooltip-popover.tooltip-error {
267
+ background-color: var(--color-error);
268
+ color: var(--color-error-content);
269
+ }
270
+ .tooltip-popover.tooltip-error[data-placement='bottom']::before {
271
+ border-bottom-color: var(--color-error);
272
+ }
273
+ .tooltip-popover.tooltip-error[data-placement='top']::before {
274
+ border-top-color: var(--color-error);
275
+ }
276
+ .tooltip-popover.tooltip-error[data-placement='right']::before {
277
+ border-right-color: var(--color-error);
278
+ }
279
+ .tooltip-popover.tooltip-error[data-placement='left']::before {
280
+ border-left-color: var(--color-error);
281
+ }
282
+ }
283
+ </style>
@@ -0,0 +1,20 @@
1
+ <script setup>
2
+ import { inject } from 'vue'
3
+
4
+ const id = inject('tooltipId')
5
+ const targetEl = inject('targetEl')
6
+ </script>
7
+
8
+ <template>
9
+ <div
10
+ :id="id"
11
+ ref="targetEl"
12
+ :aria-describedby="`${id}-content`"
13
+ :popovertarget="`${id}-content`"
14
+ popovertargetaction="toggle"
15
+ :style="{ 'anchor-name': `--${id}` }"
16
+ class="tooltip-target inline-block"
17
+ >
18
+ <slot />
19
+ </div>
20
+ </template>