跳转到内容

DownloadTrigger 下载触发器

用于将文本或 Blob 保存为本地文件。

用法

下载文本文件

组件结构

加粗的是必需部件。

data-scope="download-trigger"root

示例

异步内容

点击后获取下载内容

Blob

下载 JSON 文件

变体

设置触发器外观

尺寸

使用小、中、大三档尺寸

禁用

禁止触发下载

设计指引

何时使用

  • 导出 CSV、JSON、日志或配置文件。
  • 点击后才获取或生成下载内容。

何时不用

  • 文件已有稳定地址时,使用原生 <a download>
  • 复制少量文字时,使用剪贴板
  • 接收用户文件时,使用文件上传

特性

  • 接受字符串、Blob 与异步数据函数。
  • preparing 期间保留焦点并阻止重复触发。
  • 通过完成与失败事件返回本次文件名和错误。
  • 缺省是中性淡底 subtle,只有 solid 才是品牌实心;按下有统一的缩放与换底反馈。

组合

  • 进度条组合展示可量化的长任务。
  • 通过变体与颜色调整操作层级。

最佳实践

  • 文件名应包含正确扩展名。
  • 保留下载图标与可见文字;只有下载是页面主操作时才使用 solid
  • 大文件优先使用服务端下载地址。
  • 失败事件应连接可见反馈。

反模式

  • 不要将“下载已发起”等同于“文件已写入磁盘”。
  • 不要在页面加载时预先生成大文件。

API 参考

产物

自定义元素<xh-download-trigger>
Vue 组件XhDownloadTrigger
组合式函数useDownloadTrigger
状态机downloadTriggerMachine
皮肤@xihan-ui/styles/download-trigger.css

Props

属性类型必填说明
dataDownloadTriggerData要下载的内容:文本、Blob,或点击时才调用的取数函数(可返回 Promise)。
fileNamestring写出的文件名;未提供或空串时回退为内建默认名。
mimeTypestring内容类型;提供后以它为准,Blob 自带的类型也按它重新包装。未提供时文本按纯文本处理。
disabledboolean禁用:按钮不可聚焦、不可点击。
variantActionVariant变体:solid / subtle / outline / ghost,默认 subtle(缺省中性淡底,solid 才品牌实心)。
toneTone颜色:brand / neutral / success / warning / danger / info。
sizeSize尺寸:sm / md / lg。
translationsPartial<DownloadTriggerTranslations>
onDownloadComplete(details: DownloadTriggerCompleteDetails) => void数据已交给浏览器时通知一次。此时只说明下载已发起,浏览器是否把文件写入磁盘组件无法感知。
onDownloadError(details: DownloadTriggerErrorDetails) => void取数失败或无法创建下载时通知;此时状态已回到 idle。

事件

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

事件载荷说明
download-completeDownloadTriggerCompleteDetails数据已交给浏览器;detail 为 { fileName }
download-errorDownloadTriggerErrorDetails取数失败或无法创建下载;detail 为 { error, fileName },此时状态已回到 idle

插槽

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhDownloadTriggerdefaultDownloadTriggerSlotProps

状态

公开状态写入 data-state

部件取值
root'idle' | 'preparing'

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

状态idle · preparing

事件DOWNLOAD.TRIGGER · DOWNLOAD.SUCCESS · DOWNLOAD.ERROR · PRESS.START · PRESS.END

判据isDisabled · canPress

connect API

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

成员类型说明
statusDownloadTriggerStatus
preparingboolean数据获取中。按钮不因此禁用,只是期间再次点击不会重复发起。
disabledboolean
fileNamestring本次将写出的文件名(prop 未提供时是内建默认名)。
download() => void发起一次下载意图,与点击按钮走同一路径:禁用时不生效,取数在途时不重复发起。
getRootProps() => T['button']

无障碍

键盘

规格出处:W3C APG

按键生效条件行为
Enter / Spacefocus in root, 未禁用发起一次下载;取数在途时这两个键同样不会重复发起
Enter / Spaceheld in root, not disabled, not preparing按住期间投影 data-pressed,与指针 :active 同一副按压面;抬起或失焦撤下

ARIA

以下属性由 connect 生成。

部件属性
rootaria-busy'true' | undefined
rootaria-disabled'true' | undefined
rootaria-labelprops.translations.trigger
  • 触发器使用原生 <button type="button">
  • 准备数据时使用 aria-busyaria-disabled,但不移除焦点。
  • 仅显示图标时必须提供可访问名称。

