Hover card
For sighted users to preview content available behind a link.
Preview
<script setup lang="ts">
import { CalendarDays } from "lucide-vue-next";
import {
HoverCard,
HoverCardTrigger,
HoverCardContent,
} from "~/components/ui/hover-card";
import { Button } from "~/components/ui/button";
</script>
<template>
<HoverCard>
<HoverCardTrigger>
<Button variant="link">@nuxtjs</Button>
</HoverCardTrigger>
<HoverCardContent class="w-48">
<div class="flex justify-between space-x-4">
<div class="space-y-1">
<h4 class="text-sm font-semibold">@nuxtjs</h4>
<p class="text-sm">The Vue Framework</p>
<div className="flex items-center pt-2">
<CalendarDays class="mr-2 h-4 w-4 opacity-70" />
<span class="text-xs text-muted-foreground"> Joined December 2021 </span>
</div>
</div>
</div>
</HoverCardContent>
</HoverCard>
</template>
HoverCardContent
Installation
Copy and paste this into your project
// ~/components/ui/hover-card.tsx
import {
HoverCard as HoverCardPrimitive,
HoverCardContent as HoverCardContentPrimitive,
HoverCardPositioner,
HoverCardTrigger,
HoverCardProps,
} from "@ark-ui/vue";
import { ExtendProps, cn } from "~/lib/utils";
import { defineComponent, Teleport, onMounted, ref } from "vue";
const HoverCard = defineComponent({
props: {} as ExtendProps<HoverCardProps>,
setup(_, { slots }) {
const key = ref("ssr");
onMounted(() => {
key.value = "csr";
});
return () => (
<HoverCardPrimitive key={key.value}>
{slots.default?.()}
</HoverCardPrimitive>
);
},
});
const HoverCardContent = defineComponent({
setup(_, { slots, attrs }) {
return () => (
<Teleport to="body">
<HoverCardPositioner>
<HoverCardContentPrimitive
class={cn(
"z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
attrs.class ?? ""
)}
>
{slots.default?.()}
</HoverCardContentPrimitive>
</HoverCardPositioner>
</Teleport>
);
},
});
export { HoverCard, HoverCardTrigger, HoverCardContent };
Usage
import { HoverCard, HoverCardContent, HoverCardTrigger } from "~/components/ui/hover-card";
<HoverCard>
<HoverCardTrigger>
<a href="https://vuejs.org/">Vue</a>
</HoverCardTrigger>
<HoverCardContent>
The Vue Framework
</HoverCardContent>
</HoverCard>