For AI agents: the complete documentation index is available at https://a3s-lab.github.io/UI/v0.4.0/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/UI/v0.4.0/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/UI/v0.4.0/components/form-system/signature.md.

签名

a3s.signature 是官方宿主能力扩展。浏览器只负责采集手写轨迹或键入姓名,保存、删除、查看、授权和审计均由宿主服务处理。

实时示例FormSignatureReference[]
发布确认签名必填

核对发布内容后完成签署

手写签名区域

在区域内使用鼠标、触控笔或触摸输入。 按退格键或删除键可撤销最后一笔。

受控值
{
  "approvalSignature": []
}

表单受控值只保留最多一个稳定引用。手写点位、键入姓名、图片、对象 URL、访问令牌和请求状态不会进入表单文档或表单值。

值结构

interface FormSignatureReference {
  id: string;
  method: 'drawn' | 'typed';
  signedAt: string;
}
属性类型约束用途
idstring1–512 字符宿主存储中的稳定签名标识
method'drawn' | 'typed'固定枚举记录采集方式
signedAtstringRFC 3339 date-time记录宿主确认的签署时间

字段值使用零个或一个引用的数组:

{
  "approvalSignature": [
    {
      "id": "sig_01K25TB9Q8",
      "method": "drawn",
      "signedAt": "2026-08-09T09:30:00.000Z"
    }
  ]
}

引用对象不接受额外属性。签名图像、原始轨迹、签署姓名、证书、设备信息和临时访问地址应由宿主根据 id 解析。

Schema

import { createFormSignatureSchema } from '@a3s-lab/ui/form/react';

const schema = {
  type: 'object',
  properties: {
    approvalSignature: createFormSignatureSchema({ required: true }),
  },
  required: ['approvalSignature'],
  additionalProperties: false,
};
参数类型默认值行为
requiredbooleanfalsetrue 时生成 minItems: 1

生成结果固定包含 maxItems: 1、uniqueItems: true 和闭合引用对象 Schema。父对象的 required 决定字段属性是否必须存在,数组的 minItems 决定是否必须完成签署。

UI 节点属性

const node = {
  id: 'approvalSignature',
  kind: 'field',
  label: '发布确认签名',
  description: '核对发布内容后完成签署',
  schemaPath: '/properties/approvalSignature',
  widget: 'a3s.signature',
  customProps: {
    captureMode: 'drawn-or-typed',
    penColor: 'ink',
  },
};
属性类型默认值运行时行为
customProps.captureMode'drawn' | 'typed' | 'drawn-or-typed''drawn-or-typed'限制可用采集方式
customProps.penColor'ink' | 'blue''ink'设置手写轨迹颜色,不改变受控值
Schema minItems0 | 10控制签名是否必填
Schema maxItems11单个字段最多保存一个引用

Designer 组件目录、设计态和属性面板均由 createSignatureNodeRegistry 提供。签名字段无需在应用内重复注册目录项。

宿主签名服务

import type {
  FormSignatureService,
  FormSignatureReference,
} from '@a3s-lab/ui/form/react';

const signatureService: FormSignatureService = {
  async save({ capture, previous, signal, node, plan, valuePath }) {
    const response = await signatureApi.save({
      capture,
      previousId: previous?.id,
      formDigest: plan.digest,
      nodeId: node.id,
      valuePath,
      signal,
    });

    return {
      id: response.id,
      method: capture.method,
      signedAt: response.signedAt,
    } satisfies FormSignatureReference;
  },

  async remove({ signature, signal, plan }) {
    await signatureApi.remove(signature.id, {
      formDigest: plan.digest,
      signal,
    });
  },

  async open({ signature, signal }) {
    const temporaryUrl = await signatureApi.authorizePreview(signature.id, signal);
    window.open(temporaryUrl, '_blank', 'noopener,noreferrer');
  },
};

save 请求

属性类型说明
captureFormSignatureCapture当前内存中的手写轨迹或键入姓名
previousFormSignatureReference | undefined重新签名时的旧引用,可用于原子替换
signalAbortSignal取消、卸载和任务替换信号
nodeCompiledNode当前签名字段及配置
planFormPlan当前不可变编译结果
valuePathstring | undefined当前具体值路径
rowIndicesreadonly number[]嵌套重复组中的具体行索引

