Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor looses focus - gets blurred after pressing on Bold/Italic #132

Open
dr-zr opened this issue Feb 14, 2024 · 2 comments
Open

Editor looses focus - gets blurred after pressing on Bold/Italic #132

dr-zr opened this issue Feb 14, 2024 · 2 comments

Comments

@dr-zr
Copy link

dr-zr commented Feb 14, 2024

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 #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?

@ashirkhan94
Copy link

ashirkhan94 commented Feb 22, 2024

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?

@nhuthuynh195
Copy link

Death lib

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants