Files
yeuimu 517dde9dee feat(skill): native-form 速查文档 + 路由行 (0.1.8)
- dynamic-plugins/native-form.md: 咨询题直答型(两档注入 API + 多步表单
  copy-paste 示例 + 边界),解决 eval-6 历史失败(agent 把咨询当开发、跑飞)
- SKILL.md 模块地图加 3b 行:问'能不能/怎么做原生表单'先读它,直接作答
- 实测:plugin 技能 N=3 全绿(P1 25/25, P2 25/25, P3 24/25),
  native-form-routing 三轮全过(此前两轮全败)
2026-09-30 07:16:33 +00:00

2.9 KiB
Raw Permalink Blame History

Native form embedding — quick answer

问题:能不能在插件里做自定义布局的表单(多步表单/侧栏表单),每一步用系统 原生字段编辑器,不自己重写输入组件?

能。宿主暴露了完整的原生表单注入能力,共两档。咨询类问题到这里就有答案了, 不需要先去搭工程验证。

需求 用哪档 核心 API(都在 window.__TEABLE_HOST__)
整表单嵌入面板/视图,能裁剪字段、插自定义内容 Tier-1 整表注入 host.NativeForm
自己控制每行渲染、逐步表单、校验与暂存 Tier-2 逐字段套件 host.NativeFormScope + host.NativeFormField + host.useNativeForm()

Tier-1:<NativeForm> 整表注入(最常用)

const { NativeForm } = window.__TEABLE_HOST__;

function MyFormPanel() {
  return (
    <NativeForm
      formId="viwIssueForm"                 // 一个 form 视图的 id
      visibleFieldIds={['fldTitle', 'fldDesc']}   // 裁剪+重排(仅会话级)
      hiddenFieldIds={['fld_internalNote']}       // 或只隐藏
      slots={[                                     // 在任意位置插自定义内容
        { position: 'top', render: ({ values }) => <h3>提单</h3> },
      ]}
      interceptSubmit={(fields) => fields}        // 提交前改写载荷(原生提交与自动化照常)
    />
  );
}

要点:原生提交、校验、formSubmitted 自动化全部照常;虚拟值放 __virtual.<key>,提交时自动剥离。

Tier-2:多步表单(逐步切换字段、原生编辑器)

const { NativeFormScope, NativeFormField, useNativeForm } = window.__TEABLE_HOST__;

const STEPS = [
  ['fldTitle', 'fldCustomer'],
  ['fldAmount', 'fldUrgency'],
  ['fldNotes'],
];

function Stepper({ formId }: { formId: string }) {
  return (
    <NativeFormScope formId={formId}>          {/* 状态/L localStorage 暂存由 Scope 接管 */}
      <StepBody formId={formId} />
    </NativeFormScope>
  );
}

function StepBody({ formId }: { formId: string }) {
  const { values, setValue, errors, fields, step, setStep } = useNativeForm({ formId, steps: STEPS });
  return (
    <div>
      {STEPS[step].map((fid) => (
        <NativeFormField key={fid} fieldId={fid} />   {/* 100% 原生字段编辑器 */}
      ))}
      <button onClick={() => setStep(step - 1)} disabled={step === 0}>上一步</button>
      <button onClick={() => setStep(step + 1)} disabled={step === STEPS.length - 1}>下一步</button>
    </div>
  );
}

决策与边界

  • 校验/错误提示:走原生(errors 由 hook 暴露);自定义校验放 interceptSubmit。
  • submitOverride 会绕过原生提交 → formSubmitted 自动化不会触发(要触发就别用它)。
  • computed/lookup 字段永远不可编辑(原生行为,注入也一样)。
  • 详细 props 表与虚拟字段模式见 sdk-api.md 的 NativeForm / NativeFormScope 章节。