Lzh on GitHub

Alert Dialog

模态对话框会用重要内容打断用户并期望得到回应。
<script setup lang="ts">
import {
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogOverlay,
  AlertDialogPortal,
  AlertDialogRoot,
  AlertDialogTitle,
  AlertDialogTrigger,
} from 'reka-ui'

function handleAction() {
  // eslint-disable-next-line no-alert
  alert('clicked action button!')
}
</script>

<template>
  <AlertDialogRoot>
    <AlertDialogTrigger
      class="bg-white text-sm text-grass11 font-semibold hover:bg-white/90 shadow-sm border inline-flex h-[35px] items-center justify-center rounded-md px-[15px] leading-none outline-none focus:shadow-[0_0_0_2px] dark:focus:shadow-green-800 focus:shadow-black transition-all"
    >
      Delete account
    </AlertDialogTrigger>
    <AlertDialogPortal>
      <AlertDialogOverlay class="bg-gray-300/90 dark:bg-blackA9 data-[state=open]:animate-overlayShow fixed inset-0 z-30" />
      <AlertDialogContent
        class="z-[100] text-sm data-[state=open]:animate-contentShow fixed top-[50%] left-[50%] max-h-[85vh] w-[90vw] max-w-[500px] translate-x-[-50%] translate-y-[-50%] rounded-lg bg-white p-[25px] shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] focus:outline-none"
      >
        <AlertDialogTitle class="text-mauve12 m-0 text-[17px] font-semibold">
          Are you absolutely sure?
        </AlertDialogTitle>
        <AlertDialogDescription class="text-mauve11 mt-4 mb-5 text-sm leading-normal">
          This action cannot be undone. This will permanently delete your account and remove your data from our servers.
        </AlertDialogDescription>
        <div class="flex justify-end gap-4">
          <AlertDialogCancel
            class="text-mauve11 bg-mauve4 hover:bg-mauve5 focus:shadow-mauve7 inline-flex h-[35px] items-center justify-center rounded-md px-[15px] font-semibold leading-none outline-none focus:shadow-[0_0_0_2px]"
          >
            Cancel
          </AlertDialogCancel>
          <AlertDialogAction
            class="text-red-900 bg-red-400 hover:bg-red-500 focus:shadow-red-700 inline-flex h-[35px] items-center justify-center rounded-md px-[15px] font-semibold leading-none outline-none focus:shadow-[0_0_0_2px]"
            @click="handleAction"
          >
            Yes, delete account
          </AlertDialogAction>
        </div>
      </AlertDialogContent>
    </AlertDialogPortal>
  </AlertDialogRoot>
</template>

功能特性

  • 焦点自动锁定。
  • 可以受控或不受控。
  • 通过 TitleDescription 组件管理屏幕阅读器公告。
  • 按下 Esc 键自动关闭组件。

安装

从命令行安装组件。

npm add reka-ui

结构

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

<script setup lang="ts">
  import {
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogOverlay,
    AlertDialogPortal,
    AlertDialogRoot,
    AlertDialogTitle,
    AlertDialogTrigger,
  } from 'reka-ui'
</script>

<template>
  <AlertDialogRoot>
    <AlertDialogTrigger />
    <AlertDialogPortal>
      <AlertDialogOverlay />
      <AlertDialogContent>
        <AlertDialogTitle />
        <AlertDialogDescription />
        <AlertDialogCancel />
        <AlertDialogAction />
      </AlertDialogContent>
    </AlertDialogPortal>
  </AlertDialogRoot>
</template>

API 参考

Root

包含警告对话框的所有部分。

Prop默认值类型说明
defaultOpenboolean对话框首次渲染时的打开状态。当您不需要控制其打开状态时使用。
openboolean对话框的受控打开状态。可以绑定为 v-model:open 。

事件

事件名称Payload 类型说明
update:open[value: boolean]当对话框的打开状态改变时调用事件处理程序。

默认插槽

插槽参数插槽参数类型说明
openboolean当前打开状态
close(): void关闭对话框

Trigger

一个打开对话框的按钮。

Prop默认值类型说明
as'button'AsTag | Component此组件应渲染为的元素或组件。可以被 asChild 覆盖。
asChildboolean更改作为子元素传递的默认渲染元素,合并它们的道具和行为。请阅读我们的 Composition 指南以了解更多详细信息。

数据属性值

属性名称
[data-state]"open" | "closed"

Portal

使用时,将您的覆盖层和内容部分传送到 body 中。

Prop默认值类型说明
deferboolean推迟 Teleport 目标的解析,直到应用程序的其他部分已安装(需要 Vue 3.5.0+) 参考
disabledboolean禁用传送并以内联方式呈现组件 参考
forceMountboolean当需要更多控制时,用于强制挂载。在使用 Vue 动画库控制动画时非常有用。
tostring | HTMLElementVue 原生传送组件 prop 参考

Overlay

对话框打开时,覆盖视图中非活动部分的图层。

Prop默认值类型说明
as'div'AsTag | Component此组件应渲染为的元素或组件。可以被 asChild 覆盖。
asChildboolean更改作为子元素传递的默认渲染元素,合并它们的道具和行为。请阅读我们的 Composition 指南以了解更多详细信息。
forceMountboolean当需要更多控制时,用于强制挂载。在使用 Vue 动画库控制动画时非常有用。

