Problem
When editing a Page in Studio, the source field under Variables (Data Context section) renders as a plain text <Input>. The user must manually type a component id (e.g. project_picker) — there's no dropdown or picker to select from the component IDs already placed on the page's region tree.
The object field on the same form correctly renders as a dropdown (widget: 'ref:object' picks from registered objects), establishing the expected UX.
Where the gap is
-
Form spec: The variables field is declared as { field: 'variables', type: 'repeater' } with no sub-field widget hints. There's no way to tell SchemaForm that the source sub-field inside a variable should render as a component picker.
-
Zod schema (@objectstack/spec): source is defined as z.string().optional(). No widget metadata attached.
-
Widgets registry (@object-ui/app-shell widgets.tsx): No widget exists for "pick a component ID from the page's canvas component tree." The closest analogue is ref:object which picks from the object registry.
-
SchemaForm (@object-ui/app-shell SchemaForm.tsx): The FieldRow component calls inferWidget() — since neither the zod schema nor the form spec provides a widget hint for source, it falls through to the default: a plain <Input> for string types.
Suggested resolution approach
Two parts:
Part A — form spec: Add sub-field widget declarations inside the variables repeater, so something like:
{ field: 'variables', type: 'repeater', fields: [
{ field: 'name', ... },
{ field: 'type', ... },
{ field: 'defaultValue', ... },
{ field: 'source', widget: 'ref:component', ... }, // new widget hint
] }
Part B — new widget: Implement a ref:component widget in widgets.tsx that:
- Reads the page draft's
regions / children tree (already available in the form's value context)
- Extracts all component
id values from the component tree
- Renders them as a
<Select> dropdown
- Falls back gracefully to a plain input when the page has no regions/components
The widget context in ResourceEditPage.tsx would need to be extended to pass the current draft's component IDs (or the draft value itself, since Variables already lives inside the same form).
Affected files
packages/app-shell/src/views/metadata-admin/widgets.tsx — new ref:component widget renderer + WIDGETS registration
packages/spec/src/ui/page.form.ts — add sub-field config to the variables repeater
packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx — extend WidgetContext if needed
packages/app-shell/src/views/metadata-admin/SchemaForm.tsx — may need minor wiring if the form spec's sub-field widget handling needs adjustment
Expected behavior after fix
Opening a Page in Studio with existing components (e.g. an element:record_picker with id="project_picker") and adding a variable shows a source dropdown listing project_picker and any other component IDs on the page, rather than a free-text input.
Problem
When editing a Page in Studio, the
sourcefield under Variables (Data Context section) renders as a plain text<Input>. The user must manually type a componentid(e.g.project_picker) — there's no dropdown or picker to select from the component IDs already placed on the page's region tree.The
objectfield on the same form correctly renders as a dropdown (widget: 'ref:object'picks from registered objects), establishing the expected UX.Where the gap is
Form spec: The
variablesfield is declared as{ field: 'variables', type: 'repeater' }with no sub-field widget hints. There's no way to tellSchemaFormthat thesourcesub-field inside a variable should render as a component picker.Zod schema (
@objectstack/spec):sourceis defined asz.string().optional(). No widget metadata attached.Widgets registry (
@object-ui/app-shellwidgets.tsx): No widget exists for "pick a component ID from the page's canvas component tree." The closest analogue isref:objectwhich picks from the object registry.SchemaForm (
@object-ui/app-shellSchemaForm.tsx): TheFieldRowcomponent callsinferWidget()— since neither the zod schema nor the form spec provides a widget hint forsource, it falls through to the default: a plain<Input>for string types.Suggested resolution approach
Two parts:
Part A — form spec: Add sub-field widget declarations inside the
variablesrepeater, so something like:Part B — new widget: Implement a
ref:componentwidget inwidgets.tsxthat:regions/childrentree (already available in the form'svaluecontext)idvalues from the component tree<Select>dropdownThe widget context in
ResourceEditPage.tsxwould need to be extended to pass the current draft's component IDs (or the draft value itself, sinceVariablesalready lives inside the same form).Affected files
packages/app-shell/src/views/metadata-admin/widgets.tsx— newref:componentwidget renderer + WIDGETS registrationpackages/spec/src/ui/page.form.ts— add sub-field config to thevariablesrepeaterpackages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx— extend WidgetContext if neededpackages/app-shell/src/views/metadata-admin/SchemaForm.tsx— may need minor wiring if the form spec's sub-field widget handling needs adjustmentExpected behavior after fix
Opening a Page in Studio with existing components (e.g. an
element:record_pickerwithid="project_picker") and adding a variable shows asourcedropdown listingproject_pickerand any other component IDs on the page, rather than a free-text input.