跳至内容

HoverCard

供视力正常的用户预览链接后可用的内容。
Radix UI
vue
<script setup lang="ts">
import { ref } from 'vue'
import { HoverCardArrow, HoverCardContent, HoverCardPortal, HoverCardRoot, HoverCardTrigger } from 'radix-vue'

const hoverState = ref(false)
</script>

<template>
  <HoverCardRoot v-model:open="hoverState">
    <HoverCardTrigger
      class="inline-block cursor-pointer rounded-full shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] outline-none focus:shadow-[0_0_0_2px_white]"
      href="https://twitter.com/radix_ui"
      target="_blank"
      rel="noreferrer noopener"
    >
      <img
        class="block h-[45px] w-[45px] rounded-full"
        src="https://pbs.twimg.com/profile_images/1337055608613253126/r_eiMp2H_400x400.png"
        alt="Radix UI"
      >
    </HoverCardTrigger>
    <HoverCardPortal>
      <HoverCardContent
        class="data-[side=bottom]:animate-slideUpAndFade data-[side=right]:animate-slideLeftAndFade data-[side=left]:animate-slideRightAndFade data-[side=top]:animate-slideDownAndFade w-[300px] rounded-md bg-white p-5 shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] data-[state=open]:transition-all"
        :side-offset="5"
      >
        <div class="flex flex-col gap-[7px]">
          <img
            class="block h-[60px] w-[60px] rounded-full"
            src="https://pbs.twimg.com/profile_images/1337055608613253126/r_eiMp2H_400x400.png"
            alt="Radix UI"
          >
          <div class="flex flex-col gap-[15px]">
            <div>
              <div class="text-mauve12 m-0 text-[15px] font-medium leading-[1.5]">
                Radix
              </div>
              <div class="text-mauve10 m-0 text-[15px] leading-[1.5]">
                @radix_ui
              </div>
            </div>
            <div class="text-mauve12 m-0 text-[15px] leading-[1.5]">
              Components, icons, colors, and templates for building high-quality, accessible UI. Free and open-source.
            </div>
            <div class="flex gap-[15px]">
              <div class="flex gap-[5px]">
                <div class="text-mauve12 m-0 text-[15px] font-medium leading-[1.5]">
                  0
                </div>
                <div class="text-mauve10 m-0 text-[15px] leading-[1.5]">
                  Following
                </div>
              </div>
              <div class="flex gap-[5px]">
                <div class="text-mauve12 m-0 text-[15px] font-medium leading-[1.5]">
                  2,900
                </div>
                <div class="text-mauve10 m-0 text-[15px] leading-[1.5]">
                  Followers
                </div>
              </div>
            </div>
          </div>
        </div>

        <HoverCardArrow
          class="fill-white"
          :width="8"
        />
      </HoverCardContent>
    </HoverCardPortal>
  </HoverCardRoot>
</template>

功能

  • 可以是受控的或不受控的。
  • 自定义侧面、对齐方式、偏移量、碰撞处理。
  • 可以选择渲染一个指向箭头。
  • 支持自定义打开和关闭延迟。
  • 被屏幕阅读器忽略。

安装

从命令行安装组件。

sh
$ npm add radix-vue

解剖

导入所有部分并将其组合在一起。

vue
<script setup>
import { HoverCardArrow, HoverCardContent, HoverCardPortal, HoverCardRoot, HoverCardTrigger } from 'radix-vue'
</script>

<template>
  <HoverCardRoot>
    <HoverCardTrigger />
    <HoverCardPortal>
      <HoverCardContent>
        <HoverCardArrow />
      </HoverCardContent>
    </HoverCardPortal>
  </HoverCardRoot>
</template>

API 参考

包含悬停卡的所有部分。

道具默认类型
closeDelay
300
数字

鼠标离开触发器或内容到悬停卡关闭的持续时间。

defaultOpen

悬停卡首次渲染时的打开状态。当您不需要控制其打开状态时使用。

打开
布尔值

悬停卡的受控打开状态。可以绑定为 v-model:open

openDelay
700
数字

