@pop-ui/editor-core
v0.0.1
Published
Slate 에디터 AST의 **순수 타입 정의**와 **플랫폼 무관 유틸리티** 패키지.
Readme
@pop-ui/editor-core
Slate 에디터 AST의 순수 타입 정의와 플랫폼 무관 유틸리티 패키지.
React, DOM 등 런타임 의존성이 없으므로 React Native readonly 렌더러 등 어디서든 타입과 유틸만 가져다 쓸 수 있다.
목차
설치
npm install @pop-ui/editor-core
# peer
npm install slate| peer | version |
|------|---------|
| slate | ^0.120.0 |
타입
블록 엘리먼트 — TEditorElement
모든 블록 타입의 유니온. 베이스 인터페이스(IBaseElement → IBaseTextElement / IBaseListElement)를 상속한다.
IBaseElement { type }
├─ IBaseTextElement { children: ICustomText[] }
└─ IBaseListElement { children: ILiElement[] }| 타입 | 인터페이스 | 베이스 | 주요 필드 |
|------|-----------|--------|----------|
| p | IPElement | IBaseTextElement | |
| h1 h2 h3 | IH1Element IH2Element IH3Element | IBaseTextElement | |
| ul | IUlElement | IBaseListElement | |
| ol | IOlElement | IBaseListElement | |
| li | ILiElement | IBaseTextElement | |
| img | IImgElement | IBaseTextElement | src, alt?, caption? |
| a | IAElement | IBaseTextElement | href |
| hr | IHrElement | IBaseTextElement | variant?: 'default' \| 'short' |
| blockquote | IBlockquoteElement | IBaseTextElement | variant?: 'default' \| 'solid' |
| spot | ISpotElement | IBaseTextElement | spotId, spotName?, spotAddress?, spotThumbnail? |
인라인 텍스트 — ICustomText
interface ICustomText {
text: string;
bold?: boolean;
italic?: boolean;
underline?: boolean;
color?: string; // hex
hashtag?: boolean; // decorator가 설정, 저장 X
href?: string; // 인라인 링크
}블록 활성화 — IBlocksConfig
어떤 블록을 활성화할지 제어한다. p는 항상 활성.
interface IBlocksConfig {
heading?: boolean | THeadingLevel[]; // 'h1' | 'h2' | 'h3'
list?: boolean | TListType[]; // 'ul' | 'ol'
blockquote?: boolean | TBlockquoteVariant[];
hr?: boolean | THrVariant[];
image?: boolean;
spot?: boolean;
link?: boolean;
}포맷 / 도구 설정
interface IFormatsConfig {
bold?: boolean;
italic?: boolean;
hashtag?: boolean;
}
interface IToolsConfig {
charCount?: boolean;
dragAndDrop?: boolean;
htmlPaste?: boolean;
floatingToolbar?: boolean;
}기타 공통 타입
| 타입 | 설명 |
|------|------|
| IContentStats | { charCount, hashtags: string[], spotIds: number[] } |
| IParseHtmlToSlateResult | { blocks: TEditorElement[], imageUrls: string[] } |
| ISpotData | { id, name, address?, thumbnail? } |
| IProcessedImage | { originalSrc, newSrc, file? } |
유틸리티
상수
import {
VOID_ELEMENTS, // ['img', 'spot', 'hr', 'a']
HEADING_ELEMENTS, // ['h1', 'h2', 'h3']
LIST_ELEMENTS, // ['ul', 'ol']
DRAGGABLE_ELEMENTS, // ['img', 'spot', 'hr', 'a']
} from '@pop-ui/editor-core';computeContentStats
Slate AST를 순회하여 글자 수 · 해시태그 · 스팟 ID를 추출한다.
const stats: IContentStats = computeContentStats(content);
// { charCount: 142, hashtags: ['맛집', '서울'], spotIds: [301, 455] }decorateHashtags
Slate decorate prop에 전달하여 #태그를 하이라이트한다.
<Slate decorate={([node, path]) => decorateHashtags([node, path])}>타입 가드
isDraggableElement(type: string): boolean
isElementOfType(node: Node, types: readonly string[]): boolean
findLiEntry(editor: Editor): NodeEntry | undefined
findListEntry(editor: Editor): NodeEntry | undefined사용 예시
React Native readonly 렌더링
import type { TEditorElement, ICustomText } from '@pop-ui/editor-core';
import { computeContentStats } from '@pop-ui/editor-core';
function ReadonlyRenderer({ blocks }: { blocks: TEditorElement[] }) {
const stats = computeContentStats(blocks);
return (
<View>
{blocks.map((block, i) => (
<BlockView key={i} block={block} />
))}
<Text>글자 수: {stats.charCount}</Text>
</View>
);
}Related
| 패키지 | 설명 |
|--------|------|
| @pop-ui/editor | 로직 + UI 통합 에디터 (React/DOM) |
