Editor looses focus - gets blurred after pressing on Bold/Italic
I'm experiencing issues with the bold and italic toolbar options.
The issue is that the editor input gets blurred after a user presses on the toolbar buttons.
The issues most likely occur because the selection-change fires and has range: null
I've looked at similar issues and found this https://github.com/imnapo/react-native-cn-quill/issues/93 , but nobody answered 😕
I've used the handleSelectionChange function from the examples folder. When pressing bold/italic I get "Cursor not in the editor"
const handleSelectionChange = async (data: SelectionChangeData) => {
const { range } = data;
if (range) {
if (range.length === 0) {
console.log("User cursor is on", range.index);
} else {
const text = await editor.current?.getText(
range.index,
range.length,
);
console.log("User has highlighted", text);
}
} else {
console.log("Cursor not in the editor");
}
};
Code:
const maximizeIcon = require("@resources/assets/icons/maximize-solid.png");
const minimizeIcon = require("@resources/assets/icons/minimize-solid.png");
const baseToolbarOptions: NonNullable<
NonNullable<EditorProps["quill"]>["modules"]
>["toolbar"] = [
["bold", "italic"],
[{ list: "ordered" }, { list: "bullet" }],
[{ indent: "-1" }, { indent: "+1" }],
];
const toolbarResizeActions = ["maximize", "minimize"];
const toolbarResizeIcons = {
maximize: maximizeIcon,
minimize: minimizeIcon,
};
const webViewProps: EditorProps["webview"] = {
scrollEnabled: true, // enable scrolling in the web view
nestedScrollEnabled: true, // enable nested scrolling
};
interface Props extends EditorProps {
readonly enabled: boolean;
readonly placeholder?: string;
readonly allowResize?: boolean;
}
export const TextEditor = forwardRef<QuillEditor, Props>(
function TextEditor(props, _ref) {
const styles = useStyles();
const { colors, dark } = useTheme();
const { height } = useWindowDimensions();
useImagePasteHandler();
const [containerSize, setContainerSize] = useState<
DimensionValue | undefined
>();
const editor = useTextEditorRefStore((state) => state.ref);
//#region Toolbar
const toolbarOptions = useMemo(() => {
if (!props.allowResize) {
return baseToolbarOptions;
}
return baseToolbarOptions.concat([
[containerSize ? "minimize" : "maximize"],
]);
}, [containerSize, props.allowResize]);
const toolbarStyles = useMemo((): CustomStyles => {
return {
toolbar: {
provider: (props) => ({
...props,
borderColor: colors.backgroundHighlight,
}),
root: (props) => ({
...props,
backgroundColor: colors.backgroundHighlight,
}),
},
};
}, [colors.backgroundHighlight]);
//#endregion
//#region Editor
const quill = useMemo((): EditorProps["quill"] => {
return {
modules: undefined,
placeholder: props.placeholder ?? "",
theme: "bubble",
};
}, [props.placeholder]);
const theme = useMemo((): EditorProps["theme"] => {
return {
placeholder: colors.textMute,
background: colors.backgroundHighlight,
color: colors.text,
};
}, [colors.backgroundHighlight, colors.text, colors.textMute]);
const customStyles = useMemo((): EditorProps["customStyles"] => {
return [
`.ql-stroke { stroke: ${colors.text} !important; }`,
`.ql-fill {fill: ${colors.text} !important;}`,
`.ql-active .ql-stroke { stroke: ${colors.primary} !important;}`,
`.ql-active .ql-fill { stroke: ${colors.primary} !important;}`,
".ql-tooltip { visibility: hidden !important } ",
];
}, [colors.primary, colors.text]);
//#endregion
const handleSelectionChange = async (data: SelectionChangeData) => {
const { range } = data;
if (range) {
if (range.length === 0) {
console.log("User cursor is on", range.index);
} else {
const text = await editor.current?.getText(
range.index,
range.length,
);
console.log("User has highlighted", text);
}
} else {
console.log("Cursor not in the editor");
}
};
const handleToolbarActions = (name: string) => {
const editorState = useTextEditorRefStore.getState();
switch (name) {
case "maximize":
setContainerSize(height);
editorState.isMaximized = true;
break;
default:
editorState.isMaximized = false;
setContainerSize(undefined);
break;
}
};
useEffect(
function updateWritePermission() {
useTextEditorRefStore
.getState()
.ref.current?.enable(props.enabled);
},
[props.enabled],
);
useEffect(
function resetText() {
if (props.initialHtml) {
return;
}
useTextEditorRefStore.getState().ref.current?.setText("");
},
[props.initialHtml],
);
return (
<View style={dss.flex1}>
<QuillToolbar
editor={editor}
options={toolbarOptions}
styles={toolbarStyles}
theme={dark ? "dark" : "light"}
custom={{
handler: handleToolbarActions,
actions: props.allowResize
? toolbarResizeActions
: undefined,
icons: props.allowResize
? toolbarResizeIcons
: undefined,
}}
/>
<QuillEditor
style={[styles.editor, props.style]}
quill={quill}
theme={theme}
onSelectionChange={handleSelectionChange}
ref={editor}
{...props}
customStyles={customStyles}
webview={webViewProps}
/>
</View>
);
},
);
const useStyles = createStyleSheetHook(() => {
return StyleSheet.create({
editor: {
flexGrow: 1,
flex: 1,
padding: 0,
},
});
});
Video: https://github.com/imnapo/react-native-cn-quill/assets/155077894/8004ea60-a87c-4844-a095-c2b74761422e
@imnapo I apologize for tagging, but as an owner of this repository, do you have any idea how to solve this issue?
Hi @dr-zr , Facing the same Issue in Android version 10 and lower But for me, it works in Android version 12. Any Update on this?