生态产品多个设计器现已发布候选版本

查看生态总览
跳转到内容

Approval 审批 alpha ​

危险操作执行前的人工闸门:批准或拒绝,超时按拒绝处理,可附带勾选式的授权范围。

用法 ​

勾选与判定是原子的:批准的载荷带着批准的项,不存在已批准但范围尚未同步的窗口

要动你的工作区

它想读一遍 src/ 并写回改动。

Waiting for your decision

判定:(未判定)

组件结构 ​

加粗的是必需部件。

data-scope="approval":root · pending-indicator · title · description · live-region · group · item · item-indicator · item-text · note · timer · result · footer · approve-trigger · deny-trigger

示例 ​

超时按拒绝收口 ​

默认不提供超时值:替宿主制定安全策略比不制定更危险。到期落为拒绝,expired 只是显示态

要执行一条删除命令

没人答的话,到点按拒绝处理。

判定:(未判定)

附加备注 ​

备注与勾选同批取快照,随判定载荷一起发出;留空时不带该字段,它不参与必选项是否勾满的判断

要把这批改动推上去

推之前可以留一句话,随判定一起交给宿主。

判定:(未判定)

形态与尺寸 ​

variant 改变该闸门与正文分开的方式,size 改变标题、条目与按钮的几何档;判定链不变

描边(缺省)

弱底分区

无壳内联

小档

大档

拒绝要写理由 ​

requireReason 让用户拒绝时必须写明理由:备注空着就按拒绝或 Escape,焦点落到备注框并标为无效,写上理由再按才拒绝;超时照常按拒绝收口

要删除远端分支 release/2.1

拒绝时写一句理由,Agent 会据此换个做法。

判定:(未判定)

批量处理 ​

闸门是单发的,批量是宿主的编排:每条请求一个闸门、判定受控,上面一行放全部批准与全部拒绝;全部批准只收必选项已勾满的那几条(canApproveScopes),没勾满的留着逐条处理

读取 package.json

只读,不改任何文件。

运行 pnpm install

会改写 node_modules 与锁文件。

写入 src/config.ts

把超时从 5 秒改成 30 秒。

3 项待决

设计指引 ​

何时使用 ​

  • Agent 执行写文件、发请求、付费等实际操作前需要用户确认。
  • 授权带范围:批准的同时需要说明批准了哪些项。

何时不用 ​

  • 只需要一句确认时,使用弹出确认。
  • 判定结果不影响任何执行时,它不是闸门,应使用提示。

特性 ​

  • 超时一律按拒绝处理,由状态机结构保证,不依赖调用方遵守约定:判定的取值只有批准与拒绝,expired 只是显示状态;通往批准的转移只有一条;到期事件只在待决状态有转移,迟到的定时事件静默丢弃。
  • 不提供默认超时值,由宿主决定安全策略。时长非有限数或非正数时不启动计时器,停留在待决状态;既不按 0ms 立即到期,也不视为无限期放行。
  • 拒绝路径始终可达:状态机层的拒绝不受必选项和任何闸门限制,超时、卸载兜底与宿主的 deny() 入口都能落地。拒绝按钮与 Escape 另有一道挂起闸门:判定在途时与批准按钮一起锁定,避免等待宿主响应期间产生第二条判定。
  • 勾选与判定是原子的:批准的载荷携带已勾选的授权项,不存在已批准但范围未同步的窗口。
  • 备注(note)与勾选同批快照,随判定载荷一起发出;为空时不携带该字段。备注不参与必选项是否勾满的判断。
  • requireReason 让用户拒绝时必须写明理由:备注空着(或只有空白)就按拒绝钮或 Escape,不发判定,焦点移到备注框并标为无效;写上理由再按即拒绝,理由随载荷的 note 发出。它只拦人手按的这两条路:超时、卸载兜底与宿主的 deny() 不是用户的判定,照常落地;没渲染备注框时也照常拒绝——写不了理由的地方不能拦住拒绝。
  • requestId 变化即重新进入待决并按新时长重启计时;不为上一轮补发拒绝,旧结果由宿主自行作废。重入时勾选与备注回到各自默认值。
  • 判定落定后 result 部件才显示,语气随判定变化:批准取成功档,拒绝与超时取危险档。它对读屏隐藏,同一句话由播报区读出一次。
  • 两个按钮位于 actions 行内,间距与对齐由库统一处理,使用者不需要另写容器。
  • 待决时 pending-indicator 在右上角显示一颗呼吸的圆点,颜色随语气、缺省取警示色,判定落定即收起;它不占作者排的版面。减弱动效下圆点静止。

