-
Notifications
You must be signed in to change notification settings - Fork 65
feat: form binder object models support #3816
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
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3816 +/- ##
==========================================
+ Coverage 86.27% 86.69% +0.41%
==========================================
Files 123 127 +4
Lines 8474 8764 +290
Branches 1301 1356 +55
==========================================
+ Hits 7311 7598 +287
- Misses 1140 1143 +3
Partials 23 23
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
"@vaadin/hilla-lit-form": "file:../../../ts/lit-form", | ||
"@vaadin/icon": "25.0.0-alpha21", | ||
"@vaadin/icons": "25.0.0-alpha21", | ||
"@vaadin/icon": "25.0.0-alpha20", |
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.
Maybe, this is wrong? 🤔
constructor(context: Element, Model: DetachedModelConstructor<M>, config?: BinderConfiguration<Value<M>>) { | ||
constructor( | ||
context: Element, | ||
modelClass: DetachedModelConstructor<M & AbstractModel> | (M & Model), |
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.
Shouldn't it also be ProvisionalModel
?
function getModelValidators<M extends ProvisionalModel>(model: M): ReadonlyArray<Validator<Value<M>>> { | ||
if (model instanceof AbstractModel) { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
return model[_validators]; | ||
} | ||
|
||
const validators: Array<Validator<Value<M>>> = | ||
model instanceof NumberModel ? [new Validators.IsNumber(model[$optional]) as Validator<Value<M>>] : []; | ||
|
||
for (const constraint of model[$constraints]) { | ||
const validator = getConstraintValidator<Value<M>>(constraint); | ||
validators.push(validator); | ||
} | ||
|
||
return validators; | ||
} | ||
|
||
function createEmptyValue<M extends ProvisionalModel>(model: M) { | ||
if (model instanceof AbstractModel) { | ||
return model.constructor.createEmptyValue(); | ||
} | ||
|
||
return model[$defaultValue]; | ||
} |
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 guess, it'd need some docs to describe that there are some checks for transition period. Or, maybe, I'd put it in another file with all the proxies.
while (model[_parent] instanceof AbstractModel) { | ||
name = `${String(model[_key])}${name ? `.${name}` : ''}`; | ||
model = model[_parent]; | ||
while (model[$owner] instanceof AbstractModel || model[$owner] === Model || model[$owner] instanceof Model) { |
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.
while (model[$owner] instanceof AbstractModel || model[$owner] === Model || model[$owner] instanceof Model) { | |
while (model[$owner] instanceof AbstractModel || model[$owner] instanceof Model) { |
You don't have to separately check if it is a Model
. instanceof
should do it for you.
this.initializeValue(); | ||
|
||
const key = this.model[_key]; | ||
const key = this.model[$key]; |
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 was confused seeing a $key
here. Probably, it requires a small description in a doc comment
export const $from = Symbol('from'); | ||
export const $to = Symbol('to'); | ||
|
||
export type ModelConverter<FM extends Model = Model, TM extends Model = Model> = { |
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'd also added an explicit reference to that StackOverflow question.
/** | ||
* The model of a `Record<string, V>` data, which is a special case | ||
* of `ObjectModel<Record<string, V>>` that is used to represent an arbitrary | ||
* object with string keys, such as a Java `Map<String, Object>`. |
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.
Why not the MapModel
then? 🤔
* | ||
* @param model - The model to get the value from. | ||
*/ | ||
export function getValue<T>(this: void, model: Model<T>): T { |
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.
Why not just a simple value
?
export function useForm<M extends AbstractModel>( | ||
Model: DetachedModelConstructor<M>, | ||
export function useForm<M extends ProvisionalModel>( | ||
modelClass: DetachedModelConstructor<M & AbstractModel> | (M & Model), |
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.
ProvisionModel
?
describe('@vaadin/hilla-react-form', () => { | ||
type UseFormSpy = sinon.SinonSpy<Parameters<typeof _useForm>, ReturnType<typeof _useForm>>; | ||
const useForm = sinon.spy(_useForm) as typeof _useForm; | ||
const useForm = sinon.spy(_useForm) as unknown as typeof _useForm; |
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.
Is it possible to remove cast to unknown
? It looks kinda broken
Fixes #3436