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

查看生态总览
跳转到内容

SignaturePad 签名板 ​

用指针书写的画布:按下落笔、移动成迹、抬起收笔,输出可缩放、可直接提交的 SVG;签名数据可存下后原样回显,逐步撤销与重做。

用法 ​

一块画布加一条笔迹路径即可:按下落笔、移动成迹、抬起收笔

组件结构 ​

加粗的是必需部件。

data-scope="signature-pad":root · label · control · guide · path · undo-trigger · redo-trigger · clear-trigger · status · hidden-input

示例 ​

标题、基准线与清空 ​

基准线是纯画面(带 aria-hidden),清空按钮是原生 button,读屏朗读的是 translations 中的文案

请在下方签名

参与表单 ​

提供 name 后带上表单影子,提交的是一份独立 SVG;表单重置会把画布清空

验收签名(必填)尚未签名

笔迹外形 ​

drawing 调整笔宽与压感:thinning 越大,划得越快笔画越细,simulatePressure 决定压感取设备值还是按速度计算

只读与禁用 ​

只读时已绘制的笔迹可见但不可修改,禁用时连清空按钮都不可按下;两者都使用原生 disabled,不只是视觉置灰

只读
禁用

取出签名 ​

签名定稿时 draw-end 带上一份可直接入库的 SVG;提交前用 empty 拦截一次,空签名不应离开客户端

SVG 0 字节

撤销与重做 ​

一笔或一次清空是一步;没有可撤销、可重做的一步时按钮置灰,焦点仍留在原处

回显已存的签名 ​

存下 value-change 给出的数据,编辑页把它交回 defaultValue 即原样回显,之后照常续写与撤销

共 2 笔

设计指引 ​

何时使用 ​

  • 承诺书、回执、验收单上需要手写签名。
  • 交付确认、上门服务签收等需要留下确认痕迹的场景。

何时不用 ​

  • 需要已有的签名图片时,属于上传,使用文件上传。
  • 需要打字签名或姓名核对时,属于一行文本,使用文本字段。
  • 需要在图片上圈画批注时,本组件只绘制自己的画布,不承载底图。

特性 ​

  • 笔迹是 SVG 填充路径,放大不模糊;每一笔是同一条路径上的一条子路径。
  • 第一笔落下时测量一次画布并固定这套坐标,画布的 viewBox 与导出的 SVG 都使用它:容器变宽变窄时,已有笔迹跟随缩放而不是停留在原像素上错位。清空后重新测量。
  • drawing 一组选项调整笔画外形:size 决定粗细,thinning 让粗细随压感变化,simulatePressure 决定压感取设备值还是按落笔速度计算。
  • 签名数据 value 是逐笔的点加上笔迹坐标系({ strokes, surface }),无损:原样存下,编辑页交回 defaultValue 即回显,之后照常续写、撤销与重做;提供 value 即受控,定稿只经 value-change 送出。导出的 SVG 是它的一种画法,轮廓已偏移成填充面,读不回逐笔的点,所以回显要存数据而不是 SVG。
  • 撤销与重做以一步为单位:一笔、一次清空都是一步,误清之后撤销能找回整份签名。再落一笔或清空后重做栈作废;宿主从外面换了一份签名(受控写回另一条记录、换了 defaultValue 后重置)时撤销与重做栈一并作废。落笔途中不认撤销与重做。
  • 带 name 即参与表单提交,提交的是一份独立的 SVG 文档;表单重置回到 defaultValue(未提供时清空画布)并清掉撤销历史。
  • 笔迹变化时发出 draw,签名定稿时发出 draw-end 与 value-change:抬笔、清空、撤销、重做、表单重置都发出,落笔途中逐点只发 draw。按 draw-end 缓存待提交的 SVG 不会取到过期版本。
  • 指针划出画布甚至划出窗口都持续跟随,抬起即收笔;落笔的指针被捕获,手掌与第二根手指的移动不会续进这一笔。
  • 画布是一块字段外壳:静息不填底 + --xh-border-control 描边 + 4px 控件圆角、无影;落笔时描边加深,只读只换淡底,禁用退到 --xh-border-default + --xh-bg-subtle。画布按宽高比撑高,吃不下字段家族配方钉死的控件行高,因此外壳按同一套字段规则自绘。
  • 标签走字段标签档(14 / 500 / --xh-fg-default),贴画布 --xh-space-1;状态句是说明角色(13 / --xh-fg-muted)。
  • 清空按钮走 Action Control text 档 sm:缺省 outline 描边,白底承载阶梯悬停 100 → 按下 200,按下缩放并换底;空画布时只把静息前景压淡,按钮照常可按。
  • 撤销与重做按钮与清空按钮同一身份;没有可撤销、可重做的一步时投影 aria-disabled 与家族置灰面,焦点仍留在钮上。
  • 不写结构时按标准结构铺出整套部件(Vue 不写默认插槽、React 不给 children、Web Components 不写部件或只写 root),三端出自同一个结构函数:label 给标题文字,接着是画布(基准线与笔迹)、清空按钮与状态,给了 name 再带表单影子;清空按钮的字与状态句取 translations。撤销与重做按钮不在其中,要用时手写结构。Web Components 里标题可以写在宿主的直接子节点 slot="label" 上接管。