数据属性值

属性名称
[data-state]"open" | "closed"

Content

包含对话框打开时要渲染的内容。

Prop默认值类型说明
as'div'AsTag | Component此组件应渲染为的元素或组件。可以被 asChild 覆盖。
asChildboolean更改作为子元素传递的默认渲染元素,合并它们的道具和行为。请阅读我们的 Composition 指南以了解更多详细信息。
disableOutsidePointerEventsboolean设置为 true 时, DismissableLayer 外部元素上的悬停/聚焦/点击交互将被禁用。用户需要在外部元素上点击两次才能与其交互:一次关闭 DismissableLayer ,再次触发该元素。
forceMountboolean当需要更多控制时,用于强制挂载。在使用 Vue 动画库控制动画时非常有用。

事件

事件名称Payload 类型说明
closeAutoFocus[event: Event]自动对焦关闭时调用的事件处理程序。可以阻止。
escapeKeyDown[event: KeyboardEvent]按下 Esc 键时调用的事件处理程序。可以阻止。
focusOutside[event: FocusOutsideEvent]当焦点移出 DismissableLayer 时调用的事件处理程序。可以阻止。
interactOutside[event: PointerDownOutsideEvent | FocusOutsideEvent]当 DismissableLayer 之外发生交互时调用的事件处理程序。具体来说,当 pointerdown 事件发生在 DismissableLayer 之外或焦点移到 DismissableLayer 之外时。可以阻止。
openAutoFocus[event: Event]自动聚焦打开时调用的事件处理程序。可以阻止。
pointerDownOutside[event: PointerDownOutsideEvent]pointerdown 事件发生在 DismissableLayer 之外时调用的事件处理程序。可以阻止。

数据属性值

属性名称
[data-state]"open" | "closed"

Cancel

一个关闭对话框的按钮。此按钮应与 AlertDialogAction 按钮在视觉上有所区别。

Prop默认值类型说明
as'button'AsTag | Component此组件应渲染为的元素或组件。可以被 asChild 覆盖。
asChildboolean更改作为子元素传递的默认渲染元素,合并它们的 props 和行为。请阅读我们的 Composition 指南以了解更多详细信息。

Action

一个关闭对话框的按钮。这些按钮应与 AlertDialogCancel 按钮在视觉上有所区别。

Prop默认值类型说明
as'button'AsTag | Component此组件应渲染为的元素或组件。可以被 asChild 覆盖。
asChildboolean更改作为子元素传递的默认渲染元素,合并它们的 props 和行为。请阅读我们的 Composition 指南以了解更多详细信息。

Title

对话框打开时要宣布的可访问名称。或者,您可以为 AlertDialogContent 提供 aria-labelaria-labelledby 并排除此组件。

Prop默认值类型说明
as'h2'AsTag | Component此组件应渲染为的元素或组件。可以被 asChild 覆盖。
asChildboolean更改作为子元素传递的默认渲染元素,合并它们的 props 和行为。请阅读我们的 Composition 指南以了解更多详细信息。

Description

对话框打开时要宣布的可访问描述。或者,您可以为 AlertDialogContent 提供 aria-describedby 并排除此组件。

Prop默认值类型说明
as'p'AsTag | Component此组件应渲染为的元素或组件。可以被 asChild 覆盖。
asChildboolean更改作为子元素传递的默认渲染元素,合并它们的 props 和行为。请阅读我们的 Composition 指南以了解更多详细信息。

示例

异步表单提交后关闭

使用受控 prop 在异步操作完成后通过编程方式关闭警告对话框。

<script setup>
  import {
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogOverlay,
    AlertDialogPortal,
    AlertDialogRoot,
    AlertDialogTitle,
    AlertDialogTrigger,
  } from 'reka-ui'
  const wait = () => new Promise(resolve => setTimeout(resolve, 1000))
  const open = ref(false)
</script>

<template>
  <AlertDialogRoot v-model:open="open">
    <AlertDialogTrigger>Open</AlertDialogTrigger>
    <AlertDialogPortal>
      <AlertDialogOverlay />
      <AlertDialogContent>
        <form
          @submit.prevent="
            (event) => {
              wait().then(() => open = false);
            }
          "
        >
          <!-- some inputs -->
          <button type="submit">
            Submit
          </button>
        </form>
      </AlertDialogContent>
    </AlertDialogPortal>
  </AlertDialogRoot>
</template>

自定义传送门容器

自定义警告对话框传送到的元素。

<script setup>
  import { ref } from 'vue'
  const container = ref(null)
</script>

<template>
  <div>
    <AlertDialogRoot>
      <AlertDialogTrigger />
      <AlertDialogPortal :to="container">
        <AlertDialogOverlay />
        <AlertDialogContent>...</AlertDialogContent>
      </AlertDialogPortal>
    </AlertDialogRoot>
    
    <div ref="container" />
  </div>
</template>

可访问性

遵循 Alert and Message Dialogs WAI-ARIA design pattern

键盘交互

描述
Space打开/关闭对话框。
Enter打开/关闭对话框。
Tab将焦点移动到下一个可聚焦元素。
Shift + Tab将焦点移动到上一个可聚焦元素。
Esc关闭对话框并将焦点移动到 AlertDialogTrigger