
3D Extruded Buildings & Urban Footprints
Real-world 3D building extrusions with dynamic sunlight shadows, terrain DEM elevations, and pitch/bearing camera controls.
hover-carduiRich popover triggered by hover/focus instead of click. Use for inline previews — user cards on @mentions, link previews, KPI explanations. Built on reka-ui with a configurable open/close delay.
Also available for React ->$pnpm dlx shadcn-vue@latest add https://uipkge.dev/r/vue/hover-card.json$npx shadcn-vue@latest add https://uipkge.dev/r/vue/hover-card.json$yarn dlx shadcn-vue@latest add https://uipkge.dev/r/vue/hover-card.json$bunx shadcn-vue@latest add https://uipkge.dev/r/vue/hover-card.jsonnpx shadcn-vue@latest add @uipkge/hover-cardInstalls to:app/components/ui/hover-card/<script setup lang="ts">
import type { HoverCardRootEmits, HoverCardRootProps } from 'reka-ui'
import { HoverCardRoot, useForwardPropsEmits } from 'reka-ui'
const props = defineProps<HoverCardRootProps>()
const emits = defineEmits<HoverCardRootEmits>()
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>
<HoverCardRoot v-slot="slotProps" data-uipkge data-slot="hover-card" v-bind="forwarded">
<slot v-bind="slotProps" />
</HoverCardRoot>
</template>
<script setup lang="ts">
import type { HoverCardContentProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { reactiveOmit } from '@vueuse/core'
import { HoverCardContent, HoverCardPortal, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils'
defineOptions({
inheritAttrs: false,
})
const props = withDefaults(defineProps<HoverCardContentProps & { class?: HTMLAttributes['class'] }>(), {
sideOffset: 4,
})
const delegatedProps = reactiveOmit(props, 'class')
const forwardedProps = useForwardProps(delegatedProps)
</script>
<template>
<HoverCardPortal>
<HoverCardContent
data-uipkge
data-slot="hover-card-content"
v-bind="{ ...$attrs, ...forwardedProps }"
:class="
cn(
'bg-popover text-popover-foreground motion-safe:data-[state=open]:animate-in motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=open]:ease-emphasized motion-safe:data-[state=open]:blur-in-2 motion-safe:data-[state=closed]:blur-out-2 motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=open]:fade-in-0 motion-safe:data-[state=closed]:zoom-out-95 motion-safe:data-[state=open]:zoom-in-95 motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[side=left]:slide-in-from-right-2 motion-safe:data-[side=right]:slide-in-from-left-2 motion-safe:data-[side=top]:slide-in-from-bottom-2 z-50 w-64 rounded-md border p-4 shadow-md outline-hidden motion-safe:data-[state=closed]:duration-[var(--dur-exit)] motion-safe:data-[state=open]:duration-200',
props.class,
)
"
>
<slot />
</HoverCardContent>
</HoverCardPortal>
</template>
<script setup lang="ts">
import type { HoverCardTriggerProps } from 'reka-ui'
import { HoverCardTrigger } from 'reka-ui'
const props = defineProps<HoverCardTriggerProps>()
</script>
<template>
<HoverCardTrigger data-uipkge data-slot="hover-card-trigger" v-bind="props">
<slot />
</HoverCardTrigger>
</template>
export { default as HoverCard } from './HoverCard.vue'
export { default as HoverCardContent } from './HoverCardContent.vue'
export { default as HoverCardTrigger } from './HoverCardTrigger.vue'
Raw manifest:https://uipkge.dev/r/vue/hover-card.json