@teriusu/rich-editor 0.10.8 → 0.11.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/dist/components/BubbleToolbar.svelte +40 -36
- package/dist/components/BubbleToolbar.svelte.d.ts +3 -0
- package/dist/components/BubbleToolbar.svelte.d.ts.map +1 -1
- package/dist/components/EmojiSuggestionMenu.svelte +291 -0
- package/dist/components/EmojiSuggestionMenu.svelte.d.ts +9 -0
- package/dist/components/EmojiSuggestionMenu.svelte.d.ts.map +1 -0
- package/dist/components/FixedToolbar.svelte +53 -47
- package/dist/components/FixedToolbar.svelte.d.ts +3 -0
- package/dist/components/FixedToolbar.svelte.d.ts.map +1 -1
- package/dist/components/FloatingHelper.svelte +219 -0
- package/dist/components/FloatingHelper.svelte.d.ts +14 -0
- package/dist/components/FloatingHelper.svelte.d.ts.map +1 -0
- package/dist/components/InputModal.svelte +7 -3
- package/dist/components/InputModal.svelte.d.ts +3 -0
- package/dist/components/InputModal.svelte.d.ts.map +1 -1
- package/dist/components/MathModal.svelte +33 -29
- package/dist/components/MathModal.svelte.d.ts +3 -0
- package/dist/components/MathModal.svelte.d.ts.map +1 -1
- package/dist/components/MediaPickerModal.svelte +7 -3
- package/dist/components/MediaPickerModal.svelte.d.ts +3 -0
- package/dist/components/MediaPickerModal.svelte.d.ts.map +1 -1
- package/dist/components/SlashCommandMenu.svelte +88 -72
- package/dist/components/SlashCommandMenu.svelte.d.ts +3 -0
- package/dist/components/SlashCommandMenu.svelte.d.ts.map +1 -1
- package/dist/components/TableBubbleMenu.svelte +41 -33
- package/dist/components/TableBubbleMenu.svelte.d.ts +3 -0
- package/dist/components/TableBubbleMenu.svelte.d.ts.map +1 -1
- package/dist/components/TipTapEditor.svelte +239 -127
- package/dist/components/TipTapEditor.svelte.d.ts +7 -0
- package/dist/components/TipTapEditor.svelte.d.ts.map +1 -1
- package/dist/extensions/CardBlock.d.ts.map +1 -1
- package/dist/extensions/CardBlock.js +6 -4
- package/dist/extensions/FileAttachment.d.ts.map +1 -1
- package/dist/extensions/FileAttachment.js +2 -1
- package/dist/extensions/FixedDetails.d.ts.map +1 -1
- package/dist/extensions/FixedDetails.js +5 -3
- package/dist/extensions/LegacyBlock.d.ts.map +1 -1
- package/dist/extensions/LegacyBlock.js +8 -6
- package/dist/extensions/Math.d.ts.map +1 -1
- package/dist/extensions/Math.js +5 -2
- package/dist/extensions/MbusVideo.d.ts.map +1 -1
- package/dist/extensions/MbusVideo.js +73 -9
- package/dist/extensions/MediaToolbar.d.ts +41 -0
- package/dist/extensions/MediaToolbar.d.ts.map +1 -0
- package/dist/extensions/MediaToolbar.js +196 -0
- package/dist/extensions/MediaToolbar.test.d.ts +2 -0
- package/dist/extensions/MediaToolbar.test.d.ts.map +1 -0
- package/dist/extensions/MediaToolbar.test.js +231 -0
- package/dist/extensions/OrderedListMarker.d.ts +2 -0
- package/dist/extensions/OrderedListMarker.d.ts.map +1 -0
- package/dist/extensions/OrderedListMarker.js +114 -0
- package/dist/extensions/OrderedListMarker.test.d.ts +2 -0
- package/dist/extensions/OrderedListMarker.test.d.ts.map +1 -0
- package/dist/extensions/OrderedListMarker.test.js +176 -0
- package/dist/extensions/PdfBlock.d.ts.map +1 -1
- package/dist/extensions/PdfBlock.js +25 -23
- package/dist/extensions/ResizableImage.d.ts.map +1 -1
- package/dist/extensions/ResizableImage.js +20 -1
- package/dist/extensions/TableKeymap.d.ts +16 -0
- package/dist/extensions/TableKeymap.d.ts.map +1 -0
- package/dist/extensions/TableKeymap.js +97 -0
- package/dist/extensions/TableKeymap.test.d.ts +2 -0
- package/dist/extensions/TableKeymap.test.d.ts.map +1 -0
- package/dist/extensions/TableKeymap.test.js +147 -0
- package/dist/extensions/TabsBlock.d.ts.map +1 -1
- package/dist/extensions/TabsBlock.js +12 -9
- package/dist/extensions/TiptapMidibus.d.ts.map +1 -1
- package/dist/extensions/TiptapMidibus.js +60 -6
- package/dist/extensions/UploadSkeleton.d.ts +61 -0
- package/dist/extensions/UploadSkeleton.d.ts.map +1 -0
- package/dist/extensions/UploadSkeleton.js +233 -0
- package/dist/extensions/UploadSkeleton.test.d.ts +2 -0
- package/dist/extensions/UploadSkeleton.test.d.ts.map +1 -0
- package/dist/extensions/UploadSkeleton.test.js +128 -0
- package/dist/extensions/VideoEmbed.d.ts +8 -0
- package/dist/extensions/VideoEmbed.d.ts.map +1 -1
- package/dist/extensions/VideoEmbed.js +226 -45
- package/dist/extensions/VideoEmbed.test.js +131 -2
- package/dist/i18n/en.d.ts +3 -0
- package/dist/i18n/en.d.ts.map +1 -0
- package/dist/i18n/en.js +191 -0
- package/dist/i18n/es.d.ts +3 -0
- package/dist/i18n/es.d.ts.map +1 -0
- package/dist/i18n/es.js +191 -0
- package/dist/i18n/index.d.ts +43 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +109 -0
- package/dist/i18n/index.test.d.ts +2 -0
- package/dist/i18n/index.test.d.ts.map +1 -0
- package/dist/i18n/index.test.js +173 -0
- package/dist/i18n/ja.d.ts +3 -0
- package/dist/i18n/ja.d.ts.map +1 -0
- package/dist/i18n/ja.js +191 -0
- package/dist/i18n/ko.d.ts +198 -0
- package/dist/i18n/ko.d.ts.map +1 -0
- package/dist/i18n/ko.js +215 -0
- package/dist/i18n/zh-hans.d.ts +3 -0
- package/dist/i18n/zh-hans.d.ts.map +1 -0
- package/dist/i18n/zh-hans.js +191 -0
- package/dist/i18n/zh-hant.d.ts +3 -0
- package/dist/i18n/zh-hant.d.ts.map +1 -0
- package/dist/i18n/zh-hant.js +192 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -1
- package/dist/static/highlight.d.ts +13 -0
- package/dist/static/highlight.d.ts.map +1 -0
- package/dist/static/highlight.js +99 -0
- package/dist/static/index.d.ts +33 -0
- package/dist/static/index.d.ts.map +1 -0
- package/dist/static/index.js +367 -0
- package/dist/static/index.test.d.ts +2 -0
- package/dist/static/index.test.d.ts.map +1 -0
- package/dist/static/index.test.js +194 -0
- package/dist/static/tokenizer.d.ts +52 -0
- package/dist/static/tokenizer.d.ts.map +1 -0
- package/dist/static/tokenizer.js +289 -0
- package/dist/styles/editor.css +1 -1
- package/dist/utils/emoji-data.d.ts +15 -0
- package/dist/utils/emoji-suggestion.d.ts +48 -0
- package/dist/utils/emoji-suggestion.d.ts.map +1 -0
- package/dist/utils/emoji-suggestion.js +51 -0
- package/dist/utils/emoji-suggestion.test.d.ts +2 -0
- package/dist/utils/emoji-suggestion.test.d.ts.map +1 -0
- package/dist/utils/emoji-suggestion.test.js +117 -0
- package/dist/utils/floating-helper.d.ts +60 -0
- package/dist/utils/floating-helper.d.ts.map +1 -0
- package/dist/utils/floating-helper.js +63 -0
- package/dist/utils/floating-helper.test.d.ts +2 -0
- package/dist/utils/floating-helper.test.d.ts.map +1 -0
- package/dist/utils/floating-helper.test.js +141 -0
- package/dist/utils/guard-vscode-paste.d.ts +19 -0
- package/dist/utils/guard-vscode-paste.d.ts.map +1 -0
- package/dist/utils/guard-vscode-paste.js +46 -0
- package/dist/utils/guard-vscode-paste.test.d.ts +2 -0
- package/dist/utils/guard-vscode-paste.test.d.ts.map +1 -0
- package/dist/utils/guard-vscode-paste.test.js +86 -0
- package/dist/utils/media-size.d.ts +29 -0
- package/dist/utils/media-size.d.ts.map +1 -0
- package/dist/utils/media-size.js +90 -0
- package/dist/utils/resize.d.ts +12 -0
- package/dist/utils/resize.d.ts.map +1 -1
- package/dist/utils/resize.js +5 -5
- package/dist/utils/sanitize.d.ts +2 -0
- package/dist/utils/sanitize.d.ts.map +1 -1
- package/dist/utils/sanitize.js +28 -3
- package/package.json +8 -1
|
@@ -31,40 +31,48 @@
|
|
|
31
31
|
import { insertTableSized } from "../utils/table";
|
|
32
32
|
import type { SlashMenuItem, ToolbarFeature, PromptHandler } from "../types";
|
|
33
33
|
import type { Component } from "svelte";
|
|
34
|
+
import { defaultTranslator, type EditorMessageKey, type EditorTranslator } from "../i18n";
|
|
34
35
|
|
|
35
36
|
const SI = 14;
|
|
36
37
|
|
|
37
|
-
/** 각 feature가 속하는 섹션
|
|
38
|
-
const SECTION_MAP: Record<string,
|
|
39
|
-
"code-block": "
|
|
40
|
-
math: "
|
|
41
|
-
file: "
|
|
42
|
-
pdf: "
|
|
43
|
-
paragraph: "
|
|
44
|
-
h1: "
|
|
45
|
-
h2: "
|
|
46
|
-
h3: "
|
|
47
|
-
mbus: "
|
|
48
|
-
video: "
|
|
49
|
-
card: "
|
|
50
|
-
"bullet-list": "
|
|
51
|
-
"ordered-list": "
|
|
52
|
-
checklist: "
|
|
53
|
-
toggle: "
|
|
54
|
-
blockquote: "
|
|
55
|
-
"horizontal-rule": "
|
|
56
|
-
table: "
|
|
57
|
-
"columns-2": "
|
|
58
|
-
"columns-3": "
|
|
59
|
-
tabs: "
|
|
60
|
-
link: "
|
|
61
|
-
image: "
|
|
38
|
+
/** 각 feature가 속하는 섹션(메시지 키 — 라벨은 렌더 시 `t()` 로 푼다) */
|
|
39
|
+
const SECTION_MAP: Record<string, EditorMessageKey> = {
|
|
40
|
+
"code-block": "sectionFrequent",
|
|
41
|
+
math: "sectionFrequent",
|
|
42
|
+
file: "sectionMedia",
|
|
43
|
+
pdf: "sectionMedia",
|
|
44
|
+
paragraph: "sectionBasic",
|
|
45
|
+
h1: "sectionBasic",
|
|
46
|
+
h2: "sectionBasic",
|
|
47
|
+
h3: "sectionBasic",
|
|
48
|
+
mbus: "sectionMedia",
|
|
49
|
+
video: "sectionMedia",
|
|
50
|
+
card: "sectionBlock",
|
|
51
|
+
"bullet-list": "sectionList",
|
|
52
|
+
"ordered-list": "sectionList",
|
|
53
|
+
checklist: "sectionList",
|
|
54
|
+
toggle: "sectionList",
|
|
55
|
+
blockquote: "sectionBlock",
|
|
56
|
+
"horizontal-rule": "sectionBlock",
|
|
57
|
+
table: "sectionLayout",
|
|
58
|
+
"columns-2": "sectionLayout",
|
|
59
|
+
"columns-3": "sectionLayout",
|
|
60
|
+
tabs: "sectionLayout",
|
|
61
|
+
link: "sectionMedia",
|
|
62
|
+
image: "sectionMedia",
|
|
62
63
|
};
|
|
63
|
-
const SECTION_ORDER = [
|
|
64
|
+
const SECTION_ORDER: EditorMessageKey[] = [
|
|
65
|
+
"sectionFrequent",
|
|
66
|
+
"sectionBasic",
|
|
67
|
+
"sectionList",
|
|
68
|
+
"sectionBlock",
|
|
69
|
+
"sectionLayout",
|
|
70
|
+
"sectionMedia",
|
|
71
|
+
];
|
|
64
72
|
|
|
65
73
|
const SLASH_MENU_ITEMS_DATA: {
|
|
66
74
|
feature: ToolbarFeature;
|
|
67
|
-
|
|
75
|
+
labelKey: EditorMessageKey;
|
|
68
76
|
keywords: string;
|
|
69
77
|
icon: Component<{ size?: number }>;
|
|
70
78
|
/** 항목 오른쪽에 작게 보여 줄 입력 규칙. 없으면 안 그린다. */
|
|
@@ -74,19 +82,21 @@
|
|
|
74
82
|
* ⚠️ 토글 제목처럼 **같은 feature 인데 다른 자리**에 놓아야 하는 것 때문에 필요하다
|
|
75
83
|
* (셋 다 `toggle` 이지만 토글은 리스트, 토글 제목은 제목 옆이 맞다).
|
|
76
84
|
*/
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
/** `labelKey` 의 `{…}` 자리 값 (토글 제목 1~3 처럼 같은 키를 나눠 쓸 때). */
|
|
86
|
+
labelParams?: Record<string, string | number>;
|
|
87
|
+
section?: EditorMessageKey;
|
|
88
|
+
command: (editor: Editor, t: EditorTranslator) => void;
|
|
79
89
|
}[] = [
|
|
80
90
|
{
|
|
81
91
|
feature: "paragraph",
|
|
82
|
-
|
|
92
|
+
labelKey: "paragraph",
|
|
83
93
|
keywords: "paragraph text 본문 단락",
|
|
84
94
|
icon: Type,
|
|
85
95
|
command: (editor) => editor.chain().focus().setParagraph().run(),
|
|
86
96
|
},
|
|
87
97
|
{
|
|
88
98
|
feature: "h1",
|
|
89
|
-
|
|
99
|
+
labelKey: "heading1",
|
|
90
100
|
keywords: "heading h1 제목",
|
|
91
101
|
icon: Heading1,
|
|
92
102
|
shortcut: "# ",
|
|
@@ -95,7 +105,7 @@
|
|
|
95
105
|
},
|
|
96
106
|
{
|
|
97
107
|
feature: "h2",
|
|
98
|
-
|
|
108
|
+
labelKey: "heading2",
|
|
99
109
|
keywords: "heading h2 제목",
|
|
100
110
|
icon: Heading2,
|
|
101
111
|
shortcut: "## ",
|
|
@@ -104,7 +114,7 @@
|
|
|
104
114
|
},
|
|
105
115
|
{
|
|
106
116
|
feature: "h3",
|
|
107
|
-
|
|
117
|
+
labelKey: "heading3",
|
|
108
118
|
keywords: "heading h3 제목",
|
|
109
119
|
icon: Heading3,
|
|
110
120
|
shortcut: "### ",
|
|
@@ -113,7 +123,7 @@
|
|
|
113
123
|
},
|
|
114
124
|
{
|
|
115
125
|
feature: "bullet-list",
|
|
116
|
-
|
|
126
|
+
labelKey: "bulletList",
|
|
117
127
|
keywords: "bullet list 목록 리스트",
|
|
118
128
|
icon: List,
|
|
119
129
|
shortcut: "- ",
|
|
@@ -121,7 +131,7 @@
|
|
|
121
131
|
},
|
|
122
132
|
{
|
|
123
133
|
feature: "ordered-list",
|
|
124
|
-
|
|
134
|
+
labelKey: "orderedList",
|
|
125
135
|
keywords: "ordered number list 번호 리스트",
|
|
126
136
|
icon: ListOrdered,
|
|
127
137
|
shortcut: "1. ",
|
|
@@ -129,7 +139,7 @@
|
|
|
129
139
|
},
|
|
130
140
|
{
|
|
131
141
|
feature: "checklist",
|
|
132
|
-
|
|
142
|
+
labelKey: "taskList",
|
|
133
143
|
keywords: "checklist task todo 체크 할일",
|
|
134
144
|
icon: CheckSquare,
|
|
135
145
|
shortcut: "[] ",
|
|
@@ -137,7 +147,7 @@
|
|
|
137
147
|
},
|
|
138
148
|
{
|
|
139
149
|
feature: "blockquote",
|
|
140
|
-
|
|
150
|
+
labelKey: "blockquote",
|
|
141
151
|
keywords: "quote blockquote 인용",
|
|
142
152
|
icon: Quote,
|
|
143
153
|
shortcut: "\" ",
|
|
@@ -145,7 +155,7 @@
|
|
|
145
155
|
},
|
|
146
156
|
{
|
|
147
157
|
feature: "horizontal-rule",
|
|
148
|
-
|
|
158
|
+
labelKey: "divider",
|
|
149
159
|
keywords: "divider hr horizontal rule 구분",
|
|
150
160
|
icon: Minus,
|
|
151
161
|
shortcut: "---",
|
|
@@ -153,7 +163,7 @@
|
|
|
153
163
|
},
|
|
154
164
|
{
|
|
155
165
|
feature: "code-block",
|
|
156
|
-
|
|
166
|
+
labelKey: "code",
|
|
157
167
|
keywords: "code 코드 블록 cpp c++ python 파이썬",
|
|
158
168
|
icon: Code2,
|
|
159
169
|
shortcut: "```",
|
|
@@ -162,7 +172,7 @@
|
|
|
162
172
|
},
|
|
163
173
|
{
|
|
164
174
|
feature: "math",
|
|
165
|
-
|
|
175
|
+
labelKey: "math",
|
|
166
176
|
keywords: "math latex tex 수식 공식 수학 katex 시그마 분수",
|
|
167
177
|
icon: Sigma,
|
|
168
178
|
shortcut: "$$",
|
|
@@ -172,7 +182,7 @@
|
|
|
172
182
|
},
|
|
173
183
|
{
|
|
174
184
|
feature: "toggle",
|
|
175
|
-
|
|
185
|
+
labelKey: "toggle",
|
|
176
186
|
keywords: "toggle details 접기 펼치기 토글",
|
|
177
187
|
icon: ChevronRight,
|
|
178
188
|
shortcut: "> ",
|
|
@@ -188,8 +198,9 @@
|
|
|
188
198
|
*/
|
|
189
199
|
{
|
|
190
200
|
feature: "toggle",
|
|
191
|
-
|
|
192
|
-
|
|
201
|
+
labelKey: "toggleHeading",
|
|
202
|
+
labelParams: { level: 1 },
|
|
203
|
+
section: "sectionBasic",
|
|
193
204
|
keywords: "toggle heading 접기 제목 토글제목 h1",
|
|
194
205
|
icon: ToggleHeading1,
|
|
195
206
|
shortcut: "# > ",
|
|
@@ -197,8 +208,9 @@
|
|
|
197
208
|
},
|
|
198
209
|
{
|
|
199
210
|
feature: "toggle",
|
|
200
|
-
|
|
201
|
-
|
|
211
|
+
labelKey: "toggleHeading",
|
|
212
|
+
labelParams: { level: 2 },
|
|
213
|
+
section: "sectionBasic",
|
|
202
214
|
keywords: "toggle heading 접기 제목 토글제목 h2",
|
|
203
215
|
icon: ToggleHeading2,
|
|
204
216
|
shortcut: "## > ",
|
|
@@ -206,8 +218,9 @@
|
|
|
206
218
|
},
|
|
207
219
|
{
|
|
208
220
|
feature: "toggle",
|
|
209
|
-
|
|
210
|
-
|
|
221
|
+
labelKey: "toggleHeading",
|
|
222
|
+
labelParams: { level: 3 },
|
|
223
|
+
section: "sectionBasic",
|
|
211
224
|
keywords: "toggle heading 접기 제목 토글제목 h3",
|
|
212
225
|
icon: ToggleHeading3,
|
|
213
226
|
shortcut: "### > ",
|
|
@@ -215,7 +228,7 @@
|
|
|
215
228
|
},
|
|
216
229
|
{
|
|
217
230
|
feature: "table",
|
|
218
|
-
|
|
231
|
+
labelKey: "table",
|
|
219
232
|
keywords: "table 표 테이블",
|
|
220
233
|
icon: TableIcon,
|
|
221
234
|
command: (editor) =>
|
|
@@ -223,59 +236,59 @@
|
|
|
223
236
|
},
|
|
224
237
|
{
|
|
225
238
|
feature: "columns-2",
|
|
226
|
-
|
|
239
|
+
labelKey: "columns2",
|
|
227
240
|
keywords: "column 컬럼 2단 분할",
|
|
228
241
|
icon: Columns2,
|
|
229
242
|
command: (editor) => editor.chain().focus().setColumns(2).run(),
|
|
230
243
|
},
|
|
231
244
|
{
|
|
232
245
|
feature: "columns-3",
|
|
233
|
-
|
|
246
|
+
labelKey: "columns3",
|
|
234
247
|
keywords: "column 컬럼 3단 분할",
|
|
235
248
|
icon: Columns3,
|
|
236
249
|
command: (editor) => editor.chain().focus().setColumns(3).run(),
|
|
237
250
|
},
|
|
238
251
|
{
|
|
239
252
|
feature: "tabs",
|
|
240
|
-
|
|
253
|
+
labelKey: "tabs",
|
|
241
254
|
keywords: "tab tabs 탭 탭블록 전환 분할",
|
|
242
255
|
icon: PanelTop,
|
|
243
256
|
command: (editor) => editor.chain().focus().setTabs(3).run(),
|
|
244
257
|
},
|
|
245
258
|
{
|
|
246
259
|
feature: "image",
|
|
247
|
-
|
|
260
|
+
labelKey: "image",
|
|
248
261
|
keywords: "image 이미지 사진 img",
|
|
249
262
|
icon: ImageIcon,
|
|
250
|
-
command: (editor) => {
|
|
251
|
-
const url = window.prompt("
|
|
263
|
+
command: (editor, t) => {
|
|
264
|
+
const url = window.prompt(t("promptImageUrl"));
|
|
252
265
|
if (url) editor.chain().focus().setImage({ src: url }).run();
|
|
253
266
|
},
|
|
254
267
|
},
|
|
255
268
|
{
|
|
256
269
|
feature: "video",
|
|
257
|
-
|
|
270
|
+
labelKey: "video",
|
|
258
271
|
keywords: "video 영상 유튜브 youtube vimeo 동영상",
|
|
259
272
|
icon: Youtube,
|
|
260
|
-
command: (editor) => {
|
|
273
|
+
command: (editor, t) => {
|
|
261
274
|
// 붙여넣은 주소는 `setVideoEmbed` 가 임베드용으로 바꿔 준다.
|
|
262
|
-
const url = window.prompt(
|
|
275
|
+
const url = window.prompt(t("promptVideoUrl"));
|
|
263
276
|
if (url) editor.chain().focus().setVideoEmbed({ src: url }).run();
|
|
264
277
|
},
|
|
265
278
|
},
|
|
266
279
|
{
|
|
267
280
|
feature: "mbus",
|
|
268
|
-
|
|
281
|
+
labelKey: "mbusVideo",
|
|
269
282
|
keywords: "mbus video 미디버스 영상",
|
|
270
283
|
icon: Tv,
|
|
271
|
-
command: (editor) => {
|
|
272
|
-
const url = window.prompt("
|
|
284
|
+
command: (editor, t) => {
|
|
285
|
+
const url = window.prompt(t("promptMbusUrl"));
|
|
273
286
|
if (url) editor.chain().focus().setMbusVideo({ src: url }).run();
|
|
274
287
|
},
|
|
275
288
|
},
|
|
276
289
|
{
|
|
277
290
|
feature: "card",
|
|
278
|
-
|
|
291
|
+
labelKey: "card",
|
|
279
292
|
keywords: "card 카드 상자 박스 강조 배경",
|
|
280
293
|
icon: SquareDashed,
|
|
281
294
|
command: (editor) => {
|
|
@@ -284,11 +297,11 @@
|
|
|
284
297
|
},
|
|
285
298
|
{
|
|
286
299
|
feature: "link",
|
|
287
|
-
|
|
300
|
+
labelKey: "link",
|
|
288
301
|
keywords: "link url 링크 하이퍼",
|
|
289
302
|
icon: LinkIcon,
|
|
290
|
-
command: (editor) => {
|
|
291
|
-
const url = window.prompt("
|
|
303
|
+
command: (editor, t) => {
|
|
304
|
+
const url = window.prompt(t("promptLinkUrl"));
|
|
292
305
|
if (url)
|
|
293
306
|
editor
|
|
294
307
|
.chain()
|
|
@@ -311,6 +324,7 @@
|
|
|
311
324
|
onPromptLink,
|
|
312
325
|
onPromptMbus,
|
|
313
326
|
onPromptVideo,
|
|
327
|
+
t = defaultTranslator,
|
|
314
328
|
}: {
|
|
315
329
|
editor: Editor;
|
|
316
330
|
features: Set<ToolbarFeature>;
|
|
@@ -330,6 +344,8 @@
|
|
|
330
344
|
* 기본 대화상자라 화면이 멈추고 앱과 모양이 따로 논다(사용자 지적).
|
|
331
345
|
*/
|
|
332
346
|
onPromptVideo?: PromptHandler;
|
|
347
|
+
/** 에디터 UI 번역 함수. 미주입 시 ko. */
|
|
348
|
+
t?: EditorTranslator;
|
|
333
349
|
} = $props();
|
|
334
350
|
|
|
335
351
|
async function runItem(item: (typeof SLASH_MENU_ITEMS_DATA)[number]) {
|
|
@@ -358,7 +374,7 @@
|
|
|
358
374
|
if (url) editor.chain().focus().setMbusVideo({ src: url }).run();
|
|
359
375
|
return;
|
|
360
376
|
}
|
|
361
|
-
item.command(editor);
|
|
377
|
+
item.command(editor, t);
|
|
362
378
|
}
|
|
363
379
|
|
|
364
380
|
let selectedIndex = $state(0);
|
|
@@ -370,7 +386,7 @@
|
|
|
370
386
|
if (onFileUpload) {
|
|
371
387
|
items.push({
|
|
372
388
|
feature: "file" as ToolbarFeature,
|
|
373
|
-
|
|
389
|
+
labelKey: "fileAttach",
|
|
374
390
|
keywords: "file attach 파일 첨부",
|
|
375
391
|
icon: Paperclip,
|
|
376
392
|
command: () => onFileUpload!(),
|
|
@@ -379,7 +395,7 @@
|
|
|
379
395
|
if (onPdfUpload) {
|
|
380
396
|
items.push({
|
|
381
397
|
feature: "pdf" as ToolbarFeature,
|
|
382
|
-
|
|
398
|
+
labelKey: "pdfFile",
|
|
383
399
|
keywords: "pdf 파일 문서",
|
|
384
400
|
icon: FileText,
|
|
385
401
|
command: () => onPdfUpload!(),
|
|
@@ -393,7 +409,7 @@
|
|
|
393
409
|
return q
|
|
394
410
|
? allItems.filter(
|
|
395
411
|
(item) =>
|
|
396
|
-
item.
|
|
412
|
+
t(item.labelKey, item.labelParams).toLowerCase().includes(q) ||
|
|
397
413
|
item.keywords.toLowerCase().includes(q),
|
|
398
414
|
)
|
|
399
415
|
: allItems;
|
|
@@ -458,7 +474,7 @@
|
|
|
458
474
|
bind:this={menuEl}
|
|
459
475
|
class="slash-menu z-50 bg-popover border border-border rounded-xl shadow-xl p-2"
|
|
460
476
|
>
|
|
461
|
-
<p class="text-xs text-muted-foreground px-2 py-1"
|
|
477
|
+
<p class="text-xs text-muted-foreground px-2 py-1">{t('noResult')}</p>
|
|
462
478
|
</div>
|
|
463
479
|
{:else}
|
|
464
480
|
<div
|
|
@@ -467,10 +483,10 @@
|
|
|
467
483
|
>
|
|
468
484
|
{#each SECTION_ORDER as section}
|
|
469
485
|
{@const sectionItems = filtered.filter(
|
|
470
|
-
(it) => (it.section ?? SECTION_MAP[it.feature] ?? '
|
|
486
|
+
(it) => (it.section ?? SECTION_MAP[it.feature] ?? 'sectionBasic') === section,
|
|
471
487
|
)}
|
|
472
488
|
{#if sectionItems.length > 0}
|
|
473
|
-
<p class="slash-section">{section}</p>
|
|
489
|
+
<p class="slash-section">{t(section)}</p>
|
|
474
490
|
{#each sectionItems as item}
|
|
475
491
|
{@const i = filtered.indexOf(item)}
|
|
476
492
|
<button
|
|
@@ -492,7 +508,7 @@
|
|
|
492
508
|
<span class="slash-icon">
|
|
493
509
|
<item.icon size={SI} />
|
|
494
510
|
</span>
|
|
495
|
-
<span class="slash-label">{item.
|
|
511
|
+
<span class="slash-label">{t(item.labelKey, item.labelParams)}</span>
|
|
496
512
|
{#if item.shortcut}
|
|
497
513
|
<!--
|
|
498
514
|
쳐서 만드는 법을 항목 옆에 적어 둔다(사용자 요청). 메뉴를 한 번 쓰고 나면
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Editor } from "@tiptap/core";
|
|
2
2
|
import type { ToolbarFeature, PromptHandler } from "../types";
|
|
3
3
|
import type { Component } from "svelte";
|
|
4
|
+
import { type EditorTranslator } from "../i18n";
|
|
4
5
|
type $$ComponentProps = {
|
|
5
6
|
editor: Editor;
|
|
6
7
|
features: Set<ToolbarFeature>;
|
|
@@ -20,6 +21,8 @@ type $$ComponentProps = {
|
|
|
20
21
|
* 기본 대화상자라 화면이 멈추고 앱과 모양이 따로 논다(사용자 지적).
|
|
21
22
|
*/
|
|
22
23
|
onPromptVideo?: PromptHandler;
|
|
24
|
+
/** 에디터 UI 번역 함수. 미주입 시 ko. */
|
|
25
|
+
t?: EditorTranslator;
|
|
23
26
|
};
|
|
24
27
|
declare const SlashCommandMenu: Component<$$ComponentProps, {}, "">;
|
|
25
28
|
type SlashCommandMenu = ReturnType<typeof SlashCommandMenu>;
|
|
@@ -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;AA8B3C,OAAO,KAAK,EAAiB,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,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;AA8B3C,OAAO,KAAK,EAAiB,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAA4C,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEzF,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;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,8BAA8B;IAC9B,CAAC,CAAC,EAAE,gBAAgB,CAAC;CACtB,CAAC;AAsdJ,QAAA,MAAM,gBAAgB,qCAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|
|
@@ -19,26 +19,34 @@
|
|
|
19
19
|
import { onMount } from "svelte";
|
|
20
20
|
import { cn } from "../utils/cn";
|
|
21
21
|
import { splitCellPreservingHeaders } from "../utils/splitCell";
|
|
22
|
+
import { defaultTranslator, type EditorMessageKey, type EditorTranslator } from "../i18n";
|
|
22
23
|
|
|
23
|
-
const PRESET_COLORS = [
|
|
24
|
-
{
|
|
25
|
-
{
|
|
26
|
-
{
|
|
27
|
-
{
|
|
28
|
-
{
|
|
29
|
-
{
|
|
30
|
-
{
|
|
31
|
-
{
|
|
32
|
-
{
|
|
24
|
+
const PRESET_COLORS: { labelKey: EditorMessageKey; value: string }[] = [
|
|
25
|
+
{ labelKey: "bgNone", value: "" },
|
|
26
|
+
{ labelKey: "bgGray", value: "#f1f5f9" },
|
|
27
|
+
{ labelKey: "bgBlue", value: "#dbeafe" },
|
|
28
|
+
{ labelKey: "bgGreen", value: "#dcfce7" },
|
|
29
|
+
{ labelKey: "bgYellow", value: "#fef9c3" },
|
|
30
|
+
{ labelKey: "bgOrange", value: "#ffedd5" },
|
|
31
|
+
{ labelKey: "bgRed", value: "#fee2e2" },
|
|
32
|
+
{ labelKey: "bgPurple", value: "#ede9fe" },
|
|
33
|
+
{ labelKey: "bgPink", value: "#fce7f3" },
|
|
33
34
|
];
|
|
34
35
|
|
|
35
|
-
const LINE_HEIGHTS = [
|
|
36
|
-
{
|
|
37
|
-
{
|
|
38
|
-
{
|
|
36
|
+
const LINE_HEIGHTS: { labelKey: EditorMessageKey; value: string }[] = [
|
|
37
|
+
{ labelKey: "spacingNarrow", value: "0.8" },
|
|
38
|
+
{ labelKey: "spacingNormal", value: "1.0" },
|
|
39
|
+
{ labelKey: "spacingWide", value: "1.4" },
|
|
39
40
|
];
|
|
40
41
|
|
|
41
|
-
let {
|
|
42
|
+
let {
|
|
43
|
+
editor,
|
|
44
|
+
t = defaultTranslator,
|
|
45
|
+
}: {
|
|
46
|
+
editor: Editor;
|
|
47
|
+
/** 에디터 UI 번역 함수. 미주입 시 ko. */
|
|
48
|
+
t?: EditorTranslator;
|
|
49
|
+
} = $props();
|
|
42
50
|
|
|
43
51
|
let visible = $state(false);
|
|
44
52
|
let pos = $state({ top: 0, left: 0, width: 0 });
|
|
@@ -143,7 +151,7 @@
|
|
|
143
151
|
onmousedown={(e) => e.preventDefault()}
|
|
144
152
|
role="toolbar"
|
|
145
153
|
tabindex="-1"
|
|
146
|
-
aria-label=
|
|
154
|
+
aria-label={t('tableEdit')}
|
|
147
155
|
style="top: {pos.top}px; left: {pos.left}px; width: {pos.width}px"
|
|
148
156
|
>
|
|
149
157
|
<div
|
|
@@ -163,7 +171,7 @@
|
|
|
163
171
|
>
|
|
164
172
|
<ArrowUpToLine size={iconSize} />
|
|
165
173
|
</button>
|
|
166
|
-
<span class="hce-table-btn-tooltip"
|
|
174
|
+
<span class="hce-table-btn-tooltip">{t('rowAddAbove')}</span>
|
|
167
175
|
</div>
|
|
168
176
|
|
|
169
177
|
<div class="hce-table-btn-wrap">
|
|
@@ -179,7 +187,7 @@
|
|
|
179
187
|
>
|
|
180
188
|
<ArrowDownToLine size={iconSize} />
|
|
181
189
|
</button>
|
|
182
|
-
<span class="hce-table-btn-tooltip"
|
|
190
|
+
<span class="hce-table-btn-tooltip">{t('rowAddBelow')}</span>
|
|
183
191
|
</div>
|
|
184
192
|
|
|
185
193
|
<div class="hce-table-btn-wrap">
|
|
@@ -196,7 +204,7 @@
|
|
|
196
204
|
>
|
|
197
205
|
<ArrowLeftToLine size={iconSize} />
|
|
198
206
|
</button>
|
|
199
|
-
<span class="hce-table-btn-tooltip"
|
|
207
|
+
<span class="hce-table-btn-tooltip">{t('colAddLeft')}</span>
|
|
200
208
|
</div>
|
|
201
209
|
|
|
202
210
|
<div class="hce-table-btn-wrap">
|
|
@@ -213,7 +221,7 @@
|
|
|
213
221
|
>
|
|
214
222
|
<ArrowRightToLine size={iconSize} />
|
|
215
223
|
</button>
|
|
216
|
-
<span class="hce-table-btn-tooltip"
|
|
224
|
+
<span class="hce-table-btn-tooltip">{t('colAddRight')}</span>
|
|
217
225
|
</div>
|
|
218
226
|
|
|
219
227
|
<div class="w-px h-5 bg-border mx-0.5"></div>
|
|
@@ -232,7 +240,7 @@
|
|
|
232
240
|
>
|
|
233
241
|
<PanelTop size={iconSize} />
|
|
234
242
|
</button>
|
|
235
|
-
<span class="hce-table-btn-tooltip"
|
|
243
|
+
<span class="hce-table-btn-tooltip">{t('headerRowToggle')}</span>
|
|
236
244
|
</div>
|
|
237
245
|
|
|
238
246
|
<div class="hce-table-btn-wrap">
|
|
@@ -249,7 +257,7 @@
|
|
|
249
257
|
>
|
|
250
258
|
<PanelLeft size={iconSize} />
|
|
251
259
|
</button>
|
|
252
|
-
<span class="hce-table-btn-tooltip"
|
|
260
|
+
<span class="hce-table-btn-tooltip">{t('headerColToggle')}</span>
|
|
253
261
|
</div>
|
|
254
262
|
|
|
255
263
|
<div class="hce-table-btn-wrap">
|
|
@@ -265,7 +273,7 @@
|
|
|
265
273
|
>
|
|
266
274
|
<Combine size={iconSize} />
|
|
267
275
|
</button>
|
|
268
|
-
<span class="hce-table-btn-tooltip"
|
|
276
|
+
<span class="hce-table-btn-tooltip">{t('cellMerge')}</span>
|
|
269
277
|
</div>
|
|
270
278
|
|
|
271
279
|
<div class="hce-table-btn-wrap">
|
|
@@ -281,7 +289,7 @@
|
|
|
281
289
|
>
|
|
282
290
|
<SplitSquareHorizontal size={iconSize} />
|
|
283
291
|
</button>
|
|
284
|
-
<span class="hce-table-btn-tooltip"
|
|
292
|
+
<span class="hce-table-btn-tooltip">{t('cellSplit')}</span>
|
|
285
293
|
</div>
|
|
286
294
|
|
|
287
295
|
<div class="w-px h-5 bg-border mx-0.5"></div>
|
|
@@ -299,7 +307,7 @@
|
|
|
299
307
|
>
|
|
300
308
|
<UnfoldVertical size={iconSize} />
|
|
301
309
|
</button>
|
|
302
|
-
<span class="hce-table-btn-tooltip"
|
|
310
|
+
<span class="hce-table-btn-tooltip">{t('lineSpacing')}</span>
|
|
303
311
|
</div>
|
|
304
312
|
{#if showLineHeight}
|
|
305
313
|
<div
|
|
@@ -337,7 +345,7 @@
|
|
|
337
345
|
showLineHeight = false;
|
|
338
346
|
}}
|
|
339
347
|
>
|
|
340
|
-
{lh.
|
|
348
|
+
{t(lh.labelKey)}
|
|
341
349
|
</button>
|
|
342
350
|
{/each}
|
|
343
351
|
</div>
|
|
@@ -387,7 +395,7 @@
|
|
|
387
395
|
>
|
|
388
396
|
<EqualApproximately size={iconSize} />
|
|
389
397
|
</button>
|
|
390
|
-
<span class="hce-table-btn-tooltip"
|
|
398
|
+
<span class="hce-table-btn-tooltip">{t('widthEqual')}</span>
|
|
391
399
|
</div>
|
|
392
400
|
|
|
393
401
|
<!-- Background color -->
|
|
@@ -403,7 +411,7 @@
|
|
|
403
411
|
>
|
|
404
412
|
<Paintbrush size={iconSize} />
|
|
405
413
|
</button>
|
|
406
|
-
<span class="hce-table-btn-tooltip"
|
|
414
|
+
<span class="hce-table-btn-tooltip">{t('cellBackground')}</span>
|
|
407
415
|
</div>
|
|
408
416
|
{#if showColors}
|
|
409
417
|
<div
|
|
@@ -413,13 +421,13 @@
|
|
|
413
421
|
<p
|
|
414
422
|
class="text-xs font-medium text-muted-foreground mb-1.5 px-1"
|
|
415
423
|
>
|
|
416
|
-
|
|
424
|
+
{t('background')}
|
|
417
425
|
</p>
|
|
418
426
|
<div class="grid grid-cols-3 gap-1">
|
|
419
427
|
{#each PRESET_COLORS as c}
|
|
420
428
|
<button
|
|
421
429
|
type="button"
|
|
422
|
-
title={c.
|
|
430
|
+
title={t(c.labelKey)}
|
|
423
431
|
class="w-full h-7 rounded-md border border-border transition-transform hover:scale-110"
|
|
424
432
|
style="background: {c.value ||
|
|
425
433
|
'transparent'}; {!c.value
|
|
@@ -456,7 +464,7 @@
|
|
|
456
464
|
>
|
|
457
465
|
<RowsIcon size={iconSize} />
|
|
458
466
|
</button>
|
|
459
|
-
<span class="hce-table-btn-tooltip"
|
|
467
|
+
<span class="hce-table-btn-tooltip">{t('rowDelete')}</span>
|
|
460
468
|
</div>
|
|
461
469
|
|
|
462
470
|
<div class="hce-table-btn-wrap">
|
|
@@ -472,7 +480,7 @@
|
|
|
472
480
|
>
|
|
473
481
|
<ColumnsIcon size={iconSize} />
|
|
474
482
|
</button>
|
|
475
|
-
<span class="hce-table-btn-tooltip"
|
|
483
|
+
<span class="hce-table-btn-tooltip">{t('colDelete')}</span>
|
|
476
484
|
</div>
|
|
477
485
|
|
|
478
486
|
<div class="hce-table-btn-wrap">
|
|
@@ -488,7 +496,7 @@
|
|
|
488
496
|
>
|
|
489
497
|
<Trash2 size={iconSize} />
|
|
490
498
|
</button>
|
|
491
|
-
<span class="hce-table-btn-tooltip"
|
|
499
|
+
<span class="hce-table-btn-tooltip">{t('tableDelete')}</span>
|
|
492
500
|
</div>
|
|
493
501
|
</div>
|
|
494
502
|
</div>
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { Editor } from "@tiptap/core";
|
|
2
|
+
import { type EditorTranslator } from "../i18n";
|
|
2
3
|
type $$ComponentProps = {
|
|
3
4
|
editor: Editor;
|
|
5
|
+
/** 에디터 UI 번역 함수. 미주입 시 ko. */
|
|
6
|
+
t?: EditorTranslator;
|
|
4
7
|
};
|
|
5
8
|
declare const TableBubbleMenu: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
9
|
type TableBubbleMenu = ReturnType<typeof TableBubbleMenu>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableBubbleMenu.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TableBubbleMenu.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"TableBubbleMenu.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TableBubbleMenu.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAoB3C,OAAO,EAA4C,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEzF,KAAK,gBAAgB,GAAI;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,CAAC,CAAC,EAAE,gBAAgB,CAAC;CACtB,CAAC;AAyYJ,QAAA,MAAM,eAAe,sDAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|