Skip to content

refactor(ui): move useForm into Rental Checkout form view (phase 16) - #378

Merged
mnindrazaka merged 2 commits into
refactor/formfrom
refactor/form-phase-16-rental-checkout
Aug 27, 2026
Merged

refactor(ui): move useForm into Rental Checkout form view (phase 16)#378
mnindrazaka merged 2 commits into
refactor/formfrom
refactor/form-phase-16-rental-checkout

Conversation

@mnindrazaka

Copy link
Copy Markdown
Collaborator

Summary

Implements Phase 16 of docs/trd-form-ownership-refactor.md (Rental Checkout — Tier C, introduces formRef).

Since none of the earlier phases exist on refactor/form yet, this PR also adds the FormView primitive (Phase 1) that Phase 16 depends on, including its formRef escape hatch (per the TRD, formRef is introduced in Phase 16 with its first real consumer rather than sitting unused).

  • libs/ui/src/presentation/components/base/Form/FormView.tsx (+ stories, tests): the shared variant: loading | loaded | error gate, useForm mount, FormProvider/Form wiring, and the opt-in formRef escape hatch (MutableRefObject<UseFormReturn<T> | null>) documented for sibling-controller writes only.
  • domain/entities/Rental.ts: adds rentalCheckoutFormSchema (moved verbatim from the controller). It stays a partial validator ({ raw: true }, no satisfies clause) per §4.4.2 since it only enforces "at least one rental" and leaves each item's shape as z.any().
  • RentalCheckoutFormView: now owns useForm via FormView, and owns the rentals field array via the existing FieldArray primitive instead of receiving it as a prop. Also exposes the live "already added" ids to RentalItemSelect (previously read from the controller-owned field array) so the "In Cart" affordance keeps working now that the field array lives inside the view.
  • RentalCheckoutController: stripped down to { state, dispatch }useForm, the resolver, useFieldArray, and onAddItem are gone.
  • RentalCheckoutHandler: holds a formRef and writes rentals into the form through it (getValues/setValue, with the same by-id dedupe onAddItem used to do) when the sibling rentalList controller reports a selection — the Tier C bridge described in TRD §4.6.
  • RentalCheckoutScreen: form/rentalsFieldArray props replaced with variant, defaultValues, formRef.
  • Stories and tests for all of the above switch from building a throwaway useForm/useFieldArray to passing defaultValues.

Behaviour changes

None intended. RentalCheckoutUsecase has no fetch step of its own — getInitialState() is synchronously { type: 'loaded' } — so there's no real loading state to gate on. variant is effectively always { type: 'loaded' }, kept for uniformity with the other FormView consumers (same reasoning as Phase 5's WalletTransferFormView in the TRD) rather than special-cased away. The old hasFilledFormRef/form.reset workaround is removed as it was a no-op here (initial values are always { rentals: [] }, matching defaultValues already).

Deviation from the TRD

  • Included Phase 1 in this PR (not its own PR) since Phase 16 can't be built without the FormView primitive it modifies, and no earlier phase has landed on refactor/form yet.
  • Added a small, documented formProps passthrough on FormView (Tamagui <Form> style props) that isn't in the TRD's code sketch — RentalCheckoutFormView's compact vs. desktop layouts need different <Form> styling (flex={1} vs gap="$3"), which the fixed gap="$3" in the TRD's sketch doesn't support. Default behavior for every other future consumer is unchanged.

Test plan

  • npx nx test ui — 161 suites / 1164 tests pass (ran automatically via the pre-commit hook)
  • npx nx lint ui — 0 errors (23 pre-existing warnings, none in touched files)
  • npx nx build-storybook ui — builds clean
  • grep -r "useForm" libs/ui/src/presentation/controllers/RentalCheckout* → no hits
  • RentalCheckoutHandler.test.tsx's existing "In Cart" / duplicate-add / navigation / toast tests all pass unmodified against the new formRef-based add path
  • New FormView.test.tsx covers: loading/error/loaded rendering, mounting with fetched defaultValues after a loading→loaded transition, no reset on a loaded→loaded rerender, resolver validation errors, and formRef being null while loading / populated once loaded

🤖 Generated with Claude Code

https://claude.ai/code/session_014zKNfk7XgeJNzunJAg8RvX


Generated by Claude Code

Adds the FormView primitive (TRD phase 1, not yet in main) with its
formRef escape hatch, then migrates Rental Checkout onto it: useForm
now lives in RentalCheckoutFormView instead of the controller, the
rentals field array moves into the view via FieldArray, and the
sibling rentalList selection in RentalCheckoutHandler writes into the
form through formRef instead of a controller-owned onAddItem.

Behaviour changes: none intended. RentalCheckoutUsecase has no fetch
step of its own (state is always 'loaded'), so the FormView variant is
fixed loaded/uniform rather than gating on a real loading state.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014zKNfk7XgeJNzunJAg8RvX
@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gatherloop-order Error Error Aug 27, 2026 8:04am
gatherloop-pos Error Error Aug 27, 2026 8:04am

…m-phase-16-rental-checkout

# Conflicts:
#	libs/ui/src/presentation/components/base/Form/FormView.stories.tsx
#	libs/ui/src/presentation/components/base/Form/FormView.test.tsx
#	libs/ui/src/presentation/components/base/Form/FormView.tsx
@mnindrazaka
mnindrazaka merged commit 8b78852 into refactor/form Aug 27, 2026
1 of 3 checks passed
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