Open macintushar opened 2 months ago
@macintushar Without looking at the code of your widget we can't help you. I'm guessing that having the field rerender itself is the cause of the issue. React is really picky about how rerenders work especially around focus/blur behaviors and how callbacks work. I would focus on that first
Hey @heath-freenome, this is the code i'm using. It's from the docs.
const MyCustomWidget = (props: WidgetProps) => {
return (
<input
type='text'
className='custom'
value={props.value}
required={props.required}
onChange={(event) => props.onChange(event.target.value)}
/>
);
};
const widgets: RegistryWidgetsType = {
customWidget: MyCustomWidget,
};
https://github.com/user-attachments/assets/2d6cc555-c00c-40c1-ab3e-45d5cdaff260
Hey @heath-freenome, did you get some time to check out the issue? ^
Hey @heath-freenome, could you please check this out? ^
React can be picky about rendering when props change. The onChange is not a callback
function so that might be the issue. How does this work?:
const MyCustomWidget = (props: WidgetProps) => {
const { onChange, value, required } = props;
const handler = React.useCallback((event) => onChange(event.target.value));
return (
<input
type='text'
className='custom'
value={value}
required={required}
onChange={handler}
/>
);
};
const widgets: RegistryWidgetsType = {
customWidget: MyCustomWidget,
};
Hey @heath-freenome, I tested out the code you gave me with some minor changes to make it work properly (adding deps to useCallback), it seems to be working fine only if I use autoFocus as a prop. Please check out the two videos below to see what I mean:
Code v1:
const MyCustomWidget = (props: WidgetProps) => {
const { onChange, value, required } = props;
const handler = useCallback((event) => onChange(event.target.value), [onChange]);
return (
<>
<label>Custom Widget</label>
<input
type='text'
className='custom'
value={value}
required={required}
onChange={handler}
/>
</>
);
};
Output for v1
https://github.com/user-attachments/assets/1e89a658-cc94-4c35-9bc1-3e80ffeed601
Code for v2
const MyCustomWidget = (props: WidgetProps) => {
const { onChange, value, required } = props;
const handler = useCallback((event) => onChange(event.target.value), [onChange]);
return (
<>
<label>Custom Widget</label>
<input
type='text'
className='custom'
value={value}
required={required}
onChange={handler}
autoFocus
/>
</>
);
};
Output for v2
https://github.com/user-attachments/assets/ec441580-bcd6-4005-888b-eb5edb7b2d86
The diff between the two is only the autoFocus prop. It seems to loose focus anytime there is a change and the only reason it's working is because of the autoFocus. Is this expected behaviour?
Is there a way to get this to work without using the autoFocus prop?
@heath-freenome noticed another issue.
If i use a Textarea instead of an input, it results in some pretty weird behavior. It sends my cursor to the first character position every time i type. Please check out the video below
https://github.com/user-attachments/assets/43f4ebbc-ab7c-4ef5-b50e-bb0090dc4c87
Code:
const MyCustomWidget = (props: WidgetProps) => {
const { onChange, value, required } = props;
const handler = useCallback(
(event: { target: { value: any } }) => onChange(event.target.value),
[onChange],
);
return (
<>
<label>Custom Widget</label>
<textarea
className='custom'
value={value}
required={required}
onChange={handler}
autoFocus
/>
</>
);
};
@macintushar Everything you are describing lends me to believe that something in how you are wrapping the Form
is breaking the rules of React and causing the focus to be disrupted. I really do not have a lot of resources to help you debug this. Do you have a way to provide a reproducible test case using codesandbox.io?
@heath-freenome this is for something on the Multiwoven platform. It is open source but it's difficult for me to run this on a codesanbox. I'm not sure how i'd be able to show you this occurring without me getting on a call or something with you. You can run our code locally to try and emulate my steps if required.
I don't see any issues in the console w.r.t. React or me breaking the Rules of React with my code change. Please let me know how we can proceed further.
@heath-freenome All I see is this in the console which seems related to RJSF. The ID error was due to something I was testing but the other two still remain.
https://github.com/user-attachments/assets/32b1f62f-a552-4d34-a456-bad813fafdaf
@macintushar without a reproducible test case I'm not sure how to help you. Why do you need the custom widget anyway? From your demo it doesn't like the code does anything special. If you are just needing to inject an onChange handler or tweak props, then rather than build a whole component, you can wrap one of the OOTB chakra-ui
widgets using this documentation
@macintushar another wild guess is that you might be creating your widget inside of a component, which is re-created on each render. But like @heath-freenome said, without something like a CodeSandbox, we can't do much
Prerequisites
What theme are you using?
chakra-ui
Version
5.x
Current Behavior
I have added a custom widget. When I type in it in the form, it re-renders the field, which causes it to lose focus on the input field and moves the cursor's current position to the beginning of the input field. Note: If autofocus is not present in the input props, it completely loses focus and I can't type at all.
https://github.com/user-attachments/assets/aebf8d33-fb7a-4f80-ac65-e0707aeaf7e2
Expected Behavior
Ideally, it should work the same way the default input function works. It shouldn't lose focus and shouldn't rerender.
Steps To Reproduce
Environment
Anything else?
I followed the code written in the docs here https://rjsf-team.github.io/react-jsonschema-form/docs/advanced-customization/custom-widgets-fields