Skip to content

refactor(web): network connection form UX (part 7)#3363

Merged
dgdavid merged 13 commits intoenhance-network-connection-formfrom
network-tanstack-form-part7
Apr 8, 2026
Merged

refactor(web): network connection form UX (part 7)#3363
dgdavid merged 13 commits intoenhance-network-connection-formfrom
network-tanstack-form-part7

Conversation

@dgdavid
Copy link
Copy Markdown
Contributor

@dgdavid dgdavid commented Apr 6, 2026

This is the final PR of series of changes for reimplementing the network connection form using TanStack Form. Built on top of #3353, it removes the old IP settings form and its dependencies, completes the field component set, improves the name auto-sync approach, and fixes a validation gap in advanced mode.

Removal of IpSettingsForm

IpSettingsForm and its supporting components (AddressesDataList, DnsDataList, DnsSearchDataList, IpAddressInput, IpPrefixInput, and their tests) are deleted. The new ConnectionForm based on TanStack Form fully replaces them.

Bug fix: address validation in advanced mode

Addresses are optional in advanced mode, but if entered they must still be valid. Previously only manual mode validated them, so invalid entries could silently reach the server. The fix ensures to also validate entries when they are present in advanced mode, even though none are required.

generateConnectionName as a pure function

useConnectionName was a React hook that had no real React dependency: it computed a name from its arguments and returned a string. It has been replaced by generateConnectionName, a plain function in src/utils/network.ts that is easier to test and works anywhere without a component context.

Name auto-sync via form-level listeners

The previous approach used useStore to watch binding fields and a useEffect to write the derived name back. Both are replaced by TanStack Form's own listeners API), which is the idiomatic way to handle field side effects in this library.

The listener fires on mount and on every change and, as in previous approach, it skips the update when the name field is already dirty, using isDirty rather than isTouched so that focusing and blurring the field without typing does not stop auto-generation. dontRunListeners: true prevents the name write from re-triggering the listener.

DropdownField rename

ChoiceField was renamed to DropdownField since the old name gave no hint about what kind of input it renders. The TSDoc now explains that the component uses a PatternFly menu-based combobox rather than a native <select>, why the keyboard interaction differs from what users may expect, and includes a TODO for implementing the W3C-recommended arrow-key compromise.

TextField and CheckboxField

Two new field components following the same useFieldContext pattern as DropdownField and ArrayField:

  • TextField: a text input that shows validation errors inline below the input.
  • CheckboxField: a checkbox with an optional description.

Both are registered in useAppForm and wired into ConnectionForm (name field, DNS toggles) and IpSettings (gateway field), replacing the inline markup that was previously scattered across those components.

A ## Field component conventions section was added to form-contexts.ts to document the shared contract: onChange is wired internally, onBlur is intentionally not wired (submit-only validation, revisit when a use case arises), and lifecycle events belong on form.AppField via listeners, not on the component itself.

Action button form components

Two action button components are registered under formComponents so they are available on any typed form instance without form-specific wiring:

  • form.SubmitButton: reads isSubmitting via useFormContext and renders a submit button that shows a loading indicator and disables itself while the form is submitting.
  • form.CancelButton: encapsulates navigate(-1) via useNavigate, rendering a link button that returns to the previous page.

ConnectionForm's action group reduces to:

<ActionGroup>
  <form.SubmitButton />
  <form.CancelButton />
</ActionGroup>

Form conventions update

src/components/form/conventions.md has been updated to reflect the implemented state of ConnectionForm. Stale notes are replaced with accurate descriptions, conditional rendering is consistently described as "not rendered" rather than "hidden" throughout, and a new Validation section explains the submit-only approach, the cross-field onSubmitAsync pattern, and the setErrorMap workaround needed to re-enable submission after a failed attempt.

Notes for reviewers

Changelog entry postponed for the final PR from the feature branch against master.

dgdavid added 5 commits April 3, 2026 13:04
The new ConnectionForm based on TanStack Form fully replaces the old
IpSettingsForm and all its dependencies.
Addresses are optional in advanced mode, but if entered they must still
be valid. Previously only manual mode validated them, so invalid entries
could silently reach the server.
Replacing useStore + useEffect with TanStack Form's own listener API is
the idiomatic way to handle field side effects in this library.
Reusable form-aware components for text inputs and checkboxes, following
the same useFieldContext pattern as ChoiceField and ArrayField. Wired
into ConnectionForm (name field, DNS toggles) and IpSettings (gateway),
replacing the inline field markup in each place.
@dgdavid dgdavid changed the title Network tanstack form part7 refactor(web): network connection form UX (part 7) Apr 6, 2026
@dgdavid dgdavid force-pushed the network-tanstack-form-part7 branch from 10d6bb7 to ac02514 Compare April 6, 2026 15:53
@dgdavid dgdavid requested a review from teclator April 6, 2026 15:54
dgdavid and others added 3 commits April 7, 2026 09:13
"ChoiceField" gave no hint that the component renders a dropdown.

Also adds a note in its TSDoc block to clarify that the component
renders a PatternFly menu-based combobox, not a native select. It
explains the keyboard behavior difference, why the two-step interaction
is intentional (W3C APG screen reader safety), and includes a TODO for
the missing arrow-key-opens-menu behavior.
…state

Replace stale notes with accurate descriptions of what is actually implemented.

The pattern for conditional rendering consistently uses "not rendered"
instead of "hidden" throughout, since fields are conditionally mounted,
not CSS-hidden.
@dgdavid dgdavid marked this pull request as ready for review April 7, 2026 15:07
dgdavid added 3 commits April 7, 2026 16:22
Encapsulate submit state handling and cancel navigation so form
components do not need to wire them up individually. Both are registered
under formComponents and available as form.SubmitButton and
form.CancelButton.
Copy link
Copy Markdown
Contributor

@teclator teclator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dgdavid dgdavid merged commit 0ab0ffa into enhance-network-connection-form Apr 8, 2026
4 checks passed
@dgdavid dgdavid deleted the network-tanstack-form-part7 branch April 8, 2026 19:16
@imobachgs imobachgs mentioned this pull request Apr 14, 2026
imobachgs added a commit that referenced this pull request Apr 14, 2026
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.

2 participants