base-ui-vue 0.3.0 → 0.5.0
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/dist/arrow/TooltipArrow.cjs +609 -0
- package/dist/arrow/TooltipArrow.cjs.map +1 -0
- package/dist/arrow/TooltipArrow.js +478 -0
- package/dist/arrow/TooltipArrow.js.map +1 -0
- package/dist/button/Button.cjs +5 -317
- package/dist/button/Button.cjs.map +1 -1
- package/dist/button/Button.js +3 -249
- package/dist/button/Button.js.map +1 -1
- package/dist/button/ToolbarButton.cjs +19 -6
- package/dist/button/ToolbarButton.cjs.map +1 -1
- package/dist/button/ToolbarButton.js +3 -2
- package/dist/button/ToolbarButton.js.map +1 -1
- package/dist/checkbox/index.cjs +20 -9
- package/dist/checkbox/index.cjs.map +1 -1
- package/dist/checkbox/index.js +7 -2
- package/dist/checkbox/index.js.map +1 -1
- package/dist/checkbox-group/CheckboxGroup.cjs +14 -13
- package/dist/checkbox-group/CheckboxGroup.cjs.map +1 -1
- package/dist/checkbox-group/CheckboxGroup.js +2 -1
- package/dist/checkbox-group/CheckboxGroup.js.map +1 -1
- package/dist/components/FloatingPortal.cjs +66 -0
- package/dist/components/FloatingPortal.cjs.map +1 -0
- package/dist/components/FloatingPortal.js +55 -0
- package/dist/components/FloatingPortal.js.map +1 -0
- package/dist/components/FloatingRootStore.cjs +101 -0
- package/dist/components/FloatingRootStore.cjs.map +1 -0
- package/dist/components/FloatingRootStore.js +84 -0
- package/dist/components/FloatingRootStore.js.map +1 -0
- package/dist/components/FloatingTree.cjs +33 -0
- package/dist/components/FloatingTree.cjs.map +1 -0
- package/dist/components/FloatingTree.js +22 -0
- package/dist/components/FloatingTree.js.map +1 -0
- package/dist/composite/composite.cjs +6 -0
- package/dist/composite/composite.js +1 -1
- package/dist/content/ScrollAreaContent.cjs +3 -3
- package/dist/content/ScrollAreaContent.cjs.map +1 -1
- package/dist/content/ScrollAreaContent.js +1 -1
- package/dist/control/FieldControl.cjs +3 -3
- package/dist/control/FieldControl.cjs.map +1 -1
- package/dist/control/FieldControl.js +1 -1
- package/dist/control/SliderControl.cjs +3 -3
- package/dist/control/SliderControl.cjs.map +1 -1
- package/dist/control/SliderControl.js +3 -3
- package/dist/corner/ScrollAreaCorner.cjs +3 -3
- package/dist/corner/ScrollAreaCorner.cjs.map +1 -1
- package/dist/corner/ScrollAreaCorner.js +1 -1
- package/dist/decrement/NumberFieldDecrement.cjs +868 -0
- package/dist/decrement/NumberFieldDecrement.cjs.map +1 -0
- package/dist/decrement/NumberFieldDecrement.js +701 -0
- package/dist/decrement/NumberFieldDecrement.js.map +1 -0
- package/dist/description/FieldDescription.cjs +2 -2
- package/dist/description/FieldDescription.cjs.map +1 -1
- package/dist/description/FieldDescription.js +1 -1
- package/dist/error/FieldError.cjs +2 -2
- package/dist/error/FieldError.cjs.map +1 -1
- package/dist/error/FieldError.js +1 -1
- package/dist/fallback/AvatarFallback.cjs +4 -48
- package/dist/fallback/AvatarFallback.cjs.map +1 -1
- package/dist/fallback/AvatarFallback.js +4 -42
- package/dist/fallback/AvatarFallback.js.map +1 -1
- package/dist/floating-ui-vue/index.js +638 -0
- package/dist/floating-ui-vue/index.js.map +1 -0
- package/dist/form/Form.cjs +3 -3
- package/dist/form/Form.cjs.map +1 -1
- package/dist/form/Form.js +1 -1
- package/dist/group/NumberFieldGroup.cjs +72 -0
- package/dist/group/NumberFieldGroup.cjs.map +1 -0
- package/dist/group/NumberFieldGroup.js +67 -0
- package/dist/group/NumberFieldGroup.js.map +1 -0
- package/dist/group/ToolbarGroup.cjs +2 -2
- package/dist/group/ToolbarGroup.cjs.map +1 -1
- package/dist/group/ToolbarGroup.js +1 -1
- package/dist/header/AccordionHeader.cjs +2 -2
- package/dist/header/AccordionHeader.cjs.map +1 -1
- package/dist/header/AccordionHeader.js +1 -1
- package/dist/hooks/useDismiss.cjs +502 -0
- package/dist/hooks/useDismiss.cjs.map +1 -0
- package/dist/hooks/useHoverFloatingInteraction.cjs +233 -0
- package/dist/hooks/useHoverFloatingInteraction.cjs.map +1 -0
- package/dist/image/AvatarImage.cjs +4 -4
- package/dist/image/AvatarImage.cjs.map +1 -1
- package/dist/image/AvatarImage.js +1 -1
- package/dist/increment/NumberFieldIncrement.cjs +113 -0
- package/dist/increment/NumberFieldIncrement.cjs.map +1 -0
- package/dist/increment/NumberFieldIncrement.js +108 -0
- package/dist/increment/NumberFieldIncrement.js.map +1 -0
- package/dist/index.cjs +80 -8
- package/dist/index.d.cts +4328 -1600
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +4328 -1600
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index2.cjs +9435 -3236
- package/dist/index2.cjs.map +1 -1
- package/dist/index2.js +8905 -3049
- package/dist/index2.js.map +1 -1
- package/dist/rolldown-runtime.js +36 -0
- package/package.json +1 -1
- package/src/floating-ui-vue/components/FloatingPortal.ts +171 -0
- package/src/floating-ui-vue/components/FloatingPortal.vue +259 -0
- package/src/floating-ui-vue/components/FloatingRootStore.ts +83 -0
- package/src/floating-ui-vue/components/FloatingTree.ts +64 -0
- package/src/floating-ui-vue/components/FloatingTreeStore.ts +21 -0
- package/src/floating-ui-vue/hooks/useDismiss.ts +689 -0
- package/src/floating-ui-vue/hooks/useHoverFloatingInteraction.ts +244 -0
- package/src/floating-ui-vue/hooks/useHoverInteractionSharedState.ts +125 -0
- package/src/floating-ui-vue/hooks/useHoverShared.ts +53 -0
- package/src/floating-ui-vue/index.ts +48 -0
- package/src/floating-ui-vue/middleware/arrow.ts +114 -0
- package/src/floating-ui-vue/types.ts +117 -0
- package/src/floating-ui-vue/utils/composite.ts +20 -0
- package/src/floating-ui-vue/utils/constants.ts +2 -0
- package/src/floating-ui-vue/utils/createAttribute.ts +3 -0
- package/src/floating-ui-vue/utils/createEventEmitter.ts +20 -0
- package/src/floating-ui-vue/utils/element.ts +59 -0
- package/src/floating-ui-vue/utils/event.ts +15 -0
- package/src/floating-ui-vue/utils/nodes.ts +14 -0
- package/src/floating-ui-vue/utils/tabbable.ts +309 -0
- package/src/index.ts +7 -1
- package/src/number-field/decrement/NumberFieldDecrement.vue +109 -0
- package/src/number-field/group/NumberFieldGroup.vue +47 -0
- package/src/number-field/increment/NumberFieldIncrement.vue +109 -0
- package/src/number-field/index.ts +42 -0
- package/src/number-field/input/NumberFieldInput.vue +455 -0
- package/src/number-field/root/NumberFieldRoot.vue +626 -0
- package/src/number-field/root/NumberFieldRootContext.ts +94 -0
- package/src/number-field/root/useNumberFieldButton.ts +171 -0
- package/src/number-field/scrub-area/NumberFieldScrubArea.vue +359 -0
- package/src/number-field/scrub-area/NumberFieldScrubAreaContext.ts +26 -0
- package/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.vue +75 -0
- package/src/number-field/utils/constants.ts +4 -0
- package/src/number-field/utils/getViewportRect.ts +34 -0
- package/src/number-field/utils/parse.ts +248 -0
- package/src/number-field/utils/stateAttributesMapping.ts +9 -0
- package/src/number-field/utils/subscribeToVisualViewportResize.ts +27 -0
- package/src/number-field/utils/types.ts +24 -0
- package/src/number-field/utils/validate.ts +120 -0
- package/src/otp-field/index.ts +22 -0
- package/src/otp-field/input/OtpFieldInput.vue +336 -0
- package/src/otp-field/root/OtpFieldRoot.vue +583 -0
- package/src/otp-field/root/OtpFieldRootContext.ts +81 -0
- package/src/otp-field/utils/otp.ts +135 -0
- package/src/otp-field/utils/stateAttributesMapping.ts +16 -0
- package/src/radio/index.ts +28 -0
- package/src/radio/indicator/RadioIndicator.vue +90 -0
- package/src/radio/indicator/RadioIndicatorDataAttributes.ts +54 -0
- package/src/radio/root/RadioRoot.vue +544 -0
- package/src/radio/root/RadioRootContext.ts +18 -0
- package/src/radio/root/RadioRootDataAttributes.ts +46 -0
- package/src/radio/utils/stateAttributesMapping.ts +29 -0
- package/src/radio-group/RadioGroup.vue +381 -0
- package/src/radio-group/RadioGroupContext.ts +42 -0
- package/src/radio-group/RadioGroupDataAttributes.ts +6 -0
- package/src/radio-group/index.ts +10 -0
- package/src/tabs/index.ts +38 -0
- package/src/tabs/indicator/TabsIndicator.vue +201 -0
- package/src/tabs/indicator/TabsIndicatorCssVars.ts +26 -0
- package/src/tabs/indicator/TabsIndicatorDataAttributes.ts +12 -0
- package/src/tabs/indicator/prehydrationScript.min.ts +5 -0
- package/src/tabs/indicator/prehydrationScript.template.js +87 -0
- package/src/tabs/list/TabsList.vue +201 -0
- package/src/tabs/list/TabsListContext.ts +29 -0
- package/src/tabs/list/TabsListDataAttributes.ts +12 -0
- package/src/tabs/panel/TabsPanel.vue +167 -0
- package/src/tabs/panel/TabsPanelDataAttributes.ts +28 -0
- package/src/tabs/root/TabsRoot.vue +468 -0
- package/src/tabs/root/TabsRootContext.ts +56 -0
- package/src/tabs/root/TabsRootDataAttributes.ts +12 -0
- package/src/tabs/root/stateAttributesMapping.ts +9 -0
- package/src/tabs/tab/TabsTab.vue +274 -0
- package/src/tabs/tab/TabsTabDataAttributes.ts +20 -0
- package/src/tabs/utils/areTabValuesEqual.ts +6 -0
- package/src/tooltip/arrow/TooltipArrow.vue +116 -0
- package/src/tooltip/arrow/TooltipArrowDataAttributes.ts +31 -0
- package/src/tooltip/index.ts +54 -0
- package/src/tooltip/popup/TooltipPopup.vue +142 -0
- package/src/tooltip/popup/TooltipPopupDataAttributes.ts +35 -0
- package/src/tooltip/portal/TooltipPortal.vue +83 -0
- package/src/tooltip/portal/TooltipPortalContext.ts +19 -0
- package/src/tooltip/positioner/TooltipPositioner.vue +221 -0
- package/src/tooltip/positioner/TooltipPositionerContext.ts +23 -0
- package/src/tooltip/positioner/TooltipPositionerCssVars.ts +27 -0
- package/src/tooltip/positioner/TooltipPositionerDataAttributes.ts +26 -0
- package/src/tooltip/provider/TooltipProvider.vue +78 -0
- package/src/tooltip/provider/TooltipProviderContext.ts +19 -0
- package/src/tooltip/root/TooltipRoot.vue +401 -0
- package/src/tooltip/root/TooltipRootContext.ts +71 -0
- package/src/tooltip/store/TooltipHandle.ts +215 -0
- package/src/tooltip/trigger/TooltipTrigger.vue +343 -0
- package/src/tooltip/trigger/TooltipTriggerDataAttributes.ts +12 -0
- package/src/tooltip/utils/constants.ts +2 -0
- package/src/tooltip/viewport/TooltipViewport.vue +149 -0
- package/src/tooltip/viewport/TooltipViewportCssVars.ts +14 -0
- package/src/tooltip/viewport/TooltipViewportDataAttributes.ts +26 -0
- package/src/utils/FloatingPortalLite.vue +66 -0
- package/src/utils/FocusGuard.vue +36 -0
- package/src/utils/adaptiveOriginMiddleware.ts +79 -0
- package/src/utils/addEventListener.ts +16 -0
- package/src/utils/constants.ts +11 -0
- package/src/utils/createBaseUIEventDetails.ts +2 -0
- package/src/utils/detectBrowser.ts +15 -0
- package/src/utils/formatNumber.ts +35 -2
- package/src/utils/getCssDimensions.ts +19 -0
- package/src/utils/getDisabledMountTransitionStyles.ts +9 -0
- package/src/utils/hideMiddleware.ts +19 -0
- package/src/utils/mergeCleanups.ts +7 -0
- package/src/utils/platform.ts +18 -0
- package/src/utils/popupStateMapping.ts +103 -0
- package/src/utils/reasons.ts +4 -0
- package/src/utils/serializeValue.ts +17 -0
- package/src/utils/useAnchorPositioning.ts +644 -0
- package/src/utils/useInterval.ts +45 -0
- package/src/utils/usePopupAutoResize.ts +254 -0
- package/src/utils/usePopupViewport.ts +398 -0
- package/src/utils/usePositioner.ts +61 -0
- package/src/utils/usePressAndHold.ts +260 -0
- package/src/utils/useRenderElement.ts +3 -0
- package/src/utils/useValueChanged.ts +21 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
<script setup lang="ts" generic="Payload = unknown">
|
|
2
|
+
import type { BaseUIChangeEventDetails } from '../../utils/createBaseUIEventDetails'
|
|
3
|
+
import type { REASONS as TooltipReasons } from '../../utils/reasons'
|
|
4
|
+
import type { BaseUIComponentProps } from '../../utils/types'
|
|
5
|
+
import type { TooltipHandle } from '../store/TooltipHandle'
|
|
6
|
+
import type { TooltipRootContext } from './TooltipRootContext'
|
|
7
|
+
import { computed, getCurrentInstance, onScopeDispose, provide, shallowRef, toRef, watch } from 'vue'
|
|
8
|
+
import { useDismiss } from '../../floating-ui-vue'
|
|
9
|
+
import { createFloatingRootContext } from '../../floating-ui-vue/components/FloatingRootStore'
|
|
10
|
+
import { REASONS } from '../../utils/reasons'
|
|
11
|
+
import { useControllableState } from '../../utils/useControllableState'
|
|
12
|
+
import { useTimeout } from '../../utils/useTimeout'
|
|
13
|
+
import { useTransitionStatus } from '../../utils/useTransitionStatus'
|
|
14
|
+
import { useTooltipProviderContext } from '../provider/TooltipProviderContext'
|
|
15
|
+
import { createTooltipChangeEventDetails, TooltipStore } from '../store/TooltipHandle'
|
|
16
|
+
import { OPEN_DELAY } from '../utils/constants'
|
|
17
|
+
import { tooltipRootContextKey } from './TooltipRootContext'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Groups all parts of the tooltip.
|
|
21
|
+
* Doesn't render its own HTML element.
|
|
22
|
+
*
|
|
23
|
+
* Documentation: [Base UI Vue Tooltip](https://baseui-vue.com/docs/components/tooltip)
|
|
24
|
+
*/
|
|
25
|
+
defineOptions({
|
|
26
|
+
name: 'TooltipRoot',
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const props = withDefaults(defineProps<TooltipRootProps<Payload>>(), {
|
|
30
|
+
defaultOpen: false,
|
|
31
|
+
disableHoverablePopup: false,
|
|
32
|
+
trackCursorAxis: 'none',
|
|
33
|
+
disabled: false,
|
|
34
|
+
defaultTriggerId: null,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const emit = defineEmits<{
|
|
38
|
+
(e: 'openChange', open: boolean, details: TooltipRootChangeEventDetails): void
|
|
39
|
+
(e: 'openChangeComplete', open: boolean): void
|
|
40
|
+
}>()
|
|
41
|
+
|
|
42
|
+
const instance = getCurrentInstance()
|
|
43
|
+
|
|
44
|
+
const isOpenControlled = computed(() => {
|
|
45
|
+
const vnodeProps = instance?.vnode.props as Record<string, unknown> | null | undefined
|
|
46
|
+
return Boolean(vnodeProps && 'open' in vnodeProps)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const isTriggerIdControlled = computed(() => {
|
|
50
|
+
const vnodeProps = instance?.vnode.props as Record<string, unknown> | null | undefined
|
|
51
|
+
return Boolean(vnodeProps && ('triggerId' in vnodeProps || 'trigger-id' in vnodeProps))
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const localStore = new TooltipStore<Payload>()
|
|
55
|
+
const store = props.handle?.store ?? localStore
|
|
56
|
+
|
|
57
|
+
const provider = useTooltipProviderContext()
|
|
58
|
+
const closeTimer = useTimeout()
|
|
59
|
+
|
|
60
|
+
const uncontrolledTriggerId = shallowRef<string | null>(props.defaultTriggerId ?? null)
|
|
61
|
+
const activeTriggerId = computed({
|
|
62
|
+
get() {
|
|
63
|
+
return isTriggerIdControlled.value ? props.triggerId ?? null : uncontrolledTriggerId.value
|
|
64
|
+
},
|
|
65
|
+
set(next: string | null) {
|
|
66
|
+
if (!isTriggerIdControlled.value) {
|
|
67
|
+
uncontrolledTriggerId.value = next
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const { value: openState, setValue: setOpenState } = useControllableState<boolean>({
|
|
73
|
+
controlled: () => (isOpenControlled.value ? props.open : undefined),
|
|
74
|
+
default: () => props.defaultOpen ?? false,
|
|
75
|
+
name: 'TooltipRoot',
|
|
76
|
+
state: 'open',
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const disabled = toRef(props, 'disabled')
|
|
80
|
+
const disableHoverablePopup = toRef(props, 'disableHoverablePopup')
|
|
81
|
+
const trackCursorAxis = toRef(props, 'trackCursorAxis')
|
|
82
|
+
const open = computed(() => !disabled.value && openState.value)
|
|
83
|
+
const hasViewport = shallowRef(false)
|
|
84
|
+
|
|
85
|
+
const { mounted, setMounted, transitionStatus } = useTransitionStatus(open, true, true)
|
|
86
|
+
|
|
87
|
+
const instantType = shallowRef<TooltipInstantType>(undefined)
|
|
88
|
+
const preventUnmountOnClose = shallowRef(false)
|
|
89
|
+
|
|
90
|
+
const popupId = shallowRef<string | undefined>(undefined)
|
|
91
|
+
const popupRef = shallowRef<HTMLElement | null>(null)
|
|
92
|
+
const positionerRef = shallowRef<HTMLElement | null>(null)
|
|
93
|
+
const popupWidth = shallowRef<number | undefined>(undefined)
|
|
94
|
+
const popupHeight = shallowRef<number | undefined>(undefined)
|
|
95
|
+
|
|
96
|
+
const activeTrigger = computed(() =>
|
|
97
|
+
store.getTrigger(activeTriggerId.value) as ReturnType<typeof store.getTrigger>,
|
|
98
|
+
)
|
|
99
|
+
const payload = computed(() => activeTrigger.value?.payload as Payload | undefined)
|
|
100
|
+
|
|
101
|
+
function getOpenDelay(triggerDelay: number | undefined) {
|
|
102
|
+
return provider?.getOpenDelay(triggerDelay) ?? {
|
|
103
|
+
delay: triggerDelay ?? OPEN_DELAY,
|
|
104
|
+
instant: false,
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function getCloseDelay(triggerCloseDelay: number | undefined) {
|
|
109
|
+
return provider?.getCloseDelay(triggerCloseDelay) ?? triggerCloseDelay ?? 0
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function requestOpenChange(
|
|
113
|
+
nextOpen: boolean,
|
|
114
|
+
details: TooltipRootChangeEventDetails,
|
|
115
|
+
triggerId?: string | null,
|
|
116
|
+
) {
|
|
117
|
+
if (nextOpen && disabled.value) {
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const nextTriggerId = triggerId === undefined ? activeTriggerId.value : triggerId
|
|
122
|
+
const triggerChanged = nextTriggerId !== activeTriggerId.value
|
|
123
|
+
|
|
124
|
+
if (nextOpen === openState.value && !triggerChanged) {
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
preventUnmountOnClose.value = false
|
|
129
|
+
details.preventUnmountOnClose = () => {
|
|
130
|
+
preventUnmountOnClose.value = true
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
emit('openChange', nextOpen, details)
|
|
134
|
+
|
|
135
|
+
if (details.isCanceled) {
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
floatingRootContext.dispatchOpenChange(nextOpen, details)
|
|
140
|
+
|
|
141
|
+
if (triggerId !== undefined) {
|
|
142
|
+
activeTriggerId.value = triggerId
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (nextOpen) {
|
|
146
|
+
provider?.notifyOpen()
|
|
147
|
+
|
|
148
|
+
if (!mounted.value) {
|
|
149
|
+
setMounted(true)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (details.reason === REASONS.triggerFocus) {
|
|
153
|
+
instantType.value = 'focus'
|
|
154
|
+
}
|
|
155
|
+
else if (details.reason !== REASONS.triggerHover) {
|
|
156
|
+
instantType.value = undefined
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
provider?.notifyClose()
|
|
161
|
+
|
|
162
|
+
if (details.reason === REASONS.triggerPress || details.reason === REASONS.escapeKey) {
|
|
163
|
+
instantType.value = 'dismiss'
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
instantType.value = undefined
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
setOpenState(nextOpen)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function scheduleClose(
|
|
174
|
+
delay: number,
|
|
175
|
+
details: TooltipRootChangeEventDetails,
|
|
176
|
+
triggerId?: string | null,
|
|
177
|
+
) {
|
|
178
|
+
closeTimer.clear()
|
|
179
|
+
|
|
180
|
+
if (delay <= 0) {
|
|
181
|
+
requestOpenChange(false, details, triggerId)
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
closeTimer.start(delay, () => {
|
|
186
|
+
requestOpenChange(false, details, triggerId)
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function forceUnmount() {
|
|
191
|
+
closeTimer.clear()
|
|
192
|
+
setMounted(false)
|
|
193
|
+
preventUnmountOnClose.value = false
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function completeOpenChange() {
|
|
197
|
+
emit('openChangeComplete', open.value)
|
|
198
|
+
|
|
199
|
+
if (!open.value && !preventUnmountOnClose.value) {
|
|
200
|
+
setMounted(false)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (!open.value) {
|
|
204
|
+
preventUnmountOnClose.value = false
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function close() {
|
|
209
|
+
requestOpenChange(
|
|
210
|
+
false,
|
|
211
|
+
createTooltipChangeEventDetails(REASONS.imperativeAction),
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function maybeActivateTrigger(id: string) {
|
|
216
|
+
if (open.value && activeTriggerId.value == null) {
|
|
217
|
+
activeTriggerId.value = id
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
watch(disabled, (isDisabled) => {
|
|
222
|
+
if (isDisabled && openState.value) {
|
|
223
|
+
requestOpenChange(
|
|
224
|
+
false,
|
|
225
|
+
createTooltipChangeEventDetails(REASONS.disabled),
|
|
226
|
+
)
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
watch(open, (isOpen) => {
|
|
231
|
+
if (isOpen && mounted.value === false) {
|
|
232
|
+
setMounted(true)
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
const floatingRootContext = createFloatingRootContext({
|
|
237
|
+
open,
|
|
238
|
+
transitionStatus,
|
|
239
|
+
domReferenceElement: () => activeTrigger.value?.element ?? null,
|
|
240
|
+
referenceElement: () => activeTrigger.value?.element ?? null,
|
|
241
|
+
floatingElement: () => popupRef.value,
|
|
242
|
+
floatingId: () => popupId.value,
|
|
243
|
+
triggerElements: store.triggerElements,
|
|
244
|
+
clearCloseTimer: closeTimer.clear,
|
|
245
|
+
onOpenChange(nextOpen, details) {
|
|
246
|
+
requestOpenChange(
|
|
247
|
+
nextOpen,
|
|
248
|
+
details as TooltipRootChangeEventDetails,
|
|
249
|
+
)
|
|
250
|
+
},
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
const dismiss = useDismiss(floatingRootContext, {
|
|
254
|
+
enabled: () => !disabled.value,
|
|
255
|
+
referencePress: () => activeTrigger.value?.closeOnClick ?? true,
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
store.controller.value = {
|
|
259
|
+
open,
|
|
260
|
+
dismiss,
|
|
261
|
+
activeTriggerId,
|
|
262
|
+
disabled,
|
|
263
|
+
disableHoverablePopup,
|
|
264
|
+
trackCursorAxis,
|
|
265
|
+
instantType,
|
|
266
|
+
popupId,
|
|
267
|
+
requestOpenChange,
|
|
268
|
+
getOpenDelay,
|
|
269
|
+
getCloseDelay,
|
|
270
|
+
scheduleClose,
|
|
271
|
+
clearCloseTimer: closeTimer.clear,
|
|
272
|
+
forceUnmount,
|
|
273
|
+
maybeActivateTrigger,
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
onScopeDispose(() => {
|
|
277
|
+
if (store.controller.value?.requestOpenChange === requestOpenChange) {
|
|
278
|
+
store.controller.value = null
|
|
279
|
+
}
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
const context: TooltipRootContext<Payload> = {
|
|
283
|
+
store,
|
|
284
|
+
floatingRootContext,
|
|
285
|
+
dismiss,
|
|
286
|
+
open,
|
|
287
|
+
mounted,
|
|
288
|
+
transitionStatus,
|
|
289
|
+
disabled,
|
|
290
|
+
disableHoverablePopup,
|
|
291
|
+
trackCursorAxis,
|
|
292
|
+
hasViewport,
|
|
293
|
+
instantType,
|
|
294
|
+
activeTriggerId,
|
|
295
|
+
activeTrigger,
|
|
296
|
+
payload,
|
|
297
|
+
popupId,
|
|
298
|
+
popupRef,
|
|
299
|
+
positionerRef,
|
|
300
|
+
popupWidth,
|
|
301
|
+
popupHeight,
|
|
302
|
+
requestOpenChange,
|
|
303
|
+
getOpenDelay,
|
|
304
|
+
getCloseDelay,
|
|
305
|
+
scheduleClose,
|
|
306
|
+
clearCloseTimer: closeTimer.clear,
|
|
307
|
+
completeOpenChange,
|
|
308
|
+
setMounted,
|
|
309
|
+
setPopupId(id: string | undefined) {
|
|
310
|
+
popupId.value = id
|
|
311
|
+
},
|
|
312
|
+
setHasViewport(next: boolean) {
|
|
313
|
+
hasViewport.value = next
|
|
314
|
+
},
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
provide(tooltipRootContextKey, context)
|
|
318
|
+
|
|
319
|
+
defineExpose<TooltipRootActions>({
|
|
320
|
+
close,
|
|
321
|
+
unmount: forceUnmount,
|
|
322
|
+
})
|
|
323
|
+
</script>
|
|
324
|
+
|
|
325
|
+
<script lang="ts">
|
|
326
|
+
export type TooltipInstantType = 'delay' | 'dismiss' | 'focus' | undefined
|
|
327
|
+
export type TooltipTrackCursorAxis = 'none' | 'x' | 'y' | 'both'
|
|
328
|
+
|
|
329
|
+
export interface TooltipRootState {}
|
|
330
|
+
|
|
331
|
+
export interface TooltipRootProps<Payload = unknown>
|
|
332
|
+
extends BaseUIComponentProps<TooltipRootState> {
|
|
333
|
+
/**
|
|
334
|
+
* Whether the tooltip is initially open.
|
|
335
|
+
*
|
|
336
|
+
* To render a controlled tooltip, use the `open` prop instead.
|
|
337
|
+
* @default false
|
|
338
|
+
*/
|
|
339
|
+
defaultOpen?: boolean
|
|
340
|
+
/**
|
|
341
|
+
* Whether the tooltip is currently open.
|
|
342
|
+
*/
|
|
343
|
+
open?: boolean
|
|
344
|
+
/**
|
|
345
|
+
* Whether the tooltip contents can be hovered without closing the tooltip.
|
|
346
|
+
* @default false
|
|
347
|
+
*/
|
|
348
|
+
disableHoverablePopup?: boolean
|
|
349
|
+
/**
|
|
350
|
+
* Determines which axis the tooltip should track the cursor on.
|
|
351
|
+
* @default 'none'
|
|
352
|
+
*/
|
|
353
|
+
trackCursorAxis?: TooltipTrackCursorAxis
|
|
354
|
+
/**
|
|
355
|
+
* Whether the tooltip is disabled.
|
|
356
|
+
* @default false
|
|
357
|
+
*/
|
|
358
|
+
disabled?: boolean
|
|
359
|
+
/**
|
|
360
|
+
* A handle to associate the tooltip with a trigger.
|
|
361
|
+
* If specified, allows external triggers to control the tooltip's open state.
|
|
362
|
+
* Can be created with the `createTooltipHandle()` function.
|
|
363
|
+
*/
|
|
364
|
+
handle?: TooltipHandle<Payload>
|
|
365
|
+
/**
|
|
366
|
+
* ID of the trigger that the tooltip is associated with.
|
|
367
|
+
* This is useful in conjunction with the `open` prop to create a controlled tooltip.
|
|
368
|
+
* There's no need to specify this prop when the tooltip is uncontrolled (that is, when the `open` prop is not set).
|
|
369
|
+
*/
|
|
370
|
+
triggerId?: string | null
|
|
371
|
+
/**
|
|
372
|
+
* ID of the trigger that the tooltip is associated with.
|
|
373
|
+
* This is useful in conjunction with the `defaultOpen` prop to create an initially open tooltip.
|
|
374
|
+
*/
|
|
375
|
+
defaultTriggerId?: string | null
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export interface TooltipRootActions {
|
|
379
|
+
unmount: () => void
|
|
380
|
+
close: () => void
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export type TooltipRootChangeEventReason
|
|
384
|
+
= | typeof TooltipReasons.triggerHover
|
|
385
|
+
| typeof TooltipReasons.triggerFocus
|
|
386
|
+
| typeof TooltipReasons.triggerPress
|
|
387
|
+
| typeof TooltipReasons.outsidePress
|
|
388
|
+
| typeof TooltipReasons.escapeKey
|
|
389
|
+
| typeof TooltipReasons.disabled
|
|
390
|
+
| typeof TooltipReasons.imperativeAction
|
|
391
|
+
| typeof TooltipReasons.none
|
|
392
|
+
|
|
393
|
+
export type TooltipRootChangeEventDetails
|
|
394
|
+
= BaseUIChangeEventDetails<TooltipRootChangeEventReason, {
|
|
395
|
+
preventUnmountOnClose: () => void
|
|
396
|
+
}>
|
|
397
|
+
</script>
|
|
398
|
+
|
|
399
|
+
<template>
|
|
400
|
+
<slot :payload="payload" :state="{ open }" />
|
|
401
|
+
</template>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ComputedRef,
|
|
3
|
+
InjectionKey,
|
|
4
|
+
Ref,
|
|
5
|
+
ShallowRef,
|
|
6
|
+
} from 'vue'
|
|
7
|
+
import type { ElementProps, FloatingRootContext } from '../../floating-ui-vue/types'
|
|
8
|
+
import type { TransitionStatus } from '../../utils/useTransitionStatus'
|
|
9
|
+
import type { TooltipStore, TooltipTriggerRecord } from '../store/TooltipHandle'
|
|
10
|
+
import type {
|
|
11
|
+
TooltipInstantType,
|
|
12
|
+
TooltipRootChangeEventDetails,
|
|
13
|
+
TooltipTrackCursorAxis,
|
|
14
|
+
} from './TooltipRoot.vue'
|
|
15
|
+
import { inject } from 'vue'
|
|
16
|
+
|
|
17
|
+
export interface TooltipRootContext<Payload = unknown> {
|
|
18
|
+
store: TooltipStore<Payload>
|
|
19
|
+
floatingRootContext: FloatingRootContext
|
|
20
|
+
dismiss: ElementProps
|
|
21
|
+
open: Readonly<Ref<boolean>>
|
|
22
|
+
mounted: Ref<boolean>
|
|
23
|
+
transitionStatus: Ref<TransitionStatus>
|
|
24
|
+
disabled: Readonly<Ref<boolean>>
|
|
25
|
+
disableHoverablePopup: Readonly<Ref<boolean>>
|
|
26
|
+
trackCursorAxis: Readonly<Ref<TooltipTrackCursorAxis>>
|
|
27
|
+
hasViewport: Ref<boolean>
|
|
28
|
+
instantType: Ref<TooltipInstantType>
|
|
29
|
+
activeTriggerId: Ref<string | null>
|
|
30
|
+
activeTrigger: ComputedRef<TooltipTriggerRecord<Payload> | undefined>
|
|
31
|
+
payload: ComputedRef<Payload | undefined>
|
|
32
|
+
popupId: Ref<string | undefined>
|
|
33
|
+
popupRef: Ref<HTMLElement | null>
|
|
34
|
+
positionerRef: Ref<HTMLElement | null>
|
|
35
|
+
popupWidth: ShallowRef<number | undefined>
|
|
36
|
+
popupHeight: ShallowRef<number | undefined>
|
|
37
|
+
requestOpenChange: (
|
|
38
|
+
nextOpen: boolean,
|
|
39
|
+
details: TooltipRootChangeEventDetails,
|
|
40
|
+
triggerId?: string | null,
|
|
41
|
+
) => void
|
|
42
|
+
getOpenDelay: (triggerDelay: number | undefined) => { delay: number, instant: boolean }
|
|
43
|
+
getCloseDelay: (triggerCloseDelay: number | undefined) => number
|
|
44
|
+
scheduleClose: (
|
|
45
|
+
delay: number,
|
|
46
|
+
details: TooltipRootChangeEventDetails,
|
|
47
|
+
triggerId?: string | null,
|
|
48
|
+
) => void
|
|
49
|
+
clearCloseTimer: () => void
|
|
50
|
+
completeOpenChange: () => void
|
|
51
|
+
setMounted: (next: boolean) => void
|
|
52
|
+
setPopupId: (id: string | undefined) => void
|
|
53
|
+
setHasViewport: (next: boolean) => void
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const tooltipRootContextKey: InjectionKey<TooltipRootContext>
|
|
57
|
+
= Symbol('TooltipRootContext')
|
|
58
|
+
|
|
59
|
+
export function useTooltipRootContext(optional?: false): TooltipRootContext
|
|
60
|
+
export function useTooltipRootContext(optional: true): TooltipRootContext | undefined
|
|
61
|
+
export function useTooltipRootContext(optional = false): TooltipRootContext | undefined {
|
|
62
|
+
const context = inject(tooltipRootContextKey, undefined)
|
|
63
|
+
|
|
64
|
+
if (context === undefined && !optional) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
'Base UI Vue: TooltipRootContext is missing. Tooltip parts must be placed within <TooltipRoot> or receive a tooltip handle.',
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return context
|
|
71
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import type { Ref, ShallowRef } from 'vue'
|
|
2
|
+
import type { ElementProps, FloatingTriggerMap } from '../../floating-ui-vue/types'
|
|
3
|
+
import type {
|
|
4
|
+
TooltipInstantType,
|
|
5
|
+
TooltipRootChangeEventDetails,
|
|
6
|
+
TooltipRootChangeEventReason,
|
|
7
|
+
TooltipTrackCursorAxis,
|
|
8
|
+
} from '../root/TooltipRoot.vue'
|
|
9
|
+
import { shallowRef } from 'vue'
|
|
10
|
+
import { createChangeEventDetails } from '../../utils/createBaseUIEventDetails'
|
|
11
|
+
import { REASONS } from '../../utils/reasons'
|
|
12
|
+
|
|
13
|
+
export interface TooltipTriggerRecord<Payload = unknown> {
|
|
14
|
+
id: string
|
|
15
|
+
element: HTMLElement
|
|
16
|
+
payload: Payload | undefined
|
|
17
|
+
closeOnClick: boolean
|
|
18
|
+
closeDelay: number | undefined
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface TooltipRootController {
|
|
22
|
+
open: Readonly<Ref<boolean>>
|
|
23
|
+
dismiss: ElementProps
|
|
24
|
+
activeTriggerId: Ref<string | null>
|
|
25
|
+
disabled: Readonly<Ref<boolean>>
|
|
26
|
+
disableHoverablePopup: Readonly<Ref<boolean>>
|
|
27
|
+
trackCursorAxis: Readonly<Ref<TooltipTrackCursorAxis>>
|
|
28
|
+
instantType: Ref<TooltipInstantType>
|
|
29
|
+
popupId: Ref<string | undefined>
|
|
30
|
+
requestOpenChange: (
|
|
31
|
+
nextOpen: boolean,
|
|
32
|
+
details: TooltipRootChangeEventDetails,
|
|
33
|
+
triggerId?: string | null,
|
|
34
|
+
) => void
|
|
35
|
+
getOpenDelay: (triggerDelay: number | undefined) => { delay: number, instant: boolean }
|
|
36
|
+
getCloseDelay: (triggerCloseDelay: number | undefined) => number
|
|
37
|
+
scheduleClose: (
|
|
38
|
+
delay: number,
|
|
39
|
+
details: TooltipRootChangeEventDetails,
|
|
40
|
+
triggerId?: string | null,
|
|
41
|
+
) => void
|
|
42
|
+
clearCloseTimer: () => void
|
|
43
|
+
forceUnmount: () => void
|
|
44
|
+
maybeActivateTrigger: (id: string) => void
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class TooltipStore<Payload = unknown> {
|
|
48
|
+
readonly controller: ShallowRef<TooltipRootController | null> = shallowRef(null)
|
|
49
|
+
|
|
50
|
+
private readonly triggers = new Map<string, TooltipTriggerRecord<Payload>>()
|
|
51
|
+
private readonly retainedTriggers = new Map<string, TooltipTriggerRecord<Payload>>()
|
|
52
|
+
|
|
53
|
+
readonly triggerElements: FloatingTriggerMap = {
|
|
54
|
+
hasElement: (element: Element) => {
|
|
55
|
+
return Array.from(this.triggers.values()).some(record => record.element === element)
|
|
56
|
+
},
|
|
57
|
+
hasMatchingElement: (predicate: (element: Element) => boolean) => {
|
|
58
|
+
return Array.from(this.triggers.values()).some(record => predicate(record.element))
|
|
59
|
+
},
|
|
60
|
+
getById: (id: string) => {
|
|
61
|
+
return this.triggers.get(id)?.element
|
|
62
|
+
},
|
|
63
|
+
entries: () => {
|
|
64
|
+
const entries = Array.from(this.triggers.entries())
|
|
65
|
+
.map(([id, record]) => [id, record.element] as [string, HTMLElement])
|
|
66
|
+
|
|
67
|
+
return entries[Symbol.iterator]()
|
|
68
|
+
},
|
|
69
|
+
elements: () => {
|
|
70
|
+
const elements = Array.from(this.triggers.values())
|
|
71
|
+
.map(record => record.element)
|
|
72
|
+
|
|
73
|
+
return elements[Symbol.iterator]()
|
|
74
|
+
},
|
|
75
|
+
get size() {
|
|
76
|
+
return Array.from(this.entries()).length
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
readonly version = shallowRef(0)
|
|
81
|
+
|
|
82
|
+
registerTrigger(record: TooltipTriggerRecord<Payload>) {
|
|
83
|
+
this.retainedTriggers.delete(record.id)
|
|
84
|
+
this.triggers.set(record.id, record)
|
|
85
|
+
this.version.value += 1
|
|
86
|
+
this.controller.value?.maybeActivateTrigger(record.id)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
unregisterTrigger(id: string, element: HTMLElement) {
|
|
90
|
+
const existing = this.triggers.get(id)
|
|
91
|
+
|
|
92
|
+
if (existing?.element !== element) {
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const isActiveTrigger = this.controller.value?.activeTriggerId.value === id
|
|
97
|
+
|
|
98
|
+
if (isActiveTrigger) {
|
|
99
|
+
this.retainedTriggers.set(id, existing)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this.triggers.delete(id)
|
|
103
|
+
this.version.value += 1
|
|
104
|
+
|
|
105
|
+
if (isActiveTrigger) {
|
|
106
|
+
this.requestCloseWhenActiveTriggerStaysUnmounted(id)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
getTrigger(id: string | null | undefined): TooltipTriggerRecord<Payload> | undefined {
|
|
111
|
+
// Keep Map mutations visible to Vue computed refs that read trigger data.
|
|
112
|
+
void this.version.value
|
|
113
|
+
|
|
114
|
+
if (id == null) {
|
|
115
|
+
return undefined
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return this.triggers.get(id) ?? this.retainedTriggers.get(id)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private requestCloseWhenActiveTriggerStaysUnmounted(id: string) {
|
|
122
|
+
queueMicrotask(() => {
|
|
123
|
+
const controller = this.controller.value
|
|
124
|
+
|
|
125
|
+
if (
|
|
126
|
+
!controller
|
|
127
|
+
|| !controller.open.value
|
|
128
|
+
|| controller.activeTriggerId.value !== id
|
|
129
|
+
) {
|
|
130
|
+
this.retainedTriggers.delete(id)
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (this.triggers.has(id)) {
|
|
135
|
+
this.retainedTriggers.delete(id)
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const details = createTooltipChangeEventDetails(REASONS.none)
|
|
140
|
+
|
|
141
|
+
controller.requestOpenChange(false, details)
|
|
142
|
+
|
|
143
|
+
if (!details.isCanceled) {
|
|
144
|
+
controller.activeTriggerId.value = null
|
|
145
|
+
this.retainedTriggers.delete(id)
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
open(triggerId: string) {
|
|
151
|
+
const trigger = this.getTrigger(triggerId)
|
|
152
|
+
|
|
153
|
+
if (!trigger) {
|
|
154
|
+
throw new Error(`Base UI Vue: TooltipHandle.open: No trigger found with id "${triggerId}".`)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
this.controller.value?.requestOpenChange(
|
|
158
|
+
true,
|
|
159
|
+
createTooltipChangeEventDetails(REASONS.imperativeAction, undefined, trigger.element),
|
|
160
|
+
triggerId,
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
close() {
|
|
165
|
+
this.controller.value?.requestOpenChange(
|
|
166
|
+
false,
|
|
167
|
+
createTooltipChangeEventDetails(REASONS.imperativeAction),
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
get isOpen() {
|
|
172
|
+
return this.controller.value?.open.value ?? false
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function createTooltipHandle<Payload = unknown>(): TooltipHandle<Payload> {
|
|
177
|
+
return new TooltipHandle<Payload>()
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* A handle to control a tooltip imperatively and to associate detached triggers with it.
|
|
182
|
+
*/
|
|
183
|
+
export class TooltipHandle<Payload = unknown> {
|
|
184
|
+
readonly store = new TooltipStore<Payload>()
|
|
185
|
+
|
|
186
|
+
open(triggerId: string) {
|
|
187
|
+
this.store.open(triggerId)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
close() {
|
|
191
|
+
this.store.close()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
get isOpen() {
|
|
195
|
+
return this.store.isOpen
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function createTooltipChangeEventDetails(
|
|
200
|
+
reason: TooltipRootChangeEventReason,
|
|
201
|
+
event?: Event,
|
|
202
|
+
trigger?: HTMLElement,
|
|
203
|
+
): TooltipRootChangeEventDetails {
|
|
204
|
+
return createChangeEventDetails<
|
|
205
|
+
TooltipRootChangeEventReason,
|
|
206
|
+
{ preventUnmountOnClose: () => void }
|
|
207
|
+
>(
|
|
208
|
+
reason,
|
|
209
|
+
event,
|
|
210
|
+
trigger,
|
|
211
|
+
{
|
|
212
|
+
preventUnmountOnClose() {},
|
|
213
|
+
},
|
|
214
|
+
)
|
|
215
|
+
}
|