Skip to content

[BUG]: Multiple editor instances #318

@leosilberg

Description

@leosilberg

Describe the bug
Does the editor filter out messages sent by other editor instances? I"m having trouble using multiple editors open on expo web , for example if I focus one editor the other editors state changes to focused as well. Also trying to set the height dynamically every editor is getting the height update but can't filter for that specific instance

On certain payloads there is message id but I think every payload should have a source property to filter messages from that editor

import { useEffect, useState } from "react";

import {
  CoreBridge,
  CoreEditorActionType,
  RichText,
  TenTapStartKit,
  useBridgeState,
  useEditorBridge,
  useEditorContent,
  type EditorMessage,
} from "@10play/tentap-editor";
import { View, type ViewProps } from "react-native";

import { cn } from "~/lib/utils";

import type { ToolbarItem } from "./Toolbar/actions";
import { Toolbar } from "./Toolbar/Toolbar";

type TextEditorProps = {
  initialContent?: string | null;
  onContentChange: (content: string | undefined) => void;
  editable?: boolean;
  toolbarHidden?: boolean;
  toolbarFocused?: boolean;
  toolbarItems?: ToolbarItem[];
  defaultHeight?: number;
  id?: string;
};

const customFont = `* {
    font-family: 'Protest Riot', sans-serif;
}`;

export default function TextEditor({
  initialContent,
  onContentChange,
  editable = true,
  toolbarHidden,
  toolbarFocused,
  toolbarItems,
  className,
  defaultHeight,
  id,
  ...props
}: TextEditorProps & ViewProps) {
  const [height, setHeight] = useState(defaultHeight);
  const editor = useEditorBridge({
    editable,
    autofocus: false,
    avoidIosKeyboard: true,
    ...(initialContent && { initialContent }),
    theme: {
      ...(defaultHeight && {
        webview: { height, borderColor: "red", borderWidth: 1, flex: 0 },
      }),
    },
    bridgeExtensions: [...TenTapStartKit, CoreBridge.configureCSS(customFont)],
    dynamicHeight: true,
  });

  const { isFocused, isBoldActive } = useBridgeState(editor);

  const content = useEditorContent(editor, {
    type: "html",
    debounceInterval: 500,
  });
  useEffect(() => {
    content && onContentChange(content);
  }, [content]);

  useEffect(() => {
    if (initialContent && content === "<p></p>") {
      editor.setContent(initialContent);
    }
  }, [initialContent]);

  return (
    <View className={cn("gap-1", className)} {...props}>
      <Toolbar
        editor={editor}
        hidden={toolbarHidden || (toolbarFocused && !isFocused)}
        items={toolbarItems}
      />
      <View className="flex-1 rounded-md border border-input px-2">
        <RichText
          editor={editor}
          onMessage={(event) => {
            const { data } = event.nativeEvent;
            // on expo-web we sometimes get react-dev messages that come in as objects - so we ignore these
            if (typeof data !== "string") return;
            // Parse the message sent from the editor
            const { type, payload } = JSON.parse(data) as EditorMessage;
            if (type === CoreEditorActionType.DocumentHeight) {
              console.log(`TextEditor: `, id, payload);
              setHeight(payload);
            }
          }}
        />
      </View>
    </View>
  );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions