I am building a custom SlateJS editor to use in a form, utilising the react-hook-form <Controller> component.
This mostly works, but two things (I suspect are related) do not:
- Focus activation via react-hook-form initialFocus, or setFocus from the form context hook
- Resetting the form value via the form hook reset() method
This is the controller that hooks up the react-hook-form component:
const CustomEditorController = () => {
const { control } = useFormContext()
return (
<Controller
name='editor'
control={control}
render={({ field }) => (
<CustomEditor
ref={(el: any} => field.ref(el)}
name={field.name}
value={field.value}
onValueChange={field.onChange}
/>
)}
/>
)
}
The custom editor component looks like this:
const CustomEditor = React.forwardRef<any, TextEditorProps>(
(name, value, onValueChange }, ref) => {
const editor: MyEditor = useMemo(() => (withHistory(withReact(createEditor()))), [])
useImperativeHandle(ref, () => ({
focus: () => {
console.log("set focus via imperative handle");
ReactEditor.focus(editor);
},
}));
return (
<Slate
editor={editor}
initialValue={value}
onValueChange={onValueChange}
>
<Editable
name={name}
/>
</Slate>
)
}
)
With other components I have integrated with react-hook-forms, like a custom text input, you can use this ref property, and this all works perfectly - it sets focus at the right time, and resets the input value when reset() is invoked via the form hook.
But with this SlateJS editor, I can not see how I can use this ref, or otherwise how to propagate the focus/reset calls from the form to the editor.
I have found there is a ReactEditor.focus(editor) SlateJS API that can be used, but how to use that in this scenario, and what about reset() as well?
In the
CustomEditorcode, explicitly setting focus viauseImperativeHandlewas the missing piece:Fully working sandbox here https://codesandbox.io/p/sandbox/vigorous-gould-x3nwxg.