daisy-ui-kit 5.0.0-pre.10 → 5.0.0-pre.12
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.
- package/app/components/Accordion.vue +8 -5
- package/app/components/Alert.vue +2 -1
- package/app/components/Avatar.vue +10 -7
- package/app/components/AvatarGroup.vue +6 -2
- package/app/components/Badge.vue +14 -1
- package/app/components/Button.vue +60 -45
- package/app/components/Calendar.vue +24 -1
- package/app/components/CalendarInput.vue +2 -2
- package/app/components/CalendarSkeleton.vue +51 -10
- package/app/components/Card.vue +15 -2
- package/app/components/CardActions.vue +1 -1
- package/app/components/CardBody.vue +1 -1
- package/app/components/CardTitle.vue +1 -1
- package/app/components/Carousel.vue +2 -1
- package/app/components/Chat.vue +6 -1
- package/app/components/Checkbox.vue +1 -1
- package/app/components/Collapse.vue +37 -5
- package/app/components/CollapseTitle.vue +11 -1
- package/app/components/Countdown.vue +3 -3
- package/app/components/CountdownTimers.vue +4 -7
- package/app/components/Counter.vue +13 -2
- package/app/components/DaisyLink.vue +29 -15
- package/app/components/Dock.vue +1 -1
- package/app/components/DockItem.vue +1 -1
- package/app/components/Drawer.vue +15 -12
- package/app/components/DrawerContent.vue +9 -6
- package/app/components/DrawerSide.vue +9 -6
- package/app/components/Dropdown.vue +61 -50
- package/app/components/DropdownButton.vue +11 -4
- package/app/components/DropdownContent.vue +90 -19
- package/app/components/DropdownTarget.vue +9 -2
- package/app/components/Fab.vue +16 -0
- package/app/components/FabClose.vue +18 -0
- package/app/components/FabMainAction.vue +5 -0
- package/app/components/FabTrigger.vue +117 -0
- package/app/components/Fieldset.vue +1 -4
- package/app/components/FileInput.vue +1 -1
- package/app/components/Filter.vue +35 -32
- package/app/components/Flex.vue +3 -1
- package/app/components/FlexItem.vue +30 -27
- package/app/components/Footer.vue +16 -12
- package/app/components/FooterTitle.vue +8 -5
- package/app/components/Hero.vue +9 -6
- package/app/components/HeroContent.vue +9 -6
- package/app/components/Hover3D.vue +22 -0
- package/app/components/HoverGallery.vue +11 -0
- package/app/components/Indicator.vue +8 -5
- package/app/components/IndicatorItem.vue +16 -13
- package/app/components/Input.vue +47 -40
- package/app/components/Kbd.vue +2 -1
- package/app/components/Label.vue +32 -29
- package/app/components/MenuExpand.vue +1 -7
- package/app/components/MenuExpandToggle.vue +7 -1
- package/app/components/MenuItem.vue +6 -4
- package/app/components/Modal.vue +23 -17
- package/app/components/Progress.vue +13 -1
- package/app/components/Prose.vue +7 -2
- package/app/components/RadialProgress.vue +8 -8
- package/app/components/Radio.vue +1 -1
- package/app/components/RadioGroup.vue +2 -2
- package/app/components/Range.vue +2 -2
- package/app/components/RangeMeasure.vue +33 -30
- package/app/components/Rating.vue +70 -53
- package/app/components/Select.vue +44 -47
- package/app/components/SkeletonText.vue +11 -0
- package/app/components/Steps.vue +7 -2
- package/app/components/Swap.vue +4 -10
- package/app/components/Tab.vue +18 -5
- package/app/components/Text.vue +42 -22
- package/app/components/TextArea.vue +30 -27
- package/app/components/TextRotate.vue +24 -0
- package/app/components/ThemeController.vue +3 -4
- package/app/components/ThemeProvider.vue +47 -32
- package/app/components/TimelineLine.vue +1 -1
- package/app/components/TimelineStart.vue +2 -1
- package/app/components/Toast.vue +1 -6
- package/app/components/Toggle.vue +2 -2
- package/app/components/Tooltip.vue +2 -1
- package/app/utils/drawer-utils.ts +15 -13
- package/app/utils/position-area.ts +41 -0
- package/package.json +9 -7
|
@@ -1,25 +1,39 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
|
|
3
|
-
is?: string
|
|
4
|
-
hover?: boolean
|
|
2
|
+
import { computed } from 'vue'
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
const NuxtLink = resolveComponent('NuxtLink')
|
|
5
|
+
const RouterLink = resolveComponent('RouterLink')
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(
|
|
8
|
+
defineProps<{
|
|
9
|
+
is?: string
|
|
10
|
+
hover?: boolean
|
|
11
|
+
|
|
12
|
+
color?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'success' | 'info' | 'warning' | 'error'
|
|
13
|
+
neutral?: boolean
|
|
14
|
+
primary?: boolean
|
|
15
|
+
secondary?: boolean
|
|
16
|
+
accent?: boolean
|
|
17
|
+
success?: boolean
|
|
18
|
+
info?: boolean
|
|
19
|
+
warning?: boolean
|
|
20
|
+
error?: boolean
|
|
21
|
+
}>(),
|
|
22
|
+
{
|
|
23
|
+
is: 'a',
|
|
24
|
+
},
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
const resolvedComponent = computed(() => {
|
|
28
|
+
if (props.is === 'NuxtLink') return NuxtLink
|
|
29
|
+
if (props.is === 'RouterLink') return RouterLink
|
|
30
|
+
return props.is
|
|
17
31
|
})
|
|
18
32
|
</script>
|
|
19
33
|
|
|
20
34
|
<template>
|
|
21
35
|
<component
|
|
22
|
-
:is="
|
|
36
|
+
:is="resolvedComponent"
|
|
23
37
|
class="link"
|
|
24
38
|
:class="{
|
|
25
39
|
'link-neutral': neutral || color === 'neutral',
|
package/app/components/Dock.vue
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, watch } from 'vue'
|
|
3
|
-
import { createDrawerState } from '../utils/drawer-utils'
|
|
2
|
+
import { computed, watch } from 'vue'
|
|
3
|
+
import { createDrawerState } from '../utils/drawer-utils'
|
|
4
4
|
|
|
5
|
-
const props = withDefaults(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
const props = withDefaults(
|
|
6
|
+
defineProps<{
|
|
7
|
+
open?: boolean
|
|
8
|
+
name?: string
|
|
9
|
+
end?: boolean
|
|
10
|
+
}>(),
|
|
11
|
+
{
|
|
12
|
+
name: 'drawer',
|
|
13
|
+
},
|
|
14
|
+
)
|
|
12
15
|
const emit = defineEmits(['update:open'])
|
|
13
16
|
|
|
14
17
|
// sync `open` prop with drawerState.isDrawerOpen
|
|
15
18
|
const drawerState = createDrawerState(props.name)
|
|
16
19
|
watch(
|
|
17
20
|
() => props.open,
|
|
18
|
-
|
|
21
|
+
value => {
|
|
19
22
|
if (drawerState.isDrawerOpen !== value) {
|
|
20
23
|
drawerState.isDrawerOpen = value
|
|
21
24
|
}
|
|
@@ -24,7 +27,7 @@ watch(
|
|
|
24
27
|
)
|
|
25
28
|
watch(
|
|
26
29
|
() => drawerState.isDrawerOpen,
|
|
27
|
-
|
|
30
|
+
value => {
|
|
28
31
|
if (props.open !== value) {
|
|
29
32
|
emit('update:open', value)
|
|
30
33
|
}
|
|
@@ -41,7 +44,7 @@ const classes = computed(() => {
|
|
|
41
44
|
|
|
42
45
|
<template>
|
|
43
46
|
<div class="drawer" :class="classes">
|
|
44
|
-
<input :id="name" v-model="drawerState.isDrawerOpen" type="checkbox" class="drawer-toggle"
|
|
47
|
+
<input :id="name" v-model="drawerState.isDrawerOpen" type="checkbox" class="drawer-toggle" />
|
|
45
48
|
<slot v-bind="drawerState" />
|
|
46
49
|
</div>
|
|
47
50
|
</template>
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { createDrawerState } from '../utils/drawer-utils'
|
|
2
|
+
import { createDrawerState } from '../utils/drawer-utils'
|
|
3
3
|
|
|
4
|
-
const props = withDefaults(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
const props = withDefaults(
|
|
5
|
+
defineProps<{
|
|
6
|
+
name?: string
|
|
7
|
+
}>(),
|
|
8
|
+
{
|
|
9
|
+
name: 'drawer',
|
|
10
|
+
},
|
|
11
|
+
)
|
|
9
12
|
|
|
10
13
|
const drawerState = createDrawerState(props.name)
|
|
11
14
|
</script>
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { createDrawerState } from '../utils/drawer-utils'
|
|
2
|
+
import { createDrawerState } from '../utils/drawer-utils'
|
|
3
3
|
|
|
4
|
-
const props = withDefaults(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
const props = withDefaults(
|
|
5
|
+
defineProps<{
|
|
6
|
+
name?: string
|
|
7
|
+
}>(),
|
|
8
|
+
{
|
|
9
|
+
name: 'drawer',
|
|
10
|
+
},
|
|
11
|
+
)
|
|
9
12
|
|
|
10
13
|
const drawerState = createDrawerState(props.name)
|
|
11
14
|
</script>
|
|
@@ -1,54 +1,69 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { onMounted, provide,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
2
|
+
import { useId } from '#imports'
|
|
3
|
+
import { useElementHover } from '@vueuse/core'
|
|
4
|
+
import { onMounted, provide, ref, watch } from 'vue'
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(
|
|
7
|
+
defineProps<{
|
|
8
|
+
autoFocus?: boolean
|
|
9
|
+
|
|
10
|
+
placement?:
|
|
11
|
+
| 'top'
|
|
12
|
+
| 'top-start'
|
|
13
|
+
| 'top-end'
|
|
14
|
+
| 'right'
|
|
15
|
+
| 'right-start'
|
|
16
|
+
| 'right-end'
|
|
17
|
+
| 'bottom'
|
|
18
|
+
| 'bottom-start'
|
|
19
|
+
| 'bottom-end'
|
|
20
|
+
| 'left'
|
|
21
|
+
| 'left-start'
|
|
22
|
+
| 'left-end'
|
|
23
|
+
|
|
24
|
+
hover?: boolean
|
|
25
|
+
delayEnter?: number
|
|
26
|
+
delayLeave?: number
|
|
27
|
+
closeOnClickOutside?: boolean
|
|
28
|
+
}>(),
|
|
29
|
+
{
|
|
30
|
+
autoFocus: false,
|
|
31
|
+
placement: 'bottom-start',
|
|
32
|
+
hover: false,
|
|
33
|
+
delayEnter: 0,
|
|
34
|
+
delayLeave: 300,
|
|
35
|
+
closeOnClickOutside: true,
|
|
36
|
+
},
|
|
37
|
+
)
|
|
38
|
+
|
|
27
39
|
// Dropdown Visibility
|
|
28
|
-
const isOpen = defineModel('open')
|
|
40
|
+
const isOpen = defineModel('open', { default: false })
|
|
29
41
|
provide('isDropdownOpen', isOpen)
|
|
30
42
|
|
|
31
43
|
const autoFocus = ref(props.autoFocus)
|
|
32
44
|
provide('dropdownAutoFocus', autoFocus)
|
|
33
45
|
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
const
|
|
46
|
+
// Use Nuxt's useId() for unique IDs
|
|
47
|
+
const uniqueId = useId()
|
|
48
|
+
const wrapperId = `dropdown-wrapper-${uniqueId}`
|
|
49
|
+
const id = `dropdown-${uniqueId}`
|
|
37
50
|
provide('dropdownId', id)
|
|
38
51
|
|
|
39
|
-
//
|
|
52
|
+
// Provide placement for CSS anchor positioning
|
|
53
|
+
provide('dropdownPlacement', ref(props.placement))
|
|
54
|
+
|
|
55
|
+
// Provide closeOnClickOutside for popover mode selection
|
|
56
|
+
provide('dropdownCloseOnClickOutside', ref(props.closeOnClickOutside))
|
|
57
|
+
|
|
58
|
+
// Provide hover mode for button behavior
|
|
59
|
+
provide('dropdownHover', ref(props.hover))
|
|
60
|
+
|
|
61
|
+
// References
|
|
40
62
|
const buttonEl = ref(null)
|
|
41
63
|
const contentEl = ref(null)
|
|
42
|
-
const floatingConfig = reactive({
|
|
43
|
-
placement: ref(props.placement),
|
|
44
|
-
strategy: ref(props.strategy),
|
|
45
|
-
whileElementsMounted: autoUpdate,
|
|
46
|
-
})
|
|
47
|
-
const { floatingStyles } = useFloating(buttonEl, contentEl, floatingConfig)
|
|
48
64
|
|
|
49
65
|
provide('buttonEl', buttonEl)
|
|
50
66
|
provide('contentEl', contentEl)
|
|
51
|
-
provide('floatingStyles', floatingStyles)
|
|
52
67
|
|
|
53
68
|
// Visibility Utils
|
|
54
69
|
function toggle() {
|
|
@@ -67,29 +82,25 @@ provide('closeDropdown', close)
|
|
|
67
82
|
const dropdownWrapper = ref(null)
|
|
68
83
|
|
|
69
84
|
onMounted(() => {
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
setTimeout(() => {
|
|
75
|
-
isOpen.value = false
|
|
76
|
-
}, 50)
|
|
77
|
-
}
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
// Sync with top-level isHovered ref. For SSR compatibility.
|
|
85
|
+
// Note: closeOnClickOutside is handled automatically by popover="auto"
|
|
86
|
+
// The popover API provides "light dismiss" behavior by default
|
|
87
|
+
|
|
88
|
+
// Sync with hover state for SSR compatibility
|
|
81
89
|
if (props.hover) {
|
|
82
90
|
const hover = useElementHover(dropdownWrapper, {
|
|
83
91
|
delayLeave: props.delayLeave,
|
|
84
92
|
delayEnter: props.delayEnter,
|
|
85
93
|
})
|
|
86
|
-
|
|
94
|
+
|
|
95
|
+
watch(hover, newValue => {
|
|
96
|
+
isOpen.value = newValue
|
|
97
|
+
})
|
|
87
98
|
}
|
|
88
99
|
})
|
|
89
100
|
</script>
|
|
90
101
|
|
|
91
102
|
<template>
|
|
92
|
-
<div :id="wrapperId" ref="dropdownWrapper" class="relative inline-block
|
|
103
|
+
<div :id="wrapperId" ref="dropdownWrapper" class="relative inline-block">
|
|
93
104
|
<slot v-bind="{ toggle, open, close }" />
|
|
94
105
|
</div>
|
|
95
106
|
</template>
|
|
@@ -3,14 +3,21 @@ import { inject } from 'vue'
|
|
|
3
3
|
|
|
4
4
|
const id = inject('dropdownId')
|
|
5
5
|
const isOpen = inject('isDropdownOpen')
|
|
6
|
-
const toggleDropdown = inject('toggleDropdown')
|
|
7
6
|
const buttonEl = inject('buttonEl')
|
|
8
|
-
|
|
9
|
-
const toggle = toggleDropdown
|
|
7
|
+
const isHover = inject('dropdownHover')
|
|
10
8
|
</script>
|
|
11
9
|
|
|
12
10
|
<template>
|
|
13
|
-
<Button
|
|
11
|
+
<Button
|
|
12
|
+
:id="id"
|
|
13
|
+
ref="buttonEl"
|
|
14
|
+
:aria-expanded="isOpen"
|
|
15
|
+
aria-haspopup="menu"
|
|
16
|
+
:popovertarget="`${id}-content`"
|
|
17
|
+
:popovertargetaction="isHover ? 'show' : undefined"
|
|
18
|
+
:style="{ 'anchor-name': `--${id}` }"
|
|
19
|
+
class="dropdown-button"
|
|
20
|
+
>
|
|
14
21
|
<slot />
|
|
15
22
|
</Button>
|
|
16
23
|
</template>
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { inject, nextTick, ref, watchEffect } from 'vue'
|
|
3
2
|
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
|
|
3
|
+
import { computed, inject, nextTick, watch, watchEffect } from 'vue'
|
|
4
|
+
import { getPositionArea, getPositionFallbacks } from '../utils/position-area'
|
|
4
5
|
|
|
5
6
|
const autoFocus = inject('dropdownAutoFocus')
|
|
6
7
|
const id = inject('dropdownId')
|
|
7
8
|
const isOpen = inject('isDropdownOpen')
|
|
8
|
-
const isOpenDelayed = ref(isOpen.value)
|
|
9
9
|
const contentEl = inject('contentEl')
|
|
10
|
-
const
|
|
10
|
+
const placement = inject('dropdownPlacement')
|
|
11
|
+
const closeOnClickOutside = inject('dropdownCloseOnClickOutside')
|
|
11
12
|
|
|
12
13
|
// Dropdown Utils
|
|
13
14
|
const toggle = inject('toggleDropdown')
|
|
14
15
|
const open = inject('openDropdown')
|
|
15
16
|
const close = inject('closeDropdown')
|
|
16
17
|
|
|
18
|
+
// Compute CSS position-area value based on placement
|
|
19
|
+
const positionArea = computed(() => getPositionArea(placement.value))
|
|
20
|
+
const positionFallbacks = computed(() => getPositionFallbacks(placement.value))
|
|
21
|
+
|
|
22
|
+
// Determine popover mode: "auto" for light dismiss, "manual" to disable it
|
|
23
|
+
const popoverMode = computed(() => (closeOnClickOutside.value ? 'auto' : 'manual'))
|
|
24
|
+
|
|
17
25
|
let activate
|
|
18
26
|
let deactivate
|
|
19
27
|
|
|
@@ -29,28 +37,91 @@ if (autoFocus.value) {
|
|
|
29
37
|
}
|
|
30
38
|
})
|
|
31
39
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
|
|
41
|
+
// Sync popover state with isOpen model (for programmatic control)
|
|
42
|
+
watch(
|
|
43
|
+
isOpen,
|
|
44
|
+
async newValue => {
|
|
45
|
+
if (contentEl.value) {
|
|
46
|
+
try {
|
|
47
|
+
// Check current popover state
|
|
48
|
+
const isPopoverOpen = contentEl.value.matches(':popover-open')
|
|
49
|
+
|
|
50
|
+
// Only programmatically control if state differs
|
|
51
|
+
if (newValue && !isPopoverOpen) {
|
|
52
|
+
contentEl.value.showPopover()
|
|
53
|
+
if (autoFocus.value) {
|
|
54
|
+
await nextTick()
|
|
55
|
+
activate?.()
|
|
56
|
+
}
|
|
57
|
+
} else if (!newValue && isPopoverOpen) {
|
|
58
|
+
contentEl.value.hidePopover()
|
|
59
|
+
if (autoFocus.value) {
|
|
60
|
+
deactivate?.()
|
|
61
|
+
await nextTick()
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} catch (e) {
|
|
65
|
+
// Silently handle if popover API is not supported
|
|
66
|
+
console.warn('Popover API not supported:', e)
|
|
67
|
+
}
|
|
41
68
|
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
69
|
+
},
|
|
70
|
+
{ flush: 'post' },
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
// Listen to popover toggle events to sync back to isOpen model
|
|
74
|
+
function handleToggle(event) {
|
|
75
|
+
const newState = event.newState === 'open'
|
|
76
|
+
|
|
77
|
+
if (isOpen.value !== newState) {
|
|
78
|
+
isOpen.value = newState
|
|
79
|
+
|
|
80
|
+
if (newState && autoFocus.value) {
|
|
81
|
+
nextTick().then(() => activate?.())
|
|
82
|
+
} else if (!newState && autoFocus.value) {
|
|
83
|
+
deactivate?.()
|
|
46
84
|
}
|
|
47
|
-
isOpenDelayed.value = false
|
|
48
85
|
}
|
|
49
|
-
}
|
|
86
|
+
}
|
|
50
87
|
</script>
|
|
51
88
|
|
|
52
89
|
<template>
|
|
53
|
-
<div
|
|
90
|
+
<div
|
|
91
|
+
:id="`${id}-content`"
|
|
92
|
+
ref="contentEl"
|
|
93
|
+
:anchor="id"
|
|
94
|
+
:aria-labelledby="id"
|
|
95
|
+
role="menu"
|
|
96
|
+
:popover="popoverMode"
|
|
97
|
+
class="dropdown-content dropdown-popover"
|
|
98
|
+
:style="{
|
|
99
|
+
'position-anchor': `--${id}`,
|
|
100
|
+
'position-area': positionArea,
|
|
101
|
+
'position-try-fallbacks': positionFallbacks,
|
|
102
|
+
}"
|
|
103
|
+
@toggle="handleToggle"
|
|
104
|
+
>
|
|
54
105
|
<slot v-bind="{ toggle, open, close }" />
|
|
55
106
|
</div>
|
|
56
107
|
</template>
|
|
108
|
+
|
|
109
|
+
<style>
|
|
110
|
+
@layer components {
|
|
111
|
+
/* Reset default popover styles - in components layer so utilities can override */
|
|
112
|
+
.dropdown-popover[popover] {
|
|
113
|
+
border: none;
|
|
114
|
+
color: inherit;
|
|
115
|
+
overflow: visible;
|
|
116
|
+
/* Use auto for inset to allow anchor positioning to work */
|
|
117
|
+
inset: auto;
|
|
118
|
+
margin: 0;
|
|
119
|
+
background-color: transparent;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* Position anchoring support */
|
|
123
|
+
.dropdown-popover[popover]:popover-open {
|
|
124
|
+
position: fixed;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
</style>
|
|
@@ -3,12 +3,19 @@ import { inject } from 'vue'
|
|
|
3
3
|
|
|
4
4
|
const id = inject('dropdownId')
|
|
5
5
|
const isOpen = inject('isDropdownOpen')
|
|
6
|
-
const toggle = inject('toggleDropdown')
|
|
7
6
|
const buttonEl = inject('buttonEl')
|
|
8
7
|
</script>
|
|
9
8
|
|
|
10
9
|
<template>
|
|
11
|
-
<div
|
|
10
|
+
<div
|
|
11
|
+
:id="id"
|
|
12
|
+
ref="buttonEl"
|
|
13
|
+
:aria-expanded="isOpen"
|
|
14
|
+
aria-haspopup="menu"
|
|
15
|
+
:popovertarget="`${id}-content`"
|
|
16
|
+
:style="{ 'anchor-name': `--${id}` }"
|
|
17
|
+
class="dropdown-target"
|
|
18
|
+
>
|
|
12
19
|
<slot />
|
|
13
20
|
</div>
|
|
14
21
|
</template>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
function handleMouseDown(event: MouseEvent) {
|
|
3
|
+
event.preventDefault()
|
|
4
|
+
const fab = (event.currentTarget as HTMLElement)?.closest('.fab')
|
|
5
|
+
if (fab instanceof HTMLElement) {
|
|
6
|
+
fab.blur()
|
|
7
|
+
}
|
|
8
|
+
if (document.activeElement instanceof HTMLElement) {
|
|
9
|
+
document.activeElement.blur()
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<div class="fab-close" @mousedown="handleMouseDown">
|
|
16
|
+
<slot />
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
defineOptions({
|
|
3
|
+
inheritAttrs: false,
|
|
4
|
+
})
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(
|
|
7
|
+
defineProps<{
|
|
8
|
+
btn?: boolean
|
|
9
|
+
join?: boolean
|
|
10
|
+
close?: 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
|
+
ghost?: boolean
|
|
23
|
+
link?: boolean
|
|
24
|
+
glass?: boolean
|
|
25
|
+
outline?: boolean
|
|
26
|
+
dash?: boolean
|
|
27
|
+
soft?: boolean
|
|
28
|
+
|
|
29
|
+
shape?: 'circle' | 'square' | 'wide' | 'block'
|
|
30
|
+
circle?: boolean
|
|
31
|
+
square?: boolean
|
|
32
|
+
wide?: boolean
|
|
33
|
+
block?: boolean
|
|
34
|
+
|
|
35
|
+
noAnimation?: boolean
|
|
36
|
+
active?: boolean
|
|
37
|
+
|
|
38
|
+
size?: 'lg' | 'md' | 'sm' | 'xs' | 'xl'
|
|
39
|
+
xl?: boolean
|
|
40
|
+
lg?: boolean
|
|
41
|
+
md?: boolean
|
|
42
|
+
sm?: boolean
|
|
43
|
+
xs?: boolean
|
|
44
|
+
}>(),
|
|
45
|
+
{
|
|
46
|
+
btn: true,
|
|
47
|
+
},
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
function handleMouseDown(event: MouseEvent) {
|
|
51
|
+
if (!props.close) return
|
|
52
|
+
const fab = (event.currentTarget as HTMLElement)?.closest('.fab')
|
|
53
|
+
// Only close if FAB is already open (has focus within)
|
|
54
|
+
if (fab instanceof HTMLElement && fab.matches(':focus-within')) {
|
|
55
|
+
event.preventDefault()
|
|
56
|
+
fab.blur()
|
|
57
|
+
if (document.activeElement instanceof HTMLElement) {
|
|
58
|
+
document.activeElement.blur()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<template>
|
|
65
|
+
<div
|
|
66
|
+
tabindex="0"
|
|
67
|
+
role="button"
|
|
68
|
+
v-bind="$attrs"
|
|
69
|
+
:class="{
|
|
70
|
+
btn,
|
|
71
|
+
'join-item': join,
|
|
72
|
+
|
|
73
|
+
'btn-neutral': neutral || color === 'neutral',
|
|
74
|
+
'btn-primary': primary || color === 'primary',
|
|
75
|
+
'btn-secondary': secondary || color === 'secondary',
|
|
76
|
+
'btn-accent': accent || color === 'accent',
|
|
77
|
+
'btn-info': info || color === 'info',
|
|
78
|
+
'btn-success': success || color === 'success',
|
|
79
|
+
'btn-warning': warning || color === 'warning',
|
|
80
|
+
'btn-error': error || color === 'error',
|
|
81
|
+
|
|
82
|
+
'text-primary': (primary || color === 'primary') && link,
|
|
83
|
+
'text-secondary': (secondary || color === 'secondary') && link,
|
|
84
|
+
'text-neutral': (neutral || color === 'neutral') && link,
|
|
85
|
+
'text-accent': (accent || color === 'accent') && link,
|
|
86
|
+
'text-info': (info || color === 'info') && link,
|
|
87
|
+
'text-success': (success || color === 'success') && link,
|
|
88
|
+
'text-warning': (warning || color === 'warning') && link,
|
|
89
|
+
'text-error': (error || color === 'error') && link,
|
|
90
|
+
|
|
91
|
+
glass,
|
|
92
|
+
|
|
93
|
+
'btn-circle': circle || shape === 'circle',
|
|
94
|
+
'btn-square': square || shape === 'square',
|
|
95
|
+
'btn-wide': wide || shape === 'wide',
|
|
96
|
+
'btn-block': block || shape === 'block',
|
|
97
|
+
|
|
98
|
+
'btn-xl': xl || size === 'xl',
|
|
99
|
+
'btn-lg': lg || size === 'lg',
|
|
100
|
+
'btn-md': md || size === 'md',
|
|
101
|
+
'btn-sm': sm || size === 'sm',
|
|
102
|
+
'btn-xs': xs || size === 'xs',
|
|
103
|
+
|
|
104
|
+
'btn-outline': outline,
|
|
105
|
+
'btn-dash': dash,
|
|
106
|
+
'btn-ghost': ghost,
|
|
107
|
+
'btn-soft': soft,
|
|
108
|
+
'btn-link': link,
|
|
109
|
+
|
|
110
|
+
'no-animation': noAnimation,
|
|
111
|
+
'btn-active': active,
|
|
112
|
+
}"
|
|
113
|
+
@mousedown="handleMouseDown"
|
|
114
|
+
>
|
|
115
|
+
<slot />
|
|
116
|
+
</div>
|
|
117
|
+
</template>
|
|
@@ -6,10 +6,7 @@ const { is = 'fieldset', legend } = defineProps<{
|
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
8
|
<template>
|
|
9
|
-
<component
|
|
10
|
-
:is="is"
|
|
11
|
-
class="fieldset bg-base-200 border-base-300 rounded-box border p-4"
|
|
12
|
-
>
|
|
9
|
+
<component :is="is" class="fieldset bg-base-200 border-base-300 rounded-box border p-4">
|
|
13
10
|
<legend v-if="legend" class="fieldset-legend">
|
|
14
11
|
{{ legend }}
|
|
15
12
|
</legend>
|