mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-15 04:29:37 +01:00
fix(Popover): allow manual mode without blocking normal behaviour
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<HPopover ref="popover" v-slot="{ open: headlessOpen, close }" :class="ui.wrapper" v-bind="attrs" @mouseleave="onMouseLeave">
|
||||
<!-- eslint-disable-next-line vue/no-template-shadow -->
|
||||
<HPopover ref="popover" v-slot="{ open, close }" :class="ui.wrapper" v-bind="attrs" @mouseleave="onMouseLeave">
|
||||
<HPopoverButton
|
||||
ref="trigger"
|
||||
as="div"
|
||||
@@ -8,7 +9,7 @@
|
||||
role="button"
|
||||
@mouseover="onMouseOver"
|
||||
>
|
||||
<slot :open="(open !== undefined) ? open : headlessOpen" :close="close">
|
||||
<slot :open="open" :close="close">
|
||||
<button :disabled="disabled">
|
||||
Open
|
||||
</button>
|
||||
@@ -16,16 +17,16 @@
|
||||
</HPopoverButton>
|
||||
|
||||
<Transition v-if="overlay" appear v-bind="ui.overlay.transition">
|
||||
<div v-if="(open !== undefined) ? open : headlessOpen" :class="[ui.overlay.base, ui.overlay.background]" @click="$emit('update:open')" />
|
||||
<div v-if="open" :class="[ui.overlay.base, ui.overlay.background]" />
|
||||
</Transition>
|
||||
|
||||
<div v-if="(open !== undefined) ? open : headlessOpen" ref="container" :class="[ui.container, ui.width]" :style="containerStyle" @mouseover="onMouseOver">
|
||||
<div v-if="open" ref="container" :class="[ui.container, ui.width]" :style="containerStyle" @mouseover="onMouseOver">
|
||||
<Transition appear v-bind="ui.transition">
|
||||
<div>
|
||||
<div v-if="popper.arrow" data-popper-arrow :class="Object.values(ui.arrow)" />
|
||||
|
||||
<HPopoverPanel :class="[ui.base, ui.background, ui.ring, ui.rounded, ui.shadow]" static>
|
||||
<slot name="panel" :open="(open !== undefined) ? open : headlessOpen" :close="close" />
|
||||
<slot name="panel" :open="open" :close="close" />
|
||||
</HPopoverPanel>
|
||||
</div>
|
||||
</Transition>
|
||||
@@ -94,7 +95,7 @@ export default defineComponent({
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
emits: ['update:open', 'open', 'close'],
|
||||
emits: ['update:open'],
|
||||
setup (props, { emit }) {
|
||||
const { ui, attrs } = useUI('popover', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||
|
||||
@@ -102,8 +103,8 @@ export default defineComponent({
|
||||
|
||||
const [trigger, container] = usePopper(popper.value)
|
||||
|
||||
// https://github.com/tailwindlabs/headlessui/blob/f66f4926c489fc15289d528294c23a3dc2aee7b1/packages/%40headlessui-vue/src/components/popover/popover.ts#L151
|
||||
const popover = ref<any>(null)
|
||||
// https://github.com/tailwindlabs/headlessui/blob/f66f4926c489fc15289d528294c23a3dc2aee7b1/packages/%40headlessui-vue/src/components/popover/popover.ts#L151
|
||||
const popoverApi = ref<any>(null)
|
||||
|
||||
let openTimeout: NodeJS.Timeout | null = null
|
||||
@@ -116,6 +117,10 @@ export default defineComponent({
|
||||
}
|
||||
const popoverProvidesSymbols = Object.getOwnPropertySymbols(popoverProvides)
|
||||
popoverApi.value = popoverProvidesSymbols.length && popoverProvides[popoverProvidesSymbols[0]]
|
||||
|
||||
if (props.open) {
|
||||
popoverApi.value?.togglePopover()
|
||||
}
|
||||
})
|
||||
|
||||
const containerStyle = computed(() => {
|
||||
@@ -170,9 +175,22 @@ export default defineComponent({
|
||||
}, props.closeDelay)
|
||||
}
|
||||
|
||||
watch(() => props.open, (newValue: boolean, oldValue: boolean) => {
|
||||
if (!popoverApi.value) return
|
||||
if (oldValue === undefined || newValue === oldValue) return
|
||||
|
||||
if (newValue) {
|
||||
// No `openPopover` method and `popoverApi.value.togglePopover` won't work because of the `watch` below
|
||||
popoverApi.value.popoverState = 0
|
||||
} else {
|
||||
popoverApi.value.closePopover()
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => popoverApi.value?.popoverState, (newValue: number, oldValue: number) => {
|
||||
if (oldValue === undefined) return
|
||||
emit(newValue === 0 ? 'open' : 'close')
|
||||
if (oldValue === undefined || newValue === oldValue) return
|
||||
|
||||
emit('update:open', newValue === 0)
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user