Tanstack form basics#64
Conversation
|
I wil have a look at this tomorrow! |
|
Really into this direction overall. One structural thing I'd like us to lock in now, while the pattern is still greenfield and there's nothing to migrate: 1. Drop the
What these components actually are is form fields: a control + label + description + error + required, composed together. We already have a
Reads naturally: "a Field wrapping a Checkbox." The registry keys in 2. Keep the primitive a pure primitive. Right now
Caveat worth noting: a checkbox label sits inline next to the box and toggles it, unlike an input label which sits above. So 3. This also cleans up an inconsistency that's already in the diff.
Standardising on "primitive = pure base-ui wrapper, One follow-up: Happy to pair on the rename since it's all new code anyway. |
There was a problem hiding this comment.
Looks good overall.
- While I do think the
tsfprefix is not great, I understand its purpose as it really is locked into the tanstack form hooks. If we want to make that agnostic, we'd have to abstract those hooks away which I don't think is worth the effort. Let's hope we don't do any major lib migrations anytime soon 😉 - I think its important to be consistent with the field/input naming. Checkbox would need a field as well as a "raw" checkbox. That aligns with the rest of the form controls. This also fixes the latent issue that we can't compose a checkbox with some other UI without dragging along the label and form semantics in this current impl.
|
Made some solid improvements based on the feedback. BaseUI is now extended as described in the docs for the form elements. I kept in some console.logs and superfluous error messages, so that consumers can really understand how it works. It it still easy to remove the whole example. I'm pretty happy with this. Please re-review! |
|
Looks good overall, I can get behind this! There's a few merge conflicts and I found things I think are important to address before we merge. |
Merged it this morning and processed comments! |
|
I think overall we are now in the right direction to use this as a proper template 🚀, one thing left to fix is the build 😆 |
|
Build & nitpick fixed. @maanlamp can you check the comments I wrote and resolve if you are ok with it? |
Closes #41.
Process our findings of the studio day. I make the commits so that they are feature-based and the files in it not (heavily) updated one after another. So that may be a good way to review this bulky change.
Here's an AI summary:
Introduces a reusable TanStack Form (TSF) setup includes a working form-example route and adoption docs.
What's new
Form composition (
lib/forms/,components/form/)useAppForm/withFormhook wiring field connectors in one place.tsf-wrap base-ui primitives and bind them to TSFFieldwrapper handles label / description / error / required, plusform.scssmixins (invalid,disabled) reused across controls.checkbox.tsx) kept separate, per thetsf-convention.Validation helpers (
lib/forms/validation-helpers.ts) ⭐These are the key utilities that make TSF easier to work with:
mutateAndValidate(mutation)— bridges TanStack Query mutations into TSF'sonSubmitAsync, turning backend errors into form/field errors. Temporary shim until TSF#2188.apiErrorToFormErrors(error)— maps an RFC9457 problem-details API error onto{ form, fields }, convertingsnake_casepaths tocamelCase.normalizeFieldErrors(errors)— flattens TSF's mixed error shapes (string /{message}/ arrays) intostring[].getFieldErrors(state, fields)— pulls normalized errors for a set of fields.lib/api/error-helpers.ts(parseErrorString) for unknown/poorly-typed errors.Docs & example
A new docs folder that should help people adopt the template. The idea of the
docs/snippets/folder is to have practical examples of preferred implementations (but should not be in code -lest it needs to be removed).