Skip to content

layout: narrow keyed field parts.control by widget (#176) - #177

Open
timkindberg wants to merge 1 commit into
mainfrom
feat/176-layout-control-widget
Open

layout: narrow keyed field parts.control by widget (#176)#177
timkindberg wants to merge 1 commit into
mainfrom
feat/176-layout-control-widget

Conversation

@timkindberg

Copy link
Copy Markdown
Owner

Reaching a field through layout's keyed door still made you write a c.kind guard, even though the brand already knew the widget. Found this while reviewing #174.

<Default
  of={root.children.username}
  parts={{ control: (c) => <input {...c.attrs} /> }} // no guard now
/>
  • LayoutNode's field branch is a new LayoutField — an EField with parts.control Extracted down to ControlForWidget<TS['fields'][Path]['widget']>
  • ControlOverrideOf already preferred a handle's live parts.control over Core's wide PartsOverrides, so nothing else needed wiring
  • Widget overrides re-narrow for free — useFormTree already re-brands form through ApplyWidgetOverrides
  • New test renders an input + a choicegroup through guard-free parts.control, with a @ts-expect-error proving the narrowing. Four existing layout assertions moved to toExtend since the handle is a subtype now
  • Amended ADR 055's consequence bullet, which used to say widget narrowing stays the intercept-rules job

The function intercept door keeps the full union on purpose — it fires for every node so it genuinely can't know more (ADR 029 §5). Unbranded trees keep AnyKindNode.

npm run gate green.

Closes #176

`layout`'s FormShape-keyed field handles returned a plain `EField`, so
`<Default of={root.children.username} parts={{ control }} />` still forced
a `c.kind` guard even though the brand already knew the widget.

`LayoutNode`'s field branch is now `LayoutField`, an `EField` whose
`parts.control` is `Extract`ed to `ControlForWidget<TS['fields'][Path]['widget']>`
— the same archetype the typed-rules door hands `FieldProps`. The floor keeps
the union (a function intercept fires for every node and cannot know more,
ADR 029 §5); unbranded trees keep `AnyKindNode`. Widget overrides re-narrow
for free through the brand `useFormTree` already threads.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

layout: FormShape-keyed field handles should narrow parts.control by widget

1 participant