Uh oh!
There was an error while loading. Please reload this page.
fix(plugin-form,types): carry mobile_fullscreen on the field metadata, where widgets actually read (#3245) - #3300
Merged
Conversation
…ta, where widgets actually read (#3245) `ObjectForm` stamped the fullscreen-textarea opt-in onto the FormField itself. The form renderer forwards `field: field.field || field`, so an auto-generated field — which always stashes the object-field metadata on `.field` — handed the widget metadata that never carried the flag, while `stripRegisteredFieldProps` dropped the FormField-level copy. Every generated form silently lost the feature; only the hand-authored `customFields` path (no `.field` to shadow the FormField) ever worked. Stamp the flag onto the object the renderer will forward — `f.field || f`, resolved exactly as `renderFieldComponent` resolves it — so there stays one carrier in one place (#3232 / #3233). The FormField branch is kept for the no-`.field` case: synthesizing a metadata object there would light the affordance up while replacing the field's `rows` / `placeholder` with defaults. Declare `mobile_fullscreen` on `@object-ui/types`' `BaseFieldMetadata`, hence on the `FieldMetadata` union `FieldWidgetComponentProps.field` resolves to. Not an `@objectstack/spec` property — it is a projection of the form-level `ObjectFormSchema.mobile.fullscreenLongText` setting, not authored metadata. This removes the producer's `as FormField` cast, the last untyped end of the chain. Adds the feature's first integration coverage: real `ObjectForm` → real form renderer → real `TextAreaField`, no mocks. It fails against the old producer and passes against the new one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NVPjPzmmAJ2Ngtvgg5MSRa
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
xuyushun441-sys
marked this pull request as ready for review
August 3, 2026 13:38
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 3, 2026
Merged
akarma-synetal pushed a commit
to akarma-synetal/objectui
that referenced
this pull request
Aug 6, 2026
…een 别名 (objectstack-ai#3303) (objectstack-ai#3397) * fix(components): read the fullscreen long-text flag on one spelling (objectstack-ai#3303) The built-in `textarea` branch resolved the flag as `mobile_fullscreen || fullscreen`, and both prop strips carried a matching entry discarding a `fullscreen` key. That alias had zero producers: neither this repo nor `@objectstack/spec` publishes a form-field `fullscreen` property (the only `fullscreen` keys that exist belong to the unrelated feedback/loading overlay), so the second term was undefined from the day it was written. Its cost was not a wrong value, it was a second spelling: the renderer advertised a flag that quietly does nothing, which is the lenient consumer fallback AGENTS.md #0.1 forbids and the same mechanism as objectstack-ai#3245 / objectstack-ai#3301. `ObjectForm` is the sole producer and stamps `mobile_fullscreen` (objectstack-ai#3245/objectstack-ai#3300) — also the single spelling `TextAreaField` and `RichTextField` read, so the built-in branch was the last place where a producer-less spelling still "worked". Removing the strip entries puts `fullscreen` in the ordinary unknown-key class rather than giving a key nobody produces a dedicated discard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt * docs(changeset): record the fullscreen-flag convergence (objectstack-ai#3303) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes#3245
按 2026-08-03 维护者裁决走 方案 A:生产者把 flag 盖到元数据载体上;
mobile_fullscreen不进@objectstack/spec,只在@object-ui/types的 widget 侧字段元数据类型上声明。方案 B(新增宿主 prop 契约)未采纳。前置核对
基线含 #3233(PR #3296,
packages/fields/src/withFieldCarrier.tsx已在origin/main)。issue 正文的六步断链在现状下逐条复核仍然成立(行号已漂移,以下为现状行号):ObjectForm.tsx:567type: mapFieldTypeToFormType(field.type)→field:textareaObjectForm.tsx:584field: field把原始元数据挂到.field槽ObjectForm.tsx:1049({ ...f, mobile_fullscreen: true } as FormField)—— 盖在 FormField 自己身上form.tsx:1826-1837field:textarea不在BUILTIN_FIELD_TYPES,走已注册 widget 分支form.tsx:1372form.tsx:275-289stripRegisteredFieldProps显式剔除mobile_fullscreenprop结论未变:自动生成字段拿不到 flag,手写
customFields拿得到——而自动生成是绝大多数表单的路径。断链证明(先红后绿)
按裁决指定的顺序,先补集成用例钉住现状。用例全链路真实:真
ObjectForm→ 真 form 渲染器 → 真注册表 → 真TextAreaField,除 dataSource 外无 mock。这个特性此前零集成覆盖,两端的单测各自全绿,正是它断了这么久没人发现的原因。改生产者之前(红):
改生产者之后(绿):
改动
生产者(
packages/plugin-form/src/ObjectForm.tsx) —— flag 盖到「渲染器将要转发为field的那个对象」上,即用渲染器自己的解析方式f.field || f解析载体:as FormField硬转随之消失(FormField.field本就声明为Record< string, any >,无需强转)。类型(
packages/types/src/field-types.ts) ——mobile_fullscreen?: boolean声明在BaseFieldMetadata上,因而落在FieldWidgetComponentProps.field所解析到的整个FieldMetadata联合上。注释写明:它是表单级ObjectFormSchema.mobile.fullscreenLongText向字段元数据的投影,生产者唯一(ObjectForm),消费者唯一(TextAreaField读field,#3233 之后没有第二个载体),不是可书写元数据、不进@objectstack/spec。声明在 base 而非单个
TextareaFieldMetadata成员上,是因为TextAreaField拿到的是未收窄的联合——声明在单个成员上会让那次读取变成编译错误,把下一个作者直接推回as any,也就是这个 issue 要消灭的东西。为什么保留「无
.field时盖在 FormField 上」这一支不是防御性冗余,而是被测试逼出来的。无条件写成
{ ...f, field: { ...f.field, flag } }时,手写customFields的对照用例照样绿——因为它从undefined凭空造出一个只含 flag 的元数据对象,flag 确实到达了 widget。但渲染器随后会把这个 stub 当作field转发,而TextAreaField的rows/placeholder是从元数据读的、不是从 props 读的,于是它们静默退回默认值。所以对照用例被加强为同时断言
rows="9"与placeholder,这条捷径才会失败而不是通过。Sabotage 验证(每条新断言逐一验证)
.field分支(无条件盖元数据)mobile.fullscreenLongText开关BaseFieldMetadata上的声明tsc -p tsconfig.test.json报 6 处 TS2339/TS2353 ✅S2 是加强对照用例前没能红的那一条——先失败、再据此补强断言。
验证
changeset:
minor(additive 类型声明 + 行为修复),正文写明「flag 的唯一合法载体是字段元数据,生产者是 ObjectForm」。范围
只改
packages/plugin-form+packages/types+ 测试。未触碰packages/components/packages/fields源码(#3233 收敛态是只读依赖,#3290 正在并行改form.tsx),spec 零改动,content/docs/releases/未碰。顺带发现的相邻缺陷已另开 unassigned issue,不在本 PR 修。
Generated by Claude Code