Skip to content

feat: data-driven converter forms with createFormHook pattern#6

Merged
crippledgeek merged 13 commits into
masterfrom
feature/data-driven-forms
Mar 4, 2026
Merged

feat: data-driven converter forms with createFormHook pattern#6
crippledgeek merged 13 commits into
masterfrom
feature/data-driven-forms

Conversation

@crippledgeek
Copy link
Copy Markdown
Owner

Summary

  • Data-driven form configs: Replace 4 verbose converter pages (~170 lines each) with declarative config objects + a generic ConverterPage renderer — pages reduced to ~5 lines each
  • createFormHook/withForm pattern: Adopt TanStack Form v1's composition API (createFormHookContexts + createFormHook) to eliminate all form: any types via React context
  • Field listeners API: Replace useEffect + useRef mode-change detection with TanStack Form's listeners API on the mode field
  • Absorb useFormHelpers: Merge focus management and mode-reset logic into useConverterForm, deleting the separate hook
  • Add @tanstack/react-store: Direct dependency for selective useStore subscriptions (mode-only re-renders)

Test plan

  • Build passes (npm run build)
  • Lint passes (npm run lint)
  • Zero any types in src/
  • Manual verification: all 4 converter pages render and convert correctly
  • Mode switching clears output and resets input
  • Validation errors display correctly
  • Reset button works

- Extract duplicated FieldError into shared FieldErrorMessage component
- Extract conditionalInputValidation helper in validation-schemas.ts
- Remove dead BetterReadonly/NeverOnSet types from utils.ts
- Remove unused @tanstack/zod-form-adapter dependency
- Simplify useThemeController setTheme logic
- Remove empty prop types from Header and Layout
- Use cn() in Loader for className composition
chore: idiomatic TypeScript simplifications
Introduce ConverterConfig<T>, FieldConfig, and SelectOption types that
describe converter forms declaratively. Create config objects for all
four converters (binary, base64, hex, URL encoder) that encode field
layout, validation schema, default values, and conversion logic.
Replace loose options object with a typed ConverterConfig parameter.
Absorb focus-management logic from useFormHelpers (registerInputRef,
focusFirstError). Replace manual store.subscribe() with reactive
useStore selector for mode changes. Wrap handleReset and focusFirstError
in useCallback. onSubmit now delegates to config.onSubmit and handles
try/catch + setOutput internally.
Create composable field wrappers that pair TanStack Form's form.Field
render-prop with the existing FormSelect/FormTextArea primitives and
FieldErrorMessage. ConvertActions encapsulates the Reset + Convert
button pair with form.Subscribe for canSubmit/isSubmitting state.
Update barrel export to include new components.
Import useStore from @tanstack/react-form instead of @tanstack/react-store
to match the store version used by form-core. Use loosely typed form prop
(any) in SelectField, TextAreaField, ConvertActions, and FieldRenderer to
accommodate ReactFormExtendedApi which adds Field/Subscribe beyond the base
FormApi type. Add ConverterPage generic renderer and export from barrel.
- Replace useEffect+useRef mode-change detection with TanStack Form
  listeners API on the mode field's AppField
- Add ConverterFormBase interface (mode + input) as generic constraint
- Make FieldConfig<T> generic to eliminate visibleWhen double-cast
- Remove useStore import from useConverterForm (no longer needed)
Field components (SelectField, TextAreaField) cannot use useFormContext
because it only works inside formComponents registered with createFormHook.
Access the form state via field.form.state instead.
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 4, 2026

Deploy Preview for devkit-app ready!

Name Link
🔨 Latest commit 99fa6f4
🔍 Latest deploy log https://app.netlify.com/projects/devkit-app/deploys/69a812c1ae7bef00087492ea
😎 Deploy Preview https://deploy-preview-6--devkit-app.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@crippledgeek crippledgeek merged commit d4dbb56 into master Mar 4, 2026
6 checks passed
@crippledgeek crippledgeek deleted the feature/data-driven-forms branch March 4, 2026 11:15
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.

1 participant