采集联合类型:

type FormSignatureCapture =
  | {
      method: 'drawn';
      strokes: readonly {
        points: readonly {
          x: number;       // 0–1 归一化横坐标
          y: number;       // 0–1 归一化纵坐标
          pressure: number; // 0–1 压力值
        }[];
      }[];
    }
  | {
      method: 'typed';
      text: string; // 去除首尾空白,最多 120 个字符
    };

手写采集最多保留 128 笔和 4,096 个点。限制在浏览器采集阶段执行,宿主仍需校验请求大小、签署权限、表单 digest、字段身份和业务状态。

React

import { assertCompiled } from '@a3s-lab/ui/form/core';
import {
  createSignatureNodeRegistry,
  FormRenderer,
} from '@a3s-lab/ui/form/react';
import '@a3s-lab/ui/form/a3s-ui.css';

const nodeRegistry = createSignatureNodeRegistry({
  service: signatureService,
  getErrorMessage(error, operation) {
    return operation === 'save' ? '签名未保存,请检查连接后重试。' : undefined;
  },
});

const plan = assertCompiled(document, {
  capabilities: { widgets: Object.keys(nodeRegistry) },
});

<FormRenderer
  plan={plan}
  value={value}
  onChange={setValue}
  nodeRegistry={nodeRegistry}
/>;

Vue

<script setup lang="ts">
import { ref } from 'vue';
import { A3SFormRenderer } from '@a3s-lab/ui/form/vue';
import { createSignatureNodeRegistry } from '@a3s-lab/ui/form/react';
import '@a3s-lab/ui/form/a3s-ui.css';

const value = ref({ approvalSignature: [] });
const nodeRegistry = createSignatureNodeRegistry({ service: signatureService });
</script>

<template>
  <A3SFormRenderer
    :plan="plan"
    v-model="value"
    :node-registry="nodeRegistry"
  />
</template>

Web Component

import { defineA3SFormElements } from '@a3s-lab/ui/form/web-component';
import { createSignatureNodeRegistry } from '@a3s-lab/ui/form/react';

defineA3SFormElements();

const renderer = document.querySelector('a3s-form-renderer');
renderer.plan = plan;
renderer.value = { approvalSignature: [] };
renderer.nodeRegistry = createSignatureNodeRegistry({ service: signatureService });
renderer.addEventListener('value-change', (event) => {
  renderer.value = event.detail;
});

交互状态

状态行为
空状态显示允许的签名方式和保存入口
手写归一化采集鼠标、触控笔或触摸轨迹;支持撤销和清空
键入限制 120 个字符并显示本地预览
保存中锁定采集,提供取消操作,卸载时终止请求
保存失败保留当前采集内容并提供重试
已保存显示采集方式和本地化签署时间
重新签名旧引用保持有效,宿主成功返回后才原子替换
删除中宿主成功后才清空受控值
只读禁止采集、替换和删除;宿主提供的查看操作保持可用

宿主在保存或删除期间替换受控值时,组件不会覆盖新值,而是报告冲突并要求重新核对。

键盘与辅助技术

  • 默认同时提供手写和键入方式,键盘用户可直接完成键入签名;
  • 签名方式使用标准 tab 语义,输入框保留原生姓名自动填充;
  • 手写区域可获得焦点,Backspace 或 Delete 撤销最后一笔;
  • 保存、删除和错误状态通过 status 或 alert 语义播报;
  • 仅允许手写时,宿主必须提供符合签署政策的无障碍替代流程;
  • 只读签名仍可调用经过宿主授权的查看操作。

安全边界

  • 表单值不得保存原始轨迹、键入姓名、Base64 图片、Blob URL、Cookie、令牌或临时签名地址;
  • save 必须校验用户权限、表单 revision、plan digest、字段身份和允许的采集方式;
  • previous 用于宿主执行原子替换,避免先删除旧记录造成签署空窗;
  • remove 和 open 每次执行时都需要重新授权;
  • 宿主错误应映射为可展示文案,服务端堆栈、对象路径和凭据不得进入界面;
  • 法律效力、身份核验、证书、时间戳、保留期和审计证据由宿主策略决定。