페이스북 편집기 렉시콜을 해봤습니다!(2) 기능을 추가해 보았습니다!

페이스북(Meta)제 편집기 라이브러리Lexical에 대해 더 많은 조사 시간을 얻었기 때문에 2탄!
저번 기사에 나온 것처럼 역시 공식 게임과 같은 도구막대 UI는 없다.
프로그램 라이브러리는 편집기 기능만 있으니 각자 필요한 UI를 만들어야 하지 않을까 싶습니다.
sandbox 도구 모음의 코드 설정을 빌려 쓸 때 게임 라운드와 같은 것이 순조롭게 이동합니다!

노드 정보


Lexical 편집기에서 모든 요소는 Node 단위로 관리됩니다.
플러그인을 사용하여 h1, 링크 등 각종 요소를 사용하기 위해서는 우선 초기 설정에서 사용하고자 하는 유형의 노드를 지정해야 한다.
노드의 지정을 취소하면 처리는 통과할 수 있지만 기능이 없습니다.
import { HeadingNode, QuoteNode } from "@lexical/rich-text"
import { AutoLinkNode, LinkNode } from "@lexical/link"

const Editor: NextPage = () => {  
  // エディタ設定
  const initialConfig:any = {
    theme: ExampleTheme,
    onError,
    // 使いたいノードを指定する
    nodes: [
      HeadingNode,
      QuoteNode,
      AutoLinkNode,
      LinkNode
    ]
  };
  
  return (
    <>
      <LexicalComposer initialConfig={initialConfig}>
목록, 표와 코드 블록 등 각자 대응하는 노드를 준비했다.
혼자 기능을 만들고 싶을 때는 맞춤형 노드를 자제할 필요가 있는 것 같다.
따라서 사용자 정의 노드를 만들어서 공식 문서 의 텍스트 색을 바꾸고 기능을 추가하고 싶습니다!

노드 유형


렉시컬의 노드는 기본 5종(Root, Line Break, Element, Text, Decorator)이며, 이 가운데 맞춤형 노드를 위한 경우ElementNodeTextNodeDecoratorNode 3종이다.

ElementNode

ElementNode는 h1, p 등 블록급 요소와 링크 등 내연 요소에 사용된다.
블록 레벨과 내연 모두 정지!스트롱과 u 등에 대한 장식은 TextNode와 비슷한 것 같습니다.어떻게 구분해서 사용하죠?속성 값을 사용하시겠습니까?

TextNode

TextNode는 텍스트를 장식하는 노드입니다.formatmodestyle의 속성.
format는 장식의 종류로bold,italic,underline,strikethrough,code,subscript,superrscriept를 지정할 수 있습니다.
모드는 삭제에 관한 규칙인 것 같습니다.token 변경 불가, 삭제 시 한꺼번에 사라집니다.inert도 토큰과 마찬가지로 변경할 수 없지만 커서를 넣어도 부분을 선택할 수 없습니다.segment 단어 구분자로 삭제한 것 같습니다.
문서에 쓰여 있지 않지만 기본값은 한 글자 한 글자 삭제未指定입니다.누르면 되나요?
스타일은 CSS를 기술할 수 있습니다.

DecoratorNode

DecoratorNode 참고서를 읽어도 잘 모르겠어요.
자세한 거 알면 보고할게.

사용자 정의 노드 만들기


기본 규칙


노드 클래스 속성에는 __부터 시작하는 규칙이 있습니다.
export class ColoredNode extends TextNode {
  __color: string;
노드는 반드시 getTypeclone 이런 방법이 있어야 한다.
getType은 노드의 이름을 되돌려줍니다.매뉴얼에 따로 쓰여 있지는 않지만 편집에서 반드시 독특한 부분이 있어야 한다고 생각한다.
  static getType(): string {
    return 'colored';
  }
clone 쓰기 복제 노드 처리.편집기에서 복사하고 붙여넣을 때 작용하는 것 같습니다.
  static clone(node: ColoredNode): ColoredNode {
    return new ColoredNode(node.__text, node.__color, node.__key);
  }

구조자 정보


노드의 구조기는 기본적으로 constructor(text: string, key?: NodeKey)이다.
  constructor(text: string, key?: NodeKey): void {
    super(text, key);
  }
text는 텍스트 노드일 때 문자 자체를 가리키는 것 같다.ElementNode에서는 이 매개변수가 무엇에 사용되는지 모릅니다.HeadingNode를 초기화할 때h1 등의 문자열이 전달됩니다.key는 nulllable이고 HeadingNode가 초기화되었을 때 지정되지 않았습니다.클론에서만 사용할 수 있습니다.사용자 정의 노드에서 구조기의 매개 변수가 증가할 때 마지막에 놓을 것 같다key.

createDom 및 업데이트Dom

createDomupdateDom는 이 노드에 대응하는 DOM(HTML 요소)을 만드는 방법이다.
createDom은 DOM의 초기화 방법으로 되돌아갑니다HTMLElement.
  createDOM(): HTMLElement {
    const dom = document.createElement('p');
    return dom;
  }
업데이트DOM을 업데이트할 때createDom으로 재제작이 필요한지 답장true/false.
지금 어떤 자리에 있어야 될지 모르겠어요, 진짜.
  updateDOM(prevNode: ColoredNode, dom: HTMLElement): boolean {
    return false;
  }

텍스트 색상을 수정하기 위한 사용자 지정 노드 만들기


이번에는 TextNode를 확장하고 스타일 속성을 사용하여 CSS에서 텍스트 색을 지정할 수 있는 사용자 정의 노드를 만들고 싶습니다.

노드 설정


여기는 공식 홈페이지입니다.
ColoredNode.ts
export class ColoredNode extends TextNode {
  __color: string;

  constructor(text: string, color: string, key?: NodeKey): void {
    super(text, key);
    this.__color = color;
  }

  static getType(): string {
    return 'colored';
  }

  static clone(node: ColoredNode): ColoredNode {
    return new ColoredNode(node.__text, node.__color, node.__key);
  }

  createDOM(config: EditorConfig): HTMLElement {
    const element = super.createDOM(config);
    element.style.color = this.__color;
    return element;
  }

  updateDOM(
    prevNode: ColoredNode,
    dom: HTMLElement,
    config: EditorConfig,
  ): boolean {
    const isUpdated = super.updateDOM(prevNode, dom, config);
    if (prevNode.__color !== this.__color) {
      dom.style.color = this.__color;
    }
    return isUpdated;
  }
}

확장 도구 모음


먼저 도구 모음에서 색상 변경 버튼을 만듭니다.
이런 느낌.

ToolbarPlugin.tsx
<Divider />
<button
  onClick={()=>onColorSelect("black")}
  className="toolbar-item spaced">
</button>
<button
  onClick={()=>onColorSelect("red")}
  className="toolbar-item spaced">
</button>
<button
  onClick={()=>onColorSelect("green")}
  className="toolbar-item spaced">
</button>
<button
  onClick={()=>onColorSelect("blue")}
  className="toolbar-item spaced">
</button>
다음에 선택한 부분을 방금 만든 사용자 정의 노드ColoredNode의 처리로 바꿉니다.
ToolbarPlugin.tsx
  const onColorSelect = (color:string) => {
    editor.update(() => {
      const selection:any = $getSelection();
      if ($isRangeSelection(selection)) {
        const text = selection.getTextContent()
        const colored = new ColoredNode(text, color)
        selection.removeText()
        selection.insertNodes([colored])
      }
    })
  }
이렇게 하면 준비할 수 있어요!

다 했어!


실제로 이 기능을 사용해 보면 텍스트의 색깔이 잘 변한다!잘 됐다!

하지만 이렇게 하면 실용적이지 못하다.
이 방법으로 선택한 부분에 bold 같은 장식이 있으면 장식이 사라진다.
그리고 색깔을 바꾼 교재에 bold 등 장식을 덧붙여도 색깔이 돌아왔다.
잘 안되네.
더 좋은 방법이 있을 것 같아요.
그래도 상당히 노력했어요!
이번에는 이게 다야.
역시 공식 홈페이지의 참고가 충실하기 전에 일찍 손을 대는 게 좋을 것 같아요!
만지기가 힘들다!!!

좋은 웹페이지 즐겨찾기