Diego Gaona
Diego Gaona

Reputation: 520

React-Admin RichTextInput with TipTap with Image extension not working

I want to insert on my RichTextInput component on React-Admin, but that is not working.
Even the example on the docs about using HorizontalRules are not working too. The button doesn't work, and by default ra-input-rich-text already have HorizontalRules extension, it works if I input "---" on the text.

What I want exactly is put the image url with a button on my toolbar and it would be inserted where my cursor is on the editor. But even manually putting the tag (as <img src="https://source.unsplash.com/8xznAGy4HcY/800x400" />), the image is not rendered.

This is my current RichTextInput component:

import {
    DefaultEditorOptions,
    RichTextInput,
    RichTextInputToolbar,
    LevelSelect,
    FormatButtons,
    AlignmentButtons,
    ListButtons,
    LinkButtons,
    QuoteButtons,
    ClearButtons
} from 'ra-input-rich-text';
import { ToggleButton } from '@mui/material';
import { useEditor } from '@tiptap/react'
import Image from '@tiptap/extension-image'
import Remove from '@mui/icons-material/Remove';

import { Box } from '@mui/material';

export const MyRichTextInput = ({ size, ...props }) => {
    const editor = useEditor(MyEditorOptions)
    return (
        <RichTextInput
            editorOptions={MyEditorOptions}
            toolbar={
                <RichTextInputToolbar>
                    <Box sx={{
                        display: 'flex',
                        flexDirection: 'row',
                        alignItems: 'center',
                        flexWrap: 'wrap',
                    }} >
                        <LevelSelect size={size} />
                        <FormatButtons size={size} />
                        <AlignmentButtons size={size} />
                        <ListButtons size={size} />
                        <LinkButtons size={size} />
                        <QuoteButtons size={size} />
                        <ClearButtons size={size} />
                    </Box>
                    <ToggleButton
                    value="Image"
                    aria-label="Add an image"
                    title="Add an image"
                    onClick={() => editor.chain().focus().setImage({ src: url }).run()}
                    selected={editor && editor.isActive('image')}
                >
                    <Remove fontSize="inherit" />
                </ToggleButton>
                </RichTextInputToolbar>
            }
            label="Body"
            source="body"
            {...props}
        />
    )
}

export const MyEditorOptions = {
    ...DefaultEditorOptions,
    extensions: [
        ...DefaultEditorOptions.extensions,
        Image
        
    ],
};

What I need to put an image and this be rendered here and in the "RichTextField"? And how to create a button to ask me the url and insert the image on the editor?

Upvotes: 0

Views: 1729

Answers (2)

umeboshi1112
umeboshi1112

Reputation: 1

Tiptap edits input by manipulating the editor object held by the target RichTextInput component. You can access the editor object in the context of the target RichTextInput component by using useTiptapEditor(). So you need to create another button or toolbar component and then load it.

MyImageButton component

import * as React from 'react';
import { useTranslate } from 'ra-core';
import { useTiptapEditor } from 'ra-input-rich-text';
import { ToggleButton } from '@mui/material';
import ImageIcon from '@mui/icons-material/Image';

export const MyImageButton = (props) => {
    const translate = useTranslate();
    const editor = useTiptapEditor();

    const label = translate('ra.tiptap.image', { _: 'Image' });

    const addImage = React.useCallback(() => {
        const url = window.prompt(
            translate('ra.tiptap.image_dialog', { _: 'Image URL' })
        );

        if (url) {
            editor.chain().focus().setImage({ src: url }).run();
        }
    }, [editor, translate]);

    return editor ? (
        <ToggleButton
            aria-label={label}
            title={label}
            {...props}
            disabled={!editor?.isEditable}
            value="image"
            onClick={addImage}
        >
            <ImageIcon fontSize="inherit" />
        </ToggleButton>
    ) : null;
};

then load it in RichTextInput

import {
    DefaultEditorOptions,
    RichTextInput,
    RichTextInputToolbar,
    LevelSelect,
    FormatButtons,
    AlignmentButtons,
    ListButtons,
    LinkButtons,
    QuoteButtons,
    ClearButtons,
} from 'ra-input-rich-text';
import HorizontalRule from '@tiptap/extension-horizontal-rule';
import Image from '@tiptap/extension-image'
import { MyImageButton } from './CustomEditorInputImageButton';

export const MyRichTextInput = ({ size, ...props }) => {
    return (
        <RichTextInput
            toolbar={
                <RichTextInputToolbar>
                    <LevelSelect size={size} />
                    <FormatButtons size={size} />
                    <AlignmentButtons size={size} />
                    <ListButtons size={size} />
                    <LinkButtons size={size} />
                    <QuoteButtons size={size} />
                    <ClearButtons size={size} />
                    <MyImageButton />
                </RichTextInputToolbar>
            }
            label="Body"
            source="body"
            {...props}
        />
    );
}

export const MyEditorOptions = {
    ...DefaultEditorOptions,
    extensions: [
        ...DefaultEditorOptions.extensions,
        Image,
        HorizontalRule,
    ],
};

Upvotes: 0

Diego Gaona
Diego Gaona

Reputation: 520

They updated React Admin (I was using 4.15) to 4.20 and now it supports Image and horizontal line. And now the toolbar is responsive.

Mor info in the issue: https://github.com/marmelab/react-admin/issues/7806

Upvotes: 1

Related Questions