Skip to content

feat: add form component and use_form_data hook - #58

Merged
Archmonger merged 4 commits into
mainfrom
fix-7-form-component
Sep 20, 2026
Merged

Archmonger merged 4 commits into
mainfrom
fix-7-form-component

Conversation

@Archmonger

@Archmonger Archmonger commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

Description

Implements a Form component a la React Router's Form, addressing #7.

Form submissions are intercepted client-side, serialized via FormData into JSON, navigated via pushState (GET-method), and the submitted data is made available through the use_form_data() hook. Non-file fields only; file serialization is deferred.

Changes

JavaScript:

  • Added Form component (src/js/src/components.ts) that intercepts submit events via class-based selectors (same pattern as Link), serializes FormData to Record<string, string[]>, navigates with query params, and fires onSubmitCallback to the server.
  • Added FormProps / FormSubmitData types to src/js/src/types.ts.

Python:

  • form(attributes, *children) in src/reactpy_router/components.py — mirrors the link() pattern. Renders a <form> with a unique CSS class and the JS Form listener as a sibling.
  • use_form_data() hook in src/reactpy_router/hooks.py — returns the most recently submitted form data (dict[str, list[str]]).
  • FormDataState context wired into the router in routers.py so form data is available to all routed components.
  • Both form and use_form_data exported from __init__.py.

Tests (6 new):

  • test_simple_form — basic form submission navigates to action URL
  • test_form_no_page_reload — verifies no full page reload on submit
  • test_form_action_url_with_query_string — action URL with pre-existing query params
  • test_form_use_form_data — submitted data retrievable via use_form_data()
  • test_form_with_multiple_values — multiple checkbox values serialized correctly
  • test_form_class_name — className attribute pass-through

Checklist

Please update this checklist as you complete each item:

  • Tests have been developed for bug fixes or new functionality.
  • The changelog has been updated, if necessary.
  • Documentation has been updated, if necessary.
  • GitHub Issues closed by this PR have been linked.

By submitting this pull request I agree that all contributions comply with this project's open source license(s).

Implements a `form` component akin to React Router's `<Form>` component.
- JS-side Form component intercepts submit events, serializes FormData
  into JSON, navigates via pushState, and passes form data to the server.
- Python-side form() function renders a <form> element with a
  corresponding JS listener. On submit, form data is stored in context
  and the router navigates to the action URL.
- use_form_data() hook retrieves the most recently submitted form data.
- Form data context (FormDataState) is wired into the router so it's
  available to all routed components.
- Non-file fields only; file serialization deferred to future work.

Closes #7
@Archmonger
Archmonger marked this pull request as ready for review July 23, 2026 00:53
@Archmonger
Archmonger requested a review from a team as a code owner July 23, 2026 00:53
@Archmonger Archmonger linked an issue Jul 23, 2026 that may be closed by this pull request
Integrate scroll_restoration (#57) with the form/use_form_data feature:
- Union of exports in __init__.py, index.ts, types.ts, components.ts
- Union of component_from_file bindings in components.py
- Combined test imports
The starlette project moved from the .io domain to .dev. Fixes the docs
linkcheck job failure (ClientConnectorDNSError for www.starlette.io).
@Archmonger
Archmonger merged commit fd77fb5 into main Sep 20, 2026
17 of 18 checks passed
@Archmonger
Archmonger deleted the fix-7-form-component branch September 21, 2026 08:30
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.

form component

1 participant