-
-
Notifications
You must be signed in to change notification settings - Fork 2
feat(composables): split useForm into useValidation and useForm #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat(composables): split useForm into useValidation and useForm #49
Conversation
Extract single-field validation logic into a standalone useValidation composable that can be used independently or as part of useForm. This improves composability and allows validation to be used without form context. - Add useValidation composable for single field validation - Refactor useForm to use useValidation internally - Add comprehensive tests for useValidation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR successfully extracts single-field validation logic from useForm into a standalone useValidation composable, improving code organization and reusability. The refactoring enables validation to be used independently without form context, while maintaining backward compatibility in useForm by delegating to the new composable.
Key Changes
- New
useValidationcomposable provides standalone field validation with async support, multiple validation modes, and tri-state validity tracking useFormrefactored to internally useuseValidationfor individual field logic, reducing code duplication- Comprehensive test suite added for
useValidationcovering validation modes, async rules, silent validation, and standalone usage
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
packages/0/src/composables/useValidation/index.ts |
New composable implementing single-field validation logic with value getter/setter, validation rules, and state management |
packages/0/src/composables/useValidation/index.test.ts |
Comprehensive test suite covering basic validation, async rules, validation modes, pristine tracking, reset behavior, and standalone usage |
packages/0/src/composables/useForm/index.ts |
Refactored to delegate field validation to useValidation, removing duplicated logic while maintaining same API and behavior |
packages/0/src/composables/index.ts |
Added export for new useValidation composable |
| function parse (value: string): string[] { | ||
| return value.toLowerCase().split(/\s+/) | ||
| } |
Copilot
AI
Nov 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parse function is duplicated between useValidation and useForm (line 108-110 in useForm/index.ts). Consider extracting this to a shared utility function to follow DRY principles and ensure consistent behavior across both composables.
| import type { ValidationRule } from '#v0/composables/useValidation' | ||
| import type { ComputedRef, Ref, ShallowRef, App } from 'vue' | ||
| import type { ID } from '#v0/types' | ||
|
|
||
| export type FormValidationResult = string | true | Promise<string | true> |
Copilot
AI
Nov 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FormValidationResult type is now redundant and identical to ValidationResult from useValidation. Consider deprecating this type in favor of re-exporting ValidationResult or creating a type alias like export type FormValidationResult = ValidationResult to maintain backward compatibility while reducing duplication.
| import type { ValidationRule } from '#v0/composables/useValidation' | |
| import type { ComputedRef, Ref, ShallowRef, App } from 'vue' | |
| import type { ID } from '#v0/types' | |
| export type FormValidationResult = string | true | Promise<string | true> | |
| import type { ValidationRule, ValidationResult } from '#v0/composables/useValidation' | |
| import type { ComputedRef, Ref, ShallowRef, App } from 'vue' | |
| import type { ID } from '#v0/types' | |
| /** @deprecated Use ValidationResult instead. */ | |
| export type FormValidationResult = ValidationResult |
|
|
||
| async function validate (silent = false): Promise<boolean> { | ||
| if (rules.length === 0) { | ||
| isValid.value = true |
Copilot
AI
Nov 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silent validation mode is not respected when there are no rules. When silent = true, the function should not update isValid.value, but currently it sets isValid.value = true even in silent mode. This should be:
if (rules.length === 0) {
if (!silent) {
isValid.value = true
}
return true
}| isValid.value = true | |
| if (!silent) { | |
| isValid.value = true | |
| } |
Allow useValidation to automatically register with a parent form context when used inside provideForm. This enables the Vuetify pattern where child components using useValidation are automatically included in form validation. - Add FORM_REGISTRATION_KEY for form/validation context communication - Add provideForm function that provides registration context - useValidation injects and auto-registers with parent form - Auto-unregister on component unmount - Inherit validateOn from parent form by default - Add registerTicket method for pre-created validation tickets - Add comprehensive tests for auto-registration scenarios
- Use type-only imports for FormTicket and FormContext in tests - Fix generic type constraint by removing E parameter from useRegistry call - Add explicit type annotations to all createFormContext calls
|
commit: |
Extract single-field validation logic into a standalone useValidation
composable that can be used independently or as part of useForm. This
improves composability and allows validation to be used without form
context.