跳转到内容

Clipboard 剪贴板 ​

用于复制纯文本并反馈复制状态。

用法 ​

复制安装命令

组件结构 ​

加粗的是必需部件。

data-scope="clipboard":root · label · control · input · copy-trigger · indicator · status

示例 ​

独立按钮 ​

内容已在页面中展示时,只保留复制按钮

变体 ​

设置复制按钮的外观

尺寸 ​

使用小、中、大三档尺寸

设计指引 ​

何时使用 ​

  • 复制命令、链接、密钥或标识符。
  • 需要在复制前让用户核对内容。

何时不用 ​

  • 复制富文本或图片。
  • 内容需要先编辑时,使用文本字段。

特性 ​

  • 只读输入框在聚焦时自动选中文本。
  • 复制状态依次为 idle、copying 与 copied。
  • timeout 控制成功状态的停留时间。
  • 输入框、标签与状态提示均可按场景省略。
  • 复制按钮缺省是中性淡底 subtle,只有 solid 才是品牌实心;按下有统一的缩放与换底反馈。

组合 ​

  • 与代码视图组合复制代码。
  • 使用 indicator 切换复制前后的图标或文字。

最佳实践 ​

  • 保留可见文本,让用户可以核对并手动复制。
  • 复制按钮使用明确的可访问名称。
  • 默认使用中性工具面;只有复制是页面主操作时才使用 solid。
  • 成功反馈只替换图标与文字,不改变控件尺寸或轮廓。

反模式 ​

  • 不要将复制成功作为同步结果处理。
  • 不要复制用户无法核对的隐藏内容。

API 参考 ​

产物 ​

层值
自定义元素<xh-clipboard>
Vue 组件XhClipboardControl XhClipboardCopyTrigger XhClipboardIndicator XhClipboardInput XhClipboardLabel XhClipboardRoot XhClipboardStatus
组合式函数useClipboard
状态机clipboardMachine
皮肤@xihan-ui/styles/clipboard.css

Props ​

属性类型必填说明
valuestring要复制的文本;未提供时复制空串。
timeoutnumber复制成功后指示器保持多久(毫秒),默认 3000;<=0 或非有限数表示不自动回落。
disabledboolean禁用:复制按钮不可点击,作者调用 api.copy() 也无效(守卫在状态机层)。
variantActionVariant变体:solid / subtle / outline / ghost,默认 subtle(缺省中性淡底,solid 才品牌实心)。
toneTone颜色:brand / neutral / success / warning / danger / info。
sizeSize尺寸:sm / md / lg。
translationsPartial<ClipboardTranslations>
onStatusChange(details: ClipboardStatusChangeDetails) => void状态每次落定时通知一次;挂载时的 idle 是初始态,不通知。
onCopyError(details: ClipboardCopyErrorDetails) => void写入失败时通知;此时状态已回到 idle。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
status-changeClipboardStatusChangeDetails状态变化;detail 为 { status: 'copying' | 'copied' | 'idle' }
copy-errorClipboardCopyErrorDetails写入失败;detail 为 { error, value },此时状态已回到 idle

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhClipboardRootdefaultClipboardRootSlotProps

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhClipboardIndicatorcopiedboolean该标记属于哪一侧:true = 复制成功后的对勾,false(默认)= 平时的复制图标。
XhClipboardRootchildrenSlotChildren<ClipboardRootSlotProps>

状态 ​

公开状态写入 data-state。

部件取值
root'idle' | 'copying' | 'copied'
label'idle' | 'copying' | 'copied'
control'idle' | 'copying' | 'copied'
input'idle' | 'copying' | 'copied'
copy-trigger'idle' | 'copying' | 'copied'
indicator'idle' | 'copying' | 'copied'
status'idle' | 'copying' | 'copied'

以下名称仅用于内部状态机。

状态:idle · copying · copied

事件:COPY.TRIGGER · COPY.SUCCESS · COPY.ERROR · after.timeout · PRESS.START · PRESS.END

判据:isDisabled · canPress

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
statusClipboardStatus
disabledboolean
announcementstring播报区未提供内容时朗读的语句;未达到已复制档时为空串。
copiedboolean已复制成功且仍在停留窗口内。指示器与样式的唯一判据。
valuestring当前要复制的文本(prop 未提供时为空串)。
copy() => void发起一次复制意图,与点击按钮走同一路径。
getRootProps() => T['element']
getLabelProps() => T['label']
getControlProps() => T['element']
getInputProps() => T['input']
getCopyTriggerProps() => T['button']
getIndicatorProps(props: ClipboardIndicatorProps) => T['element']
getStatusProps() => T['element']复制成功的播报区,视觉隐藏;未提供内容时朗读 announcement。

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Enter / Spaceheld in copy-trigger, not disabled, not copying按住期间投影 data-pressed,与指针 :active 同一副按压面;抬起或失焦撤下