组合 ​

  • 与表单字段搭配:标题、说明与错误提示交给字段,签名板只负责画布。直接放进字段时,字段的标题并进画布的名字,说明与错误文案进描述链;点字段标题,焦点交给签名板里第一颗可聚焦的按钮(画布本身不可聚焦,一笔都没有时按钮都不可用,焦点不动)。
  • 放入表单,提供 name 后随表单提交与重置。
  • 与对话框搭配做签名确认:确认按钮的可用状态读取 empty。

节点形状是硬约束 ​

画布这一族部件必须落在特定标签上,写错不报错,但无法绘制:

  • control 必须是 <svg>;
  • guide 必须是 control 内的 <line>;
  • path 必须是 control 内的 <path>;
  • undo-trigger、redo-trigger、clear-trigger 必须是原生 <button>,hidden-input 必须是原生 <input>。

viewBox 由组件写入,作者不要在 control 上再写。

两个适配器的分工 ​

  • Vue:XhSignaturePadRoot 的默认插槽给出 value / empty / paths / drawing / canUndo / canRedo / statusText 与 toSvg() / clear() / undo() / redo(),签名数据走 v-model:value;也可以用 useSignaturePad() 自行获取。XhSignaturePadGuide 与 XhSignaturePadPath 必须写在 XhSignaturePadControl 内:SVG 命名空间由该子树带下,移出后会成为 HTML 元素,无法绘制。
  • Web Components:结构由作者编写(Light DOM,不投影插槽)。<xh-signature-pad> 上有 clear()、undo()、redo()、toSvg() 与只读的 empty / canUndo / canRedo;value / defaultValue 是对象,只走 property。提交前取签名用 toSvg(),不需要缓存上一次 draw-end。
  • 两侧的 status 部件内都不需要自行写文字:节点为空时由适配器填入语言包里的文案;写了文字则以作者的为准。

最佳实践 ​

  • 给清空按钮一句可见文字或稳定的图标语义,不只依靠一个叉。
  • 清空之后安置焦点:按钮被禁用或收起时焦点会回到 <body>,键盘用户每清空一次就丢失一次位置。要么让按钮始终可按(本组件的默认做法),要么清空后显式把焦点交给下一个落点。
  • 提交前用 empty 拦截:空签名与潦草签名是两回事,前者应在客户端拦截。
  • 需要缓存待提交的 SVG 时按 draw-end 缓存:清空与表单重置同样会发出它,缓存不会停留在旧版本。不要嗅探清空按钮的点击。
  • 存储的是 SVG 文本,不是位图。需要位图时在服务端渲染,不在前端截屏。
  • 需要在编辑页回显、续写的签名,同时存下 value-change 给出的数据;只存 SVG 的签名只能展示,不能再改。

反模式 ​

  • 把画布做得很窄:手写需要面积,过窄的画布只会产生无法辨认的字迹。
  • 让签名成为唯一的确认方式却不提供替代路径,这是可达性问题。
  • 把签名图当作身份凭证。它证明的是有人在画布上书写过,不是书写者的身份。

API 参考 ​

产物 ​

层值
自定义元素<xh-signature-pad>
Vue 组件XhSignaturePadClearTrigger XhSignaturePadControl XhSignaturePadGuide XhSignaturePadHiddenInput XhSignaturePadLabel XhSignaturePadPath XhSignaturePadRedoTrigger XhSignaturePadRoot XhSignaturePadStatus XhSignaturePadUndoTrigger
组合式函数useSignaturePad
状态机signaturePadMachine
皮肤@xihan-ui/styles/signature-pad.css

