diff --git a/.changeset/plugin-form-readme-truth-5011.md b/.changeset/plugin-form-readme-truth-5011.md new file mode 100644 index 000000000..768808e18 --- /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 9f4c77130..9fa3a446d 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',