组合 ​

  • 放入工具调用的 approval 部件位:该位置常驻于开关与详情之间,不会被折叠隐藏。
  • 需要弹窗时每个闸门一个对话框:role="alertdialog"、关闭 closeOnEscape,并把 initialFocus 设为本组件导出的 APPROVAL_DENY_SELECTOR。浮层只保留批准与拒绝两个出口,Escape 仍冒泡到闸门并判为拒绝。
  • 剩余时间的显示交给计时器,判定权仍由本组件持有。不要把倒计时直接渲染为 timer 节点:两套解剖打在同一节点上会互相覆盖,应让 timer 作为外层容器。
  • 需要连续询问多件事时,使用步骤条或走马灯串联多个闸门。本组件是单发闸门,data-state 的四个值互斥,不表达序号。
  • 批量处理(一轮里 Agent 提了好几条请求):每条请求一个闸门,status 受控,上面一行放“全部批准 / 全部拒绝”,由宿主直接写各闸门的 status。全部批准只收必选项已勾满的那几条,用 canApproveScopes(scopes, grantedScopes) 判,没勾满的留给用户逐条处理;受控写回不再派发 decision,批量的判定记录由宿主自己写。批量不做成组件内建:哪几条能一起批、批量是否也要理由,都是宿主的安全策略。
  • 需要提供“稍后再说”入口时,该入口由宿主实现,不属于闸门。常见做法是在 onDecision 之外另留延后路径,或按上一条把闸门放进对话框;浮层内仍只有批准与拒绝两个出口。

最佳实践 ​

  • 判定落定后两个按钮都会禁用,浮层不再有出口,宿主必须在判定回调中关闭浮层。
  • 卸载即拒绝(denyOnUnmount)默认关闭。启用前确认列表换 key、路由切换、热更新等任何一次重新挂载都会替用户发出判定。

反模式 ​

  • 把超时做成到点自动放行。
  • 用可关闭的浮层承载闸门:关闭窗口既不是批准也不是拒绝,闸门会悬空。

API 参考 ​

产物 ​

层值
自定义元素<xh-approval>
Vue 组件XhApprovalApproveTrigger XhApprovalDenyTrigger XhApprovalDescription XhApprovalFooter XhApprovalGroup XhApprovalItem XhApprovalItemIndicator XhApprovalItemText XhApprovalLiveRegion XhApprovalNote XhApprovalPendingIndicator XhApprovalResult XhApprovalRoot XhApprovalTimer XhApprovalTitle
组合式函数useApproval
状态机approvalMachine
皮肤@xihan-ui/styles/approval.css

Props ​

