简体中文
Approval 审批 alpha
危险操作执行前的人工闸门:批准或拒绝,超时按拒绝处理,可附带勾选式的授权范围。
用法
勾选与判定是原子的:批准的载荷带着批准的项,不存在已批准但范围尚未同步的窗口
要动你的工作区
它想读一遍 src/ 并写回改动。
读取 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 秒。
设计指引
何时使用
- 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
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
requestId | string | 本轮请求的身份。变化即重新进入待决,并按新时长重新计时。 | |
status | ApprovalStatus | 提供即受控。 | |
defaultStatus | ApprovalStatus | ||
timeoutMs | number | 超时无人应答时按拒绝收口。默认不提供默认值:替宿主决定安全策略比不决定更危险。 非有限值或非正数同样不启动计时器,既不按 0ms 立即到期,也不视为无限期放行。 | |
scopes | readonly ApprovalScope[] | ||
grantedScopes | readonly string[] | ||
defaultGrantedScopes | readonly string[] | ||
note | string | 附在判定上的一段自由文本。提供即受控。 它只随判定载荷发出,不参与必选项是否全部勾选的判断。 | |
defaultNote | string | ||
requireReason | boolean | 用户拒绝时必须写明理由(备注非空)。备注空着时按拒绝钮或 Escape 不发判定, 而是把焦点移到备注框并标为无效。只管人手按的这两条路:超时、卸载兜底与宿主的 deny() 不是用户的判定,照常落地;没渲染备注框时也照常拒绝——写不了理由就不能拦住拒绝。 | |
loading | boolean | 判定在途:只阻止重复批准,不阻止拒绝。 | |
denyOnEscape | boolean | Escape 判为拒绝,默认开启。 | |
denyOnUnmount | boolean | 卸载时若仍待决则按拒绝派发一次,默认关闭。 机制成立不等于默认值成立:列表更换 key、路由切换、热更新的任何一次重挂, 都会替用户发出未做过的判定。 | |
live | 'polite' | 'assertive' | 播报档位,默认 polite。 | |
variant | ControlVariant | 形态:outline 描边、subtle 底色分区、ghost 无壳内联。默认 outline。 | |
tone | Tone | ||
size | Size | ||
parts | TitleDescriptionParts | 作者实际渲染了哪些部件,由适配器统计;省略即按都在场处理(服务端直出与挂载前)。 title 不在场时不写 aria-labelledby;description 不在场、或渲染了但读不出一句话(判断同 hasNamingContent)时不写 aria-describedby。 | |
translations | Partial<ApprovalTranslations> | ||
onDecision | (details: ApprovalDecisionDetails) => void | ||
onGrantedScopesChange | (details: ApprovalScopesChangeDetails) => void | ||
onNoteChange | (details: ApprovalNoteChangeDetails) => void |
ApprovalScope
scopes 的元素。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
value | string | 是 | |
label | string | ||
required | boolean | 必选项:未全部勾选时不能批准。 | |
disabled | boolean |
事件
自定义元素将载荷放在 detail;Vue 使用同名 emit。
| 事件 | 载荷 | 说明 |
|---|---|---|
decision | ApprovalDecisionDetails | 判定落定;detail 为 { requestId, decision, source, scopes } |
granted-scopes-change | ApprovalScopesChangeDetails | 勾选的授权项变化;detail 为 { value: string[] } |
note-change | ApprovalNoteChangeDetails | 备注变化;detail 为 { value: string } |
插槽
仅列出带载荷的插槽。
| Vue 组件 | 插槽 | 载荷 | 说明 |
|---|---|---|---|
XhApprovalItem | default | ApprovalScopeSlotProps | |
XhApprovalRoot | default | ApprovalRootSlotProps |
React 适配器 props
只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。
| React 组件 | 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
XhApprovalItem | scopeValue | string | 是 | 该项授权范围的取值。 |
XhApprovalItem | scopeLabel | string | ||
XhApprovalItem | scopeRequired | boolean | 必选项:未全部勾选时无法批准。 | |
XhApprovalItem | scopeDisabled | boolean | ||
XhApprovalItem | children | SlotChildren<ApprovalScopeSlotProps> | ||
XhApprovalItemIndicator | scopeValue | string | 是 | |
XhApprovalItemText | scopeValue | string | 是 | |
XhApprovalRoot | children | SlotChildren<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() 返回对应部件的宿主属性。
| 成员 | 类型 | 说明 |
|---|---|---|
status | ApprovalStatus | |
settled | boolean | 已判定:两个按钮都收起出口。 |
loading | boolean | |
grantedScopes | string[] | |
note | string | 备注中的文字;未填写时为空串。 |
canApprove | boolean | 必选项是否全部勾选。 |
reasonMissing | boolean | 要求写理由而备注还空着:此时用户按拒绝只会把焦点带到备注框。 |
announcement | string | 按 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 生成。
| 部件 | 属性 | 值 |
|---|---|---|
root | aria-describedby | description 部件的 id | undefined |
root | aria-labelledby | title 部件的 id | undefined |
root | role | 'group' |
pending-indicator | aria-hidden | 'true' |
live-region | aria-atomic | 'true' |
live-region | aria-live | props.live |
group | aria-label | translations.scopes |
group | role | 'group' |
item | aria-checked | 'true' | 'false' |
item | aria-disabled | 'true' | 'false' |
item | aria-required | 'true' | 'false' |
item | role | 'checkbox' |
item-indicator | aria-hidden | 'true' |
note | aria-invalid | 'true' | undefined |
note | aria-label | translations.reason | translations.note |
note | aria-required | 'true' | undefined |
timer | aria-hidden | 'true' |
result | aria-hidden | 'true' |
approve-trigger | aria-busy | 'true' | undefined |
approve-trigger | aria-disabled | 'true' | 'false' |
approve-trigger | aria-label | translations.approve |
deny-trigger | aria-busy | 'true' | undefined |
deny-trigger | aria-disabled | 'true' | 'false' |
deny-trigger | aria-label | translations.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 生成;条件不成立时不输出无值属性。
| 部件 | 属性 | 值 |
|---|---|---|
root | data-loading | ''(条件成立时才出现) |
root | data-size | props.size |
root | data-state | 'pending' | 'approved' | 'denied' | 'expired' |
root | data-tone | props.tone |
root | data-variant | props.variant |
pending-indicator | data-state | 'pending' | 'approved' | 'denied' | 'expired' |
item | data-disabled | ''(条件成立时才出现) |
item | data-pressed | ''(条件成立时才出现) |
item | data-state | 'checked' | 'unchecked' |
item | data-value | item.value |
item | data-xh-action-control | '' |
item | data-xh-action-display | 'always' |
item | data-xh-action-profile | 'row' |
item | data-xh-action-size | props.size |
item | data-xh-action-variant | 'ghost' |
item-indicator | data-state | 'checked' | 'unchecked' |
item-text | data-value | item.value |
note | data-invalid | ''(条件成立时才出现) |
note | data-state | 'pending' | 'approved' | 'denied' | 'expired' |
timer | data-state | 'pending' | 'approved' | 'denied' | 'expired' |
result | data-state | 'pending' | 'approved' | 'denied' | 'expired' |
result | data-tone | 'success' | 'danger' | undefined |
footer | data-loading | ''(条件成立时才出现) |
footer | data-xh-loading-ring | '' |
approve-trigger | data-disabled | ''(条件成立时才出现) |
approve-trigger | data-loading | ''(条件成立时才出现) |
approve-trigger | data-pressed | ''(条件成立时才出现) |
approve-trigger | data-state | 'pending' | 'approved' | 'denied' | 'expired' |
approve-trigger | data-tone | props.tone |
approve-trigger | data-xh-action-control | '' |
approve-trigger | data-xh-action-display | 'always' |
approve-trigger | data-xh-action-profile | 'text' |
approve-trigger | data-xh-action-size | props.size |
approve-trigger | data-xh-action-variant | 'solid' |
approve-trigger | data-xh-ink-surface | '' |
deny-trigger | data-disabled | ''(条件成立时才出现) |
deny-trigger | data-loading | ''(条件成立时才出现) |
deny-trigger | data-pressed | ''(条件成立时才出现) |
deny-trigger | data-state | 'pending' | 'approved' | 'denied' | 'expired' |
deny-trigger | data-xh-action-control | '' |
deny-trigger | data-xh-action-display | 'always' |
deny-trigger | data-xh-action-profile | 'text' |
deny-trigger | data-xh-action-size | props.size |
deny-trigger | data-xh-action-variant | 'outline' |
CSS 变量
本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。
| 变量 | 部件 | CSS 属性 | 状态 | 默认来源 | 说明 |
|---|---|---|---|---|---|
--xh-approval-action-font-size | approve-triggerdeny-trigger | font-size | default | --xh-text-label-size | approval 的 approve-trigger、deny-trigger 部件 font-size 覆盖槽。 |
--xh-approval-action-font-weight | approve-triggerdeny-trigger | font-weight | default | --xh-text-label-weight | approval 的 approve-trigger、deny-trigger 部件 font-weight 覆盖槽。 |
--xh-approval-action-h | approve-triggerdeny-trigger | block-sizemin-block-size | defaultxh-action-profile=row | --xh-_approval-action-h | approval 的 approve-trigger、deny-trigger 部件 block-size、min-block-size 覆盖槽。 |
--xh-approval-action-px | approve-triggerdeny-trigger | padding-inline | default | --xh-_approval-action-px | approval 的 approve-trigger、deny-trigger 部件 padding-inline 覆盖槽。 |
--xh-approval-action-radius | approve-triggerdeny-trigger | border-radius | default | --xh-shape-control | approval 的 approve-trigger、deny-trigger 部件 border-radius 覆盖槽。 |
--xh-approval-approve-bg | approve-trigger | --xh-ink-surfacebackground-color | defaultloadingxh-ink-surface | --xh-_action-variant-bg-loading--xh-_action-variant-bg-rest | approval 的 approve-trigger 部件 --xh-ink-surface、background-color 覆盖槽。 |
--xh-approval-approve-bg-hover | approve-trigger | background-color | disabledhoverloadingnot([data-disabled])not([data-loading]) | --xh-_action-variant-bg-hover | approval 的 approve-trigger 部件 background-color 覆盖槽。 |
--xh-approval-approve-bg-off | approve-trigger | --xh-ink-surfacebackground-color | disabledxh-ink-surface | --xh-_action-variant-bg-disabled | approval 的 approve-trigger 部件 --xh-ink-surface、background-color 覆盖槽。 |
--xh-approval-approve-fg | approve-trigger | color | defaultdisabledhoveris(:active, [data-pressed])loadingnot([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-shadow | approve-trigger | box-shadow | defaultdisabledhoveris(:active, [data-pressed])loadingnot([data-disabled])not([data-loading])pressed | --xh-_highlight-tone | approval 的 approve-trigger 部件 box-shadow 覆盖槽。 |
--xh-approval-bg | root | background | defaultvariant=subtle | --xh-bg-subtle--xh-bg-surface | approval 的 root 部件 background 覆盖槽。 |
--xh-approval-border | root | borderborder-color | defaulttone | --xh-_tone--xh-border-default | approval 的 root 部件 border、border-color 覆盖槽。 |
--xh-approval-border-settled | root | border-color | not([data-state='pending'])state=pending | --xh-border-default | approval 的 root 部件 border-color 覆盖槽。 |
--xh-approval-deny-bg | deny-trigger | --xh-ink-surfacebackground-color | defaultxh-ink-surface | --xh-_action-variant-bg-rest | approval 的 deny-trigger 部件 --xh-ink-surface、background-color 覆盖槽。 |
--xh-approval-deny-bg-hover | deny-trigger | background-color | disabledhoverloadingnot([data-disabled])not([data-loading]) | --xh-_action-variant-bg-hover | approval 的 deny-trigger 部件 background-color 覆盖槽。 |
--xh-approval-deny-bg-off | deny-trigger | --xh-ink-surfacebackground-color | disabledxh-ink-surface | --xh-_action-variant-bg-disabled | approval 的 deny-trigger 部件 --xh-ink-surface、background-color 覆盖槽。 |
--xh-approval-deny-border | deny-trigger | border | default | --xh-_action-variant-border-rest | approval 的 deny-trigger 部件 border 覆盖槽。 |
--xh-approval-deny-border-off | deny-trigger | border-color | disabled | --xh-_action-variant-border-disabled | approval 的 deny-trigger 部件 border-color 覆盖槽。 |
--xh-approval-deny-fg | deny-trigger | color | defaultdisabledhoveris(:active, [data-pressed])loadingnot([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-fg | description | color | default | --xh-fg-muted | approval 的 description 部件 color 覆盖槽。 |
--xh-approval-description-font-size | description | font-size | default | --xh-text-secondary-size | approval 的 description 部件 font-size 覆盖槽。 |
--xh-approval-footer-gap | footer | gap | default | --xh-space-2 | approval 的 footer 部件 gap 覆盖槽。 |
--xh-approval-gap | root | gap | default | --xh-_approval-gap | approval 的 root 部件 gap 覆盖槽。 |
--xh-approval-group-gap | group | gap | default | --xh-space-1 | approval 的 group 部件 gap 覆盖槽。 |
--xh-approval-icon-size | root | --xh-icon-size | default | --xh-_approval-icon-size | approval 的 root 部件 --xh-icon-size 覆盖槽。 |
--xh-approval-indicator-bg-checked | item-indicator | background | state=checked | --xh-bg-brand | approval 的 item-indicator 部件 background 覆盖槽。 |
--xh-approval-indicator-border | item-indicator | border | default | --xh-border-control | approval 的 item-indicator 部件 border 覆盖槽。 |
--xh-approval-indicator-border-checked | item-indicator | border-color | state=checked | --xh-bg-brand | approval 的 item-indicator 部件 border-color 覆盖槽。 |
--xh-approval-indicator-fg | item-indicator | color | default | --xh-fg-on-brand | approval 的 item-indicator 部件 color 覆盖槽。 |
--xh-approval-indicator-icon-size | item-indicator | --xh-icon-size | default | --xh-_approval-indicator-glyph | approval 的 item-indicator 部件 --xh-icon-size 覆盖槽。 |
--xh-approval-indicator-radius | item-indicator | border-radius | default | --xh-shape-inset | approval 的 item-indicator 部件 border-radius 覆盖槽。 |
--xh-approval-indicator-size | item-indicator | --xh-icon-sizeblock-sizeinline-size | default | --xh-control-indicator-size | approval 的 item-indicator 部件 --xh-icon-size、block-size、inline-size 覆盖槽。 |
--xh-approval-item-bg-hover | item | background-color | disabledhoverloadingnot([data-disabled])not([data-loading]) | --xh-_action-variant-bg-hover | approval 的 item 部件 background-color 覆盖槽。 |
--xh-approval-item-font-size | item | font-size | default | --xh-_approval-item-font-size | approval 的 item 部件 font-size 覆盖槽。 |
--xh-approval-item-gap | item | gap | default | --xh-space-1_5 | approval 的 item 部件 gap 覆盖槽。 |
--xh-approval-item-px | item | padding-inline | default | --xh-space-2 | approval 的 item 部件 padding-inline 覆盖槽。 |
--xh-approval-item-py | item | padding-block | xh-action-profile=row | --xh-space-1 | approval 的 item 部件 padding-block 覆盖槽。 |
--xh-approval-item-radius | item | border-radius | default | --xh-_action-profile-radius | approval 的 item 部件 border-radius 覆盖槽。 |
--xh-approval-item-text-fg | item-text | color | default | --xh-fg-muted | approval 的 item-text 部件 color 覆盖槽。 |
--xh-approval-item-text-fg-checked | itemitem-text | color | state=checked | --xh-fg-default | approval 的 item、item-text 部件 color 覆盖槽。 |
--xh-approval-loading-duration | footer | animation | xh-loading-ring | --xh-motion-loop-spin | approval 的 footer 部件 animation 覆盖槽。 |
--xh-approval-note-bg | note | background | default | --xh-bg-field | approval 的 note 部件 background 覆盖槽。 |
--xh-approval-note-bg-disabled | note | background | disabled | --xh-bg-subtle | approval 的 note 部件 background 覆盖槽。 |
--xh-approval-note-bg-focus | note | background | focus-within | --xh-bg-surface | approval 的 note 部件 background 覆盖槽。 |
--xh-approval-note-bg-invalid | note | background | invalid | --xh-bg-field-invalid | approval 的 note 部件 background 覆盖槽。 |
--xh-approval-note-border | note | border | default | --xh-border-control | approval 的 note 部件 border 覆盖槽。 |
--xh-approval-note-border-disabled | note | border-color | disabled | --xh-border-default | approval 的 note 部件 border-color 覆盖槽。 |
--xh-approval-note-border-focus | note | border-colorbox-shadow | focus-within | --xh-border-control-focus | approval 的 note 部件 border-color、box-shadow 覆盖槽。 |
--xh-approval-note-border-hover | note | border-color | hoverinvalidnot(:disabled, :focus, [data-invalid]) | --xh-border-strong | approval 的 note 部件 border-color 覆盖槽。 |
--xh-approval-note-border-invalid | note | border-color | invalid | --xh-border-invalid | approval 的 note 部件 border-color 覆盖槽。 |
--xh-approval-note-fg | note | color | default | --xh-fg-default | approval 的 note 部件 color 覆盖槽。 |
--xh-approval-note-font-size | note | font-size | default | --xh-_approval-note-font-size | approval 的 note 部件 font-size 覆盖槽。 |
--xh-approval-note-px | note | padding-inline | default | --xh-space-2 | approval 的 note 部件 padding-inline 覆盖槽。 |
--xh-approval-note-py | note | padding-block | default | --xh-space-1_5 | approval 的 note 部件 padding-block 覆盖槽。 |
--xh-approval-note-radius | note | border-radius | default | --xh-shape-control | approval 的 note 部件 border-radius 覆盖槽。 |
--xh-approval-p | pending-indicatorroot | inset-block-startinset-inline-endpadding | default | --xh-_approval-p | approval 的 pending-indicator、root 部件 inset-block-start、inset-inline-end、padding 覆盖槽。 |
--xh-approval-pending-indicator-color | pending-indicator | background | default | --xh-_tone-soft | approval 的 pending-indicator 部件 background 覆盖槽。 |
--xh-approval-pending-indicator-radius | pending-indicator | border-radius | default | --xh-shape-circle | approval 的 pending-indicator 部件 border-radius 覆盖槽。 |
--xh-approval-pending-indicator-size | pending-indicator | block-sizeinline-size | default | --xh-space-2 | approval 的 pending-indicator 部件 block-size、inline-size 覆盖槽。 |
--xh-approval-radius | root | border-radius | default | --xh-shape-surface | approval 的 root 部件 border-radius 覆盖槽。 |
--xh-approval-result-bg | result | background | default | --xh-_tone-subtle | approval 的 result 部件 background 覆盖槽。 |
--xh-approval-result-bg-denied | result | background | is([data-state='denied'], [data-state='expired'])state=deniedstate=expired | --xh-_tone-subtle | approval 的 result 部件 background 覆盖槽。 |
--xh-approval-result-fg | result | color | default | --xh-_tone-fg | approval 的 result 部件 color 覆盖槽。 |
--xh-approval-result-fg-denied | result | color | is([data-state='denied'], [data-state='expired'])state=deniedstate=expired | --xh-_tone-fg | approval 的 result 部件 color 覆盖槽。 |
--xh-approval-result-font-size | result | font-size | default | --xh-text-caption-size | approval 的 result 部件 font-size 覆盖槽。 |
--xh-approval-result-font-weight | result | font-weight | default | --xh-font-weight-medium | approval 的 result 部件 font-weight 覆盖槽。 |
--xh-approval-result-gap | result | gap | default | --xh-space-1 | approval 的 result 部件 gap 覆盖槽。 |
--xh-approval-result-h | result | min-block-size | default | --xh-chip-h-sm | approval 的 result 部件 min-block-size 覆盖槽。 |
--xh-approval-result-px | result | padding-inline | default | --xh-space-1_5 | approval 的 result 部件 padding-inline 覆盖槽。 |
--xh-approval-result-py | result | padding-block | default | 0 | approval 的 result 部件 padding-block 覆盖槽。 |
--xh-approval-result-radius | result | border-radius | default | --xh-shape-control | approval 的 result 部件 border-radius 覆盖槽。 |
--xh-approval-shadow | root | box-shadow | default | none | approval 的 root 部件 box-shadow 覆盖槽。 |
--xh-approval-timer-fg | timer | color | default | --xh-fg-muted | approval 的 timer 部件 color 覆盖槽。 |
--xh-approval-timer-font-size | timer | font-size | default | --xh-text-caption-size | approval 的 timer 部件 font-size 覆盖槽。 |
--xh-approval-title-fg | title | color | default | --xh-fg-default | approval 的 title 部件 color 覆盖槽。 |
--xh-approval-title-font-size | title | font-size | default | --xh-text-label-size | approval 的 title 部件 font-size 覆盖槽。 |
--xh-approval-title-font-weight | title | font-weight | default | --xh-font-weight-medium | approval 的 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" 下自动镜像。
