S
SolidJS•2w ago
Paul

onChange + onKeyDown same as react?

I have a component:
<For each={_value()}>
{(char, index) => (
<Input
onChange={(event: Event) => console.log('onChange', index())}
onKeyDown={(event: KeyboardEvent) => console.log('onKeyDown', index())}
<For each={_value()}>
{(char, index) => (
<Input
onChange={(event: Event) => console.log('onChange', index())}
onKeyDown={(event: KeyboardEvent) => console.log('onKeyDown', index())}
The React version shows: onKeyDown onChange When an input is changed. Solid hover only shows: onKeyDown and then with a blur, it shows the onChange. Is the Solid different to React for this, or do I need to use different mechanisms? See videos. Thanks!
16 Replies
REEEEE
REEEEE•2w ago
You would need to use onInput
Paul
PaulOP•2w ago
Awesome that was it. Thanks! It doesn't move to the next input. So maybe something else. Going to debug...
Paul
PaulOP•2w ago
const [inputsRef, setInputsRef] = createSignal<Array<HTMLInputElement | null>>(
Array(local.length || 0).fill(null)
);

<Input
ref={(el: HTMLInputElement) => {
const i = index();
setInputsRef(prev => {
const next = [...prev];
next[i] = el;
return next;
});
}}
const [inputsRef, setInputsRef] = createSignal<Array<HTMLInputElement | null>>(
Array(local.length || 0).fill(null)
);

<Input
ref={(el: HTMLInputElement) => {
const i = index();
setInputsRef(prev => {
const next = [...prev];
next[i] = el;
return next;
});
}}
@REEEEE would you know a better way of assigning the ref? The end result should be (see image). But instead I'm getting [null, null, null, null].
No description
bigmistqke
bigmistqke•2w ago
Are you passing the ref inside the Input-component to the input element? Code looks good Only thing I see is that it will not change the length of the inputsRef-array if local.length becomes smaller
REEEEE
REEEEE•2w ago
I could be wrong but I think that method of using Array and fill, causes issues Although in this case it probably shouldn't 🤔
bigmistqke
bigmistqke•2w ago
Right? With the way how it is spread and the index set
REEEEE
REEEEE•2w ago
Yeah that's what I'm thinking. Could be when/where it's logged?
Paul
PaulOP•2w ago
In the input component:
<Box ref={ref}
<Box ref={ref}
And in the box component it also gets assigned to the element. I'm pretty sure it's working as I'm now 80/106 components correctly ported. Although I think I will make a poc to ensure it is.
bigmistqke
bigmistqke•2w ago
Shouldn't it be props.ref? Are you destructuring somewhere?
Paul
PaulOP•2w ago
It's using a polymorphic factory to get the ref:
export const Input = polymorphicFactory<InputFactory>((_props, ref) => {
export const Input = polymorphicFactory<InputFactory>((_props, ref) => {
bigmistqke
bigmistqke•2w ago
Mmm... can you show me how that works?
Paul
PaulOP•2w ago
This is the code: https://raw.githubusercontent.com/paulm17/mantinesolid/refs/heads/main/packages/%40mantine/core/src/core/factory/polymorphic-factory.tsx As to how it works. Way above my paygrade 😅 I had to use AI to get it over the line.
bigmistqke
bigmistqke•2w ago
What problem is this code solving? Mimicking React.ForwardRef? Can you try to do props.ref instead of ref? Throughout all the layers?
Paul
PaulOP•2w ago
Pretty much yes. For this and the factory.tsx it's assigning both the props and the refs to the component. There is another layer above which coalesces the theme and other data to be available to the component. Sure, it might be tomorrow now as I have ran out of time. I do appreciate your input. (pardon the pun)
bigmistqke
bigmistqke•2w ago
Ye my bet is here is where the problem is. Iirc in react 19 they r gonna get rid of the ForwardRef and do it like solid, so maybe it's worth to already change the abstraction to have it more solid-like. Ye, ur doing this type-assertion so it all looks good type-wise, but I think there is some proper hallucination going on over here .
Paul
PaulOP•2w ago
I can confirm that refs work just fine actually.
import { Anchor, Box, Breadcrumbs, Button, Input, Stack } from "@mantine/core";
import { createSignal } from "solid-js";

export default function StoryComponent() {
const [ref, setRef] = createSignal<HTMLDivElement>();
const [ref2, setRef2] = createSignal<HTMLDivElement>();
const [ref3, setRef3] = createSignal<HTMLInputElement>();

const handleClick = () => {
console.log(ref()?.getBoundingClientRect());
}

const handleClick2 = () => {
console.log(ref2()?.getBoundingClientRect());
}

const handleClick3 = () => {
console.log(ref3()?.value);
}

return (
<Stack>
<Box style={{width: "200px"}}>
<Button size="compact-xs" fullWidth ref={setRef} onClick={handleClick}>click Me for Button</Button>
</Box>
<Button onClick={handleClick2}>click Me for BreadCrumbs</Button>
<Button onClick={handleClick3}>click Me for Input</Button>
<Breadcrumbs>
<Anchor ref={setRef2}>Link 1</Anchor>
<Anchor>Link 2</Anchor>
<Anchor>Link 3</Anchor>
</Breadcrumbs>
<Input ref={setRef3} value="frog" />
</Stack>
)
}
import { Anchor, Box, Breadcrumbs, Button, Input, Stack } from "@mantine/core";
import { createSignal } from "solid-js";

export default function StoryComponent() {
const [ref, setRef] = createSignal<HTMLDivElement>();
const [ref2, setRef2] = createSignal<HTMLDivElement>();
const [ref3, setRef3] = createSignal<HTMLInputElement>();

const handleClick = () => {
console.log(ref()?.getBoundingClientRect());
}

const handleClick2 = () => {
console.log(ref2()?.getBoundingClientRect());
}

const handleClick3 = () => {
console.log(ref3()?.value);
}

return (
<Stack>
<Box style={{width: "200px"}}>
<Button size="compact-xs" fullWidth ref={setRef} onClick={handleClick}>click Me for Button</Button>
</Box>
<Button onClick={handleClick2}>click Me for BreadCrumbs</Button>
<Button onClick={handleClick3}>click Me for Input</Button>
<Breadcrumbs>
<Anchor ref={setRef2}>Link 1</Anchor>
<Anchor>Link 2</Anchor>
<Anchor>Link 3</Anchor>
</Breadcrumbs>
<Input ref={setRef3} value="frog" />
</Stack>
)
}
Isolated where it breaks: export const Input = polymorphicFactory<InputFactory>((_props, ref) => { ref={ref} changed to: ref={(props as any).ref} now works. I resolved the issue in the polymorphic factory. Can't match the typings. AI quickly folds 😂 @bigmistqke @REEEEE thanks for the help!

Did you find this page helpful?