swordev / suid

A port of Material-UI (MUI) built with SolidJS.
https://suid.io
MIT License
676 stars 48 forks source link

How to properly use `inputRef` with TypeScript? #163

Closed NinoM4ster closed 1 year ago

NinoM4ster commented 1 year ago

Hello, I've been struggling to find a way to utilize the inputRef parameter on TextInput components.

My use-case is needing to call .focus() on the input field inside onMount() (because autofocus doesn't work when navigating), but the reference passed via ref returns a <div>, not an <input>, which forces me to do this:

(usernameRef?.firstChild as HTMLInputElement).focus();

(...which somehow works even though firstChild is a <label>, not an <input>)

It would be great if usernameRef?.focus() just worked but it doesn't, so I'm left with no other choice but to use the code above.

I've tried using inputRef in many different ways but nothing seems to work because it takes a Ref<HTMLInputElement> type which I can't do anything with and I was not able to find any documentation or examples on how to use it.

juanrgm commented 1 year ago

With SolidJS you only can use the ref property, other variants as inputRef are working but you must use a callback.

<TextField inputRef={element => setTimeout(() => element.focus())} />

or

import createRef from "@suid/system/createRef";

let element: HTMLInputElement

onMount(() => element.focus());

<TextField inputRef={e => element = e} />

or

import createRef from "@suid/system/createRef";

const element = createRef();

onMount(() => element.ref.focus());

<TextField inputRef={element} />

The autoFocus property doesn't work? https://stackblitz.com/edit/angular-lzcp1h?file=src%2FApp.tsx (you must open the URL of the embedded browser in a new tab).

NinoM4ster commented 1 year ago

The autoFocus property doesn't work?

During my testing, not consistently. If I refreshed the page it would focus but if I navigated to the page (via solid router's useNavigate()) it just wouldn't.

I've poorly replicated an approximation of my current code structure and surprisingly it does work in the demo, but only the first time. If you navigate back and then forth a second time it doesn't focus.

https://stackblitz.com/edit/angular-lzcp1h-yvbam4?file=src/Home.tsx

Also, thank you so much for the inputRef explanation. I did notice Ref was a function but didn't realize it was supposed to be used as a callback. It all makes sense now.

I think this issue can be closed now since it was originally about inputRef.

Edit: Just tested it again locally and the same behavior applies. autoFocus works only the first time (refresh at /, navigate to /page works; go back, go forth doesn't).

juanrgm commented 1 year ago

The code also fails with a native input element (<input type="text" autofocus />), so it seems to be a SolidJS issue.

https://stackblitz.com/edit/angular-lzcp1h-dty8wb?file=src/Page.tsx

Even so, I will track this in case a global solution could be applied.