Demos
How to import
<script lang="ts">
import { Popconfirm } from '@fibrae/semi-ui-svelte';
</script>
Basic Usage
Popconfirm is based on the Tooltip component. Children support the same type as Tooltip. For details, please refer to Tooltip Cautions
Code
<script lang="ts">
import { Button, Popconfirm, Toast } from '@fibrae/semi-ui-svelte';
const onConfirm = () => {
Toast.success('确认保存!');
};
const onCancel = () => {
Toast.warning('取消保存!');
};
</script>
<Popconfirm {onCancel} {onConfirm} title="确定是否要保存此修改?">
<Button>保存</Button>
{#snippet content()}此修改将不可逆{/snippet}
</Popconfirm>Type collocation
Developers can use scenario-based okType/cancelType and the icon snippet to match different styles of bubble confirmation boxes. Without icon the default warning icon is shown; icon={null} renders no icon.
Code
<script lang="ts">
import { IconAlertTriangle } from '@fibrae/semi-icons-svelte';
import { Button, Popconfirm, Radio, RadioGroup, type RadioValue } from '@fibrae/semi-ui-svelte';
type TypeKey = 'default' | 'warning' | 'danger' | 'tertiary';
const typeMap: Record<TypeKey, { okType?: 'danger'; color?: string }> = {
default: {},
warning: { color: 'var(--semi-color-warning)' },
danger: { okType: 'danger', color: 'var(--semi-color-danger)' },
tertiary: { color: 'var(--semi-color-tertiary)' },
};
const keys = Object.keys(typeMap) as TypeKey[];
let value = $state<RadioValue | undefined>('default');
let visible = $state(true);
const type = $derived(keys.find((key) => key === value) ?? 'default');
</script>
<div>
<RadioGroup bind:value style="margin-top: 14px; margin-bottom: 14px" type="button">
{#each keys as key (key)}
<Radio value={key}>
<span style={`color: var(--semi-color-${key === 'default' ? 'primary' : key})`}>{key}</span>
</Radio>
{/each}
</RadioGroup>
<div>
<Popconfirm bind:visible okType={typeMap[type].okType} title="确定是否要保存此修改?" trigger="custom">
<Button onclick={() => (visible = !visible)}>点击此处</Button>
{#snippet icon()}
<IconAlertTriangle size="extra-large" style={typeMap[type].color ? `color: ${typeMap[type].color}` : undefined} />
{/snippet}
{#snippet content()}此修改将不可逆{/snippet}
</Popconfirm>
</div>
</div>Delay hide
onConfirm and onCancel can be closed after click through return Promise.
When onCancel and onConfirm are triggered, the corresponding Button will automatically switch to loading: true
promise solve will close the bubble confirmation box, the bubble will remain when promise reject, and button loading will automatically switch to false
Code
<script lang="ts">
import { Button, Popconfirm } from '@fibrae/semi-ui-svelte';
const onConfirm = () =>
new Promise<void>((resolve) => {
setTimeout(() => {
console.log('resolve,close popconfirm');
resolve();
}, 2000);
});
const onCancel = () =>
new Promise<void>((_resolve, reject) => {
setTimeout(() => {
console.log('reject, popconfirm still exist');
reject();
}, 2000);
});
</script>
<Popconfirm {onCancel} {onConfirm} title="确定是否要保存此修改?">
<Button>保存</Button>
{#snippet content()}此修改将不可逆{/snippet}
</Popconfirm>Initialize the Focus Position of Popup Layer
okButtonProps and cancelButtonProps support passing in the autoFocus parameter, which will automatically focus at this position when the panel is opened.
The content snippet receives { initialFocusRef } as its argument. Bind it to the focusable DOM or component with {@attach initialFocusRef}, and it will automatically focus at this position when the panel is opened. When a button autoFocus and initialFocusRef are both given, the button wins.
Code
<script lang="ts">
import { Button, Popconfirm, Space } from '@fibrae/semi-ui-svelte';
</script>
{#snippet text()}此修改将不可逆{/snippet}
<Space>
<Popconfirm content={text} okButtonProps={{ autoFocus: true, type: 'danger' }} title="确定是否要保存此修改?">
<Button>确认聚焦</Button>
</Popconfirm>
<Popconfirm cancelButtonProps={{ autoFocus: true }} content={text} title="确定是否要保存此修改?">
<Button>取消聚焦</Button>
</Popconfirm>
<Popconfirm title="确定是否要保存此修改?">
<Button>内容聚焦</Button>
{#snippet content({ initialFocusRef })}
<input {@attach initialFocusRef} placeholder="focus here" />
{/snippet}
</Popconfirm>
</Space>Use with Tooltip or Popover
Please refer to Use with Tooltip/Popover
API Reference
Props
| Property | Description | Type | Default |
|---|---|---|---|
| afterClose | Called after the card has closed and its leave animation has finished. | TooltipProps['afterClose'] | - |
| afterOpen | Called after the card has opened and its enter animation has finished, or right after opening when there is no enter animation, controlled or not; not called for an open that is closed before the enter animation ends. | TooltipProps['afterOpen'] | - |
| aria-describedby | aria-describedby of the dialog. Defaults to the content when there are both a title and content. | string | - |
| aria-label | aria-label of the dialog. When given, it takes precedence over the title. | string | - |
| aria-labelledby | aria-labelledby of the dialog. Defaults to the title, or to the content without a title. | string | - |
| arrowPointAtCenter | Whether the arrow points at the center of the trigger. Requires showArrow. | boolean | - |
| arrowStyle | borderColor, backgroundColor and borderOpacity of the arrow. | ArrowStyle | - |
| autoAdjustOverflow | Whether the popup flips automatically when it would be clipped. | boolean | - |
| cancelButtonProps | Props of the cancel button. autoFocus focuses it on open; onclick runs before the built-in cancel handling. | PopconfirmButtonProps | - |
| cancelText | Cancel button text. Defaults to the locale entry Popconfirm.cancel. | string | - |
| cancelType | Type of the cancel button. | ButtonType | "tertiary" |
| child | Snippet that renders the trigger element itself. Its argument { props } must be spread whole onto the trigger; when child is passed, children has no effect. | TooltipProps['child'] | - |
| children | Snippet for the trigger. It is wrapped in Tooltip's own span, which receives the trigger attributes. | TooltipProps['children'] | - |
| class | Class name of the confirmation card. | string | - |
| clickToHide | Whether a click on the popup or anything inside it closes it. | boolean | - |
| closeOnEsc | Whether Esc closes the open card. With trigger custom it only calls onEscKeyDown and the caller decides whether to close. | boolean | - |
| condition | Whether it may be triggered. Only an explicit false disables the hover, click and focus triggers. Changing it from true to false closes an open card at once; with a controlled visible it only calls onVisibleChange(false), and the card closes once the caller writes back. | boolean | - |
| content | Snippet for the content of the card. Its argument { initialFocusRef } is a callback; write {@attach initialFocusRef} to bind it to the element that receives focus on open. Omitted, no content area is rendered. | TypeSnippet<[RenderContentProps]> | - |
| contentClassName | Class name of the content container. | ClassValue | - |
| disableArrowKeyDown | Whether the arrow keys on the trigger are prevented from moving focus into the card. | boolean | - |
| disabled | Whether it is disabled. A disabled Popconfirm renders only the trigger and never opens. | boolean | false |
| disableFocusListener | Whether keyboard focus is ignored when trigger is hover. | boolean | - |
| guardFocus | Whether Tab cycles inside the card while focus is in it. | boolean | - |
| icon | Snippet for a custom icon. The default warning icon shows when omitted; null renders no icon. | Snippet | null | - |
| keepDOM | Whether the content stays mounted while closed. | boolean | - |
| motion | Whether the popup is animated. | boolean | - |
| mouseEnterDelay | Milliseconds before the card shows after the pointer enters. Applies to the hover and focus triggers. | number | - |
| mouseLeaveDelay | Milliseconds before the card hides after the pointer leaves. Applies to the hover and focus triggers. | number | - |
| okButtonProps | Props of the confirm button. autoFocus focuses it on open; onclick runs before the built-in confirm handling. | PopconfirmButtonProps | - |
| okText | Confirm button text. Defaults to the locale entry Popconfirm.confirm. | string | - |
| okType | Type of the confirm button. | ButtonType | "primary" |
| onCancel | Called when the cancel or close button is clicked, with the button's native click event. A returned Promise keeps the button loading and closes the card once it resolves; a rejection keeps it open. | Type(event: MouseEvent) => Promise<unknown> | void | - |
| onClickOutSide | Called when the mouse is pressed outside of the trigger and the open card. Only for trigger click, contextMenu or custom. | TooltipProps['onClickOutSide'] | - |
| onConfirm | Called when the confirm button is clicked, with the button's native click event. A returned Promise keeps the button loading and closes the card once it resolves; a rejection keeps it open. | Type(event: MouseEvent) => Promise<unknown> | void | - |
| onEscKeyDown | Called when Esc is pressed while the card is open and closeOnEsc is true. | TooltipProps['onEscKeyDown'] | - |
| onOpen | Called once per opening when the card is shown, as its enter animation starts, before afterOpen, controlled or not; not called for a hover open withdrawn because the pointer already left. | TooltipProps['onOpen'] | - |
| onVisibleChange | Called when the visibility changes; with a controlled visible it reports only requests from user interaction, not changes the caller makes to visible. | TooltipProps['onVisibleChange'] | - |
| position | Position of the popup relative to the trigger element, in twelve directions. | TooltipProps['position'] | - |
| prefixCls | Class prefix of the confirmation card. | string | "semi-popconfirm" |
| returnFocusOnClose | Whether focus returns to the trigger after closing. It also works with a controlled visible, and has no effect with trigger custom. | boolean | - |
| role | ARIA role of the popup. Defaults to dialog. | string | "dialog" |
| showArrow | Whether the arrow is shown. | boolean | - |
| showCloseIcon | Whether the close button in the corner is shown. | boolean | true |
| spacing | Distance in pixels between the popup and the trigger. An object sets the horizontal and vertical distances. | number | { x: number; y: number } | - |
| stopPropagation | Whether click, mousedown and focus in/out events on the popup stop propagating. | boolean | string | true |
| style | Style string of the confirmation card. | string | - |
| title | Title, a string or a snippet, which also names the dialog. | string | Snippet | - |
| trigger | When the card shows: hover, focus, click, contextMenu or custom. With custom, visible alone decides. | TooltipProps['trigger'] | "click" |
| visible | Whether it is shown; bind it with bind:visible. When given, this value decides; trigger keeps its value and the trigger events still work. | boolean | - |
Methods
| Method | Description | Type |
|---|---|---|
| focusTrigger | Focuses the trigger. Only works when returnFocusOnClose is true and trigger is not custom; does nothing when disabled. | Type() => void |
class and style land on the confirmation card, and the props in okButtonProps and cancelButtonProps land on their buttons (except autoFocus); bind:this receives the focusTrigger handle. Popconfirm has no root DOM element, so other undeclared native attributes and events are dropped.
Accessibility
ARIA
- Whatever the trigger,
hoverandfocusincluded, the Popconfirm popup has roledialog, named bytitle(bycontentwhen there is notitle); theroleprop overrides it - For the rest, please refer to Popover
Keyboard and focus
- Popconfirm must have trigger, trigger can be focused, use
Enterkey to open Popconfirm - After Popconfirm is activated, press the arrow key ⬇️ to move the focus to Popconfirm. The initial focus of Popconfirm should follow several principles:
- If the Popconfirm contains the last step of an irreversible process, such as: deleting data, etc., then this initial focus is preferably on the least destructive interactable element, such as: the cancel button (by passing the
autoFocusto the objectcancelButtonProps) - If you only read text in Popconfirm, it is recommended to set the initial focus on the most likely interactive elements, such as: confirm button (implemented by passing
autoFocusto the objectokButtonProps)
- If the Popconfirm contains the last step of an irreversible process, such as: deleting data, etc., then this initial focus is preferably on the least destructive interactable element, such as: the cancel button (by passing the
- Keyboard users can dismiss Popconfirm by pressing
Escand focus should return to the trigger. After the user closes the Pop through the interactive element within the Popconfirm, the focus should also return to the trigger (except when trigger iscustom) - When it is opened, after the user clicks
Escin the blank space in Popconfirm, the focus will also return to the trigger (except when trigger iscustom)
Design Tokens
| Sass variable | Value | Usage |
|---|---|---|
| $color-popconfirm_header-text | var(--semi-color-text-0) | 标题文字颜色 |
| $color-popconfirm_body-text | var(--semi-color-text-2) | 正文文字颜色 |
| $color-popconfirm_header_alert-icon | var(--semi-color-warning) | 警示图标颜色 |
| $width-popconfirm-icon | 24px | 图标宽度 |
| $width-popconfirm-maxWidth | 400px | 整体最大宽度 |
| $spacing-popconfirm-top | 24px | 顶部内边距 |
| $spacing-popconfirm-bottom | 20px | 底部内边距 |
| $spacing-popconfirm_with_arrow-padding | 12px | 顶部内边距 |
| $spacing-popconfirm_header_title-marginBottom | 8px | header 标题底部外边距 |
| $spacing-popconfirm_body_p-padding | 0 | body 正文内边距 |
| $spacing-popconfirm_body_p-margin | 0 | body 正文外边距 |
| $spacing-popconfirm_footer-marginTop | 25px | footer 顶部外边距 |
| $spacing-popconfirm_footer_btn-marginRight | 8px | footer 按钮右侧外边距 |
| $spacing-popconfirm_popover_with_arrow_inner-padding | ($spacing-popconfirm-top - $spacing-popconfirm_with_arrow-padding) ($spacing-popconfirm-top - $spacing-popconfirm_with_arrow-padding) ($spacing-popconfirm-top - $spacing-popconfirm_with_arrow-padding) ($spacing-popconfirm-bottom - $spacing-popconfirm_with_arrow-padding) | 带三角形箭头时的内边距 |
| $spacing-popconfirm_popover_with_arrow_inner_rtl-padding | ($spacing-popconfirm-top - $spacing-popconfirm_with_arrow-padding) ($spacing-popconfirm-bottom - $spacing-popconfirm_with_arrow-padding) ($spacing-popconfirm-top - $spacing-popconfirm_with_arrow-padding) ($spacing-popconfirm-top - $spacing-popconfirm_with_arrow-padding) | 带三角形箭头时的内边距(rtl) |
| $spacing-popconfirm_header_icon-marginRight | 12px | header 图标的右侧外边距 |
| $font-popconfirm_header_title-fontWeight | $font-weight-bold | header 标题字重 |
| $radius-popconfirm-popover | var(--semi-border-radius-medium) | 气泡确认框圆角大小 |
FAQ
-
Why does the Popconfirm floating layer lose its width and wrap unexpectedly when the width is not enough near the screen border?
After Chromium 104, the wrapping rendering strategy when the width of the screen border text is not enough has changed. For details, see issue #1022, the semi-side has been This problem was fixed in v2.17.0.