属性类型必填说明
requestIdstring本轮请求的身份。变化即重新进入待决,并按新时长重新计时。
statusApprovalStatus提供即受控。
defaultStatusApprovalStatus
timeoutMsnumber超时无人应答时按拒绝收口。默认不提供默认值:替宿主决定安全策略比不决定更危险。 非有限值或非正数同样不启动计时器,既不按 0ms 立即到期,也不视为无限期放行。
scopesreadonly ApprovalScope[]
grantedScopesreadonly string[]
defaultGrantedScopesreadonly string[]
notestring附在判定上的一段自由文本。提供即受控。 它只随判定载荷发出,不参与必选项是否全部勾选的判断。
defaultNotestring
requireReasonboolean用户拒绝时必须写明理由(备注非空)。备注空着时按拒绝钮或 Escape 不发判定, 而是把焦点移到备注框并标为无效。只管人手按的这两条路:超时、卸载兜底与宿主的 deny() 不是用户的判定,照常落地;没渲染备注框时也照常拒绝——写不了理由就不能拦住拒绝。
loadingboolean判定在途:只阻止重复批准,不阻止拒绝。
denyOnEscapebooleanEscape 判为拒绝,默认开启。
denyOnUnmountboolean卸载时若仍待决则按拒绝派发一次,默认关闭。 机制成立不等于默认值成立:列表更换 key、路由切换、热更新的任何一次重挂, 都会替用户发出未做过的判定。
live'polite' | 'assertive'播报档位,默认 polite。
variantControlVariant形态:outline 描边、subtle 底色分区、ghost 无壳内联。默认 outline。
toneTone
sizeSize
partsTitleDescriptionParts作者实际渲染了哪些部件,由适配器统计;省略即按都在场处理(服务端直出与挂载前)。 title 不在场时不写 aria-labelledby;description 不在场、或渲染了但读不出一句话(判断同 hasNamingContent)时不写 aria-describedby。
translationsPartial<ApprovalTranslations>
onDecision(details: ApprovalDecisionDetails) => void
onGrantedScopesChange(details: ApprovalScopesChangeDetails) => void
onNoteChange(details: ApprovalNoteChangeDetails) => void

ApprovalScope ​

scopes 的元素。

字段类型必填说明
valuestring是
labelstring
requiredboolean必选项:未全部勾选时不能批准。
disabledboolean

事件 ​

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

事件载荷说明
decisionApprovalDecisionDetails判定落定;detail 为 { requestId, decision, source, scopes }
granted-scopes-changeApprovalScopesChangeDetails勾选的授权项变化;detail 为 { value: string[] }
note-changeApprovalNoteChangeDetails备注变化;detail 为 { value: string }

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhApprovalItemdefaultApprovalScopeSlotProps
XhApprovalRootdefaultApprovalRootSlotProps

React 适配器 props ​

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

React 组件属性类型必填说明
XhApprovalItemscopeValuestring是该项授权范围的取值。
XhApprovalItemscopeLabelstring
XhApprovalItemscopeRequiredboolean必选项:未全部勾选时无法批准。
XhApprovalItemscopeDisabledboolean
XhApprovalItemchildrenSlotChildren<ApprovalScopeSlotProps>
XhApprovalItemIndicatorscopeValuestring是
XhApprovalItemTextscopeValuestring是
XhApprovalRootchildrenSlotChildren<ApprovalRootSlotProps>

状态 ​

公开状态写入 data-state。

部件取值
root'pending' | 'approved' | 'denied' | 'expired'
pending-indicator'pending' | 'approved' | 'denied' | 'expired'
item'checked' | 'unchecked'
item-indicator'checked' | 'unchecked'
note'pending' | 'approved' | 'denied' | 'expired'
timer'pending' | 'approved' | 'denied' | 'expired'
result'pending' | 'approved' | 'denied' | 'expired'
approve-trigger'pending' | 'approved' | 'denied' | 'expired'
deny-trigger'pending' | 'approved' | 'denied' | 'expired'

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

状态:pending · approved · denied · expired

事件:APPROVE · DENY · SCOPE.TOGGLE · SCOPE.SET · NOTE.SET · after.timeout · CONTROLLED.PENDING · CONTROLLED.APPROVE · CONTROLLED.DENY · CONTROLLED.EXPIRE · REQUEST.RESET · PRESS.START · PRESS.END · REASON.PROMPT

判据:isStatusControlled · canApprove · isEditable · canApproveControlled · canPress

connect API ​

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

