From be379cbc004007e94c8dc7f8df1dd5ef3a5a714e Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 8 Jun 2026 13:15:22 -0500 Subject: [PATCH] Revert "Add field configuration option to provide editor (#5106)" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 56405d5f04d83c5f7fcde7ee213cca81f0e3b13c. The per-usage `edit:` option on field declarations needs a more thorough design pass — review surfaced several issues with the shape (collection/wrap contract, attribute forwarding, view-slot dedup, autosave-on-view) that warrant rethinking the API before shipping it. Pull it out for now; the consuming branch (edit-realm-config-cs-10056) is moving back to a `static edit` on the parent card. --- packages/base/card-api.gts | 53 +--- packages/base/contains-many-component.gts | 37 +-- packages/base/field-component.gts | 25 +- packages/base/links-to-many-component.gts | 53 +--- .../per-usage-edit-override-test.gts | 251 ------------------ 5 files changed, 31 insertions(+), 388 deletions(-) delete mode 100644 packages/host/tests/integration/components/per-usage-edit-override-test.gts diff --git a/packages/base/card-api.gts b/packages/base/card-api.gts index 548ba71d4b7..ad4c791d110 100644 --- a/packages/base/card-api.gts +++ b/packages/base/card-api.gts @@ -323,16 +323,6 @@ interface Options { isUsed?: true; // Optional: per-usage configuration provider merged with FieldDef-level configuration configuration?: ConfigurationInput; - // Optional: per-usage edit component that overrides the FieldDef's - // `static edit` for this specific field declaration. Lets a parent - // card customize the editor for one of its fields without having - // to subclass the FieldDef or replace its own `static edit`. - // ComponentLike rather than BaseDefComponent so that wrap-style - // overrides on collection fields (containsMany / linksToMany) can - // declare their own Args shape — e.g. accepting `@values` and - // `@defaultEditor`. The runtime contract per field type is documented - // at the rendering sites. - edit?: ComponentLike; } interface RelationshipOptions extends Options { @@ -555,15 +545,6 @@ export interface Field< computeVia: undefined | (() => unknown); // Optional per-usage configuration stored on the field descriptor configuration?: ConfigurationInput; - // Optional per-usage edit component override — when set, the field - // renders with this Component in edit format instead of the - // FieldDef's `static edit`. - // ComponentLike rather than BaseDefComponent so that wrap-style - // overrides on collection fields (containsMany / linksToMany) can - // declare their own Args shape — e.g. accepting `@values` and - // `@defaultEditor`. The runtime contract per field type is documented - // at the rendering sites. - edit?: ComponentLike; // Declarative relationship query definition, if provided queryDefinition?: QueryWithInterpolations; captureQueryFieldSeedData?( @@ -649,7 +630,6 @@ class ContainsMany implements Field< readonly computeVia: undefined | (() => unknown); readonly name: string; readonly description: string | undefined; - readonly edit?: ComponentLike; readonly isUsed: undefined | true; readonly isPolymorphic: undefined | true; configuration: ConfigurationInput | undefined; @@ -977,7 +957,6 @@ class Contains implements Field { readonly computeVia: undefined | (() => unknown); readonly name: string; readonly description: string | undefined; - readonly edit?: ComponentLike; readonly isUsed: undefined | true; readonly isPolymorphic: undefined | true; configuration: ConfigurationInput | undefined; @@ -1206,7 +1185,6 @@ class LinksTo implements Field { readonly computeVia: undefined | (() => unknown); readonly name: string; readonly description: string | undefined; - readonly edit?: ComponentLike; readonly isUsed: undefined | true; readonly isPolymorphic: undefined | true; readonly configuration?: ConfigurationInput; @@ -1599,25 +1577,14 @@ class LinksTo implements Field { {{#if (shouldRenderEditor @format defaultFormats.cardDef isComputed) }} - {{#if linksToField.edit}} - - {{else}} - - {{/if}} + {{else if broken}} ( isUsed, }); (instance as any).configuration = options?.configuration; - (instance as any).edit = options?.edit; return makeDescriptor(instance); }, description: options?.description, @@ -2352,7 +2318,6 @@ export function contains( isUsed, }); (instance as any).configuration = options?.configuration; - (instance as any).edit = options?.edit; return makeDescriptor(instance); }, description: options?.description, @@ -2379,7 +2344,6 @@ export function linksTo( queryDefinition: query, }); (instance as any).configuration = options?.configuration; - (instance as any).edit = options?.edit; return makeDescriptor(instance); }, description: options?.description, @@ -2406,7 +2370,6 @@ export function linksToMany( queryDefinition: query, }); (instance as any).configuration = options?.configuration; - (instance as any).edit = options?.edit; return makeDescriptor(instance); }, description: options?.description, diff --git a/packages/base/contains-many-component.gts b/packages/base/contains-many-component.gts index 37196f34a53..14a5b336afd 100644 --- a/packages/base/contains-many-component.gts +++ b/packages/base/contains-many-component.gts @@ -353,36 +353,13 @@ export function getContainsManyComponent({ {{setOverrides model.value}} {{#if (shouldRenderEditor @format defaultFormats.fieldDef isComputed)}} - {{#if field.edit}} - {{!-- Per-usage edit override on a containsMany. - Contract: the override receives the containing card as - @model, the current values array as @values, and a - pre-bound default ContainsManyEditor as @defaultEditor - so it can wrap (e.g. render a banner above) the standard - iteration + add/remove/sortable UI without - reimplementing it. --}} - - {{else}} - - {{/if}} + {{else}} {{#let (coalesce @format defaultFormats.fieldDef) diff --git a/packages/base/field-component.gts b/packages/base/field-component.gts index 672212fcfe8..feb40ded310 100644 --- a/packages/base/field-component.gts +++ b/packages/base/field-component.gts @@ -234,28 +234,9 @@ export function getBoxComponent( ) { viewSlot = 'embedded'; } - // Per-usage `edit` override on an atomic field wins over the - // FieldDef's `static edit`. Restricted to `contains` / `linksTo` - // here — collection fields (`containsMany` / `linksToMany`) carry - // their own override path in their component files, where the - // wrap-style contract can pass `@defaultEditor`. Without this - // gate the collection's field descriptor would also reach each - // iterated item and replace its template, blanking the item rows. - // The per-usage override expresses stronger intent than the - // view-slot dedup above: if the consumer explicitly supplied - // `edit:`, they asked for a different component in edit format, - // so it must win even when the FieldDef aliases its embedded / - // isolated slot to the same reference as its `static edit`. - // (Toggling embedded↔edit will remount as a result — that's - // correct; the consumer opted into a different component.) - let isAtomicFieldType = - field?.fieldType === 'contains' || field?.fieldType === 'linksTo'; - let CardOrFieldFormatComponent: BaseDefComponent = - effectiveFormat === 'edit' && isAtomicFieldType && field?.edit - ? field.edit - : viewSlot - ? componentClass[viewSlot] - : componentClass[effectiveFormat]; + let CardOrFieldFormatComponent: BaseDefComponent = viewSlot + ? componentClass[viewSlot] + : componentClass[effectiveFormat]; return { CardOrFieldFormatComponent, fields, diff --git a/packages/base/links-to-many-component.gts b/packages/base/links-to-many-component.gts index f1bd6b2502a..721c78d5896 100644 --- a/packages/base/links-to-many-component.gts +++ b/packages/base/links-to-many-component.gts @@ -658,46 +658,19 @@ export function getLinksToManyComponent({