@teriusu/rich-editor 0.9.13 → 0.10.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/FixedToolbar.svelte +18 -3
- package/dist/components/FixedToolbar.svelte.d.ts.map +1 -1
- package/dist/components/SlashCommandMenu.svelte +18 -3
- package/dist/components/SlashCommandMenu.svelte.d.ts.map +1 -1
- package/dist/components/TipTapEditor.svelte +7 -0
- package/dist/components/TipTapEditor.svelte.d.ts.map +1 -1
- package/dist/components/icons/ToggleHeading1.svelte +12 -0
- package/dist/components/icons/ToggleHeading1.svelte.d.ts +7 -0
- package/dist/components/icons/ToggleHeading1.svelte.d.ts.map +1 -0
- package/dist/components/icons/ToggleHeading2.svelte +8 -0
- package/dist/components/icons/ToggleHeading2.svelte.d.ts +7 -0
- package/dist/components/icons/ToggleHeading2.svelte.d.ts.map +1 -0
- package/dist/components/icons/ToggleHeading3.svelte +8 -0
- package/dist/components/icons/ToggleHeading3.svelte.d.ts +7 -0
- package/dist/components/icons/ToggleHeading3.svelte.d.ts.map +1 -0
- package/dist/components/icons/ToggleHeadingIcon.svelte +68 -0
- package/dist/components/icons/ToggleHeadingIcon.svelte.d.ts +9 -0
- package/dist/components/icons/ToggleHeadingIcon.svelte.d.ts.map +1 -0
- package/dist/extensions/TabsBlock.d.ts +18 -0
- package/dist/extensions/TabsBlock.d.ts.map +1 -0
- package/dist/extensions/TabsBlock.js +697 -0
- package/dist/extensions/TabsBlock.test.d.ts +2 -0
- package/dist/extensions/TabsBlock.test.d.ts.map +1 -0
- package/dist/extensions/TabsBlock.test.js +539 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/styles/editor.css +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -2
- package/dist/utils/lowlight.d.ts +1 -1
- package/dist/utils/lowlight.d.ts.map +1 -1
- package/dist/utils/lowlight.js +12 -1
- package/dist/utils/lowlight.test.js +14 -0
- package/dist/utils/sanitize.d.ts.map +1 -1
- package/dist/utils/sanitize.js +2 -0
- package/package.json +1 -1
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
Paperclip,
|
|
29
29
|
Columns2,
|
|
30
30
|
Columns3,
|
|
31
|
+
PanelTop,
|
|
31
32
|
SquareDashed,
|
|
32
33
|
Tv,
|
|
33
34
|
Youtube,
|
|
@@ -37,6 +38,7 @@
|
|
|
37
38
|
} from "lucide-svelte";
|
|
38
39
|
import { cn } from "../utils/cn";
|
|
39
40
|
import { insertTableSized } from "../utils/table";
|
|
41
|
+
import ToggleHeadingIcon from "./icons/ToggleHeadingIcon.svelte";
|
|
40
42
|
import InputModal from "./InputModal.svelte";
|
|
41
43
|
import type { ToolbarFeature, PromptHandler } from "../types";
|
|
42
44
|
|
|
@@ -206,6 +208,7 @@
|
|
|
206
208
|
has("table") ||
|
|
207
209
|
has("columns-2") ||
|
|
208
210
|
has("columns-3") ||
|
|
211
|
+
has("tabs") ||
|
|
209
212
|
has("horizontal-rule") ||
|
|
210
213
|
has("code-block") ||
|
|
211
214
|
has("math"),
|
|
@@ -427,9 +430,11 @@
|
|
|
427
430
|
토글 제목 — 접히는 제목. 만드는 일은 입력 규칙(`# > `)과 **같은 커맨드**가 한다.
|
|
428
431
|
제목 바로 아래에 두는 게 맞지만 이 메뉴는 `본문 → 제목 → 목록 → 블록` 순이라,
|
|
429
432
|
토글 옆에 붙여 **접히는 것끼리** 모은다.
|
|
433
|
+
|
|
434
|
+
⚠️ 아이콘은 `제목 N` 과 **달라야 한다.** 한동안 둘 다 lucide `HeadingN` 이라 메뉴에서
|
|
435
|
+
구분이 안 됐다(사용자 지적) — 삼각형이 붙은 `ToggleHeadingIcon` 을 쓴다.
|
|
430
436
|
-->
|
|
431
437
|
{#each [1, 2, 3] as level}
|
|
432
|
-
{@const Icon = level === 1 ? Heading1 : level === 2 ? Heading2 : Heading3}
|
|
433
438
|
<button
|
|
434
439
|
type="button"
|
|
435
440
|
class={cn(
|
|
@@ -445,7 +450,7 @@
|
|
|
445
450
|
.run(),
|
|
446
451
|
)}
|
|
447
452
|
>
|
|
448
|
-
<
|
|
453
|
+
<ToggleHeadingIcon size={14} level={level as 1 | 2 | 3} /> 토글 제목 {level}
|
|
449
454
|
<span class="hce-menu-shortcut">{'#'.repeat(level)} > </span>
|
|
450
455
|
</button>
|
|
451
456
|
{/each}
|
|
@@ -678,7 +683,7 @@
|
|
|
678
683
|
</button>
|
|
679
684
|
{/if}
|
|
680
685
|
|
|
681
|
-
{#if has('horizontal-rule') || has('columns-2') || has('columns-3') || has('card')}
|
|
686
|
+
{#if has('horizontal-rule') || has('columns-2') || has('columns-3') || has('tabs') || has('card')}
|
|
682
687
|
<div class="h-px bg-border my-1"></div>
|
|
683
688
|
{/if}
|
|
684
689
|
{#if has('horizontal-rule')}
|
|
@@ -714,6 +719,16 @@
|
|
|
714
719
|
<Columns3 size={14} /> 3단 컬럼
|
|
715
720
|
</button>
|
|
716
721
|
{/if}
|
|
722
|
+
{#if has('tabs')}
|
|
723
|
+
<button
|
|
724
|
+
type="button"
|
|
725
|
+
class="w-full text-left px-2.5 py-1.5 text-xs transition-colors flex items-center gap-2 hover:bg-muted"
|
|
726
|
+
onclick={() =>
|
|
727
|
+
runInsert(() => editor.chain().focus().setTabs(3).run())}
|
|
728
|
+
>
|
|
729
|
+
<PanelTop size={14} /> 탭
|
|
730
|
+
</button>
|
|
731
|
+
{/if}
|
|
717
732
|
{#if has('card')}
|
|
718
733
|
<button
|
|
719
734
|
type="button"
|
|
@@ -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;
|
|
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;AAwCtC,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;;;;;OAKG;IACH,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,0CAA0C;IAC1C,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAuiBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
|
|
@@ -18,12 +18,16 @@
|
|
|
18
18
|
Paperclip,
|
|
19
19
|
Columns2,
|
|
20
20
|
Columns3,
|
|
21
|
+
PanelTop,
|
|
21
22
|
Type,
|
|
22
23
|
Tv,
|
|
23
24
|
Youtube,
|
|
24
25
|
SquareDashed,
|
|
25
26
|
Sigma,
|
|
26
27
|
} from "lucide-svelte";
|
|
28
|
+
import ToggleHeading1 from "./icons/ToggleHeading1.svelte";
|
|
29
|
+
import ToggleHeading2 from "./icons/ToggleHeading2.svelte";
|
|
30
|
+
import ToggleHeading3 from "./icons/ToggleHeading3.svelte";
|
|
27
31
|
import { insertTableSized } from "../utils/table";
|
|
28
32
|
import type { SlashMenuItem, ToolbarFeature, PromptHandler } from "../types";
|
|
29
33
|
import type { Component } from "svelte";
|
|
@@ -52,6 +56,7 @@
|
|
|
52
56
|
table: "레이아웃",
|
|
53
57
|
"columns-2": "레이아웃",
|
|
54
58
|
"columns-3": "레이아웃",
|
|
59
|
+
tabs: "레이아웃",
|
|
55
60
|
link: "미디어",
|
|
56
61
|
image: "미디어",
|
|
57
62
|
};
|
|
@@ -177,13 +182,16 @@
|
|
|
177
182
|
* 토글 제목 — 접히는 제목. 입력 규칙(`# > `)으로도 만들 수 있지만 그것만 있으면
|
|
178
183
|
* **메뉴에는 없는 기능**이 된다(사용자 요청으로 추가).
|
|
179
184
|
* 만드는 일은 입력 규칙과 **같은 커맨드**가 한다(`setToggleHeading`).
|
|
185
|
+
*
|
|
186
|
+
* ⚠️ 아이콘은 `제목 N` 과 **달라야 한다.** 한동안 둘 다 lucide `HeadingN` 이라 메뉴에서
|
|
187
|
+
* 구분이 안 됐다(사용자 지적) — 삼각형이 붙은 `ToggleHeadingN` 을 쓴다.
|
|
180
188
|
*/
|
|
181
189
|
{
|
|
182
190
|
feature: "toggle",
|
|
183
191
|
label: "토글 제목 1",
|
|
184
192
|
section: "기본",
|
|
185
193
|
keywords: "toggle heading 접기 제목 토글제목 h1",
|
|
186
|
-
icon:
|
|
194
|
+
icon: ToggleHeading1,
|
|
187
195
|
shortcut: "# > ",
|
|
188
196
|
command: (editor) => editor.chain().focus().setToggleHeading(1).run(),
|
|
189
197
|
},
|
|
@@ -192,7 +200,7 @@
|
|
|
192
200
|
label: "토글 제목 2",
|
|
193
201
|
section: "기본",
|
|
194
202
|
keywords: "toggle heading 접기 제목 토글제목 h2",
|
|
195
|
-
icon:
|
|
203
|
+
icon: ToggleHeading2,
|
|
196
204
|
shortcut: "## > ",
|
|
197
205
|
command: (editor) => editor.chain().focus().setToggleHeading(2).run(),
|
|
198
206
|
},
|
|
@@ -201,7 +209,7 @@
|
|
|
201
209
|
label: "토글 제목 3",
|
|
202
210
|
section: "기본",
|
|
203
211
|
keywords: "toggle heading 접기 제목 토글제목 h3",
|
|
204
|
-
icon:
|
|
212
|
+
icon: ToggleHeading3,
|
|
205
213
|
shortcut: "### > ",
|
|
206
214
|
command: (editor) => editor.chain().focus().setToggleHeading(3).run(),
|
|
207
215
|
},
|
|
@@ -227,6 +235,13 @@
|
|
|
227
235
|
icon: Columns3,
|
|
228
236
|
command: (editor) => editor.chain().focus().setColumns(3).run(),
|
|
229
237
|
},
|
|
238
|
+
{
|
|
239
|
+
feature: "tabs",
|
|
240
|
+
label: "탭",
|
|
241
|
+
keywords: "tab tabs 탭 탭블록 전환 분할",
|
|
242
|
+
icon: PanelTop,
|
|
243
|
+
command: (editor) => editor.chain().focus().setTabs(3).run(),
|
|
244
|
+
},
|
|
230
245
|
{
|
|
231
246
|
feature: "image",
|
|
232
247
|
label: "이미지",
|
|
@@ -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;AA8B3C,OAAO,KAAK,EAAiB,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC7E,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;;;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;CAC/B,CAAC;AAwcJ,QAAA,MAAM,gBAAgB,qCAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
|
|
@@ -123,6 +123,7 @@
|
|
|
123
123
|
import { PdfBlock } from "../extensions/PdfBlock";
|
|
124
124
|
import { Columns } from "../extensions/Columns";
|
|
125
125
|
import { Column } from "../extensions/Column";
|
|
126
|
+
import { TabsBlock, Tab } from "../extensions/TabsBlock";
|
|
126
127
|
import { transformLegacyHtml } from "../utils/sanitize";
|
|
127
128
|
import { Indent } from "../extensions/Indent";
|
|
128
129
|
import { FileAttachment } from "../extensions/FileAttachment";
|
|
@@ -611,6 +612,12 @@
|
|
|
611
612
|
: [MathDisplay.configure({ promptMath })]),
|
|
612
613
|
Columns,
|
|
613
614
|
Column,
|
|
615
|
+
/*
|
|
616
|
+
* 탭 블록도 `Columns`/`Column` 처럼 **컨테이너와 자식을 함께** 등록한다.
|
|
617
|
+
* 한쪽만 넣으면 스키마가 서지 않는다(`tabs` 의 내용이 `tab+` 다).
|
|
618
|
+
*/
|
|
619
|
+
TabsBlock,
|
|
620
|
+
Tab,
|
|
614
621
|
CodeBlockTopEscape,
|
|
615
622
|
Indent,
|
|
616
623
|
FixedDetails,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AA8FA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AA4BtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"TipTapEditor.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TipTapEditor.svelte.ts"],"names":[],"mappings":"AA8FA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AA4BtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAWjD,OAAO,EAA2B,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAQ9E,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,uDAAuD;IACvD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wCAAwC;IACxC,sBAAsB,CAAC,EAAE,aAAa,CAAC;IACvC,mDAAmD;IACnD,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,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;AA0vBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/*
|
|
3
|
+
* 단계별 얇은 껍데기. 슬래시 메뉴는 아이콘을 `Component<{ size?: number }>` 로 **데이터
|
|
4
|
+
* 표에 담아** 두고 `<item.icon size={SI} />` 로만 그린다 — 거기엔 `level` 을 넘길 자리가
|
|
5
|
+
* 없다. 그래서 단계를 미리 박아 둔 컴포넌트를 셋 만든다.
|
|
6
|
+
*/
|
|
7
|
+
import ToggleHeadingIcon from "./ToggleHeadingIcon.svelte";
|
|
8
|
+
|
|
9
|
+
let { size = 24 }: { size?: number } = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<ToggleHeadingIcon {size} level={1} />
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
size?: number;
|
|
3
|
+
};
|
|
4
|
+
declare const ToggleHeading1: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
5
|
+
type ToggleHeading1 = ReturnType<typeof ToggleHeading1>;
|
|
6
|
+
export default ToggleHeading1;
|
|
7
|
+
//# sourceMappingURL=ToggleHeading1.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleHeading1.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/icons/ToggleHeading1.svelte.ts"],"names":[],"mappings":"AAUC,KAAK,gBAAgB,GAAI;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAY5C,QAAA,MAAM,cAAc,sDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
size?: number;
|
|
3
|
+
};
|
|
4
|
+
declare const ToggleHeading2: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
5
|
+
type ToggleHeading2 = ReturnType<typeof ToggleHeading2>;
|
|
6
|
+
export default ToggleHeading2;
|
|
7
|
+
//# sourceMappingURL=ToggleHeading2.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleHeading2.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/icons/ToggleHeading2.svelte.ts"],"names":[],"mappings":"AAMC,KAAK,gBAAgB,GAAI;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAY5C,QAAA,MAAM,cAAc,sDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
size?: number;
|
|
3
|
+
};
|
|
4
|
+
declare const ToggleHeading3: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
5
|
+
type ToggleHeading3 = ReturnType<typeof ToggleHeading3>;
|
|
6
|
+
export default ToggleHeading3;
|
|
7
|
+
//# sourceMappingURL=ToggleHeading3.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleHeading3.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/icons/ToggleHeading3.svelte.ts"],"names":[],"mappings":"AAMC,KAAK,gBAAgB,GAAI;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAY5C,QAAA,MAAM,cAAc,sDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/*
|
|
3
|
+
* 토글 제목 아이콘 — 펼침 삼각형 + 제목 단계(H1·H2·H3).
|
|
4
|
+
*
|
|
5
|
+
* 메뉴에서 `토글 제목 N` 이 `제목 N` 과 **똑같은 lucide `HeadingN` 아이콘**을 쓰고 있어서,
|
|
6
|
+
* 목록만 보고는 둘을 구분할 수 없었다(사용자 지적). 접힌다는 사실을 아이콘이 말해야 한다.
|
|
7
|
+
*
|
|
8
|
+
* 삼각형은 실제 토글 손잡이(`editor.css` 의 `[data-type="details"] > button::after`,
|
|
9
|
+
* 밑변 7px · 높이 11px 채운 삼각형)와 **같은 모양·같은 비율(0.63)** 로 맞춘다 — 메뉴에서 고른
|
|
10
|
+
* 것과 문서에 생긴 것이 같아 보여야 한다. 거기 적힌 교훈도 그대로 적용된다: **작으면 점처럼
|
|
11
|
+
* 보인다.**
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ **상자를 정사각(24×24)으로 유지한다.** 슬래시 메뉴는 아이콘을 20×20 칩(`.slash-icon`)
|
|
14
|
+
* 안에 가운데 정렬로 넣고, 고정 툴바 메뉴는 `flex gap-2` 로 라벨을 잇는다. 삼각형을 글자
|
|
15
|
+
* 왼쪽 **바깥**에 덧대 폭을 넓히면 그 줄만 칩을 넘치거나 라벨이 밀린다.
|
|
16
|
+
*
|
|
17
|
+
* 그래서 삼각형은 lucide 가 비워 두는 왼쪽 여백(x 0~4)에 넣고, 제목 글자는 **줄이지 않고**
|
|
18
|
+
* 오른쪽으로 2 만 민다. 14px 로 그려지는 메뉴에서 글자를 줄이면 그만큼 읽기 어려워지고,
|
|
19
|
+
* 바로 위에 붙는 `제목 N` 과 크기가 달라 한 가족으로 안 보인다(0.7~0.9 로 줄인 안을 픽셀로
|
|
20
|
+
* 비교해 고른 값이다). 배율이 1 이라 **획 두께 보정도 필요 없다** — `scale()` 로 줄이면
|
|
21
|
+
* 획까지 같이 줄어 옆 아이콘보다 가늘어진다.
|
|
22
|
+
*/
|
|
23
|
+
interface Props {
|
|
24
|
+
/** 바깥 상자 한 변(px). lucide 아이콘과 같은 뜻이다. */
|
|
25
|
+
size?: number;
|
|
26
|
+
level?: 1 | 2 | 3;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let { size = 24, level = 1 }: Props = $props();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* lucide `heading-1|2|3` 의 **숫자 부분만**. `H` 획 세 개는 세 단계가 공유하므로 아래
|
|
33
|
+
* 마크업에 한 벌만 둔다. (lucide-svelte v0.477.0 의 `iconNode` 와 같은 값)
|
|
34
|
+
*/
|
|
35
|
+
const DIGIT: Record<1 | 2 | 3, string[]> = {
|
|
36
|
+
1: ["m17 12 3-2v8"],
|
|
37
|
+
2: ["M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1"],
|
|
38
|
+
3: [
|
|
39
|
+
"M17.5 10.5c1.7-1 3.5 0 3.5 1.5a2 2 0 0 1-2 2",
|
|
40
|
+
"M17 17.5c2 1.5 4 .3 4-1.5a2 2 0 0 0-2-2",
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<svg
|
|
46
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
47
|
+
width={size}
|
|
48
|
+
height={size}
|
|
49
|
+
viewBox="0 0 24 24"
|
|
50
|
+
fill="none"
|
|
51
|
+
stroke="currentColor"
|
|
52
|
+
stroke-width="2"
|
|
53
|
+
stroke-linecap="round"
|
|
54
|
+
stroke-linejoin="round"
|
|
55
|
+
aria-hidden="true"
|
|
56
|
+
>
|
|
57
|
+
<!-- 펼침 표식. 이 아이콘에서 유일하게 칠하는 요소라 fill·stroke 를 여기서 뒤집는다. -->
|
|
58
|
+
<path d="M1 9 4.7 12 1 15Z" fill="currentColor" stroke="none" />
|
|
59
|
+
<!-- lucide `heading-N` 을 통째로 오른쪽으로 2. `H` 획은 세 단계가 같다. -->
|
|
60
|
+
<g transform="translate(2 0)">
|
|
61
|
+
<path d="M4 12h8" />
|
|
62
|
+
<path d="M4 18V6" />
|
|
63
|
+
<path d="M12 18V6" />
|
|
64
|
+
{#each DIGIT[level] as d}
|
|
65
|
+
<path {d} />
|
|
66
|
+
{/each}
|
|
67
|
+
</g>
|
|
68
|
+
</svg>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** 바깥 상자 한 변(px). lucide 아이콘과 같은 뜻이다. */
|
|
3
|
+
size?: number;
|
|
4
|
+
level?: 1 | 2 | 3;
|
|
5
|
+
}
|
|
6
|
+
declare const ToggleHeadingIcon: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type ToggleHeadingIcon = ReturnType<typeof ToggleHeadingIcon>;
|
|
8
|
+
export default ToggleHeadingIcon;
|
|
9
|
+
//# sourceMappingURL=ToggleHeadingIcon.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleHeadingIcon.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/icons/ToggleHeadingIcon.svelte.ts"],"names":[],"mappings":"AAwBE,UAAU,KAAK;IACb,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACnB;AAoCH,QAAA,MAAM,iBAAiB,2CAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Node } from "@tiptap/core";
|
|
2
|
+
/**
|
|
3
|
+
* 탭 하나. `tabs` 안에서만 산다(`group: ""`).
|
|
4
|
+
*
|
|
5
|
+
* `isolating: true` — 탭 경계 너머로 지우기·병합이 넘어가지 않게 한다. 없으면 탭 맨 앞에서
|
|
6
|
+
* Backspace 를 눌렀을 때 앞 탭의 내용과 합쳐진다.
|
|
7
|
+
*/
|
|
8
|
+
export declare const Tab: Node<any, any>;
|
|
9
|
+
export declare const TabsBlock: Node<any, any>;
|
|
10
|
+
declare module "@tiptap/core" {
|
|
11
|
+
interface Commands<ReturnType> {
|
|
12
|
+
tabs: {
|
|
13
|
+
/** 탭 블록을 넣는다. 탭마다 빈 문단 하나. 기본 3개. */
|
|
14
|
+
setTabs: (count?: number) => ReturnType;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=TabsBlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabsBlock.d.ts","sourceRoot":"","sources":["../../src/extensions/TabsBlock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AA4DrD;;;;;GAKG;AACH,eAAO,MAAM,GAAG,gBAqDd,CAAC;AAEH,eAAO,MAAM,SAAS,gBA6lBpB,CAAC;AAEH,OAAO,QAAQ,cAAc,CAAC;IAC7B,UAAU,QAAQ,CAAC,UAAU;QAC5B,IAAI,EAAE;YACL,qCAAqC;YACrC,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;SACxC,CAAC;KACF;CACD"}
|