You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I published the first preview to npm as 0.3.0-beta.0. Please note the API is still subject to change before finishing, so use it at your own risk.
What this release addresses mainly is:
Context-based API (as an alternative to without context).
Clarify many API methods which had confusing names, were hard to understand or were inconsistent.
Leverage new typescript capabilities.
i18n support on validators.
Changes
Features
Context
Added FormicaryContext.Provider to avoid prop-drilling if desired
Now every hook optionally can have the formRef parameter omitted. If it's omitted, it will grab the formRef from the context instead.
To help with typescript support, there's a new helper method createKeyFn<FormModel>() that will give a function that should autocomplete the paths for FormModel, plus providing the correct type for each parameter.
Key selectors
String-based key selectors have now typescript support. Typescript should auto-complete the paths when using them.
useErrors will now return a type-safe dictionary of elements when using the paths overload (e.g. useErrors(form, 'name', 'age') returns type { name: Error, age: Error }).
Undefined values
useControl and useControlStateless now don't require an initial value: The value will be undefined by default.
All methods that set the value of a field accept undefined to reset them as empty.
All methods that get a value of a field can potentially return undefined for type safety, except getFormValue to make matters simple. Be aware some values could be undefined, although it should not happen if validation rules are set up and form is marked as valid.
New hook useFieldChanges(key, cb: (value, isInitial) => void) that will call the call-back every time that the field changes its value (it will also call it with the initial value setting isInitial to true)
New commands getInitialValue and getFormInitialValue to get the initial value of a field or the form respectively.
New command getAllErrors to get a map with the fields that fail validation.
Validators
All validator constructors have a consistent shape: They are functions that return a validator (e.g. isRequired()isAtLeast(5))
Validation error messages can now be customized through setValidatorMessages or through an optional parameter when creating it.
Clarified the return type of a validator: It either returns true (value is valid) or a list of error messages.
Now the type for FormRef<FormModel> is assignable to another variable with a subtype. This is particularly useful for subcomponents that only take a few properties of the whole model.
Breaking
useInput
useInput now requires the key. It will ignore the name attribute of the element it gets attached to.
This provides better type safety with validators, and make it easier to understand what property the input is going to be attached to.
Hooks with multiple key selectors (useErrors, etc.).
To improve type safety, now hooks that took arrays of keys should have them spread as parameters. E.g. useError(form, ['name', 'age']) should become useErrors(form, 'name', 'age').
The selector function validator is unaffected from this change (E.g. useError(form, v => [v.name, v.age])) is alright, but won't have the new enhanced type safety.
Validators
isRequired, isNumber and isInteger must now be called to get the actual validator.
Validators that are not isRequired will now return the value is valid if the value is nil, otherwise it would not be possible to make e.g. an optional numeric field. To migrate, they can be composed with pipeValidators(isRequired(), {{validator}}).
Validators can't return false now when the value is invalid. On that case they must return a list of errors messages.
Renames
useWatch renamed to useFieldValue - Reason: it's more descriptive of what it's returning.
useFormChanges renamed to useFormValue - Reason: it's more descriptive of what it's returning.
useControlSubscription renamed to useControlStateless - Reason: the name was misleading, it's not creating a Subscription, but returning something that you can subscribe to without using a state.
readField renamed to getFieldValue - Reason: More descriptive and consistent with the setFieldValue counterpart.
readForm renamed to getFormValue - Reason: More descriptive and consistent with the setFormValue counterpart.
The type for FormRef is now opaque. It can still be used to pass the formRef around, but its properties are private and can't be accessed. Use exported methods instead.
TODO
getInitialValue
getAllErrors
investigate arrays
add test to verify initialValue on useForm prevails over initialValue on useInput
Define what happens when a field gets unmounted: Is it saved? validators still apply? is it removed?
-> By default, value is retained. Option to have it removed on unmount.
(Release open to feedback)
The text was updated successfully, but these errors were encountered:
I'm currently working on a major release 0.3.0. Branch is in https://github.com/voliva/formicary/tree/v3.
I published the first preview to npm as
0.3.0-beta.0
. Please note the API is still subject to change before finishing, so use it at your own risk.What this release addresses mainly is:
Changes
Features
FormicaryContext.Provider
to avoid prop-drilling if desiredformRef
parameter omitted. If it's omitted, it will grab the formRef from the context instead.createKeyFn<FormModel>()
that will give a function that should autocomplete the paths forFormModel
, plus providing the correct type for each parameter.useErrors
will now return a type-safe dictionary of elements when using the paths overload (e.g.useErrors(form, 'name', 'age')
returns type{ name: Error, age: Error }
).useControl
anduseControlStateless
now don't require an initial value: The value will beundefined
by default.undefined
to reset them as empty.undefined
for type safety, exceptgetFormValue
to make matters simple. Be aware some values could beundefined
, although it should not happen if validation rules are set up and form is marked as valid.useFieldChanges(key, cb: (value, isInitial) => void)
that will call the call-back every time that the field changes its value (it will also call it with the initial value settingisInitial
to true)getInitialValue
andgetFormInitialValue
to get the initial value of a field or the form respectively.getAllErrors
to get a map with the fields that fail validation.isRequired()
isAtLeast(5)
)setValidatorMessages
or through an optional parameter when creating it.true
(value is valid) or a list of error messages.FormRef<FormModel>
is assignable to another variable with a subtype. This is particularly useful for subcomponents that only take a few properties of the whole model.Breaking
useInput
useInput
now requires the key. It will ignore thename
attribute of the element it gets attached to.useErrors
, etc.).useError(form, ['name', 'age'])
should becomeuseErrors(form, 'name', 'age')
.useError(form, v => [v.name, v.age]))
is alright, but won't have the new enhanced type safety.isRequired
,isNumber
andisInteger
must now be called to get the actual validator.isRequired
will now return the value is valid if the value is nil, otherwise it would not be possible to make e.g. an optional numeric field. To migrate, they can be composed withpipeValidators(isRequired(), {{validator}})
.false
now when the value is invalid. On that case they must return a list of errors messages.useWatch
renamed touseFieldValue
- Reason: it's more descriptive of what it's returning.useFormChanges
renamed touseFormValue
- Reason: it's more descriptive of what it's returning.useControlSubscription
renamed touseControlStateless
- Reason: the name was misleading, it's not creating a Subscription, but returning something that you can subscribe to without using a state.readField
renamed togetFieldValue
- Reason: More descriptive and consistent with thesetFieldValue
counterpart.readForm
renamed togetFormValue
- Reason: More descriptive and consistent with thesetFormValue
counterpart.FormRef
is now opaque. It can still be used to pass the formRef around, but its properties are private and can't be accessed. Use exported methods instead.TODO
-> By default, value is retained. Option to have it removed on unmount.
(Release open to feedback)
The text was updated successfully, but these errors were encountered: