feat(ui): add Tooltip, Popover, Skeleton primitives (radix-vue)

This commit is contained in:
Vadym Samoilenko 2026-05-13 10:58:41 +01:00
parent 9eb7e077ec
commit f19e5122eb
5 changed files with 106 additions and 11 deletions

View file

@ -1,17 +1,20 @@
<script setup lang="ts">
import { Toaster } from 'vue-sonner'
import TooltipProvider from '@/components/ui/TooltipProvider.vue'
</script>
<template>
<RouterView />
<Toaster
position="top-right"
:toast-options="{
style: {
background: 'hsl(var(--card))',
color: 'hsl(var(--card-foreground))',
border: '1px solid hsl(var(--border))',
},
}"
/>
<TooltipProvider>
<RouterView />
<Toaster
position="top-right"
:toast-options="{
style: {
background: 'hsl(var(--card))',
color: 'hsl(var(--card-foreground))',
border: '1px solid hsl(var(--border))',
},
}"
/>
</TooltipProvider>
</template>

View file

@ -0,0 +1,38 @@
<template>
<PopoverRoot>
<PopoverTrigger as-child>
<slot name="trigger" />
</PopoverTrigger>
<PopoverPortal>
<PopoverContent
:align="align"
:side="side"
:side-offset="sideOffset"
:class="cn(
'z-50 w-72 rounded-xl border border-border bg-popover p-4 shadow-md',
'animate-in fade-in-0 zoom-in-95',
'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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'
)"
>
<slot />
</PopoverContent>
</PopoverPortal>
</PopoverRoot>
</template>
<script setup lang="ts">
import { PopoverRoot, PopoverTrigger, PopoverPortal, PopoverContent } from 'radix-vue'
import { cn } from '@/lib/utils'
withDefaults(defineProps<{
align?: 'start' | 'center' | 'end'
side?: 'top' | 'right' | 'bottom' | 'left'
sideOffset?: number
}>(), {
align: 'start',
side: 'bottom',
sideOffset: 8
})
</script>

View file

@ -0,0 +1,8 @@
<template>
<div v-bind="$attrs" :class="cn('skeleton-shimmer rounded-md', $attrs.class as string)" />
</template>
<script setup lang="ts">
import { cn } from '@/lib/utils'
defineOptions({ inheritAttrs: false })
</script>

View file

@ -0,0 +1,37 @@
<template>
<TooltipRoot>
<TooltipTrigger as-child>
<slot />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent
:side="side"
:side-offset="sideOffset"
:class="cn(
'z-50 max-w-[280px] rounded-lg border border-border bg-popover px-3 py-1.5',
'text-xs text-popover-foreground shadow-md',
'animate-in fade-in-0 zoom-in-95',
'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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'
)"
>
{{ content }}
</TooltipContent>
</TooltipPortal>
</TooltipRoot>
</template>
<script setup lang="ts">
import { TooltipRoot, TooltipTrigger, TooltipPortal, TooltipContent } from 'radix-vue'
import { cn } from '@/lib/utils'
withDefaults(defineProps<{
content: string
side?: 'top' | 'right' | 'bottom' | 'left'
sideOffset?: number
}>(), {
side: 'top',
sideOffset: 6
})
</script>

View file

@ -0,0 +1,9 @@
<template>
<TooltipProvider :delay-duration="300" :skip-delay-duration="100">
<slot />
</TooltipProvider>
</template>
<script setup lang="ts">
import { TooltipProvider } from 'radix-vue'
</script>