Props ​

属性类型必填说明
labelledboolean作者渲染了 label 部件时置真,由适配器统计而不是判断标题文字是否有值。 为假时可聚焦部件不把 label 的 id 写进 aria-labelledby:指向未渲染的 id 是无效引用,作者写在控件上的 aria-label 也会被它压住。
ariaLabelstring不显示出来的名字,写成 aria-label 落在与字段标签同一个部件上。 放进字段(字段接线)或渲染了 label 部件时名字以它们为准,aria-labelledby 盖过它。
disabledboolean整块不可交互:不响应落笔,清空、撤销与重做按钮也不可按下。
readOnlyboolean只读:已绘制的签名照常显示,但不可修改。
requiredboolean
invalidboolean校验未通过的标记,只改变外观与表单影子上的 aria-invalid。
namestring表单字段名;提供后表单影子才带 name 并参与提交。
valueSignaturePadValue签名数据。提供即受控:抬笔、清空、撤销与重做都只发 onValueChange,由宿主写回。
defaultValueSignaturePadValue非受控的初值,也是表单重置回到的那一份;编辑页回显已存的签名用它。
drawingSignaturePadDrawingOptions笔迹外形。默认为 4px 恒定粗细。
translationsPartial<SignaturePadTranslations>
onDraw(details: SignaturePadDrawDetails) => void每收进一个点通知一次,清空、撤销、重做与表单重置时也通知一次。
onDrawEnd(details: SignaturePadDrawEndDetails) => void签名定稿时通知一次并附带可直接提交的 SVG:抬笔、清空、撤销、重做与表单重置都发出。
onValueChange(details: SignaturePadValueChangeDetails) => void签名数据变了:与 onDrawEnd 同一批时机,落笔途中不发。受控时是唯一出口。
onClear() => void用户按清空钮(clear-trigger)清掉了值;先发值变化,再发它。程序化的 clear() 不发。

事件 ​

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

事件载荷说明
drawSignaturePadDrawDetails笔迹变化时通知一次(含清空、撤销、重做与表单重置);detail 为 { paths: string[], path: string }
draw-endSignaturePadDrawEndDetails签名定稿时通知一次(抬笔、清空、撤销、重做、表单重置);detail 为 { paths: string[], svg: string },svg 可直接存储
value-changeSignaturePadValueChangeDetails签名数据定稿,时机同 draw-end;detail 为 { value: { strokes, surface } },可原样存下再赋回 defaultValue 回显
clear``用户按清空钮(clear-trigger)清掉了值;先发值变化,再发它。程序化的 clear() 不发。

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhSignaturePadRootdefaultSignaturePadRootSlotProps
XhSignaturePadRootlabel—

React 适配器 props ​

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

React 组件属性类型必填说明
XhSignaturePadRootlabelReactNode标题。不给 children 时铺 label 部件。
XhSignaturePadRootchildrenSlotChildren<SignaturePadRootSlotProps>

状态 ​

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

状态:drawing · idle

事件:DRAW.START · DRAW.MOVE · DRAW.END · STROKES.CLEAR · HISTORY.UNDO · HISTORY.REDO · FORM.RESET · PRESS.START · PRESS.END

判据:canDraw · canPress

connect API ​

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

