There is a way to have tooltip and popover on the same button ? #1449
-
I want to have both tooltip and popover on the same button, but it's obvious there is a problem with props, there is a way to achieve this ? I'm on Nuxt 3 with Vue 3 SFC syntax. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
Merging the props for the popover and tooltip trigger is the way to solve this. I believe Vue has a Here's a react example I've created: Please take that and make something that works for Vue. |
Beta Was this translation helpful? Give feedback.
-
Thanks, based on your example with React, I ended up with this : <script lang="ts" setup>
import * as tooltip from "@zag-js/tooltip";
import * as popover from "@zag-js/popover";
import { normalizeProps, useMachine } from "@zag-js/vue";
// import { mergeProps } from "@zag-js/core";
import { mergeProps } from "@zag-js/vue";
const props = defineProps<{
icon: string
size?: number
variant?: string
tooltip?: string
}>()
const [ tooltipState, tooltipSend ] = useMachine(tooltip.machine({ id: useId(), closeDelay: 0 }));
const tooltipApi = computed(() => tooltip.connect(tooltipState.value, tooltipSend, normalizeProps));
const [ popoverState, popoverSend ] = useMachine(popover.machine({ id: useId(), positioning: "top" }));
const popoverApi = computed(() => popover.connect(popoverState.value, popoverSend, normalizeProps));
const triggerProps = mergeProps(tooltipApi.value.triggerProps, popoverApi.value.triggerProps)
// const triggerProps = mergeProps(popoverApi.value.triggerProps, tooltipApi.value.triggerProps)
</script>
<template>
<div ref="ref" :class="{'button-icon--destructive': props.variant === 'destructive'}" class="button-icon">
<button class="button-icon__button" type="button" v-bind="triggerProps">
<AppIcon :name="props.icon" :size="props.size"/>
</button>
<template v-if="props.tooltip">
<div v-if="tooltipApi.open" v-bind="tooltipApi.positionerProps">
<div v-bind="tooltipApi.contentProps">{{ props.tooltip }}</div>
</div>
</template>
<Teleport :disabled="!popoverApi.portalled" to="body">
<div v-bind="popoverApi.positionerProps">
<div v-bind="popoverApi.contentProps">
<div v-bind="popoverApi.titleProps">Presenters</div>
<div v-bind="popoverApi.descriptionProps">Description</div>
<button>Action Button</button>
<button v-bind="popoverApi.closeTriggerProps">X</button>
</div>
</div>
</Teleport>
</div>
</template> But based on the order I put the triggerProps api's in the mergeProps function, the first one not seem to work correctly in the positioning : in the above example the tooltip appear in the top left corner of the windows. |
Beta Was this translation helpful? Give feedback.
Merging the props for the popover and tooltip trigger is the way to solve this. I believe Vue has a
mergeProps
fn you can use.Here's a react example I've created:
https://github.com/chakra-ui/zag/blob/main/examples/next-ts/pages/composition/popover-tooltip.tsx
Please take that and make something that works for Vue.