ARIA ​

以下属性由 connect 生成。

部件属性值
inputaria-labelledbylabel 部件的 id
copy-triggeraria-busy'true' | undefined
copy-triggeraria-disabled'true' | undefined
copy-triggeraria-labeltranslations?.copy
indicatoraria-hiddenindicator.copied !== copied || undefined
statusaria-atomic'true'
statusaria-live'polite'
statusrole'status'

样式参考 ​

皮肤 ​

@xihan-ui/styles/clipboard.css 使用 [data-scope="clipboard"][data-part="root"] 部件选择器,位于 xihan.components 层。覆盖样式使用 xihan.overrides。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-copied''(条件成立时才出现)
rootdata-disabled''(条件成立时才出现)
rootdata-sizeprops.size
rootdata-state'idle' | 'copying' | 'copied'
rootdata-toneprops.tone
rootdata-variantprops.variant
labeldata-state'idle' | 'copying' | 'copied'
controldata-state'idle' | 'copying' | 'copied'
inputdata-state'idle' | 'copying' | 'copied'
copy-triggerdata-copied''(条件成立时才出现)
copy-triggerdata-disabled''(条件成立时才出现)
copy-triggerdata-loading''(条件成立时才出现)
copy-triggerdata-pressed''(条件成立时才出现)
copy-triggerdata-state'idle' | 'copying' | 'copied'
copy-triggerdata-xh-action-control''
copy-triggerdata-xh-action-display'always'
copy-triggerdata-xh-action-profile'text'
copy-triggerdata-xh-action-sizeprops.size
copy-triggerdata-xh-action-variantprops.variant
copy-triggerdata-xh-ink-surface''(条件成立时才出现)
indicatordata-copied''(条件成立时才出现)
indicatordata-state'idle' | 'copying' | 'copied'
statusdata-state'idle' | 'copying' | 'copied'

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-clipboard-control-active-layercontrol
copy-trigger
input
z-indexfocus-visible
hover
1clipboard 的 control、copy-trigger、input 部件 z-index 覆盖槽。
--xh-clipboard-control-gapcontrolgapdefault0clipboard 的 control 部件 gap 覆盖槽。
--xh-clipboard-control-min-wrootmin-inline-sizehas([data-scope='clipboard'][data-part='control'])--xh-control-min-wclipboard 的 root 部件 min-inline-size 覆盖槽。
--xh-clipboard-control-wrootinline-size
min-inline-size
has([data-scope='clipboard'][data-part='control'])--xh-control-wclipboard 的 root 部件 inline-size、min-inline-size 覆盖槽。
--xh-clipboard-copy-trigger-attached-radiuscontrol
copy-trigger
border-end-end-radius
border-start-end-radius
not(:first-child)--xh-clipboard-input-radiusclipboard 的 control、copy-trigger 部件 border-end-end-radius、border-start-end-radius 覆盖槽。
--xh-clipboard-copy-trigger-bgcopy-trigger--xh-ink-surface
background-color
default
focus-visible
loading
xh-ink-surface
--xh-_action-variant-bg-focus-visible
--xh-_action-variant-bg-loading
--xh-_action-variant-bg-rest
clipboard 的 copy-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-clipboard-copy-trigger-bg-activecopy-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressedclipboard 的 copy-trigger 部件 background-color 覆盖槽。
--xh-clipboard-copy-trigger-bg-disabledcopy-trigger--xh-ink-surface
background-color
disabled
xh-ink-surface
--xh-_action-variant-bg-disabledclipboard 的 copy-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-clipboard-copy-trigger-bg-hovercopy-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hoverclipboard 的 copy-trigger 部件 background-color 覆盖槽。
--xh-clipboard-copy-trigger-bordercontrol
copy-trigger
border
border-color
default
focus-visible
not(:first-child)
--xh-_action-variant-border-focus-visible
--xh-_action-variant-border-rest
--xh-border-control
clipboard 的 control、copy-trigger 部件 border、border-color 覆盖槽。
--xh-clipboard-copy-trigger-border-disabledcopy-triggerborder-colordisabled--xh-_action-variant-border-disabledclipboard 的 copy-trigger 部件 border-color 覆盖槽。
--xh-clipboard-copy-trigger-border-hovercontrol
copy-trigger
border-colordisabled
hover
is(:active, [data-pressed])
loading
not(:first-child)
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-border-hover
--xh-_action-variant-border-pressed
--xh-border-control-hover
clipboard 的 control、copy-trigger 部件 border-color 覆盖槽。
--xh-clipboard-copy-trigger-fgcopy-triggercolorcopied
default
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
xh-action-variant=solid
--xh-_action-variant-fg-focus-visible
--xh-_action-variant-fg-hover
--xh-_action-variant-fg-loading
--xh-_action-variant-fg-pressed
--xh-_action-variant-fg-rest
clipboard 的 copy-trigger 部件 color 覆盖槽。
--xh-clipboard-copy-trigger-fg-copiedcopy-triggercolorcopied
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-fg-successclipboard 的 copy-trigger 部件 color 覆盖槽。
--xh-clipboard-copy-trigger-font-sizecopy-triggerfont-sizedefault--xh-_clipboard-font-sizeclipboard 的 copy-trigger 部件 font-size 覆盖槽。
--xh-clipboard-copy-trigger-font-weightcopy-triggerfont-weightdefault--xh-text-label-weightclipboard 的 copy-trigger 部件 font-weight 覆盖槽。
--xh-clipboard-copy-trigger-gapcopy-trigger
indicator
gapdefault--xh-control-gap-smclipboard 的 copy-trigger、indicator 部件 gap 覆盖槽。
--xh-clipboard-copy-trigger-hcopy-triggerblock-sizedefault--xh-_clipboard-hclipboard 的 copy-trigger 部件 block-size 覆盖槽。
--xh-clipboard-copy-trigger-pxcopy-triggerpadding-inlinedefault--xh-_clipboard-pxclipboard 的 copy-trigger 部件 padding-inline 覆盖槽。
--xh-clipboard-copy-trigger-radiuscopy-triggerborder-radiusdefault--xh-shape-controlclipboard 的 copy-trigger 部件 border-radius 覆盖槽。
--xh-clipboard-copy-trigger-shadow-hovercopy-triggerbox-shadowdisabled
hover
loading
not([data-disabled])
not([data-loading])
noneclipboard 的 copy-trigger 部件 box-shadow 覆盖槽。
--xh-clipboard-gaprootgapdefault--xh-space-1clipboard 的 root 部件 gap 覆盖槽。
--xh-clipboard-indicator-fg-copiedindicatorcolorcopied--xh-fg-successclipboard 的 indicator 部件 color 覆盖槽。
--xh-clipboard-indicator-gapindicatorgapdefault--xh-clipboard-copy-trigger-gapclipboard 的 indicator 部件 gap 覆盖槽。
--xh-clipboard-input-autofill-bginputbox-shadow-webkit-autofill
autofill
--xh-bg-subtle-opaqueclipboard 的 input 部件 box-shadow 覆盖槽。
--xh-clipboard-input-autofill-fginput-webkit-text-fill-color-webkit-autofill
autofill
--xh-fg-defaultclipboard 的 input 部件 -webkit-text-fill-color 覆盖槽。
--xh-clipboard-input-bginputbackgrounddefault--xh-bg-subtleclipboard 的 input 部件 background 覆盖槽。
--xh-clipboard-input-borderinputborderdefault--xh-border-controlclipboard 的 input 部件 border 覆盖槽。
--xh-clipboard-input-border-focusinputborder-colorfocus-visible--xh-border-control-focusclipboard 的 input 部件 border-color 覆盖槽。
--xh-clipboard-input-fginputcolordefault--xh-fg-defaultclipboard 的 input 部件 color 覆盖槽。
--xh-clipboard-input-font-sizeinputfont-sizedefault--xh-text-body-sizeclipboard 的 input 部件 font-size 覆盖槽。
--xh-clipboard-input-hinputblock-sizedefault--xh-_clipboard-hclipboard 的 input 部件 block-size 覆盖槽。
--xh-clipboard-input-pxinputpadding-inlinedefault--xh-_clipboard-pxclipboard 的 input 部件 padding-inline 覆盖槽。
--xh-clipboard-input-radiuscontrol
copy-trigger
input
border-end-end-radius
border-radius
border-start-end-radius
default
not(:first-child)
--xh-shape-controlclipboard 的 control、copy-trigger、input 部件 border-end-end-radius、border-radius、border-start-end-radius 覆盖槽。
--xh-clipboard-label-fglabelcolordefault--xh-fg-defaultclipboard 的 label 部件 color 覆盖槽。
--xh-clipboard-label-font-sizelabelfont-sizedefault--xh-text-label-sizeclipboard 的 label 部件 font-size 覆盖槽。
--xh-clipboard-label-font-weightlabelfont-weightdefault--xh-text-label-weightclipboard 的 label 部件 font-weight 覆盖槽。
--xh-clipboard-loading-durationcopy-triggeranimationdefault--xh-motion-loop-spinclipboard 的 copy-trigger 部件 animation 覆盖槽。

动效 ​

动效角色:按压 · 状态 · 出现 · 循环(见动效规范)。

可覆盖的动效槽:--xh-clipboard-loading-duration。

共享关键帧 xh-fade-in · xh-fade-out · xh-spin 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立;opacity · visibility 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。

prefers-reduced-motion: reduce 下本组件另有降级规则。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。

Released under The MIT License