成员类型说明
valueSignaturePadValue已定稿的签名数据,可原样存下、再作为 value / defaultValue 交回来回显。
pathsreadonly string[]逐笔的填充轮廓 d 串,按落笔先后排列(含正在写的那一笔)。
emptyboolean没有任何笔迹。
drawingboolean笔正落在画布上。
disabledboolean
readOnlyboolean
canUndoboolean有可撤销的一步:上一笔、上一次清空或上一次重做。
canRedoboolean有被撤销、还能重做的一步。
statusTextstring是否已签名的文案,写入 status 部件;适配器在作者未自行编写文字时把它填入节点。
translationsSignaturePadTranslations合上作者覆盖后的文案。
toSvg() => string当前签名的独立 SVG 文档,与表单影子提交的是同一份;空签名为空串。
clear() => void
undo() => void撤销最近一步(一笔、一次清空或一次重做);没有可撤销的就什么都不做。
redo() => void重做最近撤销的一步;没有可重做的就什么都不做。
getRootProps() => T['element']
getLabelProps() => T['element']
getControlProps() => T['element']
getGuideProps() => T['element']
getPathProps() => T['element']
getClearTriggerProps() => T['button']
getUndoTriggerProps() => T['button']撤销按钮:没有可撤销的一步时 aria-disabled,焦点留在原处。
getRedoTriggerProps() => T['button']重做按钮:没有可重做的一步时 aria-disabled,焦点留在原处。
getStatusProps() => T['element']状态出口:一块 role=status 的活区域,签名与清空都会播报一次。
getHiddenInputProps() => T['input']表单出口:一份视觉隐藏的原生输入,随表单提交当前签名。

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Enter / Spacefocus on clear-trigger, 未禁用且非只读清空整块画布;清空也是一步,可撤销找回;按钮是原生 button,这两个键由平台翻成 click
Enter / Spacefocus on undo-trigger, 未禁用且非只读,且有可撤销的一步撤销最近一步(一笔或一次清空);没有可撤销的一步时按钮 aria-disabled,按下是空操作,焦点留在原处
Enter / Spacefocus on redo-trigger, 未禁用且非只读,且有被撤销的一步重做最近撤销的一步;再落一笔或清空后重做栈作废,按钮 aria-disabled
Enter / Spaceheld in clear-trigger / undo-trigger / redo-trigger, 未禁用、非只读且按钮可用按住期间投影 data-pressed,与指针 :active 同一副按压面;抬起或失焦撤下

ARIA ​

以下属性由 connect 生成。

部件属性值
controlaria-labelprops.ariaLabel
controlaria-labelledbylabel 部件的 id | undefined
controlrole'img'
guidearia-hidden'true'
undo-triggeraria-disabled'true' | undefined
undo-triggeraria-labeltranslations.undoTrigger
redo-triggeraria-disabled'true' | undefined
redo-triggeraria-labeltranslations.redoTrigger
clear-triggeraria-labeltranslations.clearTrigger
statusaria-atomic'true'
statusaria-live'polite'
statusrole'status'
hidden-inputaria-hidden'true'
hidden-inputaria-invalid'true' | 'false'
  • 签名天然依赖指针,键盘和读屏无法完成。凡是要求签名的流程,必须同时提供一条不依赖指针的替代路径:打字签名、上传签名图或线下核验。只放一块画布等于把这些用户挡在流程之外。
  • 画布报告为 role="img",不是控件:它不接受键盘、不进入 Tab 序列,伪装成控件只会让读屏用户进入无法操作的位置。
  • 画布的名称来自 label 部件;未渲染标题时退回 translations.label。
  • 是否已签名由 status 部件播报。画布是 role="img",名称固定,签名、清空、表单重置后读屏读出的都是同一句,用户无法确认笔迹是否保留。status 是 role="status" 的活动区域,值每变一次播报一次,文案使用 translations.statusEmpty / translations.statusSigned。要求签名的表单请渲染它。
  • 基准线是纯画面,带 aria-hidden,读屏不读。没有 translations.guide 文案:给装饰线命名只会增加无信息量的播报。
  • 撤销、重做与清空按钮都是原生 <button>,Enter / Space 由平台激活;按钮内只有图标时读屏读 translations.undoTrigger / translations.redoTrigger / translations.clearTrigger。
  • 撤销、重做没东西可做时用 aria-disabled 而不是原生 disabled:刚把最后一笔撤掉的那颗钮若变成原生禁用,焦点会掉回 <body>,键盘用户每撤到头一次就丢失一次位置。整块禁用或只读时三颗按钮才走原生 disabled。

样式参考 ​

皮肤 ​

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

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

数据属性 ​

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

