refactor: decouple fields from state in DynamicForms#2823
Merged
Conversation
🦋 Changeset detectedLatest commit: 7fe9882 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
c67aac3 to
a872b62
Compare
a872b62 to
a72981b
Compare
dce8c6c to
f7b23ad
Compare
f7b23ad to
a41cdaf
Compare
71aecc8 to
e06d5c6
Compare
960122d to
3d44d00
Compare
3d44d00 to
7fe9882
Compare
chanceaclark
approved these changes
Jan 15, 2026
Contributor
chanceaclark
left a comment
There was a problem hiding this comment.
Overall looks good, sucks we had to use .bind but 🤷♂️
Contributor
Author
@chanceaclark Agreed, but seems to be the recommended pattern. |
Contributor
|
TIL! |
jamesqquick
pushed a commit
that referenced
this pull request
Feb 11, 2026
* refactor: decouple fields from state in DynamicForms * fix: remove options from fields * fix: pass passwordComplexity as an arg * fix: remove fields from return state in contact form * chore: add changeset
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What/Why?
Refactor DynamicForm actions to decouple fields and passwordComplexity from state, passing them as separate arguments instead. This reduces state payload size by removing fields from state objects and stripping options from fields before passing them to actions (options are only needed for rendering, not processing). All form actions now accept a
DynamicFormActionArgsobject as the first parameter containing fields and optional passwordComplexity, followed by the previous state and formData.Testing
Locally
Migration steps
Step 1: Changes to DynamicForm component
The
DynamicFormcomponent and related utilities have been updated to support the new action signature pattern:core/vibes/soul/form/dynamic-form/index.tsx:DynamicFormActionArgs<F>interface that containsfieldsand optionalpasswordComplexityDynamicFormAction<F>type to acceptDynamicFormActionArgs<F>as the first parameterfieldsandpasswordComplexityfrom theStateinterfaceoptionsfrom fields before passing to actions (options are only needed for rendering)action.bind(null, { fields: fieldsWithoutOptions, passwordComplexity })core/vibes/soul/form/dynamic-form/utils.ts(new file):removeOptionsFromFields()utility function that strips theoptionsproperty from field definitions before passing them to actions, reducing the state payload sizeStep 2: Update DynamicForm action signatures
All form actions that use
DynamicFormmust be updated to acceptDynamicFormActionArgs<F>as the first parameter instead of including fields in the state.Update your form action function signature:
Step 2: Remove fields and passwordComplexity from state interfaces
Update state interfaces to remove fields and passwordComplexity properties:
interface State { lastResult: SubmissionResult | null; - fields: Array<Field | FieldGroup<Field>>; - passwordComplexity?: PasswordComplexitySettings | null; }Step 3: Update action implementations
Remove references to
prevState.fieldsandprevState.passwordComplexityin action implementations:const submission = parseWithZod(formData, { - schema: schema(prevState.fields, prevState.passwordComplexity), + schema: schema(fields, passwordComplexity), }); if (submission.status !== 'success') { return { lastResult: submission.reply(), - fields: prevState.fields, - passwordComplexity: prevState.passwordComplexity, }; }Step 4: Update action calls in components
For actions used with
AddressListSection, update the action signature to accept fields as the first parameter:Step 5: Update DynamicForm usage
No changes needed to
DynamicFormcomponent usage. The component automatically handles binding fields and passwordComplexity to actions. TheDynamicFormcomponent now:action.bind()Affected files
The following files were updated in this refactor:
core/vibes/soul/form/dynamic-form/index.tsx- AddedDynamicFormActionArgstype and updated action bindingcore/vibes/soul/form/dynamic-form/utils.ts- AddedremoveOptionsFromFieldsutility functioncore/app/[locale]/(default)/(auth)/register/_actions/register-customer.tscore/app/[locale]/(default)/account/addresses/_actions/address-action.tscore/app/[locale]/(default)/account/addresses/_actions/create-address.tscore/app/[locale]/(default)/account/addresses/_actions/update-address.tscore/app/[locale]/(default)/account/addresses/_actions/delete-address.tscore/app/[locale]/(default)/gift-certificates/purchase/_actions/add-to-cart.tsxcore/app/[locale]/(default)/webpages/[id]/contact/_actions/submit-contact-form.tscore/vibes/soul/sections/address-list-section/index.tsx