페이스북 편집기 렉시콜을 해봤습니다!(2) 기능을 추가해 보았습니다!
22090 단어 JavaScriptReactlexicaltech
저번 기사에 나온 것처럼 역시 공식 게임과 같은 도구막대 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)이며, 이 가운데 맞춤형 노드를 위한 경우
ElementNode
TextNode
DecoratorNode
3종이다.ElementNode
ElementNode
는 h1, p 등 블록급 요소와 링크 등 내연 요소에 사용된다.블록 레벨과 내연 모두 정지!스트롱과 u 등에 대한 장식은 TextNode와 비슷한 것 같습니다.어떻게 구분해서 사용하죠?속성 값을 사용하시겠습니까?
TextNode
TextNode
는 텍스트를 장식하는 노드입니다.format
mode
style
의 속성.format는 장식의 종류로bold,italic,underline,strikethrough,code,subscript,superrscriept를 지정할 수 있습니다.
모드는 삭제에 관한 규칙인 것 같습니다.
token
변경 불가, 삭제 시 한꺼번에 사라집니다.inert
도 토큰과 마찬가지로 변경할 수 없지만 커서를 넣어도 부분을 선택할 수 없습니다.segment
단어 구분자로 삭제한 것 같습니다.문서에 쓰여 있지 않지만 기본값은 한 글자 한 글자 삭제
未指定
입니다.누르면 되나요?스타일은 CSS를 기술할 수 있습니다.
DecoratorNode
DecoratorNode
참고서를 읽어도 잘 모르겠어요.자세한 거 알면 보고할게.
사용자 정의 노드 만들기
기본 규칙
노드 클래스 속성에는
__
부터 시작하는 규칙이 있습니다.export class ColoredNode extends TextNode {
__color: string;
노드는 반드시 getType
과clone
이런 방법이 있어야 한다.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
createDom
와 updateDom
는 이 노드에 대응하는 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 등 장식을 덧붙여도 색깔이 돌아왔다.
잘 안되네.
더 좋은 방법이 있을 것 같아요.
그래도 상당히 노력했어요!
이번에는 이게 다야.
역시 공식 홈페이지의 참고가 충실하기 전에 일찍 손을 대는 게 좋을 것 같아요!
만지기가 힘들다!!!
Reference
이 문제에 관하여(페이스북 편집기 렉시콜을 해봤습니다!(2) 기능을 추가해 보았습니다!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/haruru/articles/12206977dc0c48텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)