@gusun/design-system 0.1.0 → 0.1.1

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.
@@ -1,2 +1,716 @@
1
- import { a as e, n as t, t as n } from "./Editor-wECQz1CV.js";
2
- export { n as Editor, e as EditorToolbar, t as MergeFieldNode };
1
+ import { C as e, F as t, I as n, P as r, T as i, _ as a, a as o, i as s, n as c, s as l } from "./Tabs-C_N6MDdv.js";
2
+ import { o as u, s as d } from "./tokens-CbcaxhkP.js";
3
+ import { Fragment as f, useEffect as p, useLayoutEffect as m, useReducer as h, useRef as g, useState as _ } from "react";
4
+ import { AlignCenter as v, AlignJustify as y, AlignLeft as b, AlignRight as x, Baseline as S, Bold as C, Braces as w, Highlighter as T, Image as E, Italic as D, Link as O, Minus as k, Paperclip as A, Plus as j, Redo2 as M, Strikethrough as N, Table as P, Type as F, Underline as I, Undo2 as L } from "lucide-react";
5
+ import { jsx as R, jsxs as z } from "react/jsx-runtime";
6
+ import { EditorContent as B, useEditor as V } from "@tiptap/react";
7
+ import { StarterKit as H } from "@tiptap/starter-kit";
8
+ import { TextStyle as U } from "@tiptap/extension-text-style";
9
+ import { Color as W } from "@tiptap/extension-color";
10
+ import { Highlight as G } from "@tiptap/extension-highlight";
11
+ import { TextAlign as ee } from "@tiptap/extension-text-align";
12
+ import { Image as te } from "@tiptap/extension-image";
13
+ import { Table as ne, TableCell as re, TableHeader as ie, TableRow as ae } from "@tiptap/extension-table";
14
+ import { Node as oe, mergeAttributes as se } from "@tiptap/core";
15
+ //#region src/components/EditorToolbar.tsx
16
+ var K = (e) => e.preventDefault();
17
+ function q({ icon: e, label: t, active: r = !1, disabled: i = !1, onClick: a }) {
18
+ return /* @__PURE__ */ R(n, {
19
+ variant: "ghost",
20
+ size: "24",
21
+ icon: e,
22
+ disabled: i,
23
+ onClick: a,
24
+ onMouseDown: K,
25
+ "aria-label": t,
26
+ "aria-pressed": r
27
+ });
28
+ }
29
+ function J({ icon: e, label: t, ariaLabel: r }) {
30
+ return t ? /* @__PURE__ */ R(n, {
31
+ variant: "ghost",
32
+ size: "24",
33
+ leftIcon: e,
34
+ onMouseDown: K,
35
+ children: t
36
+ }) : /* @__PURE__ */ R(n, {
37
+ variant: "ghost",
38
+ size: "24",
39
+ icon: e,
40
+ onMouseDown: K,
41
+ title: r,
42
+ "aria-label": r
43
+ });
44
+ }
45
+ function ce() {
46
+ return /* @__PURE__ */ R("span", { className: "mx-spacing-2 self-stretch border-l border-editor-divider" });
47
+ }
48
+ var Y = [
49
+ {
50
+ key: "paragraph",
51
+ label: "본문"
52
+ },
53
+ {
54
+ key: "h1",
55
+ label: "제목 1"
56
+ },
57
+ {
58
+ key: "h2",
59
+ label: "제목 2"
60
+ },
61
+ {
62
+ key: "h3",
63
+ label: "제목 3"
64
+ }
65
+ ];
66
+ function X({ palette: e, current: t, onPick: n }) {
67
+ return /* @__PURE__ */ R(i, {
68
+ width: 80,
69
+ children: /* @__PURE__ */ R("div", {
70
+ className: "bg-list-group-bg py-spacing-4",
71
+ children: e.map((e) => {
72
+ let r = t === e.value || e.value === null && !t, i = e.swatch ?? e.value;
73
+ return /* @__PURE__ */ z("button", {
74
+ type: "button",
75
+ onMouseDown: K,
76
+ onClick: () => n(e.value),
77
+ className: `flex w-full cursor-pointer items-center gap-spacing-4 px-spacing-6 py-spacing-3 text-14 transition-colors hover:bg-list-hover-bg focus:outline-none focus-visible:bg-list-hover-bg ${r ? "text-list-selected-text" : "text-list-default-text"}`,
78
+ children: [/* @__PURE__ */ R("span", {
79
+ className: "inline-block h-[14px] w-[14px] shrink-0 rounded-round-00",
80
+ style: i ? { backgroundColor: i } : void 0
81
+ }), e.label]
82
+ }, e.label);
83
+ })
84
+ })
85
+ });
86
+ }
87
+ function Z({ initialUrl: e = "", placeholder: t, submitLabel: n, onSubmit: r, onRemove: a, removeLabel: o = "해제" }) {
88
+ let [s, c] = _(e), l = () => r(s.trim());
89
+ return /* @__PURE__ */ R(i, {
90
+ width: 300,
91
+ topArea: "input",
92
+ inputValue: s,
93
+ onInputChange: (e) => c(e.target.value),
94
+ inputPlaceholder: t,
95
+ inputProps: {
96
+ autoFocus: !0,
97
+ onKeyDown: (e) => {
98
+ e.key === "Enter" && (e.preventDefault(), l());
99
+ }
100
+ },
101
+ footer: !0,
102
+ footerButtonsFill: !0,
103
+ showCancel: !!a,
104
+ cancelText: o,
105
+ onCancel: a,
106
+ confirmText: n,
107
+ onConfirm: l
108
+ });
109
+ }
110
+ function le({ editor: e, close: t }) {
111
+ return /* @__PURE__ */ R(Z, {
112
+ initialUrl: e.getAttributes("link").href ?? "",
113
+ placeholder: "https://example.com",
114
+ submitLabel: "적용",
115
+ onSubmit: (n) => {
116
+ let r = e.chain().focus().extendMarkRange("link");
117
+ n ? r.setLink({ href: n }).run() : r.unsetLink().run(), t();
118
+ },
119
+ onRemove: () => {
120
+ e.chain().focus().extendMarkRange("link").unsetLink().run(), t();
121
+ }
122
+ });
123
+ }
124
+ function ue({ editor: e, close: t }) {
125
+ return /* @__PURE__ */ R(Z, {
126
+ placeholder: "이미지 주소(URL)",
127
+ submitLabel: "삽입",
128
+ onSubmit: (n) => {
129
+ n && e.chain().focus().setImage({ src: n }).run(), t();
130
+ }
131
+ });
132
+ }
133
+ function de({ editor: t, mergeFields: n, close: r }) {
134
+ let [o, s] = _(""), c = n.map((e) => typeof e == "string" ? {
135
+ label: e,
136
+ value: e
137
+ } : e).filter((e) => !o || e.label.toLowerCase().includes(o.toLowerCase())), l = (e) => {
138
+ t.chain().focus().insertContent({
139
+ type: "mergeField",
140
+ attrs: { value: e }
141
+ }).run(), r();
142
+ };
143
+ return /* @__PURE__ */ R(i, {
144
+ width: 180,
145
+ topArea: "search",
146
+ searchValue: o,
147
+ onSearchChange: (e) => s(e.target.value),
148
+ searchPlaceholder: "필드명 검색",
149
+ searchInputProps: { autoFocus: !0 },
150
+ children: /* @__PURE__ */ R(e, {
151
+ empty: c.length === 0,
152
+ emptyMessage: "검색 결과 없음",
153
+ children: c.map((e) => /* @__PURE__ */ R(a, {
154
+ icon: j,
155
+ title: e.label,
156
+ onClick: () => l(e.value)
157
+ }, e.value))
158
+ })
159
+ });
160
+ }
161
+ function Q({ editor: t, toolbar: n, mergeFields: r = [] }) {
162
+ if (!t) return null;
163
+ let o = (e) => !n || n.includes(e), s = (e) => e(t.chain().focus()).run(), c = t.isActive("heading", { level: 1 }) ? "h1" : t.isActive("heading", { level: 2 }) ? "h2" : t.isActive("heading", { level: 3 }) ? "h3" : "paragraph", p = (e, t) => {
164
+ s(e === "paragraph" ? (e) => e.setParagraph() : (t) => t.toggleHeading({ level: Number(e[1]) })), t();
165
+ }, m = t.getAttributes("textStyle").color ?? null, h = t.getAttributes("highlight").color ?? null, g = (e) => s(e ? (t) => t.setColor(e) : (e) => e.unsetColor()), _ = (e) => s(e ? (t) => t.setHighlight({ color: e }) : (e) => e.unsetHighlight()), A = t.isActive("table");
166
+ return /* @__PURE__ */ R("div", {
167
+ className: "flex min-w-0 flex-1 flex-wrap items-center gap-spacing-2",
168
+ children: [
169
+ [o("undo") && /* @__PURE__ */ R(q, {
170
+ icon: L,
171
+ label: "실행 취소",
172
+ disabled: !t.can().undo(),
173
+ onClick: () => s((e) => e.undo())
174
+ }, "undo"), o("redo") && /* @__PURE__ */ R(q, {
175
+ icon: M,
176
+ label: "다시 실행",
177
+ disabled: !t.can().redo(),
178
+ onClick: () => s((e) => e.redo())
179
+ }, "redo")],
180
+ [o("mergefield") && r.length > 0 && /* @__PURE__ */ R(l, {
181
+ placement: "auto-left",
182
+ menuWidth: 180,
183
+ trigger: /* @__PURE__ */ R(J, {
184
+ icon: w,
185
+ label: "머지필드"
186
+ }),
187
+ children: (e) => /* @__PURE__ */ R(de, {
188
+ editor: t,
189
+ mergeFields: r,
190
+ close: e
191
+ })
192
+ }, "mergefield")],
193
+ [o("block") && /* @__PURE__ */ R(l, {
194
+ placement: "auto-left",
195
+ menuWidth: 80,
196
+ trigger: /* @__PURE__ */ R(J, {
197
+ icon: F,
198
+ label: Y.find((e) => e.key === c)?.label
199
+ }),
200
+ children: (t) => /* @__PURE__ */ R(i, {
201
+ width: 80,
202
+ children: /* @__PURE__ */ R(e, { children: Y.map((e) => /* @__PURE__ */ R(a, {
203
+ title: e.label,
204
+ selected: c === e.key,
205
+ onClick: () => p(e.key, t)
206
+ }, e.key)) })
207
+ })
208
+ }, "block")],
209
+ [
210
+ o("bold") && /* @__PURE__ */ R(q, {
211
+ icon: C,
212
+ label: "굵게",
213
+ active: t.isActive("bold"),
214
+ onClick: () => s((e) => e.toggleBold())
215
+ }, "bold"),
216
+ o("italic") && /* @__PURE__ */ R(q, {
217
+ icon: D,
218
+ label: "기울임",
219
+ active: t.isActive("italic"),
220
+ onClick: () => s((e) => e.toggleItalic())
221
+ }, "italic"),
222
+ o("underline") && /* @__PURE__ */ R(q, {
223
+ icon: I,
224
+ label: "밑줄",
225
+ active: t.isActive("underline"),
226
+ onClick: () => s((e) => e.toggleUnderline())
227
+ }, "underline"),
228
+ o("strike") && /* @__PURE__ */ R(q, {
229
+ icon: N,
230
+ label: "취소선",
231
+ active: t.isActive("strike"),
232
+ onClick: () => s((e) => e.toggleStrike())
233
+ }, "strike")
234
+ ],
235
+ [o("color") && /* @__PURE__ */ R(l, {
236
+ placement: "auto-left",
237
+ menuWidth: 80,
238
+ trigger: /* @__PURE__ */ R(J, {
239
+ icon: S,
240
+ ariaLabel: "글자 색"
241
+ }),
242
+ children: () => /* @__PURE__ */ R(X, {
243
+ palette: d,
244
+ current: m,
245
+ onPick: g
246
+ })
247
+ }, "color"), o("highlight") && /* @__PURE__ */ R(l, {
248
+ placement: "auto-left",
249
+ menuWidth: 80,
250
+ trigger: /* @__PURE__ */ R(J, {
251
+ icon: T,
252
+ ariaLabel: "형광펜"
253
+ }),
254
+ children: () => /* @__PURE__ */ R(X, {
255
+ palette: u,
256
+ current: h,
257
+ onPick: _
258
+ })
259
+ }, "highlight")],
260
+ [
261
+ o("align") && /* @__PURE__ */ R(q, {
262
+ icon: b,
263
+ label: "왼쪽 정렬",
264
+ active: t.isActive({ textAlign: "left" }),
265
+ onClick: () => s((e) => e.setTextAlign("left"))
266
+ }, "al"),
267
+ o("align") && /* @__PURE__ */ R(q, {
268
+ icon: v,
269
+ label: "가운데 정렬",
270
+ active: t.isActive({ textAlign: "center" }),
271
+ onClick: () => s((e) => e.setTextAlign("center"))
272
+ }, "ac"),
273
+ o("align") && /* @__PURE__ */ R(q, {
274
+ icon: x,
275
+ label: "오른쪽 정렬",
276
+ active: t.isActive({ textAlign: "right" }),
277
+ onClick: () => s((e) => e.setTextAlign("right"))
278
+ }, "ar"),
279
+ o("align") && /* @__PURE__ */ R(q, {
280
+ icon: y,
281
+ label: "양쪽 정렬",
282
+ active: t.isActive({ textAlign: "justify" }),
283
+ onClick: () => s((e) => e.setTextAlign("justify"))
284
+ }, "aj")
285
+ ],
286
+ [
287
+ o("link") && /* @__PURE__ */ R(l, {
288
+ placement: "auto-left",
289
+ menuWidth: 300,
290
+ trigger: /* @__PURE__ */ R(J, {
291
+ icon: O,
292
+ ariaLabel: "링크"
293
+ }),
294
+ children: (e) => /* @__PURE__ */ R(le, {
295
+ editor: t,
296
+ close: e
297
+ })
298
+ }, "link"),
299
+ o("table") && /* @__PURE__ */ R(l, {
300
+ placement: "auto-left",
301
+ menuWidth: 140,
302
+ trigger: /* @__PURE__ */ R(J, {
303
+ icon: P,
304
+ ariaLabel: "표"
305
+ }),
306
+ children: (t) => /* @__PURE__ */ R(i, {
307
+ width: 140,
308
+ children: /* @__PURE__ */ z(e, { children: [
309
+ /* @__PURE__ */ R(a, {
310
+ title: "표 삽입 (3×3)",
311
+ onClick: () => {
312
+ s((e) => e.insertTable({
313
+ rows: 3,
314
+ cols: 3,
315
+ withHeaderRow: !0
316
+ })), t();
317
+ }
318
+ }),
319
+ /* @__PURE__ */ R(a, {
320
+ title: "위에 행 추가",
321
+ disabled: !A,
322
+ onClick: () => {
323
+ s((e) => e.addRowBefore()), t();
324
+ }
325
+ }),
326
+ /* @__PURE__ */ R(a, {
327
+ title: "아래에 행 추가",
328
+ disabled: !A,
329
+ onClick: () => {
330
+ s((e) => e.addRowAfter()), t();
331
+ }
332
+ }),
333
+ /* @__PURE__ */ R(a, {
334
+ title: "행 삭제",
335
+ disabled: !A,
336
+ onClick: () => {
337
+ s((e) => e.deleteRow()), t();
338
+ }
339
+ }),
340
+ /* @__PURE__ */ R(a, {
341
+ title: "왼쪽에 열 추가",
342
+ disabled: !A,
343
+ onClick: () => {
344
+ s((e) => e.addColumnBefore()), t();
345
+ }
346
+ }),
347
+ /* @__PURE__ */ R(a, {
348
+ title: "오른쪽에 열 추가",
349
+ disabled: !A,
350
+ onClick: () => {
351
+ s((e) => e.addColumnAfter()), t();
352
+ }
353
+ }),
354
+ /* @__PURE__ */ R(a, {
355
+ title: "열 삭제",
356
+ disabled: !A,
357
+ onClick: () => {
358
+ s((e) => e.deleteColumn()), t();
359
+ }
360
+ }),
361
+ /* @__PURE__ */ R(a, {
362
+ title: "표 삭제",
363
+ disabled: !A,
364
+ onClick: () => {
365
+ s((e) => e.deleteTable()), t();
366
+ }
367
+ })
368
+ ] })
369
+ })
370
+ }, "table"),
371
+ o("image") && /* @__PURE__ */ R(l, {
372
+ placement: "auto-left",
373
+ menuWidth: 300,
374
+ trigger: /* @__PURE__ */ R(J, {
375
+ icon: E,
376
+ ariaLabel: "이미지"
377
+ }),
378
+ children: (e) => /* @__PURE__ */ R(ue, {
379
+ editor: t,
380
+ close: e
381
+ })
382
+ }, "image"),
383
+ o("hr") && /* @__PURE__ */ R(q, {
384
+ icon: k,
385
+ label: "구분선",
386
+ onClick: () => s((e) => e.setHorizontalRule())
387
+ }, "hr")
388
+ ]
389
+ ].map((e) => e.filter(Boolean)).filter((e) => e.length).map((e, t) => /* @__PURE__ */ z(f, { children: [t > 0 && /* @__PURE__ */ R(ce, {}), e] }, t))
390
+ });
391
+ }
392
+ //#endregion
393
+ //#region src/components/MergeFieldNode.ts
394
+ var fe = "inline-flex items-center gap-spacing-3 rounded-round-4 border border-chip-blue-default-line bg-chip-blue-default-bg pl-spacing-4 pr-spacing-3 py-spacing-1 align-middle font-pretendard text-12 text-chip-blue-default-text transition-colors hover:border-chip-blue-hover-line hover:bg-chip-blue-hover-bg", pe = "<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>", me = oe.create({
395
+ name: "mergeField",
396
+ group: "inline",
397
+ inline: !0,
398
+ atom: !0,
399
+ selectable: !0,
400
+ addAttributes() {
401
+ return { value: {
402
+ default: "",
403
+ parseHTML: (e) => e.getAttribute("data-merge-field") || e.textContent || "",
404
+ renderHTML: (e) => ({ "data-merge-field": e.value })
405
+ } };
406
+ },
407
+ parseHTML() {
408
+ return [{ tag: "span[data-merge-field]" }];
409
+ },
410
+ renderHTML({ HTMLAttributes: e, node: t }) {
411
+ return [
412
+ "span",
413
+ se(e),
414
+ t.attrs.value
415
+ ];
416
+ },
417
+ addNodeView() {
418
+ return ({ node: e, editor: t, getPos: n }) => {
419
+ let r = document.createElement("span");
420
+ r.className = fe, r.contentEditable = "false";
421
+ let i = document.createElement("span");
422
+ i.className = "whitespace-nowrap", i.textContent = e.attrs.value, r.appendChild(i);
423
+ let a = document.createElement("button");
424
+ return a.type = "button", a.className = "flex shrink-0 items-center justify-center", a.setAttribute("aria-label", "머지필드 삭제"), a.innerHTML = pe, a.addEventListener("mousedown", (e) => e.preventDefault()), a.addEventListener("click", (r) => {
425
+ if (r.preventDefault(), r.stopPropagation(), typeof n != "function") return;
426
+ let i = n();
427
+ i != null && t.chain().focus().deleteRange({
428
+ from: i,
429
+ to: i + e.nodeSize
430
+ }).run();
431
+ }), r.appendChild(a), { dom: r };
432
+ };
433
+ }
434
+ }), he = [
435
+ {
436
+ value: "edit",
437
+ label: "편집"
438
+ },
439
+ {
440
+ value: "source",
441
+ label: "HTML"
442
+ },
443
+ {
444
+ value: "preview",
445
+ label: "미리보기"
446
+ }
447
+ ];
448
+ function ge() {
449
+ return [
450
+ H.configure({ link: {
451
+ openOnClick: !1,
452
+ HTMLAttributes: { rel: "noopener noreferrer nofollow" }
453
+ } }),
454
+ U,
455
+ W,
456
+ G.configure({ multicolor: !0 }),
457
+ ee.configure({ types: ["heading", "paragraph"] }),
458
+ te,
459
+ ne.configure({ resizable: !1 }),
460
+ ae,
461
+ ie,
462
+ re,
463
+ me
464
+ ];
465
+ }
466
+ function _e({ mode: e, onChange: t, readOnly: n, showSource: r }) {
467
+ let i = n ? he.filter((e) => e.value !== "edit") : he;
468
+ return r || (i = i.filter((e) => e.value !== "source")), /* @__PURE__ */ R(s, {
469
+ size: "24",
470
+ gap: "4",
471
+ value: e,
472
+ onChange: (e) => t?.(e),
473
+ items: i
474
+ });
475
+ }
476
+ function ve({ value: e, defaultValue: t = "", onChange: n, mode: i, onModeChange: a, toolbar: o, mergeFields: s = [], readOnly: c = !1, showSource: l = !0, placeholder: u = "내용을 입력하세요.", minHeight: d = 240, maxHeight: f, width: v = "fill", allowSourceEdit: y = !0, className: b = "", ...x }) {
477
+ let S = e !== void 0, C = i !== void 0, [w, T] = _(() => c ? "preview" : "edit"), E = C ? i : w, [, D] = h((e) => e + 1, 0), [O, k] = _(""), A = g(null), j = g(n);
478
+ p(() => {
479
+ j.current = n;
480
+ }, [n]);
481
+ let M = V({
482
+ editable: !c,
483
+ content: S ? e : t,
484
+ extensions: ge(),
485
+ immediatelyRender: !1,
486
+ shouldRerenderOnTransaction: !0
487
+ });
488
+ p(() => {
489
+ if (!M) return;
490
+ let e = () => j.current?.(M.getHTML());
491
+ return M.on("update", e), () => {
492
+ M.off("update", e);
493
+ };
494
+ }, [M]), p(() => {
495
+ M?.setEditable(!c);
496
+ }, [M, c]), p(() => {
497
+ c && !C && w === "edit" && T("preview");
498
+ }, [
499
+ c,
500
+ C,
501
+ w
502
+ ]), p(() => {
503
+ !l && !C && w === "source" && T("edit");
504
+ }, [
505
+ l,
506
+ C,
507
+ w
508
+ ]), m(() => {
509
+ !M || !S || e !== M.getHTML() && (M.commands.setContent(e, { emitUpdate: !1 }), E === "source" && k((t) => t === e ? t : e), D());
510
+ }, [
511
+ M,
512
+ e,
513
+ S,
514
+ E
515
+ ]);
516
+ let N = (e) => {
517
+ e !== E && (M && (E === "source" && (M.commands.setContent(O, { emitUpdate: !1 }), j.current?.(M.getHTML())), e === "source" && k(M.getHTML())), C || T(e), a?.(e));
518
+ }, P = (e) => {
519
+ let t = e.target.value;
520
+ k(t), j.current?.(t);
521
+ };
522
+ m(() => {
523
+ if (E !== "source") return;
524
+ let e = A.current;
525
+ e && (e.style.height = "auto", e.style.height = `${e.scrollHeight}px`);
526
+ }, [E, O]);
527
+ let F = y && !c, I = E === "preview" && M ? M.getHTML() : "", L = typeof d == "number" ? `${d}px` : d, H = v === "fill" ? "100%" : typeof v == "number" ? `${v}px` : v, U = (e) => f == null ? e : /* @__PURE__ */ R(r, {
528
+ maxHeight: f,
529
+ children: e
530
+ }), W;
531
+ return E === "source" ? (W = /* @__PURE__ */ R("textarea", {
532
+ ref: A,
533
+ value: O,
534
+ onChange: P,
535
+ readOnly: !F,
536
+ spellCheck: !1,
537
+ className: "block w-full resize-none overflow-hidden bg-editor-source-bg px-spacing-7 py-spacing-6 font-mono text-13 text-editor-source-text outline-none",
538
+ style: { minHeight: L }
539
+ }), W = f == null ? W : /* @__PURE__ */ R(r, {
540
+ maxHeight: f,
541
+ variant: "light",
542
+ children: W
543
+ })) : W = U(E === "preview" ? /* @__PURE__ */ R("div", {
544
+ className: "tiptap-prose px-spacing-7 py-spacing-6",
545
+ style: { minHeight: L },
546
+ dangerouslySetInnerHTML: { __html: I }
547
+ }) : /* @__PURE__ */ z("div", {
548
+ className: "relative tiptap-prose cursor-text px-spacing-7 py-spacing-6",
549
+ style: { minHeight: L },
550
+ onMouseDown: (e) => {
551
+ M && !e.target.closest(".tiptap") && (e.preventDefault(), M.commands.focus("end"));
552
+ },
553
+ children: [M?.isEmpty && /* @__PURE__ */ R("p", {
554
+ className: "pointer-events-none absolute left-spacing-7 top-spacing-6 text-14 leading-30 text-editor-placeholder",
555
+ children: u
556
+ }), /* @__PURE__ */ R(B, { editor: M })]
557
+ })), /* @__PURE__ */ z("div", {
558
+ className: `overflow-hidden rounded-round-4 border border-editor-outline bg-white ${b}`,
559
+ style: { width: H },
560
+ ...x,
561
+ children: [/* @__PURE__ */ R("div", {
562
+ className: "border-b border-editor-divider bg-editor-toolbar-bg",
563
+ children: /* @__PURE__ */ z("div", {
564
+ className: "flex items-center justify-between gap-spacing-5 px-spacing-5 py-spacing-3",
565
+ children: [E === "edit" && !c ? /* @__PURE__ */ R(Q, {
566
+ editor: M,
567
+ toolbar: o,
568
+ mergeFields: s
569
+ }) : /* @__PURE__ */ R("span", {
570
+ className: "text-12 text-font-icon-5",
571
+ children: E === "source" ? "HTML 소스" : E === "preview" ? "미리보기" : ""
572
+ }), /* @__PURE__ */ R("div", {
573
+ className: "shrink-0",
574
+ children: /* @__PURE__ */ R(_e, {
575
+ mode: E,
576
+ onChange: N,
577
+ readOnly: c,
578
+ showSource: l
579
+ })
580
+ })]
581
+ })
582
+ }), W]
583
+ });
584
+ }
585
+ //#endregion
586
+ //#region src/components/NoticeWritingTemplate.tsx
587
+ var $ = [
588
+ {
589
+ value: "site",
590
+ label: "채용사이트 안내문",
591
+ titlePlaceholder: "채용 사이트안내문 제목을 입력하세요"
592
+ },
593
+ {
594
+ value: "email",
595
+ label: "이메일 안내문",
596
+ titlePlaceholder: "이메일 안내문 제목을 입력하세요"
597
+ },
598
+ {
599
+ value: "sms",
600
+ label: "SMS 안내문"
601
+ }
602
+ ], ye = "90byte를 초과(한글 45자)하면 멀티 문자로 전환되며, 발송 비용이 변경될 수 있습니다.", be = [
603
+ "undo",
604
+ "redo",
605
+ "mergefield"
606
+ ], xe = () => ({
607
+ site: [],
608
+ email: [],
609
+ sms: []
610
+ });
611
+ function Se({ channel: e, defaultChannel: n = "site", onChannelChange: r, onChange: i, showTabs: a = !0, tabVariant: s = "fill", enabledChannels: l, mergeFields: u = [], defaultBodies: d, showAttach: f = !0, maxAttachments: p = 5, attachGuide: m = "파일을 첨부하세요 (파일당 최대 10MB).", attachAccept: h, editorMinHeight: g = 360, editorMaxHeight: v, editorReadOnly: y = !1, editorPlaceholder: b, className: x = "", ...S }) {
612
+ let C = e !== void 0, [w, T] = _(n), E = (e) => !l || l.includes(e), D = C ? e : w, O = E(D) ? D : $.find((e) => E(e.value))?.value ?? D, k = (e) => {
613
+ C || T(e), r?.(e);
614
+ }, [j, M] = _({
615
+ site: "",
616
+ email: "",
617
+ sms: ""
618
+ }), [N, P] = _(() => ({
619
+ site: "",
620
+ email: "",
621
+ sms: "",
622
+ ...d || {}
623
+ })), [F, I] = _(xe), L = (e) => i?.({
624
+ channel: O,
625
+ titles: j,
626
+ bodies: N,
627
+ attachments: F,
628
+ ...e
629
+ }), B = $.find((e) => e.value === O) ?? $[0], V = O === "sms", H = (e) => {
630
+ let t = {
631
+ ...j,
632
+ [O]: e
633
+ };
634
+ M(t), L({ titles: t });
635
+ }, U = (e) => {
636
+ let t = {
637
+ ...N,
638
+ [O]: e
639
+ };
640
+ P(t), L({ bodies: t });
641
+ }, W = (e) => {
642
+ let t = {
643
+ ...F,
644
+ [O]: [...F[O], ...Array.from(e).map((e) => ({
645
+ name: e.name,
646
+ size: Math.max(.1, Math.round(e.size / 1048576 * 10) / 10),
647
+ id: `${e.name}-${e.size}-${Date.now()}`,
648
+ file: e
649
+ }))].slice(0, p)
650
+ };
651
+ I(t), L({ attachments: t });
652
+ }, G = (e, t) => {
653
+ let n = {
654
+ ...F,
655
+ [O]: F[O].filter((e, n) => n !== t)
656
+ };
657
+ I(n), L({ attachments: n });
658
+ };
659
+ return /* @__PURE__ */ z("div", {
660
+ className: `flex w-full flex-col gap-spacing-6 ${x}`,
661
+ ...S,
662
+ children: [
663
+ a && /* @__PURE__ */ R(c, {
664
+ items: $.map(({ value: e, label: t }) => ({
665
+ value: e,
666
+ label: t,
667
+ disabled: !E(e)
668
+ })),
669
+ value: O,
670
+ onChange: k,
671
+ variant: s
672
+ }),
673
+ V ? /* @__PURE__ */ R("p", {
674
+ className: "text-12 text-font-icon-4",
675
+ children: ye
676
+ }) : /* @__PURE__ */ z("div", {
677
+ className: "flex items-start gap-spacing-6",
678
+ children: [/* @__PURE__ */ R("div", {
679
+ className: "min-w-0 flex-1",
680
+ children: /* @__PURE__ */ R(t, {
681
+ width: "100%",
682
+ placeholder: B.titlePlaceholder,
683
+ value: j[O],
684
+ onChange: (e) => H(e.target.value)
685
+ })
686
+ }), f && /* @__PURE__ */ R(o, {
687
+ triggerText: "첨부파일",
688
+ buttonProps: { leftIcon: A },
689
+ placement: "auto-right",
690
+ menuWidth: 320,
691
+ files: F[O],
692
+ guide: m,
693
+ accept: h,
694
+ maxCount: p,
695
+ onAdd: W,
696
+ onDelete: G
697
+ })]
698
+ }),
699
+ /* @__PURE__ */ R(ve, {
700
+ value: N[O],
701
+ onChange: U,
702
+ mergeFields: u,
703
+ toolbar: V ? be : void 0,
704
+ showSource: !V,
705
+ minHeight: g,
706
+ maxHeight: v,
707
+ readOnly: y,
708
+ ...b ? { placeholder: b } : {}
709
+ })
710
+ ]
711
+ });
712
+ }
713
+ //#endregion
714
+ export { ve as Editor, Q as EditorToolbar, me as MergeFieldNode, Se as NoticeWritingTemplate };
715
+
716
+ //# sourceMappingURL=editor.js.map