成员类型说明
statusApprovalStatus
settledboolean已判定:两个按钮都收起出口。
loadingboolean
grantedScopesstring[]
notestring备注中的文字;未填写时为空串。
canApproveboolean必选项是否全部勾选。
reasonMissingboolean要求写理由而备注还空着:此时用户按拒绝只会把焦点带到备注框。
announcementstring按 status 选出的播报文本;关闭 announce 时作者不渲染该部件即可。
approve() => void
deny() => void
setGrantedScopes(next: string[]) => void
setNote(next: string) => void
isScopeGranted(value: string) => boolean
getRootProps() => T['element']
getPendingIndicatorProps() => T['element']待决时的呼吸点:判过即收,对读屏隐藏。
getTitleProps() => T['element']
getDescriptionProps() => T['element']
getLiveRegionProps() => T['element']
getGroupProps() => T['element']
getItemProps(scope: ApprovalScope) => T['element']
getItemIndicatorProps(scope: ApprovalScope) => T['element']
getItemTextProps(scope: ApprovalScope) => T['element']
getNoteProps() => T['input']
getTimerProps() => T['element']
getResultProps() => T['element']
getFooterProps() => T['element']
getApproveTriggerProps() => T['button']
getDenyTriggerProps() => T['button']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Enter / Space焦点在批准按钮上,待决、必选项已勾满、且不在挂起中判为批准,载荷带上已勾选的授权项
Enter / Space焦点在拒绝按钮上,待决且不在挂起中判为拒绝
Space焦点在授权项上,待决且该项未禁用勾选或取消该项。Enter 刻意不参与,与原生复选框一致
Enter / Space按住批准或拒绝按钮,待决且不在挂起中;批准还要必选项已勾满按住期间该钮投影 data-pressed,与指针 :active 同一副按压面(text 档定尺按钮,按下缩放并换底);抬起、失焦、判定落定或转入挂起撤下
Space按住授权项,待决、不在挂起中且该项未禁用按住期间该行投影 data-pressed,与指针 :active 同一副按压面(row 档只换面不缩放);抬起或失焦撤下。Enter 不是复选框的激活键,不进按压面
Escape焦点在闸门内,待决、未挂起、且开启 denyOnEscape判为拒绝。它不是关闭:本组件不提供不作答的出口
Enter / Space / Escape开了 requireReason、备注框在场且还空着,焦点在拒绝按钮上(Escape 则焦点在闸门内)不判定,焦点移到备注框并标为无效(aria-invalid);写上理由后再按即判为拒绝,理由随载荷的 note 发出

ARIA ​

以下属性由 connect 生成。

部件属性值
rootaria-describedbydescription 部件的 id | undefined
rootaria-labelledbytitle 部件的 id | undefined
rootrole'group'
pending-indicatoraria-hidden'true'
live-regionaria-atomic'true'
live-regionaria-liveprops.live
grouparia-labeltranslations.scopes
grouprole'group'
itemaria-checked'true' | 'false'
itemaria-disabled'true' | 'false'
itemaria-required'true' | 'false'
itemrole'checkbox'
item-indicatoraria-hidden'true'
notearia-invalid'true' | undefined
notearia-labeltranslations.reason | translations.note
notearia-required'true' | undefined
timeraria-hidden'true'
resultaria-hidden'true'
approve-triggeraria-busy'true' | undefined
approve-triggeraria-disabled'true' | 'false'
approve-triggeraria-labeltranslations.approve
deny-triggeraria-busy'true' | undefined
deny-triggeraria-disabled'true' | 'false'
deny-triggeraria-labeltranslations.deny
  • 闸门是 role=group,由标题命名、由说明描述。
  • 待决时批准键使用 aria-disabled 而不是原生 disabled:保持可聚焦,读屏可以读出不可用的原因。
  • 授权项是 role=checkbox,各占一个 Tab 停靠点,只响应 Space,与原生复选框一致。
  • 剩余时间、结果条与待决的呼吸点都对读屏隐藏:逐秒变化的数字进入活动区域会持续打断,判定结果与截止事件由播报区各读出一次。
  • 备注取 translations.note 作为可访问名称(默认 Note),占位文字取 translations.notePlaceholder。开了 requireReason 时名字换成 translations.reason(默认 Reason for denial)并带 aria-required,缺理由按过拒绝后带 aria-invalid。

