@teriusu/rich-editor 0.8.4 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -89,6 +89,17 @@
89
89
  });
90
90
  const isActive = (...args: Parameters<Editor["isActive"]>) =>
91
91
  (tick, editor.isActive(...args));
92
+ /**
93
+ * ⚠️ `isActive` 만 고쳐서는 부족했다. **되돌리기 가능 여부**와 **지금 글자색**도
94
+ * 매 트랜잭션마다 다시 읽어야 하는데, 그냥 `editor.can()` / `editor.getAttributes()` 를
95
+ * 부르면 Svelte 가 의존성을 못 봐서 처음 값에 굳는다 —
96
+ * 되돌리기가 영영 비활성으로 남고(사용자 지적), 글자색 버튼은 한 번 켜지면 색을 꺼도
97
+ * 계속 켜진 채였다.
98
+ */
99
+ const canDo = (fn: (c: ReturnType<Editor["can"]>) => boolean) =>
100
+ (tick, fn(editor.can()));
101
+ const attrOf = (name: string, key: string) =>
102
+ (tick, editor.getAttributes(name)[key] as string | undefined);
92
103
 
93
104
  const has = (f: ToolbarFeature) => features.has(f);
94
105
 
@@ -102,18 +113,40 @@
102
113
  let insertMenuEl: HTMLDivElement | undefined = $state();
103
114
  let colorMenuEl: HTMLDivElement | undefined = $state();
104
115
 
