Closed18

Mantineの Rich Text Editor の調査

hajimismhajimism

ベースはTipTapなので色々仕込みたければそっち見てねって書いてある

@mantine/tiptap provides a UI for Tiptap. RichTextEditor component works with Editor instance of tiptap. This means that you have full control over the editor state and configuration with useEditor hook.

In other words, RichTextEditor component does not manage state for you, controls just execute operations on the Editor instance. If you want to implement something that is related to state or component value (e.g. controlled mode, value transforms to HTML/Markdown), you should look for documentation on tiptap.dev website.

hajimismhajimism

Placeholderはextientionなんだ

import Placeholder from '@tiptap/extension-placeholder';

hajimismhajimism

Placeholderがというか、だいたい全部extentionとして提供されているんだな
Lexicalといっしょだね

hajimismhajimism

Lexicalよりはるかに簡潔でいいね

  <RichTextEditor.Control
      onClick={() => editor?.commands.insertContent('⭐')}
      aria-label="Insert star emoji"
      title="Insert star emoji"
    >
      <IconStar stroke={1.5} size="1rem" />
    </RichTextEditor.Control>
hajimismhajimism

外側からtext state保存したいのだけれど!

hajimismhajimism
  onUpdate={({ editor }) => {
      setContent(editor.getHTML());
  }}

一旦これで...

hajimismhajimism

わりかし最低限がこれっぽい

import { Link, RichTextEditor } from "@mantine/tiptap";
import { useEditor, EditorOptions } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import { FC } from "react";

export const CustomEditor: FC<Partial<EditorOptions>> = (props) => {
  const editor = useEditor({
    ...props,
    extensions: [StarterKit, Link],
  });

  return (
    <RichTextEditor editor={editor}>
      <RichTextEditor.Content />
    </RichTextEditor>
  );
};

hajimismhajimism

画像アップロードボタンが欲しい

hajimismhajimism

FileButton, ActionIconでツールバーのボタン作成

        <FileButton onChange={onImageUpload} accept="image/png,image/jpeg">
          {(props) => (
            <Tooltip label="画像を挿入" openDelay={200}>
              <ActionIcon {...props} variant="default" size={26}>
                <IconPhoto size={16} stroke={1.5} />
              </ActionIcon>
            </Tooltip>
          )}
        </FileButton>
hajimismhajimism

URLを生成して画像挿入

const onImageUpload = useCallback(
    async (payload: File | null) => {
      if (payload) {
        const imageUrl = await getImageUrl(payload);
        editor?.chain().focus().setImage({ src: imageUrl }).run();
      }
    },
    [editor]
  );
hajimismhajimism

なんかふつうに好きだった
Mantine殆ど揃ってて好感持てる

このスクラップは2ヶ月前にクローズされました