-
-
Notifications
You must be signed in to change notification settings - Fork 20
feat: granular field composables #205
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: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 58cfafe The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
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 |
commit: |
@logaretm Say in the Would we use So, we would do something like this? const { errorMessage } = useFieldStateInjection()!
const { inputEl, inputProps } = useTextControl({ name }) |
You can do that if you want to, as |
95d0361
to
1342a64
Compare
@genu Thinking about combining the EDIT: I just pushed this, feels much cleaner and will make migrating other fields easier. |
Just pulled the latest. It definitely feels more elegant 🚀 |
3a85049
to
6705570
Compare
@logaretm Should we export the For example, in NuxtUi, a const { labelProps } = useFormField(...) <span :id="`${labelProps?.id}-hint`">...</span> <div :id="`${labelProps?.id}-help`">...</div> |
): ExposedField<TValue> & TReturns { | ||
const exposedField = { | ||
return { | ||
_field: markRaw(field), |
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.
@logaretm Do we need to expose _field
to the user?
I'm thinking that it can be confusing as most of the _field
properties are already exposed.
Would there be any benefit to be able to extract a property from both?
const { isTouched, _field } = useTextField({ label: 'label' })
const v1 = isTouched.value
const v2 = _field.isTouched.value
return exposeField( | ||
{ | ||
/** | ||
* The id of the control element. | ||
*/ | ||
controlId, | ||
|
||
/** | ||
* Props for the control element/group. | ||
*/ | ||
controlProps, | ||
/** | ||
* Validates the field. | ||
*/ | ||
validate: updateValidity, | ||
}, | ||
field, |
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.
@logaretm Should there be distinction between useFormField
, use__Control
, and use__Field
when we expose properties?
For example, at the moment, we can do:
const { inputEl, inputProps, labelProps } = useTextControl(...)
but a Text control, technically, wouldn't ever have a label, as it would be a lower level
control.
12abf4d
to
8d838e0
Compare
/** | ||
* The id of the control element. | ||
*/ | ||
controlId, | ||
|
||
/** | ||
* Props for the control element/group. | ||
*/ | ||
controlProps, | ||
/** | ||
* Validates the field. | ||
*/ | ||
validate: updateValidity, | ||
|
||
/** | ||
* The field state. | ||
*/ | ||
field, |
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.
I believe we talked about exposing controlEl
here.
48ac966
to
e732324
Compare
* chore: register with devtools in `useFormField` * refactor: update registerField to accept Ref type and use * feat: introduce BuiltInControlTypes for consistent control type * chore: fix typo * fix: types and type reactivity in devtools --------- Co-authored-by: Abdelrahman Awad <[email protected]>
What
This PR breaks up the field composables into smaller, more granular composables for use in UI libraries that follow the field and control pattern.
How
A form-field can be defined as:
This PR models this relationship by breaking a field composable into:
use___Control
: Handles all the logic related to the control (e.g: Interactions and props).useFormField
: Handles the state and labeling/descriptions/error message relationships with the control.Usage
There are a couple of configurations to put all three composables together. A same-component approach and injectable approach.
Let's take a look at a
TextField
implementation.Same component approach
Similar to how Formwerk will expose the full field composables, where all three are composed in the same composable. In this case, the labeling is colocated with the control.
Injection Approach
This suits UI libraries more as they usually maintain their separate
FormField
component.At a
FormField
component implementation:Then, at the control level, like an
<Input >
component, you only need to call theuseTextControl
composable:Under the hood the control composable will find the form field context and hook itself up.
Misc
supports genu/ui#1