部件属性值
rootdata-disabled''(条件成立时才出现)
rootdata-drawing''(条件成立时才出现)
rootdata-empty''(条件成立时才出现)
rootdata-invalid''(条件成立时才出现)
rootdata-readonly''(条件成立时才出现)
labeldata-disabled''(条件成立时才出现)
controldata-disabled''(条件成立时才出现)
controldata-drawing''(条件成立时才出现)
controldata-empty''(条件成立时才出现)
controldata-invalid''(条件成立时才出现)
controldata-readonly''(条件成立时才出现)
guidedata-disabled''(条件成立时才出现)
pathdata-empty''(条件成立时才出现)
undo-triggerdata-disabled''(条件成立时才出现)
undo-triggerdata-pressed''(条件成立时才出现)
undo-triggerdata-xh-action-control''
undo-triggerdata-xh-action-display'always'
undo-triggerdata-xh-action-profile'text'
undo-triggerdata-xh-action-size'sm'
undo-triggerdata-xh-action-variant'outline'
redo-triggerdata-disabled''(条件成立时才出现)
redo-triggerdata-pressed''(条件成立时才出现)
redo-triggerdata-xh-action-control''
redo-triggerdata-xh-action-display'always'
redo-triggerdata-xh-action-profile'text'
redo-triggerdata-xh-action-size'sm'
redo-triggerdata-xh-action-variant'outline'
clear-triggerdata-disabled''(条件成立时才出现)
clear-triggerdata-empty''(条件成立时才出现)
clear-triggerdata-pressed''(条件成立时才出现)
clear-triggerdata-xh-action-control''
clear-triggerdata-xh-action-display'always'
clear-triggerdata-xh-action-profile'text'
clear-triggerdata-xh-action-size'sm'
clear-triggerdata-xh-action-variant'outline'
statusdata-empty''(条件成立时才出现)
hidden-inputdata-disabled''(条件成立时才出现)

CSS 变量 ​

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

变量部件CSS 属性状态默认来源说明
--xh-signature-pad-aspect-ratiocontrolaspect-ratiodefault5 / 2signature-pad 的 control 部件 aspect-ratio 覆盖槽。
--xh-signature-pad-bgcontrolbackgrounddefault--xh-bg-fieldsignature-pad 的 control 部件 background 覆盖槽。
--xh-signature-pad-bg-disabledcontrolbackgrounddisabled--xh-bg-subtlesignature-pad 的 control 部件 background 覆盖槽。
--xh-signature-pad-bg-drawingcontrolbackgrounddrawing--xh-bg-surfacesignature-pad 的 control 部件 background 覆盖槽。
--xh-signature-pad-bg-invalidcontrolbackgroundinvalid--xh-bg-field-invalidsignature-pad 的 control 部件 background 覆盖槽。
--xh-signature-pad-bg-readonlycontrolbackgrounddisabled
not([data-disabled])
readonly
--xh-bg-subtlesignature-pad 的 control 部件 background 覆盖槽。
--xh-signature-pad-bordercontrolborderdefault--xh-border-controlsignature-pad 的 control 部件 border 覆盖槽。
--xh-signature-pad-border-disabledcontrolborder-colordisabled--xh-border-defaultsignature-pad 的 control 部件 border-color 覆盖槽。
--xh-signature-pad-border-drawingcontrolborder-colordrawing--xh-border-control-focussignature-pad 的 control 部件 border-color 覆盖槽。
--xh-signature-pad-border-hovercontrolborder-colordisabled
drawing
hover
invalid
not([data-disabled])
not([data-drawing])
not([data-invalid])
not([data-readonly])
readonly
--xh-border-strongsignature-pad 的 control 部件 border-color 覆盖槽。
--xh-signature-pad-clear-bgclear-trigger--xh-ink-surface
background-color
default
focus-visible
xh-ink-surface
--xh-_action-variant-bg-focus-visible
--xh-_action-variant-bg-rest
signature-pad 的 clear-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-signature-pad-clear-bg-activeclear-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressedsignature-pad 的 clear-trigger 部件 background-color 覆盖槽。
--xh-signature-pad-clear-bg-disabledclear-trigger--xh-ink-surface
background-color
disabled
xh-ink-surface
--xh-_action-variant-bg-disabledsignature-pad 的 clear-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-signature-pad-clear-bg-hoverclear-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hoversignature-pad 的 clear-trigger 部件 background-color 覆盖槽。
--xh-signature-pad-clear-borderclear-triggerborder
border-color
default
focus-visible
--xh-_action-variant-border-focus-visible
--xh-_action-variant-border-rest
signature-pad 的 clear-trigger 部件 border、border-color 覆盖槽。
--xh-signature-pad-clear-border-hoverclear-triggerborder-colordisabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-border-hover
--xh-_action-variant-border-pressed
signature-pad 的 clear-trigger 部件 border-color 覆盖槽。
--xh-signature-pad-clear-fgclear-triggercolordefault
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-fg-focus-visible
--xh-_action-variant-fg-hover
--xh-_action-variant-fg-pressed
--xh-_action-variant-fg-rest
signature-pad 的 clear-trigger 部件 color 覆盖槽。
--xh-signature-pad-clear-fg-emptyclear-triggercolorempty--xh-fg-mutedsignature-pad 的 clear-trigger 部件 color 覆盖槽。
--xh-signature-pad-clear-font-sizeclear-triggerfont-sizedefault--xh-_action-profile-font-sizesignature-pad 的 clear-trigger 部件 font-size 覆盖槽。
--xh-signature-pad-clear-gapclear-triggergapdefault--xh-_action-profile-gapsignature-pad 的 clear-trigger 部件 gap 覆盖槽。
--xh-signature-pad-clear-hclear-triggerblock-sizedefault--xh-_action-profile-visual-sizesignature-pad 的 clear-trigger 部件 block-size 覆盖槽。
--xh-signature-pad-clear-icon-sizeclear-trigger--xh-icon-sizedefault--xh-_action-profile-glyph-sizesignature-pad 的 clear-trigger 部件 --xh-icon-size 覆盖槽。
--xh-signature-pad-clear-pxclear-triggerpadding-inlinedefault--xh-_action-profile-padding-inlinesignature-pad 的 clear-trigger 部件 padding-inline 覆盖槽。
--xh-signature-pad-clear-radiusclear-triggerborder-radiusdefault--xh-shape-controlsignature-pad 的 clear-trigger 部件 border-radius 覆盖槽。
--xh-signature-pad-clear-shadow-hoverclear-triggerbox-shadowdisabled
hover
loading
not([data-disabled])
not([data-loading])
nonesignature-pad 的 clear-trigger 部件 box-shadow 覆盖槽。
--xh-signature-pad-control-border-invalidcontrolborder-colorinvalid--xh-border-invalidsignature-pad 的 control 部件 border-color 覆盖槽。
--xh-signature-pad-gaplabel
root
gap
margin-block-end
default--xh-space-2signature-pad 的 label、root 部件 gap、margin-block-end 覆盖槽。
--xh-signature-pad-guide-strokeguidestrokedefault--xh-border-controlsignature-pad 的 guide 部件 stroke 覆盖槽。
--xh-signature-pad-inkpathfilldefault--xh-fg-defaultsignature-pad 的 path 部件 fill 覆盖槽。
--xh-signature-pad-label-fglabelcolordefault--xh-fg-mutedsignature-pad 的 label 部件 color 覆盖槽。
--xh-signature-pad-label-fg-disabledlabelcolordisabled--xh-fg-mutedsignature-pad 的 label 部件 color 覆盖槽。
--xh-signature-pad-label-font-sizelabelfont-sizedefault--xh-text-label-sizesignature-pad 的 label 部件 font-size 覆盖槽。
--xh-signature-pad-label-font-weightlabelfont-weightdefault--xh-text-label-weightsignature-pad 的 label 部件 font-weight 覆盖槽。
--xh-signature-pad-label-gaplabelmargin-block-enddefault--xh-space-2signature-pad 的 label 部件 margin-block-end 覆盖槽。
--xh-signature-pad-radiuscontrolborder-radiusdefault--xh-shape-controlsignature-pad 的 control 部件 border-radius 覆盖槽。
--xh-signature-pad-status-fgstatuscolordefault--xh-fg-mutedsignature-pad 的 status 部件 color 覆盖槽。
--xh-signature-pad-status-font-sizestatusfont-sizedefault--xh-text-secondary-sizesignature-pad 的 status 部件 font-size 覆盖槽。

动效 ​

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

background-color · border-color 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。

系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。

响应式 ​

  • 画布宽度铺满外层容器,高度由宽高比(--xh-signature-pad-aspect-ratio,默认 5 / 2)决定,窄屏上自动变矮。
  • 签名过程中转屏、拖动面板改变宽度时,已有笔迹按 viewBox 整体缩放,后续新笔与它落在同一套坐标。
  • 触摸设备上画布关闭浏览器的滚动与缩放手势,避免手指划动时页面滚动。

RTL ​

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

  • 画布与基准线不区分左右:笔迹按落笔坐标记录,方向由书写者决定。
  • 标题与清空按钮的排布跟随文档方向,皮肤全部使用逻辑属性。

Released under The MIT License