样式参考 ​

皮肤 ​

@xihan-ui/styles/approval.css 按 [data-scope="approval"][data-part="root"] 部件选择器书写,发布产物以挂载类 .xh-scope-approval 代替其中的 data-scope(特异性相同),位于 xihan.components 层。覆盖样式使用 xihan.overrides,部件选择器照常可用。

forced-colors: active 下另有一套规则:颜色交给系统,边框与状态标记改用系统色关键字。

数据属性 ​

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

部件属性值
rootdata-loading''(条件成立时才出现)
rootdata-sizeprops.size
rootdata-state'pending' | 'approved' | 'denied' | 'expired'
rootdata-toneprops.tone
rootdata-variantprops.variant
pending-indicatordata-state'pending' | 'approved' | 'denied' | 'expired'
itemdata-disabled''(条件成立时才出现)
itemdata-pressed''(条件成立时才出现)
itemdata-state'checked' | 'unchecked'
itemdata-valueitem.value
itemdata-xh-action-control''
itemdata-xh-action-display'always'
itemdata-xh-action-profile'row'
itemdata-xh-action-sizeprops.size
itemdata-xh-action-variant'ghost'
item-indicatordata-state'checked' | 'unchecked'
item-textdata-valueitem.value
notedata-invalid''(条件成立时才出现)
notedata-state'pending' | 'approved' | 'denied' | 'expired'
timerdata-state'pending' | 'approved' | 'denied' | 'expired'
resultdata-state'pending' | 'approved' | 'denied' | 'expired'
resultdata-tone'success' | 'danger' | undefined
footerdata-loading''(条件成立时才出现)
footerdata-xh-loading-ring''
approve-triggerdata-disabled''(条件成立时才出现)
approve-triggerdata-loading''(条件成立时才出现)
approve-triggerdata-pressed''(条件成立时才出现)
approve-triggerdata-state'pending' | 'approved' | 'denied' | 'expired'
approve-triggerdata-toneprops.tone
approve-triggerdata-xh-action-control''
approve-triggerdata-xh-action-display'always'
approve-triggerdata-xh-action-profile'text'
approve-triggerdata-xh-action-sizeprops.size
approve-triggerdata-xh-action-variant'solid'
approve-triggerdata-xh-ink-surface''
deny-triggerdata-disabled''(条件成立时才出现)
deny-triggerdata-loading''(条件成立时才出现)
deny-triggerdata-pressed''(条件成立时才出现)
deny-triggerdata-state'pending' | 'approved' | 'denied' | 'expired'
deny-triggerdata-xh-action-control''
deny-triggerdata-xh-action-display'always'
deny-triggerdata-xh-action-profile'text'
deny-triggerdata-xh-action-sizeprops.size
deny-triggerdata-xh-action-variant'outline'

CSS 变量 ​

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