样式参考

皮肤

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

数据属性

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

部件属性
rootdata-disabled''(条件成立时才出现)
rootdata-loading''(条件成立时才出现)
rootdata-pressed''(条件成立时才出现)
rootdata-sizeprops.size
rootdata-state'idle' | 'preparing'
rootdata-toneprops.tone
rootdata-variantprops.variant
rootdata-xh-action-control''
rootdata-xh-action-display'always'
rootdata-xh-action-profile'text'
rootdata-xh-action-sizeprops.size
rootdata-xh-action-variantprops.variant

CSS 变量

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

变量部件CSS 属性状态默认来源说明
--xh-download-trigger-bgrootbackground-colordefault
focus-visible
loading
--xh-_action-variant-bg-focus-visible
--xh-_action-variant-bg-loading
--xh-_action-variant-bg-rest
download-trigger 的 root 部件 background-color 覆盖槽。
--xh-download-trigger-bg-activerootbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-presseddownload-trigger 的 root 部件 background-color 覆盖槽。
--xh-download-trigger-bg-disabledrootbackground-colordisabled--xh-_action-variant-bg-disableddownload-trigger 的 root 部件 background-color 覆盖槽。
--xh-download-trigger-bg-hoverrootbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hoverdownload-trigger 的 root 部件 background-color 覆盖槽。
--xh-download-trigger-borderrootborder
border-color
default
focus-visible
--xh-_action-variant-border-focus-visible
--xh-_action-variant-border-rest
download-trigger 的 root 部件 border、border-color 覆盖槽。
--xh-download-trigger-border-disabledrootborder-colordisabled--xh-_action-variant-border-disableddownload-trigger 的 root 部件 border-color 覆盖槽。
--xh-download-trigger-border-hoverrootborder-colordisabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-border-hover
--xh-_action-variant-border-pressed
download-trigger 的 root 部件 border-color 覆盖槽。
--xh-download-trigger-fgrootborder-block-start-color
border-color
color
@media (prefers-reduced-motion: reduce)
default
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
motion=reduce
not([data-disabled])
not([data-loading])
pressed
where([data-motion='reduce'])
--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
download-trigger 的 root 部件 border-block-start-color、border-color、color 覆盖槽。
--xh-download-trigger-font-sizerootfont-sizedefault--xh-_action-profile-font-sizedownload-trigger 的 root 部件 font-size 覆盖槽。
--xh-download-trigger-font-weightrootfont-weightdefault--xh-text-label-weightdownload-trigger 的 root 部件 font-weight 覆盖槽。
--xh-download-trigger-gaprootgapdefault--xh-_action-profile-gapdownload-trigger 的 root 部件 gap 覆盖槽。
--xh-download-trigger-hrootblock-sizedefault--xh-_action-profile-visual-sizedownload-trigger 的 root 部件 block-size 覆盖槽。
--xh-download-trigger-icon-sizeroot--xh-icon-sizedefault--xh-_action-profile-glyph-sizedownload-trigger 的 root 部件 --xh-icon-size 覆盖槽。
--xh-download-trigger-loading-durationrootanimationdefault--xh-spin-durationdownload-trigger 的 root 部件 animation 覆盖槽。
--xh-download-trigger-loading-fgrootborder-block-start-color
border-color
@media (prefers-reduced-motion: reduce)
default
motion=reduce
where([data-motion='reduce'])
--xh-download-trigger-fgdownload-trigger 的 root 部件 border-block-start-color、border-color 覆盖槽。
--xh-download-trigger-pxrootpadding-inlinedefault--xh-_action-profile-padding-inlinedownload-trigger 的 root 部件 padding-inline 覆盖槽。
--xh-download-trigger-radiusrootborder-radiusdefault--xh-shape-controldownload-trigger 的 root 部件 border-radius 覆盖槽。
--xh-download-trigger-shadow-hoverrootbox-shadowdisabled
hover
loading
not([data-disabled])
not([data-loading])
nonedownload-trigger 的 root 部件 box-shadow 覆盖槽。

动效

关键帧 xh-download-trigger-content-hide · xh-download-trigger-loading-reveal · xh-download-trigger-rotate 随皮肤自带,不引用别处文件里的名字。时长与缓动读动效令牌,改令牌即改全局节奏。

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

响应式

皮肤另按输入能力分档:pointer: coarse:同一份皮肤在触屏与带指针的设备上不一样,与视口宽度无关。

RTL

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像;另有按 dir 分支的规则。

Released under The MIT License