鼠标进入触发器到悬停卡打开的持续时间。

发射有效负载
update:open
[value: 布尔值]

悬停卡打开状态改变时调用的事件处理程序。

插槽 (默认)有效负载
打开
布尔值

当前打开状态

触发器

悬停时打开悬停卡的链接。

道具默认类型
作为
'a'
AsTag | 组件

此组件应呈现的元素或组件。可以被 asChild 覆盖

asChild
布尔值

更改默认渲染的元素,用于作为子元素传递的元素,合并其属性和行为。

阅读我们的 组合 指南了解更多详细信息。

数据属性价值
[data-state]"open" | "closed"

门户

使用时,将内容部分传送到 body 中。

道具默认类型
禁用
布尔值

禁用传送并内联渲染组件

参考

forceMount
布尔值

用于在需要更多控制时强制挂载。在使用 Vue 动画库控制动画时很有用。

字符串 | HTMLElement

Vue 原生传送组件属性 :to

参考

内容

悬停卡打开时弹出的组件。

道具默认类型
对齐
'start' | 'center' | 'end'

相对于触发器的首选对齐方式。当发生碰撞时可能会改变。

alignOffset
数字

startend 对齐选项的像素偏移量。

arrowPadding
数字

箭头与内容边缘之间的填充。如果您的内容有圆角,这将防止它溢出角。

作为
'div'
AsTag | 组件

此组件应呈现的元素或组件。可以被 asChild 覆盖

asChild
布尔值

更改默认渲染的元素,用于作为子元素传递的元素,合并其属性和行为。

阅读我们的 组合 指南了解更多详细信息。

avoidCollisions
布尔值

true 时,覆盖侧面和对齐偏好以防止与边界边缘发生碰撞。

collisionBoundary
元素 | (元素 | 空)[] | 空

用作碰撞边界的元素。默认情况下,这是视窗,但您可以提供要包含在此检查中的其他元素。

collisionPadding
数字 | 部分<记录<'top' | 'right' | 'bottom' | 'left', 数字>>

从边界边缘开始发生碰撞检测的像素距离。接受一个数字(所有边的数字相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。

forceMount
布尔值

用于在需要更多控制时强制挂载。在使用 Vue 动画库控制动画时很有用。

hideWhenDetached
布尔值

当触发器被完全遮挡时是否隐藏内容。

prioritizePosition
布尔值

强制内容在视窗内定位。

可能会与参考元素重叠,这可能不是您想要的。

'top' | 'right' | 'bottom' | 'left'

打开时渲染的触发器的首选侧面。当发生碰撞并且 avoidCollisions 启用时,将被反转。

sideOffset
数字

与触发器的像素距离。

粘性
'partial' | 'always'

对齐轴上的粘性行为。partial 将在触发器至少部分在边界内时将内容保留在边界内,而 "always" 将始终将内容保留在边界内,而不管触发器是否在边界内。

updatePositionStrategy
'always' | 'optimized'

在每个动画帧上更新浮动元素位置的策略。

发射有效负载
escapeKeyDown
[event: KeyboardEvent]

按下 Escape 键时调用的事件处理程序。可以防止。

focusOutside
[event: FocusOutsideEvent]

焦点移出 DismissableLayer 时调用的事件处理程序。可以防止。

interactOutside
[event: PointerDownOutsideEvent | FocusOutsideEvent]

DismissableLayer 之外发生交互时调用的事件处理程序。具体来说,当在 DismissableLayer 之外发生 pointerdown 事件或焦点移出 DismissableLayer 时。可以防止。

pointerDownOutside
[event: PointerDownOutsideEvent]

DismissableLayer 之外发生 pointerdown 事件时调用的事件处理程序。可以防止。

数据属性价值
[data-state]"open" | "closed"
[data-side]"left" | "right" | "bottom" | "top"
[data-align]"start" | "end" | "center"
CSS 变量描述
--radix-hover-card-content-transform-origin
从内容和箭头位置/偏移量计算出的 transform-origin
--radix-hover-card-content-available-width
触发器与边界边缘之间的剩余宽度
--radix-hover-card-content-available-height
触发器与边界边缘之间的剩余高度
--radix-hover-card-trigger-width
触发器的宽度
--radix-hover-card-trigger-height
触发器的高度

箭头

一个可选的箭头元素,与悬停卡一起渲染。这可用于在视觉上帮助将触发器与 HoverCardContent 链接起来。必须渲染在 HoverCardContent 内。

道具默认类型
作为
'svg'
AsTag | 组件

此组件应呈现的元素或组件。可以被 asChild 覆盖

asChild
布尔值

更改默认渲染的元素,用于作为子元素传递的元素,合并其属性和行为。

阅读我们的 组合 指南了解更多详细信息。

高度
5
数字

箭头的像素高度。

宽度
10
数字

箭头的像素宽度。

示例

立即显示

使用 openDelay 属性控制悬停卡打开所需的时间。

vue
<script setup>
import {
  HoverCardArrow,
  HoverCardContent,
  HoverCardPortal,
  HoverCardRoot,
  HoverCardTrigger,
} from 'radix-vue'
</script>

<template>
  <HoverCardRoot :open-delay="0">
    <HoverCardTrigger></HoverCardTrigger>
    <HoverCardContent></HoverCardContent>
  </HoverCardRoot>
</template>

约束内容大小

您可能希望约束内容的宽度,使其与触发器的宽度匹配。您可能还想约束其高度,使其不超过视窗高度。

我们公开了几个 CSS 自定义属性,例如 --radix-hover-card-trigger-width--radix-hover-card-content-available-height 来支持这一点。使用它们来约束内容尺寸。

vue
// index.vue
<script setup>
import { HoverCardArrow, HoverCardContent, HoverCardPortal, HoverCardRoot, HoverCardTrigger } from 'radix-vue'
</script>

<template>
  <HoverCardRoot>
    <HoverCardTrigger></HoverCardTrigger>
    <HoverCardPortal>
      <HoverCardContent
        class="HoverCardContent"
        :side-offset="5"
      >

      </HoverCardContent>
    </HoverCardPortal>
  </HoverCardRoot>
</template>
css
/* styles.css */
.HoverCardContent {
  width: var(--radix-hover-card-trigger-width);
  max-height: var(--radix-hover-card-content-available-height);
}

原点感知动画

我们公开了一个 CSS 自定义属性 --radix-hover-card-content-transform-origin。使用它根据 sidesideOffsetalignalignOffset 和任何碰撞从其计算的原点对内容进行动画处理。

vue
// index.vue
<script setup>
import { HoverCardArrow, HoverCardContent, HoverCardPortal, HoverCardRoot, HoverCardTrigger } from 'radix-vue'
</script>

<template>
  <HoverCardRoot>
    <HoverCardTrigger></HoverCardTrigger>
    <HoverCardContent class="HoverCardContent">

    </HoverCardContent>
  </HoverCardRoot>
</template>
css
/* styles.css */
.HoverCardContent {
  transform-origin: var(--radix-hover-card-content-transform-origin);
  animation: scaleIn 0.5s ease-out;
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

碰撞感知动画

我们公开了 data-sidedata-align 属性。它们的值将在运行时更改以反映碰撞。使用它们创建碰撞和方向感知动画。

vue
// index.vue
<script setup>
import { HoverCardArrow, HoverCardContent, HoverCardPortal, HoverCardRoot, HoverCardTrigger } from 'radix-vue'
</script>

<template>
  <HoverCardRoot>
    <HoverCardTrigger></HoverCardTrigger>
    <HoverCardContent class="HoverCardContent">

    </HoverCardContent>
  </HoverCardRoot>
</template>
css
/* styles.css */
.HoverCardContent {
  animation-duration: 0.6s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.HoverCardContent[data-side="top"] {
  animation-name: slideUp;
}
.HoverCardContent[data-side="bottom"] {
  animation-name: slideDown;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

无障碍性

悬停卡仅供视力正常的用户使用,键盘用户将无法访问内容。

键盘交互

描述
Tab
打开/关闭悬停卡。
Enter
打开悬停卡链接