feat(forms): render any native form control under rx.form.control
All Submissions:
- Have you followed the guidelines stated in CONTRIBUTING.md file?
- Have you checked to ensure there aren't any other open Pull Requests for the desired changed?
Type of change
- New feature (non-breaking change which adds functionality)
- This change requires a documentation update
Description
Stacked on reflex-dev/reflex#7724, which teaches form compilation that a control rendered by rx.form.control takes its rx.form.field's name.
rx.form.control only accepted rx.input and rx.debounce_input as its child, so a textarea or a low-level input, textarea or select could not take a form field's name and validation messages:
TypeError: Only Radix TextFieldRoot and DebounceInput are allowed as children of FormControl
Upstream Radix Form.Control composes with any native form control, and with nothing else: the Radix docs state that it cannot yet be composed with the other form primitives such as Checkbox and Select.
FormControl.createnow accepts every component backed by a nativeinput,selectortextarea, which coversrx.input,rx.text_area,rx.debounce_input,rx.el.input,rx.el.textareaandrx.el.select, and keeps rejecting the rest with a message that says to give those controls anameand place them under the root or field instead.- A child is only rendered as the control with
asChild, soas_childis set whenever a child is given, even over an explicitas_child=False; without it Radix renders an<input>with children, which React refuses and the page fails to render. - The low-level form docs list what a Form Control renders and where the unsupported controls go.
Changes To Core Features:
- Have you added an explanation of what your changes do and why you'd like us to include them?
- Have you written new tests for your core changes, as applicable?
- Have you successfully ran tests with your changes locally?
Unit tests cover acceptance of each native control and the exact rejection message. The new Playwright test tests/integration/tests_playwright/test_radix_form_control.py runs a form with one field per accepted control, including a fully controlled input that compiles to DebounceInput, and checks that each control carries its field's name and the id its label points to, that a required textarea blocks submission and shows its rx.form.message, and that the submitted payload holds every value, with no page errors.
Generated by Claude Code