primitives

Popover

Popover — базовый примитив RevueUI (Reka UI + shadcn-совместимый API).

Загрузка превью…

src/ui/popover/Popover.vue

<script setup lang="ts">
/**
 * Порт базового радикс-слоя (registry/bases/radix/ui/popover.tsx, MIT).
 * Radix PopoverPrimitive -> reka-ui Popover*, один в один. Позиционирующая
 * CSS-переменная Radix (`--radix-popover-content-transform-origin`)
 * оставлена буквально как в оригинале (правило 1); reka-ui выставляет
 * функциональный аналог под своим префиксом, но на статичном скриншоте
 * без анимации transform-origin не влияет на итоговую раскладку. См.
 * docs/PORTING.md.
 */
import { PopoverRoot } from "reka-ui"
</script>

<template>
  <PopoverRoot data-slot="popover">
    <slot />
  </PopoverRoot>
</template>

src/ui/popover/PopoverAnchor.vue

<script setup lang="ts">
import { PopoverAnchor } from "reka-ui"
</script>

<template>
  <PopoverAnchor data-slot="popover-anchor">
    <slot />
  </PopoverAnchor>
</template>

src/ui/popover/PopoverContent.vue

<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { PopoverContent, PopoverPortal } from "reka-ui"
import { cn } from "@/lib/utils"

const props = withDefaults(
  defineProps<{
    class?: HTMLAttributes["class"]
    align?: "start" | "center" | "end"
    sideOffset?: number
  }>(),
  {
    align: "center",
    sideOffset: 4,
  }
)
</script>

<template>
  <PopoverPortal>
    <PopoverContent
      data-slot="popover-content"
      :align="props.align"
      :side-offset="props.sideOffset"
      :class="
        cn(
          'cn-popover-content z-50 w-72 origin-(--radix-popover-content-transform-origin) outline-hidden',
          props.class
        )
      "
    >
      <slot />
    </PopoverContent>
  </PopoverPortal>
</template>

src/ui/popover/PopoverDescription.vue

<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"

const props = defineProps<{
  class?: HTMLAttributes["class"]
}>()
</script>

<template>
  <p data-slot="popover-description" :class="cn('cn-popover-description', props.class)">
    <slot />
  </p>
</template>

src/ui/popover/PopoverHeader.vue

<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"

const props = defineProps<{
  class?: HTMLAttributes["class"]
}>()
</script>

<template>
  <div data-slot="popover-header" :class="cn('cn-popover-header', props.class)">
    <slot />
  </div>
</template>

src/ui/popover/PopoverTitle.vue

<script setup lang="ts">
/**
 * В оригинале это `<div>` несмотря на прописанный тип пропов
 * `React.ComponentProps<"h2">` (см. registry/bases/radix/ui/popover.tsx) —
 * буквальное поведение оригинала, не опечатка порта (правило 4a).
 */
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"

const props = defineProps<{
  class?: HTMLAttributes["class"]
}>()
</script>

<template>
  <div data-slot="popover-title" :class="cn('cn-popover-title', props.class)">
    <slot />
  </div>
</template>

src/ui/popover/PopoverTrigger.vue

<script setup lang="ts">
import { PopoverTrigger } from "reka-ui"
</script>

<template>
  <PopoverTrigger data-slot="popover-trigger">
    <slot />
  </PopoverTrigger>
</template>

src/ui/popover/index.ts

export { default as Popover } from "./Popover.vue"
export { default as PopoverAnchor } from "./PopoverAnchor.vue"
export { default as PopoverContent } from "./PopoverContent.vue"
export { default as PopoverDescription } from "./PopoverDescription.vue"
export { default as PopoverHeader } from "./PopoverHeader.vue"
export { default as PopoverTitle } from "./PopoverTitle.vue"
export { default as PopoverTrigger } from "./PopoverTrigger.vue"

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/popover.json

Зависимости реестра

npm-зависимости

  • reka-ui

Источник: порт из ReUI (Keenthemes, MIT)