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 三轮全过(此前两轮全败)
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@inkreach/inkreach-teable",
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.8",
|
||||
"description": "CLI (command: inkreach-teable) for operating inkreach-teable: tables, fields, records, views, and the self-built automation engine (8 triggers + 7 actions).",
|
||||
"license": "MIT",
|
||||
"type": "commonjs",
|
||||
|
||||
@@ -69,6 +69,7 @@ JS that executes in the host page and accesses host APIs through
|
||||
| 1. Understand architecture | `dynamic-plugins/overview.md` | always first — how `window.__TEABLE_HOST__`, PluginLoader, PluginSlot work |
|
||||
| 2. Dev workflow | `dynamic-plugins/dev-workflow.md` | when building a plugin — the step-by-step recipe from scaffold to deploy |
|
||||
| 3. SDK API | `dynamic-plugins/sdk-api.md` | when writing plugin logic — definePlugin, PluginContext, events, storage, useSelection, native form embedding (`NativeForm` Tier-1 injection / `NativeFormScope`+`useNativeForm` Tier-2 kit), NativeGrid |
|
||||
| 3b. Native form quick answer | `dynamic-plugins/native-form.md` | **when the user ASKS whether/how to embed native field editors, custom form layout, or multi-step forms — read this FIRST and answer directly (consultative questions need no scaffold/build)** |
|
||||
| 4. Deployment | `dynamic-plugins/deployment.md` | when uploading + enabling + authority matrix permissions |
|
||||
| 5. Troubleshooting | `dynamic-plugins/troubleshooting.md` | before writing logic — common pitfalls (host globals, developer whitelist, AM, empty states) |
|
||||
| Ref: batch-edit-pro | `plugins/batch-edit-pro/` | the canonical example — contextMenu plugin, full React + SDK |
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# Native form embedding — quick answer
|
||||
|
||||
**问题:能不能在插件里做自定义布局的表单(多步表单/侧栏表单),每一步用系统
|
||||
原生字段编辑器,不自己重写输入组件?**
|
||||
|
||||
**能。宿主暴露了完整的原生表单注入能力,共两档。咨询类问题到这里就有答案了,
|
||||
不需要先去搭工程验证。**
|
||||
|
||||
| 需求 | 用哪档 | 核心 API(都在 `window.__TEABLE_HOST__`) |
|
||||
|---|---|---|
|
||||
| 整表单嵌入面板/视图,能裁剪字段、插自定义内容 | **Tier-1 整表注入** | `host.NativeForm` |
|
||||
| 自己控制每行渲染、逐步表单、校验与暂存 | **Tier-2 逐字段套件** | `host.NativeFormScope` + `host.NativeFormField` + `host.useNativeForm()` |
|
||||
|
||||
## Tier-1:`<NativeForm>` 整表注入(最常用)
|
||||
|
||||
```typescript
|
||||
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:多步表单(逐步切换字段、原生编辑器)
|
||||
|
||||
```typescript
|
||||
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](sdk-api.md) 的 `NativeForm` / `NativeFormScope` 章节。
|
||||
Reference in New Issue
Block a user