@teriusu/rich-editor 0.4.1 → 0.5.0
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.
- package/README.md +8 -8
- package/dist/components/BubbleToolbar.svelte +26 -5
- package/dist/components/BubbleToolbar.svelte.d.ts +2 -1
- package/dist/components/BubbleToolbar.svelte.d.ts.map +1 -1
- package/dist/components/FixedToolbar.svelte +76 -3
- package/dist/components/FixedToolbar.svelte.d.ts +2 -0
- package/dist/components/FixedToolbar.svelte.d.ts.map +1 -1
- package/dist/components/SlashCommandMenu.svelte +25 -2
- package/dist/components/SlashCommandMenu.svelte.d.ts +2 -0
- package/dist/components/SlashCommandMenu.svelte.d.ts.map +1 -1
- package/dist/components/TipTapEditor.svelte +29 -20
- package/dist/components/TipTapEditor.svelte.d.ts +2 -1
- package/dist/components/TipTapEditor.svelte.d.ts.map +1 -1
- package/dist/extensions/FileAttachment.d.ts.map +1 -1
- package/dist/extensions/FileAttachment.js +22 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/styles/editor.css +1 -698
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +34 -1
- package/package.json +5 -2
|
@@ -21,18 +21,20 @@
|
|
|
21
21
|
Columns2,
|
|
22
22
|
Columns3,
|
|
23
23
|
} from "lucide-svelte";
|
|
24
|
-
import type { SlashMenuItem } from "../types";
|
|
24
|
+
import type { SlashMenuItem, ToolbarFeature } from "../types";
|
|
25
25
|
import type { Component } from "svelte";
|
|
26
26
|
|
|
27
27
|
const SI = 14;
|
|
28
28
|
|
|
29
29
|
const SLASH_MENU_ITEMS_DATA: {
|
|
30
|
+
feature: ToolbarFeature;
|
|
30
31
|
label: string;
|
|
31
32
|
keywords: string;
|
|
32
33
|
icon: Component<{ size?: number }>;
|
|
33
34
|
command: (editor: Editor) => void;
|
|
34
35
|
}[] = [
|
|
35
36
|
{
|
|
37
|
+
feature: "h1",
|
|
36
38
|
label: "제목 1",
|
|
37
39
|
keywords: "heading h1 제목",
|
|
38
40
|
icon: Heading1,
|
|
@@ -40,6 +42,7 @@
|
|
|
40
42
|
editor.chain().focus().toggleHeading({ level: 1 }).run(),
|
|
41
43
|
},
|
|
42
44
|
{
|
|
45
|
+
feature: "h2",
|
|
43
46
|
label: "제목 2",
|
|
44
47
|
keywords: "heading h2 제목",
|
|
45
48
|
icon: Heading2,
|
|
@@ -47,6 +50,7 @@
|
|
|
47
50
|
editor.chain().focus().toggleHeading({ level: 2 }).run(),
|
|
48
51
|
},
|
|
49
52
|
{
|
|
53
|
+
feature: "h3",
|
|
50
54
|
label: "제목 3",
|
|
51
55
|
keywords: "heading h3 제목",
|
|
52
56
|
icon: Heading3,
|
|
@@ -54,36 +58,42 @@
|
|
|
54
58
|
editor.chain().focus().toggleHeading({ level: 3 }).run(),
|
|
55
59
|
},
|
|
56
60
|
{
|
|
61
|
+
feature: "bullet-list",
|
|
57
62
|
label: "글머리 목록",
|
|
58
63
|
keywords: "bullet list 목록 리스트",
|
|
59
64
|
icon: List,
|
|
60
65
|
command: (editor) => editor.chain().focus().toggleBulletList().run(),
|
|
61
66
|
},
|
|
62
67
|
{
|
|
68
|
+
feature: "ordered-list",
|
|
63
69
|
label: "번호 목록",
|
|
64
70
|
keywords: "ordered number list 번호 리스트",
|
|
65
71
|
icon: ListOrdered,
|
|
66
72
|
command: (editor) => editor.chain().focus().toggleOrderedList().run(),
|
|
67
73
|
},
|
|
68
74
|
{
|
|
75
|
+
feature: "checklist",
|
|
69
76
|
label: "체크리스트",
|
|
70
77
|
keywords: "checklist task todo 체크 할일",
|
|
71
78
|
icon: CheckSquare,
|
|
72
79
|
command: (editor) => editor.chain().focus().toggleTaskList().run(),
|
|
73
80
|
},
|
|
74
81
|
{
|
|
82
|
+
feature: "blockquote",
|
|
75
83
|
label: "인용문",
|
|
76
84
|
keywords: "quote blockquote 인용",
|
|
77
85
|
icon: Quote,
|
|
78
86
|
command: (editor) => editor.chain().focus().toggleBlockquote().run(),
|
|
79
87
|
},
|
|
80
88
|
{
|
|
89
|
+
feature: "horizontal-rule",
|
|
81
90
|
label: "구분선",
|
|
82
91
|
keywords: "divider hr horizontal rule 구분",
|
|
83
92
|
icon: Minus,
|
|
84
93
|
command: (editor) => editor.chain().focus().setHorizontalRule().run(),
|
|
85
94
|
},
|
|
86
95
|
{
|
|
96
|
+
feature: "code-block",
|
|
87
97
|
label: "C++ 코드",
|
|
88
98
|
keywords: "code cpp c++ 코드 블록",
|
|
89
99
|
icon: Code2,
|
|
@@ -91,6 +101,7 @@
|
|
|
91
101
|
editor.chain().focus().setCodeBlock({ language: "cpp" }).run(),
|
|
92
102
|
},
|
|
93
103
|
{
|
|
104
|
+
feature: "code-block",
|
|
94
105
|
label: "Python 코드",
|
|
95
106
|
keywords: "code python 파이썬 코드 블록",
|
|
96
107
|
icon: Code2,
|
|
@@ -98,12 +109,14 @@
|
|
|
98
109
|
editor.chain().focus().setCodeBlock({ language: "python" }).run(),
|
|
99
110
|
},
|
|
100
111
|
{
|
|
112
|
+
feature: "toggle",
|
|
101
113
|
label: "토글",
|
|
102
114
|
keywords: "toggle details 접기 펼치기 토글",
|
|
103
115
|
icon: ChevronRight,
|
|
104
116
|
command: (editor) => editor.chain().focus().setDetails().run(),
|
|
105
117
|
},
|
|
106
118
|
{
|
|
119
|
+
feature: "table",
|
|
107
120
|
label: "표",
|
|
108
121
|
keywords: "table 표 테이블",
|
|
109
122
|
icon: TableIcon,
|
|
@@ -115,18 +128,21 @@
|
|
|
115
128
|
.run(),
|
|
116
129
|
},
|
|
117
130
|
{
|
|
131
|
+
feature: "columns-2",
|
|
118
132
|
label: "2단 컬럼",
|
|
119
133
|
keywords: "column 컬럼 2단 분할",
|
|
120
134
|
icon: Columns2,
|
|
121
135
|
command: (editor) => editor.chain().focus().setColumns(2).run(),
|
|
122
136
|
},
|
|
123
137
|
{
|
|
138
|
+
feature: "columns-3",
|
|
124
139
|
label: "3단 컬럼",
|
|
125
140
|
keywords: "column 컬럼 3단 분할",
|
|
126
141
|
icon: Columns3,
|
|
127
142
|
command: (editor) => editor.chain().focus().setColumns(3).run(),
|
|
128
143
|
},
|
|
129
144
|
{
|
|
145
|
+
feature: "youtube",
|
|
130
146
|
label: "YouTube 영상",
|
|
131
147
|
keywords: "youtube video 영상 동영상 유튜브",
|
|
132
148
|
icon: Video,
|
|
@@ -136,6 +152,7 @@
|
|
|
136
152
|
},
|
|
137
153
|
},
|
|
138
154
|
{
|
|
155
|
+
feature: "image",
|
|
139
156
|
label: "이미지",
|
|
140
157
|
keywords: "image 이미지 사진 img",
|
|
141
158
|
icon: ImageIcon,
|
|
@@ -145,6 +162,7 @@
|
|
|
145
162
|
},
|
|
146
163
|
},
|
|
147
164
|
{
|
|
165
|
+
feature: "link",
|
|
148
166
|
label: "링크",
|
|
149
167
|
keywords: "link url 링크 하이퍼",
|
|
150
168
|
icon: LinkIcon,
|
|
@@ -163,6 +181,7 @@
|
|
|
163
181
|
|
|
164
182
|
let {
|
|
165
183
|
editor,
|
|
184
|
+
features,
|
|
166
185
|
query,
|
|
167
186
|
onClose,
|
|
168
187
|
onPdfUpload,
|
|
@@ -170,6 +189,7 @@
|
|
|
170
189
|
onVideoUpload,
|
|
171
190
|
}: {
|
|
172
191
|
editor: Editor;
|
|
192
|
+
features: Set<ToolbarFeature>;
|
|
173
193
|
query: string;
|
|
174
194
|
onClose: () => void;
|
|
175
195
|
onPdfUpload?: () => void;
|
|
@@ -182,9 +202,10 @@
|
|
|
182
202
|
let mouseMovedSinceKeyboard = $state(true);
|
|
183
203
|
|
|
184
204
|
const allItems = $derived.by(() => {
|
|
185
|
-
const items =
|
|
205
|
+
const items = SLASH_MENU_ITEMS_DATA.filter((item) => features.has(item.feature));
|
|
186
206
|
if (onPdfUpload) {
|
|
187
207
|
items.push({
|
|
208
|
+
feature: "pdf" as ToolbarFeature,
|
|
188
209
|
label: "PDF 파일",
|
|
189
210
|
keywords: "pdf 파일 문서",
|
|
190
211
|
icon: FileText,
|
|
@@ -193,6 +214,7 @@
|
|
|
193
214
|
}
|
|
194
215
|
if (onVideoUpload) {
|
|
195
216
|
items.push({
|
|
217
|
+
feature: "video" as ToolbarFeature,
|
|
196
218
|
label: "영상 파일",
|
|
197
219
|
keywords: "video 영상 동영상 비디오 메타버스",
|
|
198
220
|
icon: Film,
|
|
@@ -201,6 +223,7 @@
|
|
|
201
223
|
}
|
|
202
224
|
if (onFileUpload) {
|
|
203
225
|
items.push({
|
|
226
|
+
feature: "file" as ToolbarFeature,
|
|
204
227
|
label: "파일 첨부",
|
|
205
228
|
keywords: "file attach 파일 첨부",
|
|
206
229
|
icon: Paperclip,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Editor } from "@tiptap/core";
|
|
2
|
+
import type { ToolbarFeature } from "../types";
|
|
2
3
|
import type { Component } from "svelte";
|
|
3
4
|
type $$ComponentProps = {
|
|
4
5
|
editor: Editor;
|
|
6
|
+
features: Set<ToolbarFeature>;
|
|
5
7
|
query: string;
|
|
6
8
|
onClose: () => void;
|
|
7
9
|
onPdfUpload?: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SlashCommandMenu.svelte.d.ts","sourceRoot":"","sources":["../../src/components/SlashCommandMenu.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"SlashCommandMenu.svelte.d.ts","sourceRoot":"","sources":["../../src/components/SlashCommandMenu.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAsB3C,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEvC,KAAK,gBAAgB,GAAI;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B,CAAC;AAwSJ,QAAA,MAAM,gBAAgB,qCAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
import BubbleToolbar from "./BubbleToolbar.svelte";
|
|
42
42
|
import SlashCommandMenu from "./SlashCommandMenu.svelte";
|
|
43
43
|
import TableBubbleMenu from "./TableBubbleMenu.svelte";
|
|
44
|
-
import type { UploadHandler, ToolbarMode } from "../types";
|
|
44
|
+
import type { UploadHandler, ToolbarMode, ToolbarFeature } from "../types";
|
|
45
|
+
import { resolveFeatures } from "../types";
|
|
45
46
|
import type { FileResolver } from "../extensions/FileAttachment";
|
|
46
47
|
|
|
47
48
|
const cellAttrs = {
|
|
@@ -115,6 +116,7 @@
|
|
|
115
116
|
extensions: extraExtensions = [],
|
|
116
117
|
editable = true,
|
|
117
118
|
toolbar = 'full',
|
|
119
|
+
features: featuresOverride,
|
|
118
120
|
}: {
|
|
119
121
|
content: string;
|
|
120
122
|
onChange: (html: string) => void;
|
|
@@ -124,8 +126,11 @@
|
|
|
124
126
|
extensions?: AnyExtension[];
|
|
125
127
|
editable?: boolean;
|
|
126
128
|
toolbar?: ToolbarMode;
|
|
129
|
+
features?: ToolbarFeature[];
|
|
127
130
|
} = $props();
|
|
128
131
|
|
|
132
|
+
const features = $derived(resolveFeatures(toolbar, featuresOverride));
|
|
133
|
+
|
|
129
134
|
let editorElement: HTMLDivElement | undefined = $state();
|
|
130
135
|
let editor: Editor | undefined = $state();
|
|
131
136
|
let uploading = $state(false);
|
|
@@ -545,13 +550,14 @@
|
|
|
545
550
|
</script>
|
|
546
551
|
|
|
547
552
|
<div
|
|
548
|
-
class="hce-editor-wrapper relative{editable && toolbar
|
|
553
|
+
class="hce-editor-wrapper relative{editable && features.has('fixed-toolbar') ? ' border border-border rounded-xl bg-background' : ''}"
|
|
549
554
|
ondragover={(e) => e.preventDefault()}
|
|
550
555
|
ondrop={(e) => { if (!onUploadFile) e.preventDefault(); }}
|
|
551
556
|
>
|
|
552
|
-
{#if editor && editable && toolbar
|
|
557
|
+
{#if editor && editable && features.has('fixed-toolbar')}
|
|
553
558
|
<FixedToolbar
|
|
554
559
|
{editor}
|
|
560
|
+
{features}
|
|
555
561
|
onPdfClick={() => pdfInputEl?.click()}
|
|
556
562
|
onFileClick={onUploadFile ? () => fileInputEl?.click() : undefined}
|
|
557
563
|
onVideoClick={onUploadFile ? () => videoInputEl?.click() : undefined}
|
|
@@ -561,54 +567,57 @@
|
|
|
561
567
|
<div bind:this={editorElement}></div>
|
|
562
568
|
|
|
563
569
|
{#if editor && editable}
|
|
564
|
-
|
|
570
|
+
{#if features.has('bubble-toolbar')}
|
|
571
|
+
<BubbleToolbar {editor} {features} />
|
|
572
|
+
{/if}
|
|
565
573
|
|
|
566
|
-
{#if
|
|
574
|
+
{#if features.has('table-menu')}
|
|
567
575
|
<TableBubbleMenu {editor} />
|
|
568
576
|
{/if}
|
|
569
577
|
|
|
570
|
-
{#if
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
>
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
</div>
|
|
579
|
-
{/if}
|
|
578
|
+
{#if features.has('upload-overlay') && uploading}
|
|
579
|
+
<div
|
|
580
|
+
class="absolute inset-0 flex items-center justify-center bg-background/60 rounded-xl"
|
|
581
|
+
>
|
|
582
|
+
<p class="text-sm text-muted-foreground animate-pulse">
|
|
583
|
+
업로드 중...
|
|
584
|
+
</p>
|
|
585
|
+
</div>
|
|
580
586
|
{/if}
|
|
581
587
|
|
|
582
|
-
{#if
|
|
588
|
+
{#if features.has('slash-menu') && slashMenuOpen}
|
|
583
589
|
<div
|
|
584
590
|
style="top: {slashMenuPos.top}px; left: {slashMenuPos.left}px"
|
|
585
591
|
class="fixed z-50"
|
|
586
592
|
>
|
|
587
593
|
<SlashCommandMenu
|
|
588
594
|
{editor}
|
|
595
|
+
{features}
|
|
589
596
|
query={slashQuery}
|
|
590
597
|
onClose={closeSlashMenu}
|
|
591
|
-
onPdfUpload={onUploadFile
|
|
598
|
+
onPdfUpload={onUploadFile && features.has('pdf')
|
|
592
599
|
? () => pdfInputEl?.click()
|
|
593
600
|
: undefined}
|
|
594
|
-
onFileUpload={onUploadFile
|
|
601
|
+
onFileUpload={onUploadFile && features.has('file')
|
|
595
602
|
? () => fileInputEl?.click()
|
|
596
603
|
: undefined}
|
|
597
|
-
onVideoUpload={onUploadFile
|
|
604
|
+
onVideoUpload={onUploadFile && features.has('video')
|
|
598
605
|
? () => videoInputEl?.click()
|
|
599
606
|
: undefined}
|
|
600
607
|
/>
|
|
601
608
|
</div>
|
|
602
609
|
{/if}
|
|
603
610
|
|
|
604
|
-
{#if
|
|
611
|
+
{#if features.has('character-count')}
|
|
605
612
|
<div
|
|
606
613
|
class="flex justify-end px-4 py-2 text-xs text-muted-foreground border-t border-border"
|
|
607
614
|
>
|
|
608
615
|
{editor.storage.characterCount.characters()} 자 ·
|
|
609
616
|
{editor.storage.characterCount.words()} 단어
|
|
610
617
|
</div>
|
|
618
|
+
{/if}
|
|
611
619
|
|
|
620
|
+
{#if features.has('pdf') || features.has('file') || features.has('video')}
|
|
612
621
|
<input
|
|
613
622
|
bind:this={pdfInputEl}
|
|
614
623
|
type="file"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AnyExtension } from "@tiptap/core";
|
|
2
|
-
import type { UploadHandler, ToolbarMode } from "../types";
|
|
2
|
+
import type { UploadHandler, ToolbarMode, ToolbarFeature } from "../types";
|
|
3
3
|
import type { FileResolver } from "../extensions/FileAttachment";
|
|
4
4
|
type $$ComponentProps = {
|
|
5
5
|
content: string;
|
|
@@ -10,6 +10,7 @@ type $$ComponentProps = {
|
|
|
10
10
|
extensions?: AnyExtension[];
|
|
11
11
|
editable?: boolean;
|
|
12
12
|
toolbar?: ToolbarMode;
|
|
13
|
+
features?: ToolbarFeature[];
|
|
13
14
|
};
|
|
14
15
|
declare const TipTapEditor: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
15
16
|
type TipTapEditor = ReturnType<typeof TipTapEditor>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAa5D,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAa5D,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE3E,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,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;AAkmBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileAttachment.d.ts","sourceRoot":"","sources":["../../src/extensions/FileAttachment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,MAAM,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9E,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE1E,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,cAAc,EAAE;YACd,iBAAiB,EAAE,CAAC,KAAK,EAAE;gBACzB,GAAG,CAAC,EAAE,MAAM,CAAC;gBACb,MAAM,CAAC,EAAE,MAAM,CAAC;gBAChB,IAAI,EAAE,MAAM,CAAC;gBACb,IAAI,CAAC,EAAE,MAAM,CAAC;aACf,KAAK,UAAU,CAAC;SAClB,CAAC;KACH;CACF;AA6BD,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"FileAttachment.d.ts","sourceRoot":"","sources":["../../src/extensions/FileAttachment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,MAAM,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9E,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE1E,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,cAAc,EAAE;YACd,iBAAiB,EAAE,CAAC,KAAK,EAAE;gBACzB,GAAG,CAAC,EAAE,MAAM,CAAC;gBACb,MAAM,CAAC,EAAE,MAAM,CAAC;gBAChB,IAAI,EAAE,MAAM,CAAC;gBACb,IAAI,CAAC,EAAE,MAAM,CAAC;aACf,KAAK,UAAU,CAAC;SAClB,CAAC;KACH;CACF;AA6BD,eAAO,MAAM,cAAc,kCAkMzB,CAAC"}
|
|
@@ -111,16 +111,33 @@ export const FileAttachment = Node.create({
|
|
|
111
111
|
const info = document.createElement("div");
|
|
112
112
|
info.style.cssText = "flex:1;min-width:0;";
|
|
113
113
|
const nameEl = document.createElement("a");
|
|
114
|
-
nameEl.target = "_blank";
|
|
115
|
-
nameEl.rel = "noopener noreferrer";
|
|
116
114
|
nameEl.textContent = node.attrs.name;
|
|
117
115
|
nameEl.style.cssText =
|
|
118
|
-
"display:block;font-size:13px;font-weight:600;color:var(--primary, #4A7DAC);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;";
|
|
116
|
+
"display:block;font-size:13px;font-weight:600;color:var(--primary, #4A7DAC);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;";
|
|
117
|
+
let resolvedSrc = null;
|
|
118
|
+
let resolvedName = node.attrs.name;
|
|
119
|
+
function triggerDownload(e) {
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
if (!resolvedSrc)
|
|
122
|
+
return;
|
|
123
|
+
fetch(resolvedSrc)
|
|
124
|
+
.then((res) => res.blob())
|
|
125
|
+
.then((blob) => {
|
|
126
|
+
const url = URL.createObjectURL(blob);
|
|
127
|
+
const a = document.createElement("a");
|
|
128
|
+
a.href = url;
|
|
129
|
+
a.download = resolvedName;
|
|
130
|
+
a.click();
|
|
131
|
+
URL.revokeObjectURL(url);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
nameEl.addEventListener("click", triggerDownload);
|
|
119
135
|
const sizeEl = document.createElement("span");
|
|
120
136
|
sizeEl.style.cssText =
|
|
121
137
|
"font-size:11px;color:var(--muted-foreground, #718096);";
|
|
122
138
|
// URL이 있으면 바로 표시
|
|
123
139
|
if (node.attrs.src) {
|
|
140
|
+
resolvedSrc = node.attrs.src;
|
|
124
141
|
nameEl.href = node.attrs.src;
|
|
125
142
|
if (node.attrs.size)
|
|
126
143
|
sizeEl.textContent = formatFileSize(node.attrs.size);
|
|
@@ -134,9 +151,11 @@ export const FileAttachment = Node.create({
|
|
|
134
151
|
if (resolver) {
|
|
135
152
|
resolver(node.attrs.fileId)
|
|
136
153
|
.then((result) => {
|
|
154
|
+
resolvedSrc = result.src;
|
|
137
155
|
nameEl.href = result.src;
|
|
138
156
|
nameEl.style.pointerEvents = "";
|
|
139
157
|
if (result.name) {
|
|
158
|
+
resolvedName = result.name;
|
|
140
159
|
nameEl.textContent = result.name;
|
|
141
160
|
icon.textContent = getFileIcon(result.name);
|
|
142
161
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,5 +16,6 @@ export { Column } from "./extensions/Column";
|
|
|
16
16
|
export { sanitizeHtml, stripHtmlToExcerpt, transformLegacyHtml } from "./utils/sanitize";
|
|
17
17
|
export { configurePdfJs, getPdfJs } from "./utils/pdf";
|
|
18
18
|
export { cn } from "./utils/cn";
|
|
19
|
-
export type { TipTapEditorProps, UploadHandler, ToolbarMode, FixedToolbarProps, BlockHandleProps, SlashCommandMenuProps, PdfViewerProps, SlashMenuItem, } from "./types";
|
|
19
|
+
export type { TipTapEditorProps, UploadHandler, ToolbarMode, ToolbarFeature, FixedToolbarProps, BlockHandleProps, SlashCommandMenuProps, PdfViewerProps, SlashMenuItem, } from "./types";
|
|
20
|
+
export { TOOLBAR_PRESETS, resolveFeatures } from "./types";
|
|
20
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGjF,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAGhC,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,aAAa,GACd,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAGjF,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAGhC,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -18,3 +18,4 @@ export { Column } from "./extensions/Column";
|
|
|
18
18
|
export { sanitizeHtml, stripHtmlToExcerpt, transformLegacyHtml } from "./utils/sanitize";
|
|
19
19
|
export { configurePdfJs, getPdfJs } from "./utils/pdf";
|
|
20
20
|
export { cn } from "./utils/cn";
|
|
21
|
+
export { TOOLBAR_PRESETS, resolveFeatures } from "./types";
|