Symptom
When a @dashforge/tw form widget (TextField, NumberField, Textarea, Switch, Checkbox, RadioGroup, Select) is rendered:
- Outside a
DashFormProvider (so useContext(DashFormContext) === undefined and isFormMode === false)
- AND without
value + onChange props
... the component silently renders as an uncontrolled input that never emits changes. No error, no warning, no visual hint — the input just doesn't work. Extremely hard to diagnose.
Context
Filed in Blueprint's dogfood report as G-29, added 2026-07-08 alongside the G-26 reclassification. Runtime verification confirmed that @dashforge/tw form widgets DO work as standalone controlled inputs (via InputHTMLAttributes<HTMLInputElement> inheritance) when value + onChange are provided. The problem is the failure mode when a consumer forgets BOTH the provider AND the controlled props.
Why this is worth fixing
- Silent no-op is the worst possible failure mode — no signal that the widget is broken
- Very common consumer mistake: mounting
<TextField> in a shell that isn't a form and forgetting to add value + onChange
- Cheap fix: single dev-only warning in a shared helper, no runtime cost in production
Acceptance
Related
- Adjacent to (but does NOT depend on) the G-26 reclassification in Blueprint's dogfood report — the widgets already work standalone; this is a paper-cut fix on top of that discovery
Symptom
When a
@dashforge/twform widget (TextField,NumberField,Textarea,Switch,Checkbox,RadioGroup,Select) is rendered:DashFormProvider(souseContext(DashFormContext) === undefinedandisFormMode === false)value+onChangeprops... the component silently renders as an uncontrolled input that never emits changes. No error, no warning, no visual hint — the input just doesn't work. Extremely hard to diagnose.
Context
Filed in Blueprint's dogfood report as G-29, added 2026-07-08 alongside the G-26 reclassification. Runtime verification confirmed that
@dashforge/twform widgets DO work as standalone controlled inputs (viaInputHTMLAttributes<HTMLInputElement>inheritance) whenvalue+onChangeare provided. The problem is the failure mode when a consumer forgets BOTH the provider AND the controlled props.Why this is worth fixing
<TextField>in a shell that isn't a form and forgetting to addvalue+onChangeAcceptance
!isFormMode && userValue === undefined && userOnChange === undefined) once per widget mountconsole.warnin dev mode only (guard onprocess.env.NODE_ENV !== 'production') — silent in prod"[@dashforge/tw] <TextField name=\"X\"> is not inside a DashFormProvider and no value/onChange were provided. Did you forget the provider, or intend controlled mode? See docs on controlled vs bridge mode."dashforge-docs-labdocuments "controlled vs bridge mode" explicitly so the warning message links somewhere usefulRelated