105
- const TEXT_COLORS = [
116
+ /*
117
+ * ⚠️ **`검정(#000000)` 은 뺐다.** `기본`(×, 색 지정 해제)과 눈으로 구별이 안 되는데
118
+ * (본문 기본색이 거의 검정이다) 두 가지가 다 있으면 헷갈린다 — 사용자가 짚은 부분이다.
119
+ *
120
+ * 남기는 쪽은 **`기본`** 이다. `검정` 만 남기면 본문 기본색으로 **되돌릴 방법이 없어지고**,
121
+ * 저장된 HTML 에 `#000000` 이 눌러앉는다. 그 글은 다크 모드에서 검정 글자가 되어
122
+ * 안 보인다(코드패스가 `sanitizeBodyColors` 로 이 자국을 걷어내고 있는 이유다).
123
+ *
124
+ * `브랜드` 는 앱마다 다르므로 값을 고정하지 않고 `--primary` 를 읽는다 —
125
+ * 정올과 코드패스가 각자 자기 색을 얻는다. 저장은 계산된 실제 색으로 한다
126
+ * (`var(--primary)` 를 그대로 저장하면 앱 밖에서 렌더할 때 색이 사라진다).
127
+ *
128
+ * ⚠️ **아홉 개로 맞춰 둔다.** 팔레트가 `grid-cols-3` 라 여덟 개면 마지막 줄에 빈 칸이
129
+ * 남아 덜 만든 것처럼 보인다(사용자 지적). `기본` + 색 여덟이 3×3 을 정확히 채운다.
130
+ * 색은 색상환을 고르게 훑도록 골랐다 — 빨강·주황·노랑·초록·파랑에 브랜드(남보라)와
131
+ * 그 사이를 메우는 분홍, 그리고 무채색 회색. 여기서 더 늘리려면 12개(3×4)로 가야 한다.
132
+ */
133
+ const TEXT_COLORS: { label: string; value: string; cssVar?: string }[] = [
106
134
  { label: "기본", value: "" },
107
- { label: "검정", value: "#000000" },
135
+ { label: "브랜드", value: "", cssVar: "--primary" },
108
136
  { label: "회색", value: "#6b7280" },
109
137
  { label: "빨강", value: "#dc2626" },
110
138
  { label: "주황", value: "#ea580c" },
111
139
  { label: "노랑", value: "#ca8a04" },
112
140
  { label: "초록", value: "#16a34a" },
113
141
  { label: "파랑", value: "#2563eb" },
114
- { label: "보라", value: "#7c3aed" }
142
+ { label: "분홍", value: "#db2777" }
115
143
  ];
116
144
 
145
+ /** `--primary` 같은 CSS 변수를 그 자리에서 실제 색 문자열로 바꾼다. */
146
+ function resolveCssVar(el: HTMLElement, name: string): string {
147
+ return getComputedStyle(el).getPropertyValue(name).trim();
148
+ }
149
+
117
150
  $effect(() => {
118
151
  if (!blockMenuOpen && !insertMenuOpen && !colorMenuOpen) return;
119
152
  function handleClick(e: MouseEvent) {
@@ -242,12 +275,12 @@
242
275
  <button
243
276
  type="button"
244
277
  onclick={() => editor.chain().focus().undo().run()}
245
- disabled={!editor.can().undo()}
278
+ disabled={!canDo((c) => c.undo())}
246
279
  data-tooltip="실행 취소"
247
280
  aria-label="실행 취소"
248
281
  class={cn(
249
282
  "p-1.5 rounded-md transition-colors text-muted-foreground hover:bg-muted hover:text-foreground",
250
- !editor.can().undo() && "opacity-30 pointer-events-none",
283
+ !canDo((c) => c.undo()) && "opacity-30 pointer-events-none",
251
284
  )}
252
285
  >
253
286
  <Undo size={iconSize} />
@@ -257,12 +290,12 @@
257
290
  <button
258
291
  type="button"
259
292
  onclick={() => editor.chain().focus().redo().run()}
260
- disabled={!editor.can().redo()}
293
+ disabled={!canDo((c) => c.redo())}
261
294
  data-tooltip="다시 실행"
262
295
  aria-label="다시 실행"
263
296
  class={cn(
264
297
  "p-1.5 rounded-md transition-colors text-muted-foreground hover:bg-muted hover:text-foreground",
265
- !editor.can().redo() && "opacity-30 pointer-events-none",
298
+ !canDo((c) => c.redo()) && "opacity-30 pointer-events-none",
266
299
  )}
267
300
  >
268
301
  <Redo size={iconSize} />
@@ -509,7 +542,7 @@
509
542
  aria-label="글자색"
510
543
  class={cn(
511
544
  "flex items-center gap-0.5 p-1.5 rounded-md transition-colors",
512
- editor.getAttributes('textStyle').color
545
+ attrOf('textStyle', 'color')
513
546
  ? "hce-active"
514
547
  : "text-muted-foreground hover:bg-muted hover:text-foreground",
515
548
  )}
@@ -531,17 +564,20 @@
531
564
  type="button"
532
565
  title={c.label}
533
566
  class="h-8 rounded-md border border-border transition-transform hover:scale-105 flex items-center justify-center text-xs font-bold bg-background"
534
- style="color: {c.value || '#6b7280'}"
535
- onclick={() => {
536
- if (c.value) {
537
- editor.chain().focus().setColor(c.value).run();
567
+ style="color: {c.cssVar ? `var(${c.cssVar})` : c.value || '#6b7280'}"
568
+ onclick={(e) => {
569
+ const color = c.cssVar
570
+ ? resolveCssVar(e.currentTarget as HTMLElement, c.cssVar)
571
+ : c.value;
572
+ if (color) {
573
+ editor.chain().focus().setColor(color).run();
538
574
  } else {
539
575
  editor.chain().focus().unsetColor().run();
540
576
  }
541
577
  colorMenuOpen = false;
542
578
  }}
543
579
  >
544
- {c.value ? "A" : "×"}
580
+ {c.cssVar || c.value ? "A" : "×"}
545
581
  </button>
546
582
  {/each}
547
583
  </div>
@@ -552,7 +588,7 @@
552
588
  <input
553
589
  type="color"
554
590
  class="h-6 w-10 cursor-pointer rounded border border-border bg-transparent p-0"
555
- value={(editor.getAttributes('textStyle').color as string) || '#000000'}
591
+ value={attrOf('textStyle', 'color') || '#000000'}
556
592
  onclick={(e) => e.stopPropagation()}
557
593
  oninput={(e) => {
558
594
  const v = (e.target as HTMLInputElement).value;
@@ -1 +1 @@
1
- {"version":3,"file":"FixedToolbar.svelte.d.ts","sourceRoot":"","sources":["../../src/components/FixedToolbar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAqCtC,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE7D,KAAK,gBAAgB,GAAI;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAyjBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"FixedToolbar.svelte.d.ts","sourceRoot":"","sources":["../../src/components/FixedToolbar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAqCtC,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE7D,KAAK,gBAAgB,GAAI;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AA6lBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -38,6 +38,7 @@
38
38
  import { FileAttachment } from "../extensions/FileAttachment";
39
39
  import { MbusVideo } from "../extensions/MbusVideo";
40
40
  import { CardBlock } from "../extensions/CardBlock";
41
+ import { MathInline, MathDisplay } from "../extensions/Math";
41
42
  import FixedToolbar from "./FixedToolbar.svelte";
42
43
  import BubbleToolbar from "./BubbleToolbar.svelte";
43
44
  import SlashCommandMenu from "./SlashCommandMenu.svelte";
@@ -148,6 +149,18 @@
148
149
 
149
150
  let editorElement: HTMLDivElement | undefined = $state();
150
151
  let editor: Editor | undefined = $state();
152
+
153
+ /*
154
+ * 글자수는 `editor.storage` 에서 읽는데 그건 `$state` 가 아니라, 그냥 부르면 첫 값에
155
+ * 굳어 **타이핑해도 숫자가 안 바뀐다**(사용자 지적). 트랜잭션마다 카운터를 올리고
156
+ * 그 카운터를 함께 읽어 Svelte 에 의존성을 알린다 — 툴바 활성 표시와 같은 방식이다.
157
+ */
158
+ let editorTick = $state(0);
159
+ const counts = $derived.by(() => {
160
+ editorTick;
161
+ const cc = editor?.storage?.characterCount;
162
+ return { chars: cc?.characters?.() ?? 0, words: cc?.words?.() ?? 0 };
163
+ });
151
164
  let uploading = $state(false);
152
165
  let pdfInputEl: HTMLInputElement | undefined = $state();
153
166
  let fileInputEl: HTMLInputElement | undefined = $state();
@@ -389,6 +402,21 @@
389
402
  }),
390
403
  MbusVideo,
391
404
  CardBlock.configure({ promptBackground: onPromptCardBackground ?? null }),
405
+ /*
406
+ * ⚠️ **수학은 여기서 등록한다.** 예전엔 `MathInline`/`MathDisplay` 를 내보내기만 하고
407
+ * 등록은 호스트에 맡겼는데, 그러면 앱마다 기억해서 `extensions` 로 넘겨야 한다 —
408
+ * 정올이 실제로 빠뜨려서 `\le` 같은 수식이 문제 본문에 **원문 그대로** 떴다.
409
+ * 두 앱 다 필요한 것이면 패키지가 갖고 있는 게 맞다.
410
+ *
411
+ * 호스트가 이미 넘겼으면 비켜선다(같은 이름 확장을 두 번 등록하면 TipTap 이 죽는다).
412
+ * `codeBlock` 이 쓰는 방식과 같다.
413
+ */
414
+ ...(extraExtensions.some((ext) => (ext as any).name === "math_inline")
415
+ ? []
416
+ : [MathInline]),
417
+ ...(extraExtensions.some((ext) => (ext as any).name === "math_display")
418
+ ? []
419
+ : [MathDisplay]),
392
420
  Columns,
393
421
  Column,
394
422
  CodeBlockTopEscape,
@@ -493,8 +521,12 @@
493
521
  /*
494
522
  * ⚠️ 예전엔 여기서 `editor = editor` 로 Svelte 를 밀었다. 그건 Svelte 4 관용구고
495
523
  * rune 에서는 **같은 참조 재대입이라 아무 일도 일어나지 않는다** — 툴바 활성 표시가
496
- * 영영 갱신되지 않았다. 이제 각 툴바가 `transaction` 을 직접 구독해 스스로 다시 그린다.
524
+ * 영영 갱신되지 않았다. 툴바는 이제 `transaction` 을 직접 구독하고, 이 컴포넌트가
525
+ * 그리는 글자수는 아래 카운터로 다시 읽는다.
497
526
  */
527
+ onTransaction: () => {
528
+ editorTick++;
529
+ },
498
530
  });
499
531
 
500
532
  editor.on("update", handleUpdate);
@@ -579,7 +611,12 @@
579
611
  />
580
612
  {/if}
581
613
 
582
- <div bind:this={editorElement}></div>
614
+ <!--
615
+ 본문이 들어가는 자리. **이름을 준다** — 호스트가 상자 높이를 정해 놓고 이 안을
616
+ 채우게 하려면 이 요소를 지목할 수 있어야 한다. 이름이 없으면 남는 높이가 아무에게도
617
+ 배분되지 않아 글자수 표시가 상자 중간에 떠 버린다.
618
+ -->
619
+ <div class="hce-editor-body" bind:this={editorElement}></div>
583
620
 
584
621
  {#if editor && editable}
585
622
  {#if features.has('bubble-toolbar')}
@@ -627,8 +664,7 @@
627
664
  <div
628
665
  class="flex justify-end px-4 py-2 text-xs text-muted-foreground border-t border-border"
629
666
  >
630
- {editor.storage.characterCount.characters()} 자 ·
631
- {editor.storage.characterCount.words()} 단어
667
+ {counts.chars} 자 · {counts.words} 단어
632
668
  </div>
633
669
  {/if}
634
670
 
@@ -1 +1 @@
1
- {"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AA6BtC,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAc5D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEhE,KAAK,gBAAgB,GAAI;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,wCAAwC;IACxC,sBAAsB,CAAC,EAAE,aAAa,CAAC;IACvC,4BAA4B;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC7B,CAAC;AA8lBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AA6BtC,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAe5D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEhE,KAAK,gBAAgB,GAAI;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,wCAAwC;IACxC,sBAAsB,CAAC,EAAE,aAAa,CAAC;IACvC,4BAA4B;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;CAC7B,CAAC;AA8nBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
package/dist/types.d.ts CHANGED
@@ -13,7 +13,14 @@ export type PromptHandler = (defaultValue: string) => Promise<string | null>;
13
13
  export type ToolbarMode = 'minimal' | 'standard' | 'full';
14
14
  /** 개별 툴바 기능 ID */
15
15
  export type ToolbarFeature = 'bold' | 'italic' | 'underline' | 'strike' | 'highlight' | 'superscript' | 'subscript' | 'code' | 'text-color' | 'align-left' | 'align-center' | 'align-right' | 'paragraph' | 'h1' | 'h2' | 'h3' | 'bullet-list' | 'ordered-list' | 'checklist' | 'blockquote' | 'horizontal-rule' | 'toggle' | 'link' | 'image' | 'pdf' | 'file' | 'mbus' | 'card' | 'columns-2' | 'columns-3' | 'table' | 'code-block' | 'undo' | 'redo' | 'fixed-toolbar' | 'bubble-toolbar' | 'slash-menu' | 'table-menu' | 'character-count' | 'upload-overlay';
16
- /** 모드별 기본 feature 프리셋 */
16
+ /**
17
+ * 모드별 기본 feature 프리셋.
18
+ *
19
+ * ⚠️ `'card'` 는 **일부러 빠져 있다.** 실제로 안 쓰여서 삽입 메뉴와 슬래시 메뉴에서
20
+ * 내렸다(사용자 요청). 다만 **확장 자체는 계속 등록된다** — 빼면 이미 카드가 들어간
21
+ * 문서가 열릴 때 노드를 못 알아보고 내용이 날아간다. 넣는 길만 닫은 것이라,
22
+ * 쓰고 싶은 호스트는 `features` 에 `'card'` 를 직접 넣으면 그대로 살아난다.
23
+ */
17
24
  export declare const TOOLBAR_PRESETS: Record<ToolbarMode, ToolbarFeature[]>;
18
25
  /** features 배열 → Set 변환. features가 있으면 그걸 쓰고 없으면 toolbar 모드 프리셋 */
19
26
  export declare function resolveFeatures(toolbar: ToolbarMode, features?: ToolbarFeature[]): Set<ToolbarFeature>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,4 +1,11 @@
1
- /** 모드별 기본 feature 프리셋 */
1
+ /**
2
+ * 모드별 기본 feature 프리셋.
3
+ *
4
+ * ⚠️ `'card'` 는 **일부러 빠져 있다.** 실제로 안 쓰여서 삽입 메뉴와 슬래시 메뉴에서
5
+ * 내렸다(사용자 요청). 다만 **확장 자체는 계속 등록된다** — 빼면 이미 카드가 들어간
6
+ * 문서가 열릴 때 노드를 못 알아보고 내용이 날아간다. 넣는 길만 닫은 것이라,
7
+ * 쓰고 싶은 호스트는 `features` 에 `'card'` 를 직접 넣으면 그대로 살아난다.
8
+ */
2
9
  export const TOOLBAR_PRESETS = {
3
10
  full: [
4
11
  'bold', 'italic', 'underline', 'strike', 'highlight',
@@ -7,7 +14,7 @@ export const TOOLBAR_PRESETS = {
7
14
  'paragraph', 'h1', 'h2', 'h3',
8
15
  'bullet-list', 'ordered-list', 'checklist',
9
16
  'blockquote', 'horizontal-rule', 'toggle',
10
- 'link', 'image', 'pdf', 'file', 'mbus', 'card',
17
+ 'link', 'image', 'pdf', 'file', 'mbus',
11
18
  'columns-2', 'columns-3', 'table', 'code-block',
12
19
  'undo', 'redo',
13
20
  'fixed-toolbar', 'slash-menu',
@@ -19,7 +26,7 @@ export const TOOLBAR_PRESETS = {
19
26
  'paragraph', 'h1', 'h2', 'h3',
20
27
  'bullet-list', 'ordered-list', 'checklist',
21
28
  'blockquote', 'horizontal-rule', 'toggle',
22
- 'link', 'image', 'pdf', 'file', 'mbus', 'card',
29
+ 'link', 'image', 'pdf', 'file', 'mbus',
23
30
  'columns-2', 'columns-3', 'table', 'code-block',
24
31
  'fixed-toolbar', 'slash-menu', 'table-menu'
25
32
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teriusu/rich-editor",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "TipTap 기반 Notion-style 리치 텍스트 에디터 (Svelte)",
5
5
  "type": "module",
6
6
  "svelte": "./dist/index.js",