fabian-hiller / modular-forms

The modular and type-safe form library for SolidJS, Qwik and Preact
https://modularforms.dev
MIT License
982 stars 53 forks source link

Using SolidJS ref for custom component #224

Closed robodna closed 2 months ago

robodna commented 2 months ago

I created a TextInput component based on the Playground's TextInput.

My TextInput component needs to reference an internal input tag it is composed of using SolidJS's ref attribute. I see <Field passes props to my custom component including a 'ref' property which I in-turn pass to my internal input tag. How do I avoid my component overriding the <Field prop's 'ref'?

Should my TextInput component use the internal input tag's id attribute to access it instead of using SolidJS's ref?

Note that it does seem to work even though Typescript is giving me the warning. Is it just Typescript complaining for nothing?

I get the warning: "Type 'null' is not assignable to type 'HTMLInputElement | ((el: HTMLInputElement) => void) | undefined'"

or

"'ref' is specified more than once, so this usage will be overwritten."

depending on if I place the ref attribute before or after the {...props}

robodna commented 2 months ago

UPDATE: I fixed this by using this type ref?:(element: HTMLInputElement) => void;

UPDATE2: Now when I try to use my TextInput custom component outside of a modularform <Field tag, I get typescript error:

"Type 'HTMLInputElement' is not assignable to type '(element: HTMLInputElement) => void'."

My current solution is to use Modularform's focus() instead of using myRef.focus(), but I"m using the TextInput component outside of ModularForms in some parts of my code and need to use 'ref'. I still wondering how ref can be used by a custom component like TextInput if the internals of that component need to reference the <input element using SolidJS's ref property. ( ModularForm hooks into it )

robodna commented 2 months ago

More details:

It appears that using a native <input ref={myRef}>element inside of a <Field does not work either so my custom element is unrelated to my issue.

Modularforms uses ref as a callback function to run before elements are attached to the DOM, and I need to use ref to access the element after it has been attached to the DOM. Does solidJS have a way to use ref as both a reference to the element and a callback?

fabian-hiller commented 2 months ago

Can you send me the code of your component?

robodna commented 2 months ago

I used the TextInput from the playground, and then just a plain <input inside the <Field element so no custom component at all. Typescript shows a warning on <input ref={myRef} since Modularform is passing ref as '(element: HTMLInputElement) => void' in props. Those 2 types are not compatible.

fabian-hiller commented 2 months ago

You can pass a custom function to ref:

<input ref={(element) => {
   // Your signal
  setRef(element);
  // Our ref function
  props.ref(element);
}} />
robodna commented 2 months ago

Ok great, that solves it.