npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bavuchoko/js-editor

v0.1.1

Published

Lightweight React WYSIWYG editor built with contentEditable

Readme

@bavuchoko/js-editor

React용 경량 WYSIWYG 에디터입니다.
contentEditable + Selection API로 구현되어 있으며 TipTap / Lexical / ProseMirror 같은 외부 에디터 엔진에 의존하지 않습니다.

Install

npm install @bavuchoko/js-editor

peer dependency:

npm install react react-dom

React 18 이상을 지원합니다.

Usage

import { useRef } from 'react'
import { Editor, type EditorHandle } from '@bavuchoko/js-editor'
import '@bavuchoko/js-editor/style.css'

function App() {
  const editorRef = useRef<EditorHandle>(null)

  const save = () => {
    // 권장: JSON으로 저장
    const json = editorRef.current?.getJson()
    // await api.save(json)
  }

  const load = (doc: unknown) => {
    editorRef.current?.setJson(doc)
  }

  return (
    <Editor
      ref={editorRef}
      theme={{
        toolbar: { background: '#fff' },
        content: { padding: 24, minHeight: 320 },
      }}
    />
  )
}

스타일(style.css)은 반드시 함께 import 해야 합니다.

Features

| 영역 | 지원 | |------|------| | 인라인 | 굵게, 기울임, 밑줄, 글자색, 배경색 | | 블록 | 본문, Heading 1–3, 인용, 코드 블록 | | 목록 | 글머리, 번호, 체크리스트 | | 정렬 | 왼쪽 / 가운데 / 오른쪽 | | 테이블 | 삽입, 셀 드래그 선택, 셀 병합, Tab/Enter 이동 | | 단축키 | Undo/Redo, 마크다운 입력 | | 보안 | 붙여넣기·initialHTML·setHtml sanitize |

플레이스홀더 문구: 내용을 입력하세요

Keyboard shortcuts

| 단축키 | 동작 | |--------|------| | Ctrl+Z / Cmd+Z | Undo | | Ctrl+Shift+Z / Cmd+Shift+Z | Redo | | Ctrl+Y / Cmd+Y | Redo | | Tab (테이블 셀) | 다음 셀로 이동 | | Enter (테이블 셀) | 아래 셀로 이동 |

툴바에 Undo/Redo 버튼은 없고 단축키만 지원합니다.

Markdown shortcuts

줄 시작에서 입력 후 스페이스:

| 입력 | 결과 | |------|------| | # | Heading 1 | | ## | Heading 2 | | ### | Heading 3 | | > | 인용 | | - 또는 * | 글머리 목록 | | 1. | 번호 목록 | | ``` + 스페이스 | 코드 블록 |

인라인:

| 입력 | 결과 | |------|------| | **텍스트** | 굵게 | | *텍스트* | 기울임 |

API

Editor props

| prop | 타입 | 설명 | |------|------|------| | initialHTML | string | 초기 HTML (sanitize 후 적용) | | theme | EditorTheme | toolbar / contentCSSProperties | | className / style | | 루트 요소 | | toolbarClassName / toolbarStyle | | 툴바 (theme.toolbar와 병합) | | contentClassName / contentStyle | | 본문 (theme.content와 병합) |

type EditorTheme = {
  toolbar?: CSSProperties
  content?: CSSProperties
}

ref methods (EditorHandle)

| method | 설명 | |--------|------| | getHtml() | 현재 본문 HTML | | setHtml(html) | HTML 로드 (sanitize + 히스토리 리셋) | | getJson() | 현재 본문 JSON (EditorDoc) | | setJson(doc) | JSON 로드 (HTML 변환 + sanitize + 히스토리 리셋) | | getText() | plain text | | focus() | 편집 영역 포커스 |

유틸 export

import {
  htmlToJson,
  jsonToHtml,
  domToJson,
  normalizeDoc,
  sanitizeHTML,
  sanitizePlainText,
  type EditorDoc,
  type BlockNode,
  type InlineNode,
  type Mark,
} from '@bavuchoko/js-editor'

| 함수 | 설명 | |------|------| | htmlToJson(html) | HTML → EditorDoc | | jsonToHtml(doc) | EditorDoc → HTML | | domToJson(element) | DOM 노드 → EditorDoc | | normalizeDoc(doc) | 알 수 없는 입력을 안전한 EditorDoc으로 정규화 | | sanitizeHTML(html) | 허용 태그/속성만 남김 | | sanitizePlainText(text) | 텍스트만 남김 |

Document JSON

저장·전송은 HTML보다 JSON을 권장합니다.

type EditorDoc = {
  type: 'doc'
  content: BlockNode[]
}

예시:

{
  "type": "doc",
  "content": [
    {
      "type": "heading",
      "attrs": { "level": 1 },
      "content": [{ "type": "text", "text": "제목" }]
    },
    {
      "type": "paragraph",
      "attrs": { "textAlign": "left" },
      "content": [
        { "type": "text", "text": "안녕하세요, " },
        {
          "type": "text",
          "text": "굵은 글씨",
          "marks": [{ "type": "bold" }]
        }
      ]
    },
    {
      "type": "taskList",
      "content": [
        {
          "type": "taskItem",
          "attrs": { "checked": false },
          "content": [{ "type": "text", "text": "할 일" }]
        }
      ]
    }
  ]
}

지원 블록: paragraph, heading, blockquote, codeBlock, bulletList, orderedList, taskList, table
지원 마크: bold, italic, underline, code, textStyle(색), highlight(배경색)

Security

  • 붙여넣기, initialHTML, setHtml / setJson 경로에서 HTML을 sanitize 합니다.
  • 허용되지 않은 태그·속성·이벤트 핸들러·위험한 URL은 제거됩니다.
  • 서버에서도 저장 전에 검증하는 것을 권장합니다. JSON으로 저장하면 스키마 검증이 쉽습니다.
// 서버에서 받은 HTML을 넣을 때
editorRef.current?.setHtml(untrustedHtml) // 내부에서 sanitize

// 더 안전하게 JSON만 받기
editorRef.current?.setJson(docFromDb)

Develop

npm install
npm run dev          # 데모 앱
npm run build        # 라이브러리 빌드 (publish용)
npm run build:demo   # 데모 앱 빌드
npm run pack:check   # 빌드 + npm pack dry-run

License

MIT