变量部件CSS 属性状态默认来源说明
--xh-approval-action-font-sizeapprove-trigger
deny-trigger
font-sizedefault--xh-text-label-sizeapproval 的 approve-trigger、deny-trigger 部件 font-size 覆盖槽。
--xh-approval-action-font-weightapprove-trigger
deny-trigger
font-weightdefault--xh-text-label-weightapproval 的 approve-trigger、deny-trigger 部件 font-weight 覆盖槽。
--xh-approval-action-happrove-trigger
deny-trigger
block-size
min-block-size
default
xh-action-profile=row
--xh-_approval-action-happroval 的 approve-trigger、deny-trigger 部件 block-size、min-block-size 覆盖槽。
--xh-approval-action-pxapprove-trigger
deny-trigger
padding-inlinedefault--xh-_approval-action-pxapproval 的 approve-trigger、deny-trigger 部件 padding-inline 覆盖槽。
--xh-approval-action-radiusapprove-trigger
deny-trigger
border-radiusdefault--xh-shape-controlapproval 的 approve-trigger、deny-trigger 部件 border-radius 覆盖槽。
--xh-approval-approve-bgapprove-trigger--xh-ink-surface
background-color
default
loading
xh-ink-surface
--xh-_action-variant-bg-loading
--xh-_action-variant-bg-rest
approval 的 approve-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-approval-approve-bg-hoverapprove-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hoverapproval 的 approve-trigger 部件 background-color 覆盖槽。
--xh-approval-approve-bg-offapprove-trigger--xh-ink-surface
background-color
disabled
xh-ink-surface
--xh-_action-variant-bg-disabledapproval 的 approve-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-approval-approve-fgapprove-triggercolordefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-fg-hover
--xh-_action-variant-fg-loading
--xh-_action-variant-fg-pressed
--xh-_action-variant-fg-rest
approval 的 approve-trigger 部件 color 覆盖槽。
--xh-approval-approve-shadowapprove-triggerbox-shadowdefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_highlight-toneapproval 的 approve-trigger 部件 box-shadow 覆盖槽。
--xh-approval-bgrootbackgrounddefault
variant=subtle
--xh-bg-subtle
--xh-bg-surface
approval 的 root 部件 background 覆盖槽。
--xh-approval-borderrootborder
border-color
default
tone
--xh-_tone
--xh-border-default
approval 的 root 部件 border、border-color 覆盖槽。
--xh-approval-border-settledrootborder-colornot([data-state='pending'])
state=pending
--xh-border-defaultapproval 的 root 部件 border-color 覆盖槽。
--xh-approval-deny-bgdeny-trigger--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-restapproval 的 deny-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-approval-deny-bg-hoverdeny-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hoverapproval 的 deny-trigger 部件 background-color 覆盖槽。
--xh-approval-deny-bg-offdeny-trigger--xh-ink-surface
background-color
disabled
xh-ink-surface
--xh-_action-variant-bg-disabledapproval 的 deny-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-approval-deny-borderdeny-triggerborderdefault--xh-_action-variant-border-restapproval 的 deny-trigger 部件 border 覆盖槽。
--xh-approval-deny-border-offdeny-triggerborder-colordisabled--xh-_action-variant-border-disabledapproval 的 deny-trigger 部件 border-color 覆盖槽。
--xh-approval-deny-fgdeny-triggercolordefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-fg-hover
--xh-_action-variant-fg-pressed
--xh-_action-variant-fg-rest
approval 的 deny-trigger 部件 color 覆盖槽。
--xh-approval-description-fgdescriptioncolordefault--xh-fg-mutedapproval 的 description 部件 color 覆盖槽。
--xh-approval-description-font-sizedescriptionfont-sizedefault--xh-text-secondary-sizeapproval 的 description 部件 font-size 覆盖槽。
--xh-approval-footer-gapfootergapdefault--xh-space-2approval 的 footer 部件 gap 覆盖槽。
--xh-approval-gaprootgapdefault--xh-_approval-gapapproval 的 root 部件 gap 覆盖槽。
--xh-approval-group-gapgroupgapdefault--xh-space-1approval 的 group 部件 gap 覆盖槽。
--xh-approval-icon-sizeroot--xh-icon-sizedefault--xh-_approval-icon-sizeapproval 的 root 部件 --xh-icon-size 覆盖槽。
--xh-approval-indicator-bg-checkeditem-indicatorbackgroundstate=checked--xh-bg-brandapproval 的 item-indicator 部件 background 覆盖槽。
--xh-approval-indicator-borderitem-indicatorborderdefault--xh-border-controlapproval 的 item-indicator 部件 border 覆盖槽。
--xh-approval-indicator-border-checkeditem-indicatorborder-colorstate=checked--xh-bg-brandapproval 的 item-indicator 部件 border-color 覆盖槽。
--xh-approval-indicator-fgitem-indicatorcolordefault--xh-fg-on-brandapproval 的 item-indicator 部件 color 覆盖槽。
--xh-approval-indicator-icon-sizeitem-indicator--xh-icon-sizedefault--xh-_approval-indicator-glyphapproval 的 item-indicator 部件 --xh-icon-size 覆盖槽。
--xh-approval-indicator-radiusitem-indicatorborder-radiusdefault--xh-shape-insetapproval 的 item-indicator 部件 border-radius 覆盖槽。
--xh-approval-indicator-sizeitem-indicator--xh-icon-size
block-size
inline-size
default--xh-control-indicator-sizeapproval 的 item-indicator 部件 --xh-icon-size、block-size、inline-size 覆盖槽。
--xh-approval-item-bg-hoveritembackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hoverapproval 的 item 部件 background-color 覆盖槽。
--xh-approval-item-font-sizeitemfont-sizedefault--xh-_approval-item-font-sizeapproval 的 item 部件 font-size 覆盖槽。
--xh-approval-item-gapitemgapdefault--xh-space-1_5approval 的 item 部件 gap 覆盖槽。
--xh-approval-item-pxitempadding-inlinedefault--xh-space-2approval 的 item 部件 padding-inline 覆盖槽。
--xh-approval-item-pyitempadding-blockxh-action-profile=row--xh-space-1approval 的 item 部件 padding-block 覆盖槽。
--xh-approval-item-radiusitemborder-radiusdefault--xh-_action-profile-radiusapproval 的 item 部件 border-radius 覆盖槽。
--xh-approval-item-text-fgitem-textcolordefault--xh-fg-mutedapproval 的 item-text 部件 color 覆盖槽。
--xh-approval-item-text-fg-checkeditem
item-text
colorstate=checked--xh-fg-defaultapproval 的 item、item-text 部件 color 覆盖槽。
--xh-approval-loading-durationfooteranimationxh-loading-ring--xh-motion-loop-spinapproval 的 footer 部件 animation 覆盖槽。
--xh-approval-note-bgnotebackgrounddefault--xh-bg-fieldapproval 的 note 部件 background 覆盖槽。
--xh-approval-note-bg-disablednotebackgrounddisabled--xh-bg-subtleapproval 的 note 部件 background 覆盖槽。
--xh-approval-note-bg-focusnotebackgroundfocus-within--xh-bg-surfaceapproval 的 note 部件 background 覆盖槽。
--xh-approval-note-bg-invalidnotebackgroundinvalid--xh-bg-field-invalidapproval 的 note 部件 background 覆盖槽。
--xh-approval-note-bordernoteborderdefault--xh-border-controlapproval 的 note 部件 border 覆盖槽。
--xh-approval-note-border-disablednoteborder-colordisabled--xh-border-defaultapproval 的 note 部件 border-color 覆盖槽。
--xh-approval-note-border-focusnoteborder-color
box-shadow
focus-within--xh-border-control-focusapproval 的 note 部件 border-color、box-shadow 覆盖槽。
--xh-approval-note-border-hovernoteborder-colorhover
invalid
not(:disabled, :focus, [data-invalid])
--xh-border-strongapproval 的 note 部件 border-color 覆盖槽。
--xh-approval-note-border-invalidnoteborder-colorinvalid--xh-border-invalidapproval 的 note 部件 border-color 覆盖槽。
--xh-approval-note-fgnotecolordefault--xh-fg-defaultapproval 的 note 部件 color 覆盖槽。
--xh-approval-note-font-sizenotefont-sizedefault--xh-_approval-note-font-sizeapproval 的 note 部件 font-size 覆盖槽。
--xh-approval-note-pxnotepadding-inlinedefault--xh-space-2approval 的 note 部件 padding-inline 覆盖槽。
--xh-approval-note-pynotepadding-blockdefault--xh-space-1_5approval 的 note 部件 padding-block 覆盖槽。
--xh-approval-note-radiusnoteborder-radiusdefault--xh-shape-controlapproval 的 note 部件 border-radius 覆盖槽。
--xh-approval-ppending-indicator
root
inset-block-start
inset-inline-end
padding
default--xh-_approval-papproval 的 pending-indicator、root 部件 inset-block-start、inset-inline-end、padding 覆盖槽。
--xh-approval-pending-indicator-colorpending-indicatorbackgrounddefault--xh-_tone-softapproval 的 pending-indicator 部件 background 覆盖槽。
--xh-approval-pending-indicator-radiuspending-indicatorborder-radiusdefault--xh-shape-circleapproval 的 pending-indicator 部件 border-radius 覆盖槽。
--xh-approval-pending-indicator-sizepending-indicatorblock-size
inline-size
default--xh-space-2approval 的 pending-indicator 部件 block-size、inline-size 覆盖槽。
--xh-approval-radiusrootborder-radiusdefault--xh-shape-surfaceapproval 的 root 部件 border-radius 覆盖槽。
--xh-approval-result-bgresultbackgrounddefault--xh-_tone-subtleapproval 的 result 部件 background 覆盖槽。
--xh-approval-result-bg-deniedresultbackgroundis([data-state='denied'], [data-state='expired'])
state=denied
state=expired
--xh-_tone-subtleapproval 的 result 部件 background 覆盖槽。
--xh-approval-result-fgresultcolordefault--xh-_tone-fgapproval 的 result 部件 color 覆盖槽。
--xh-approval-result-fg-deniedresultcoloris([data-state='denied'], [data-state='expired'])
state=denied
state=expired
--xh-_tone-fgapproval 的 result 部件 color 覆盖槽。
--xh-approval-result-font-sizeresultfont-sizedefault--xh-text-caption-sizeapproval 的 result 部件 font-size 覆盖槽。
--xh-approval-result-font-weightresultfont-weightdefault--xh-font-weight-mediumapproval 的 result 部件 font-weight 覆盖槽。
--xh-approval-result-gapresultgapdefault--xh-space-1approval 的 result 部件 gap 覆盖槽。
--xh-approval-result-hresultmin-block-sizedefault--xh-chip-h-smapproval 的 result 部件 min-block-size 覆盖槽。
--xh-approval-result-pxresultpadding-inlinedefault--xh-space-1_5approval 的 result 部件 padding-inline 覆盖槽。
--xh-approval-result-pyresultpadding-blockdefault0approval 的 result 部件 padding-block 覆盖槽。
--xh-approval-result-radiusresultborder-radiusdefault--xh-shape-controlapproval 的 result 部件 border-radius 覆盖槽。
--xh-approval-shadowrootbox-shadowdefaultnoneapproval 的 root 部件 box-shadow 覆盖槽。
--xh-approval-timer-fgtimercolordefault--xh-fg-mutedapproval 的 timer 部件 color 覆盖槽。
--xh-approval-timer-font-sizetimerfont-sizedefault--xh-text-caption-sizeapproval 的 timer 部件 font-size 覆盖槽。
--xh-approval-title-fgtitlecolordefault--xh-fg-defaultapproval 的 title 部件 color 覆盖槽。
--xh-approval-title-font-sizetitlefont-sizedefault--xh-text-label-sizeapproval 的 title 部件 font-size 覆盖槽。
--xh-approval-title-font-weighttitlefont-weightdefault--xh-font-weight-mediumapproval 的 title 部件 font-weight 覆盖槽。

动效 ​

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

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

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

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

RTL ​

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

Released under The MIT License