uosis / laminar-web-components

Web Component definitions for Laminar
MIT License
36 stars 8 forks source link

Custom validation for Textfield #16

Open silizza opened 2 years ago

silizza commented 2 years ago

Hello! We can not find a way to set the custom validation for Textfield.

There is no validityTransform ReactiveProp in Textfield modifiers. There is validityTransform in textfield ref as the documentation says. But it seems like there is no way to change it. We are trying to make it as the material documentation shows

textfield.ref.validityTransform = ...

But the error is: Reassignment to val

raquo commented 2 years ago

Everything under .ref is native JS, and the interface to that comes from scala-js-dom. it's expected that scala-js-dom will not have this property because validityTransform is not standard HTML, it's specific to one material ui library.

Instead, this should work like any other field, something like _.validityTransform := ..., however in material.sc the validityTransform property is defined with an WebComponentFieldType.Any type, and in this project the setter properties for WebComponentFieldType.Any are not generated (see def buildReactiveProperties in builder.sc), because there is no Codec to properly encode Any as a JS value (see def propCodec in builder.sc).

You need to figure out what is the correct JS type for this property (seems to be a js.Function2 according to this?), make a codec for it, and create a ReactiveProp with that property's name and that codec. Codecs are explained in Scala-DOM-Types docs. Once you have this val validityTransform = new ReactiveProp("validityTransform", yourCodec), you can use it as usual, e.g. (_ => validityTransform := yourCallback).

Implementing that in this library would follow a similar principle. I would also suggest adding something like AnyAsIsCodec or JsAnyAsIsCodec for the Any-typed properties in this library, so that the default is lack of type safety, rather than inability to set the field at all.

PS when dealing with JS callbacks, remember that JS needs js.FunctionN, not scala.FunctionN callbacks.

raquo commented 2 years ago

Actually, sorry, I spoke too fast about .ref, I forgot that in the Web Component pattern we're mixing in our own element type in it. In that case you can't assign to it because that part is only for reading, whereas the ReactiveProp API is for writing (but that part is missing for this prop because it's typed as Any, and this library doesn't generate writable ReactiveProp-s for props that are typed as Any)