写得真好,期待下一章。
这段剧情和原作不一样吧?
已收藏。
<script setup lang="ts">
import { ref } from 'vue'
import { Button, Inline, Popconfirm, Stack, Text } from '@hina-ui/vue'
const comments = ref(['写得真好,期待下一章。', '这段剧情和原作不一样吧?', '已收藏。'])
function remove(index: number) {
comments.value.splice(index, 1)
}
</script>
<template>
<Stack gap="sm" align="stretch" class="w-96">
<Inline
v-for="(comment, index) in comments"
:key="comment"
align="center"
justify="between"
gap="sm"
>
<Text size="sm">{{ comment }}</Text>
<Popconfirm
title="删除这条评论?"
description="删除后无法恢复。"
tone="danger"
confirm-text="删除"
@confirm="remove(index)"
>
<Button size="sm" variant="ghost" tone="neutral">删除</Button>
</Popconfirm>
</Inline>
<Text v-if="!comments.length" tone="muted" size="sm">没有评论了。</Text>
</Stack>
</template>
vue
用法
import { Popconfirm } from '@hina-ui/vue'
ts
气泡确认框在触发器旁边问一个问题,适合删除一行、撤销一次操作这类范围小、就地可见的确认;后果重、需要打断当前任务的确认用 AlertDialog。title 是问题,description 补充后果,底部一对按钮的文字可以用 cancelText 与 confirmText 替换。默认插槽是触发器。
<script setup lang="ts">
import { ref } from 'vue'
import { Button, Popconfirm, Stack, Text } from '@hina-ui/vue'
const done = ref(false)
</script>
<template>
<Stack gap="sm" align="start">
<Popconfirm title="把全部通知标记为已读?" @confirm="done = true">
<Button variant="outline" tone="neutral">全部已读</Button>
</Popconfirm>
<Text v-if="done" tone="muted" size="sm">已全部标记为已读。</Text>
</Stack>
</template>
vue
示例
危险操作
tone="danger" 把「确定」换成危险色,用于删除这类不可撤销的操作。
<script setup lang="ts">
import { Button, Popconfirm } from '@hina-ui/vue'
</script>
<template>
<Popconfirm
title="移除这位成员?"
description="移除后对方将无法访问这个项目。"
tone="danger"
confirm-text="移除"
>
<Button variant="outline" tone="danger">移除成员</Button>
</Popconfirm>
</template>
vue
异步确认
confirm 事件的处理函数返回 Promise 时,气泡等它结束再收回:期间「确定」显示加载指示,「取消」、Esc 与点击外部都不可用;处理函数抛出错误时气泡保持打开。
<script setup lang="ts">
import { ref } from 'vue'
import { Button, Popconfirm, Stack, Switch, Text } from '@hina-ui/vue'
const fail = ref(false)
const status = ref('')
async function retry() {
status.value = ''
await new Promise(resolve => setTimeout(resolve, 1000))
if (fail.value) {
status.value = '重试失败,请稍后再试。'
throw new Error('retry failed')
}
status.value = '已重新发送。'
}
</script>
<template>
<Stack gap="md" align="start">
<Switch v-model="fail">模拟失败</Switch>
<Popconfirm title="重新发送这封邮件?" confirm-text="重发" @confirm="retry">
<Button variant="outline" tone="neutral">重新发送</Button>
<template #content>
<Text v-if="status" tone="muted" size="sm">{{ status }}</Text>
</template>
</Popconfirm>
</Stack>
</template>
vue
位置
side 与 align 与 Popover 相同,默认在触发器正下方,空间不足时翻转到相反一侧。
<script setup lang="ts">
import { Button, Inline, Popconfirm } from '@hina-ui/vue'
const sides = ['top', 'right', 'bottom', 'left'] as const
const names = { top: '上方', right: '右侧', bottom: '下方', left: '左侧' }
</script>
<template>
<Inline gap="sm">
<Popconfirm v-for="side in sides" :key="side" title="确认这个位置?" :side="side">
<Button variant="outline" tone="neutral">{{ names[side] }}</Button>
</Popconfirm>
</Inline>
</template>
vue
受控
open 支持双向绑定,可以从外部打开或者收回。
<script setup lang="ts">
import { ref } from 'vue'
import { Button, Inline, Popconfirm } from '@hina-ui/vue'
const open = ref(false)
</script>
<template>
<Inline gap="sm">
<Button variant="outline" tone="neutral" @click="open = true">从外部打开</Button>
<Popconfirm v-model:open="open" title="清空草稿?" description="草稿里的内容会被丢弃。">
<Button variant="outline" tone="neutral">清空草稿</Button>
</Popconfirm>
</Inline>
</template>
vue
行为
- 打开后焦点落在「取消」按钮上,误按回车不会执行操作;收回后焦点回到触发器。
- Esc 与点击外部只是收回气泡,不触发
cancel事件;点「取消」才触发。 - 打开期间页面停止滚动,触发器保持按下时的样式。
- 「确定」的处理函数返回 Promise 时,气泡在其结束前处于忙碌状态,结束后收回;抛出错误则保持打开。
无障碍
- 面板是
role="dialog",名称取自触发器,问题与说明一起关联到aria-describedby。 - 忙碌期间面板带有
aria-busy。 - 按钮文字取自当前语言,可以替换。
API
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title | string | — | 必填。问题本身 |
description | string | — | 补充说明 |
confirmText | string | 当前语言 | 「确定」按钮的文字 |
cancelText | string | 当前语言 | 「取消」按钮的文字 |
tone | 'accent' | 'danger' | 'accent' | 「确定」按钮的色调 |
side | 'top' | 'right' | 'bottom' | 'left' | 'bottom' | 浮出的方向 |
align | 'start' | 'center' | 'end' | 'center' | 与触发器的对齐方式 |
sideOffset | number | 8 | 与触发器的距离,像素 |
open | boolean | — | 是否打开,支持双向绑定 |
class | string | — | 追加至面板的类名 |
插槽
| 插槽 | 说明 |
|---|---|
| default | 触发器 |
content | 说明与按钮之间的内容 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
confirm | — | 点击「确定」;处理函数返回 Promise 时等待其完成 |
cancel | — | 点击「取消」 |