Skip to content

Commit

Permalink
Merge pull request #2520 from NDLANO/fix/forward-ref-plain-text-editor
Browse files Browse the repository at this point in the history
fix: properly forward ref to PlainTextEditor
  • Loading branch information
Jonas-C authored Oct 17, 2024
2 parents bed535b + 19c6ddd commit ed4ca07
Showing 1 changed file with 54 additions and 50 deletions.
104 changes: 54 additions & 50 deletions src/components/SlateEditor/PlainTextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { FormikHandlers, useFormikContext } from "formik";
import { useEffect, useCallback, useState } from "react";
import { useEffect, useCallback, useState, forwardRef, Ref } from "react";
import { createEditor, Descendant } from "slate";
import { withHistory } from "slate-history";
import { Slate, Editable, ReactEditor, withReact } from "slate-react";
Expand Down Expand Up @@ -50,59 +50,63 @@ interface Props extends Omit<EditableProps & JsxStyleProps, "value"> {
plugins?: SlatePlugin[];
}

const PlainTextEditor = ({ onChange, value, id, submitted, className, placeholder, plugins, ...rest }: Props) => {
const [editor] = useState(() => withPlugins(withHistory(withReact(createEditor())), plugins));
const props = useFormControl({ id, readOnly: submitted, ...rest });
const PlainTextEditor = forwardRef<HTMLTextAreaElement, Props>(
({ onChange, value, id, submitted, className, placeholder, plugins, ...rest }, ref) => {
const [editor] = useState(() => withPlugins(withHistory(withReact(createEditor())), plugins));
const props = useFormControl({ id, readOnly: submitted, ...rest });

const onBlur = useCallback(() => {
ReactEditor.deselect(editor);
}, [editor]);
const onBlur = useCallback(() => {
ReactEditor.deselect(editor);
}, [editor]);

const onSlateChange = useCallback(
(val: Descendant[]) =>
onChange({
target: {
name: id,
value: val,
type: "SlateEditorValue",
},
}),
[id, onChange],
);
const onSlateChange = useCallback(
(val: Descendant[]) =>
onChange({
target: {
name: id,
value: val,
type: "SlateEditorValue",
},
}),
[id, onChange],
);

const { status, setStatus } = useFormikContext<ArticleFormType>();
const { status, setStatus } = useFormikContext<ArticleFormType>();

useEffect(() => {
if (status?.status === "revertVersion") {
ReactEditor.deselect(editor);
editor.children = value;
setStatus((prevStatus: FormikStatus) => ({
...prevStatus,
status: undefined,
}));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [status]);
useEffect(() => {
if (status?.status === "revertVersion") {
ReactEditor.deselect(editor);
editor.children = value;
setStatus((prevStatus: FormikStatus) => ({
...prevStatus,
status: undefined,
}));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [status]);

return (
<Slate editor={editor} initialValue={value} onChange={onSlateChange}>
<StyledEditable
// Forcing slate field to be deselected before selecting new field.
// Fixes a problem where slate field is not properly focused on click.
onBlur={onBlur}
// @ts-ignore is-hotkey and editor.onKeyDown does not have matching types
onKeyDown={editor.onKeyDown}
className={className}
placeholder={placeholder}
renderPlaceholder={({ children, attributes }) => {
// Remove inline styling to be able to apply styling from StyledPlaceholder
const { style, ...remainingAttributes } = attributes;
return <StyledPlaceholder {...remainingAttributes}>{children}</StyledPlaceholder>;
}}
{...props}
/>
</Slate>
);
};
return (
<Slate editor={editor} initialValue={value} onChange={onSlateChange}>
<StyledEditable
// Forcing slate field to be deselected before selecting new field.
// Fixes a problem where slate field is not properly focused on click.
onBlur={onBlur}
// @ts-ignore is-hotkey and editor.onKeyDown does not have matching types
onKeyDown={editor.onKeyDown}
className={className}
placeholder={placeholder}
renderPlaceholder={({ children, attributes }) => {
// Remove inline styling to be able to apply styling from StyledPlaceholder
const { style, ...remainingAttributes } = attributes;
return <StyledPlaceholder {...remainingAttributes}>{children}</StyledPlaceholder>;
}}
{...props}
// Weird typescript error. Let's just ignore it
ref={ref as Ref<never>}
/>
</Slate>
);
},
);

export default PlainTextEditor;

0 comments on commit ed4ca07

Please sign in to comment.