From 43a5c9dfc68ad84efc4961f69df63d3f112b3ba2 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Aug 2026 22:37:40 +0000 Subject: [PATCH] =?UTF-8?q?docs(plugin-form):=20README=20=E6=8C=89?= =?UTF-8?q?=E7=9C=9F=E5=AE=9E=E5=AF=BC=E5=87=BA=E9=9D=A2=E9=87=8D=E5=86=99?= =?UTF-8?q?=E8=99=9A=E6=9E=84=E7=9A=84=E6=89=8B=E5=8A=A8=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E4=B8=8E=E4=B8=A4=E4=B8=AA=E5=8D=8F=E8=AE=AE=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E7=9A=84=E5=AF=BC=E5=85=A5=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `packages/plugin-form/README.md` 有三处对本包导出面的断言不成立,导出名集合取自 构建产物 `dist/index.d.ts`(走 TS compiler API 的 checker.getExportsOfModule, 不是对 src 做正则),README 的每个 TypeScript 块对同一批构建产物 strict 编译验证。 - `:41` `formComponents`:纯虚构,且**改不成同族真名** —— 本包 51 个导出里没有任何 聚合组件表,所以 "Manual Registration" 整节描述的是一个不存在的机制,照抄拿到 `undefined`,`Object.entries(undefined)` 当场抛 TypeError。删该节,改教真实机制: 注册是 import 入口的副作用,六个 `ComponentRegistry.register(...)` 调用 claim 的是 `plugin-form:object-form` / `view:form` / `plugin-form:embeddable-form` / `plugin-form:form-analytics` / `plugin-form:object-master-detail-form` / `record:line_items`,其中两个 `skipFallback: true` 正是裸 `form` 与裸 `line_items` 没有被本包接管的原因;另列真实导出面,以及原片段真正想做的事(把已导出的组件注册 到自定义键)。 - `:408` `FormSchema` / `FormField`:名字是真的、包错了。两者都是协议类型,声明在 `@object-ui/types`(`src/form.ts:1055` / `:898`),本包只 import 不 re-export, 照 README 的路径导入是两条 TS2305。只改导入路径 —— ⛔ 未加 re-export,扩张公开面 是契约变更而非文档修正。 - `:156` `isRuntimeDefault`「(re-exported here)」:该谓词只由 `src/schemaDefaults.ts` 为包内自用而 re-export,从不出现在入口上,且本包只发布 `"."` 一个 export,所以 `import { isRuntimeDefault } from '@object-ui/plugin-form'` 同样是 TS2305。括注改成 re-export 的真实位置。 无代码/类型/运行时改动,diff 只有一个 README 与 changeset;声明 patch 是因为 `README.md` 在包的 `files` 里,随下次发布到 npm。 Fixes #5011 Co-authored-by: Claude --- .changeset/plugin-form-readme-truth-5011.md | 41 +++++++ packages/plugin-form/README.md | 119 ++++++++++++++++++-- 2 files changed, 151 insertions(+), 9 deletions(-) create mode 100644 .changeset/plugin-form-readme-truth-5011.md diff --git a/.changeset/plugin-form-readme-truth-5011.md b/.changeset/plugin-form-readme-truth-5011.md new file mode 100644 index 0000000000..768808e188 --- /dev/null +++ b/.changeset/plugin-form-readme-truth-5011.md @@ -0,0 +1,41 @@ +--- +'@object-ui/plugin-form': patch +--- + +`packages/plugin-form/README.md`: three assertions about this package's export +surface were false, and the export names are now taken from the built +`dist/index.d.ts` (TS compiler API `checker.getExportsOfModule`) with every +TypeScript block compiled against those same declarations under `strict`. + +- **`formComponents`** — fiction, and not a name that could be corrected: there + is no aggregate component map on the surface at all, so the "Manual + Registration" section described a mechanism that does not exist. Copying it got + `undefined` and threw on `Object.entries(undefined)`. It is replaced by what + actually happens: registration is a side effect of importing the entry, whose + six `ComponentRegistry.register(...)` calls claim + `plugin-form:object-form`, `view:form`, `plugin-form:embeddable-form`, + `plugin-form:form-analytics`, `plugin-form:object-master-detail-form` and + `record:line_items` — the two `skipFallback: true` calls being why bare `form` + and bare `line_items` are *not* taken over. The section also lists the real + export surface, and shows the thing the old snippet was reaching for: putting + an exported component on a schema type of your own, with the caveat that the + package's own registered renderers are internal wrappers that first resolve + `dataSource` from `SchemaRendererContext`. +- **`FormSchema` / `FormField`** — real types imported from the wrong package. + Both are protocol types declared in `@object-ui/types` (`src/form.ts`); this + package imports them and does not re-export them, so the documented import was + a `TS2305` pair. Only the import path changed — no re-export was added to make + the old path true, since widening a package's public surface is a contract + change and not a documentation fix. The section now also points at the form + types that *are* on this entry (`TabbedFormSchema`, `WizardFormSchema`, + `ModalFormSchema`, …). +- **`isRuntimeDefault` "(re-exported here)"** — the create-defaults section + claimed the predicate is re-exported by this package. It is re-exported by + `src/schemaDefaults.ts` for internal use only, never from the entry, and the + package publishes just the `"."` export — so `import { isRuntimeDefault } from + '@object-ui/plugin-form'` is another `TS2305`. The parenthetical now says where + the re-export actually lives. + +No code, types or runtime behaviour change — the diff is one README plus this +changeset. It declares a patch because `README.md` is in the package's published +`files`, so the correction reaches npm with the next release. diff --git a/packages/plugin-form/README.md b/packages/plugin-form/README.md index 9f4c771303..9fa3a446d7 100644 --- a/packages/plugin-form/README.md +++ b/packages/plugin-form/README.md @@ -35,18 +35,112 @@ const schema = { }; ``` -### Manual Registration +### What the side-effect import registers + +There is no component map to iterate: registration is a side effect of importing +the package entry, which makes six `ComponentRegistry.register(...)` calls. These +are the schema types those calls claim, read off the calls themselves in +`src/index.tsx`: + +| Namespaced type | Bare-name fallback | Component behind it | +|---|---|---| +| `plugin-form:object-form` | `object-form` | `ObjectForm` — metadata-driven form over one record | +| `view:form` | none | the same renderer under the view protocol | +| `plugin-form:embeddable-form` | `embeddable-form` | `EmbeddableForm` — standalone public form | +| `plugin-form:form-analytics` | `form-analytics` | `FormAnalytics` — submission dashboard | +| `plugin-form:object-master-detail-form` | `object-master-detail-form` | `MasterDetailForm` — parent + child line items in one submit | +| `record:line_items` | none | `LineItemsPanel` — child grid bound to the record on the page | + +`ComponentRegistry.register` also registers a namespaced type under its bare name +for backwards compatibility, unless the call passes `skipFallback: true` +(`@object-ui/core`, `src/registry/Registry.ts`). Two calls here do: bare `form` +stays the basic `@object-ui/components` form, and bare `line_items` is left to +whoever else claims it. + +### Public exports + +The package entry exports these — components, their prop/schema types, and the +layout helpers. There is no aggregate map among them: + +```typescript +import { + ObjectForm, + TabbedForm, + WizardForm, + SplitForm, + DrawerForm, + ModalForm, + EmbeddableForm, + MasterDetailForm, + LineItemsPanel, + FormAnalytics, + FormSectionContainer, + applyAutoLayout, + applyAutoColSpan, + inferColumns, + inferModalSize, + isWideFieldType, + isAutoGeneratedFieldType, + containerGridColsFor, + filterCreateModeFields, + filterSystemFields, + filterAutoGeneratedFields, + deriveDetail, + deriveColumns, + deriveFormFields, + findRelationshipField, + resolveInlineMode, +} from '@object-ui/plugin-form'; + +import type { + ObjectFormComponentProps, + ObjectFormProps, // deprecated alias of ObjectFormComponentProps + FormSectionContainerProps, + TabbedFormProps, + TabbedFormSchema, + FormSectionConfig, + WizardFormProps, + WizardFormSchema, + SplitFormProps, + SplitFormSchema, + DrawerFormProps, + DrawerFormSchema, + ModalFormProps, + ModalFormSchema, + EmbeddableFormProps, + EmbeddableFormConfig, + EmbeddableFormTexts, + FormAnalyticsProps, + FormSubmissionMetric, + MasterDetailFormProps, + MasterDetailFormSchema, + MasterDetailDetailConfig, + LineItemsPanelSchema, + DerivedDetail, + InlineMode, +} from '@object-ui/plugin-form'; +``` + +### Registering a component under your own key + +To put one of these components on a schema type of your own, register the +exported component: ```typescript -import { formComponents } from '@object-ui/plugin-form'; import { ComponentRegistry } from '@object-ui/core'; +import { ObjectForm } from '@object-ui/plugin-form'; -// Register form components -Object.entries(formComponents).forEach(([type, component]) => { - ComponentRegistry.register(type, component); -}); +ComponentRegistry.register('my-form', ObjectForm, { namespace: 'my-app' }); ``` +The renderers this package registers for itself are internal wrappers rather +than these exported components. `SchemaRenderer` hands a registered component its +`schema` (plus the schema's own props), but never a `dataSource` — that travels +on `SchemaRendererContext` — so each wrapper reads it off the context first. +`ObjectForm` takes `dataSource` as a prop, optional because inline `customFields` +need no adapter, so a custom-key registration either supplies one or wraps the +component the same way. + ## Schema API ### Form @@ -154,8 +248,9 @@ required to provide the value. Showing what the server *will* supply, as a non-authoritative preview, is a separate follow-up. Every consumer reads one predicate, `isRuntimeDefault` in `@object-ui/core` -(re-exported here) — which is what keeps a form from seeding a field it also -refuses to submit. The static half is decided at the producer, in +(re-exported for this package's own use by `src/schemaDefaults.ts`, not from the +package entry listed above) — which is what keeps a form from seeding a field it +also refuses to submit. The static half is decided at the producer, in `isRequiredInForm`; the conditional half cannot be, because `requiredWhen` is resolved downstream against the live record, so it is suppressed inside the one evaluator that resolves it — `resolveFieldRuleState`, reading @@ -404,8 +499,14 @@ const schema = { ## TypeScript Support +`FormSchema` and `FormField` are protocol types, so they live in +`@object-ui/types` alongside the rest of the JSON contract. This package imports +them and does not re-export them — the form types on its own entry are the +per-container ones (`TabbedFormSchema`, `WizardFormSchema`, `ModalFormSchema`, …) +listed under [Public exports](#public-exports). + ```typescript -import type { FormSchema, FormField } from '@object-ui/plugin-form'; +import type { FormSchema, FormField } from '@object-ui/types'; const emailField: FormField = { name: 'email',