@loword/loword-design-system 0.5.9 → 0.6.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/LDEditor/LDEditor.d.ts.map +1 -1
- package/dist/components/LDEditor/LDEditor.js +29 -27
- package/dist/components/LDEditor/extensions.d.ts.map +1 -1
- package/dist/components/LDEditor/extensions.js +35 -1
- package/dist/components/LDFileUpload/FileUploadBase.d.ts +35 -11
- package/dist/components/LDFileUpload/FileUploadBase.d.ts.map +1 -1
- package/dist/components/LDFileUpload/FileUploadBase.js +41 -22
- package/dist/components/LDFileUpload/LDFileUpload.d.ts +9 -4
- package/dist/components/LDFileUpload/LDFileUpload.d.ts.map +1 -1
- package/dist/components/LDFileUpload/LDFileUpload.js +113 -23
- package/dist/components/LDFileUpload/LDFileUploadList.d.ts +2 -1
- package/dist/components/LDFileUpload/LDFileUploadList.d.ts.map +1 -1
- package/dist/components/LDFileUpload/LDImageUpload.d.ts +2 -1
- package/dist/components/LDFileUpload/LDImageUpload.d.ts.map +1 -1
- package/dist/components/LDFileUpload/LDImageUploadList.d.ts +2 -1
- package/dist/components/LDFileUpload/LDImageUploadList.d.ts.map +1 -1
- package/dist/index.css +11 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/styles/components/editor.css +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LDEditor.d.ts","sourceRoot":"","sources":["../../../src/components/LDEditor/LDEditor.tsx"],"names":[],"mappings":"AAwCA,OAAO,EAEL,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAC;AAqH1B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAC7B,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,SAAS,EAAE,CAAC;CACjC;AAqVD,QAAA,MAAM,QAAQ,GAAI,4FAOf,aAAa,4CAgCf,CAAC;
|
|
1
|
+
{"version":3,"file":"LDEditor.d.ts","sourceRoot":"","sources":["../../../src/components/LDEditor/LDEditor.tsx"],"names":[],"mappings":"AAwCA,OAAO,EAEL,KAAK,SAAS,EAGf,MAAM,kBAAkB,CAAC;AAqH1B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAC7B,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,SAAS,EAAE,CAAC;CACjC;AAqVD,QAAA,MAAM,QAAQ,GAAI,4FAOf,aAAa,4CAgCf,CAAC;AAwmBF,eAAe,QAAQ,CAAC"}
|
|
@@ -374,7 +374,10 @@ const EditorToolbar = ({ handleImageUpload, allowedExtensions, }) => {
|
|
|
374
374
|
isOrderedList: editor.isActive('orderedList'),
|
|
375
375
|
canUndo: editor.can().undo(),
|
|
376
376
|
canRedo: editor.can().redo(),
|
|
377
|
-
|
|
377
|
+
// 이미지를 선택했으면 이미지의 href를, 아니면 텍스트 링크(mark)를 본다
|
|
378
|
+
isLink: editor.isActive('image')
|
|
379
|
+
? !!editor.getAttributes('image').href
|
|
380
|
+
: editor.isActive('link'),
|
|
378
381
|
isTable: editor.isActive('table'),
|
|
379
382
|
hasSelection: !editor.state.selection.empty,
|
|
380
383
|
};
|
|
@@ -398,6 +401,26 @@ const EditorToolbar = ({ handleImageUpload, allowedExtensions, }) => {
|
|
|
398
401
|
};
|
|
399
402
|
if (!editor || !state)
|
|
400
403
|
return null;
|
|
404
|
+
// 링크 대상: 이미지를 선택했으면 이미지 노드의 href, 아니면 선택 텍스트의 링크 mark
|
|
405
|
+
const getLinkHref = () => (editor.isActive('image')
|
|
406
|
+
? editor.getAttributes('image').href
|
|
407
|
+
: editor.getAttributes('link').href) || '';
|
|
408
|
+
const setLinkHref = (input) => {
|
|
409
|
+
const href = input === '' || /^https?:\/\//.test(input) ? input : `https://${input}`;
|
|
410
|
+
if (editor.isActive('image')) {
|
|
411
|
+
editor
|
|
412
|
+
.chain()
|
|
413
|
+
.focus()
|
|
414
|
+
.updateAttributes('image', { href: href || null })
|
|
415
|
+
.run();
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
const chain = editor.chain().focus().extendMarkRange('link');
|
|
419
|
+
if (href)
|
|
420
|
+
chain.setLink({ href }).run();
|
|
421
|
+
else
|
|
422
|
+
chain.unsetLink().run();
|
|
423
|
+
};
|
|
401
424
|
return (_jsxs(_Fragment, { children: [_jsxs(EditorBase.Toolbar, { className: "gap-2 rounded-t-md border border-neutral200 px-4 py-3", children: [_jsxs(ToolbarGroup, { children: [_jsx(EditorBase.Toolbar.Dropdown, { className: "min-w-30 rounded-lg border border-neutral200 bg-white shadow-lg", trigger: ({ toggle }) => (
|
|
402
425
|
// aria-label이 없으면 접근성 이름이 현재 선택값('본문'·'제목 1'…)이 되어,
|
|
403
426
|
// 드롭다운이 열렸을 때 트리거와 옵션이 같은 이름을 갖는다.
|
|
@@ -432,23 +455,11 @@ const EditorToolbar = ({ handleImageUpload, allowedExtensions, }) => {
|
|
|
432
455
|
}[align];
|
|
433
456
|
return (_jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().setTextAlign(align).run(), className: cn(iconBtn, state.align[align] && activeBtn), "aria-label": alignLabel, children: _jsx(Icon, { className: "size-5" }) }, align));
|
|
434
457
|
}), _jsx(LDDivider, {})] })] })), _jsxs(ToolbarGroup, { children: [_jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().toggleBulletList().run(), className: cn(iconBtn, state.isBulletList && activeBtn), "aria-label": "\uAE00\uBA38\uB9AC \uAE30\uD638 \uBAA9\uB85D", children: _jsx(List, { className: "size-5" }) }), _jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().toggleOrderedList().run(), className: cn(iconBtn, state.isOrderedList && activeBtn), "aria-label": "\uBC88\uD638 \uBAA9\uB85D", children: _jsx(ListOrdered, { className: "size-5" }) }), _jsx(LDDivider, {})] }), _jsxs(ToolbarGroup, { children: [_jsx(EditorBase.Toolbar.LDButton, { disabled: !state.canUndo, onClick: () => editor.chain().focus().undo().run(), className: iconBtn, "aria-label": "\uB418\uB3CC\uB9AC\uAE30", children: _jsx(Undo, { className: "size-5" }) }), _jsx(EditorBase.Toolbar.LDButton, { disabled: !state.canRedo, onClick: () => editor.chain().focus().redo().run(), className: iconBtn, "aria-label": "\uB2E4\uC2DC \uC2E4\uD589", children: _jsx(Redo, { className: "size-5" }) }), _jsx(LDDivider, {})] }), !isMobile && (_jsx(_Fragment, { children: _jsxs(ToolbarGroup, { children: [_jsx(EditorBase.Toolbar.Dropdown, { className: "min-w-70 rounded-lg border border-neutral200 bg-white p-3 shadow-lg", trigger: ({ toggle }) => (_jsx(EditorBase.Toolbar.LDButton, { disabled: !state.hasSelection, onClick: () => {
|
|
435
|
-
setLinkUrl(
|
|
458
|
+
setLinkUrl(getLinkHref());
|
|
436
459
|
toggle();
|
|
437
460
|
}, className: cn(iconBtn, state.isLink && activeBtn), "aria-label": "\uB9C1\uD06C", children: _jsx(Link2, { className: "size-5" }) })), children: ({ close }) => {
|
|
438
461
|
const applyLink = () => {
|
|
439
|
-
|
|
440
|
-
.chain()
|
|
441
|
-
.focus()
|
|
442
|
-
.extendMarkRange('link');
|
|
443
|
-
if (linkUrl === '') {
|
|
444
|
-
chain.unsetLink().run();
|
|
445
|
-
}
|
|
446
|
-
else {
|
|
447
|
-
const url = /^https?:\/\//.test(linkUrl)
|
|
448
|
-
? linkUrl
|
|
449
|
-
: `https://${linkUrl}`;
|
|
450
|
-
chain.setLink({ href: url }).run();
|
|
451
|
-
}
|
|
462
|
+
setLinkHref(linkUrl);
|
|
452
463
|
setLinkUrl('');
|
|
453
464
|
close();
|
|
454
465
|
};
|
|
@@ -460,7 +471,7 @@ const EditorToolbar = ({ handleImageUpload, allowedExtensions, }) => {
|
|
|
460
471
|
setLinkUrl('');
|
|
461
472
|
close();
|
|
462
473
|
}, className: "rounded-lg border border-neutral200 px-3 py-1.5 text-sm transition duration-300 hover:bg-mono100", children: "\uCDE8\uC18C" })] })] }));
|
|
463
|
-
} }), _jsx(EditorBase.Toolbar.LDButton, { disabled: !state.isLink, onClick: () =>
|
|
474
|
+
} }), _jsx(EditorBase.Toolbar.LDButton, { disabled: !state.isLink, onClick: () => setLinkHref(''), className: iconBtn, "aria-label": "\uB9C1\uD06C \uD574\uC81C", children: _jsx(Unlink, { className: "size-5" }) }), _jsx(LDDivider, {})] }) })), _jsxs(ToolbarGroup, { children: [_jsx(EditorBase.Toolbar.Dropdown, { className: "min-w-40 rounded-lg border border-neutral200 bg-white shadow-lg", trigger: ({ toggle }) => (_jsx(EditorBase.Toolbar.LDButton, { "aria-label": "\uD45C", onClick: toggle, className: cn(iconBtn, state.isTable && activeBtn), children: _jsx(TableIcon, { className: "size-5" }) })), children: ({ close }) => state.isTable ? (_jsx("div", { children: TABLE_ACTIONS.map(({ label, run }) => (_jsx("button", { type: "button", onClick: (e) => {
|
|
464
475
|
e.preventDefault();
|
|
465
476
|
run(editor);
|
|
466
477
|
close();
|
|
@@ -479,20 +490,11 @@ const EditorToolbar = ({ handleImageUpload, allowedExtensions, }) => {
|
|
|
479
490
|
editor.chain().focus().setColor(color.value).run();
|
|
480
491
|
close();
|
|
481
492
|
}, className: "flex w-full cursor-pointer items-center gap-2 px-3 py-2 text-left text-sm first:rounded-t-lg last:rounded-b-lg hover:bg-mono100", children: [_jsx("span", { className: "size-4 rounded-full", style: { backgroundColor: color.value } }), _jsx("span", { children: color.label })] }, color.value))) }), _jsx(EditorBase.Toolbar.Dropdown, { className: "min-w-60 rounded-lg border border-neutral200 bg-white p-3 shadow-lg", trigger: ({ toggle }) => (_jsx(EditorBase.Toolbar.LDButton, { onClick: () => {
|
|
482
|
-
setLinkUrl(
|
|
493
|
+
setLinkUrl(getLinkHref());
|
|
483
494
|
toggle();
|
|
484
495
|
}, className: cn(iconBtn, state.isLink && activeBtn), "aria-label": "\uB9C1\uD06C", children: _jsx(Link2, { className: "size-5" }) })), children: ({ close }) => {
|
|
485
496
|
const applyLink = () => {
|
|
486
|
-
|
|
487
|
-
if (linkUrl === '') {
|
|
488
|
-
chain.unsetLink().run();
|
|
489
|
-
}
|
|
490
|
-
else {
|
|
491
|
-
const url = /^https?:\/\//.test(linkUrl)
|
|
492
|
-
? linkUrl
|
|
493
|
-
: `https://${linkUrl}`;
|
|
494
|
-
chain.setLink({ href: url }).run();
|
|
495
|
-
}
|
|
497
|
+
setLinkHref(linkUrl);
|
|
496
498
|
setLinkUrl('');
|
|
497
499
|
close();
|
|
498
500
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../../src/components/LDEditor/extensions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../../src/components/LDEditor/extensions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAsChD,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,sBAAsB,GAAI,sCAGpC,sBAA2B,KAAG,UA2ChC,CAAC"}
|
|
@@ -1,8 +1,42 @@
|
|
|
1
|
+
import { mergeAttributes } from '@tiptap/core';
|
|
1
2
|
import Image from '@tiptap/extension-image';
|
|
2
3
|
import { TableKit } from '@tiptap/extension-table';
|
|
3
4
|
import TextAlign from '@tiptap/extension-text-align';
|
|
4
5
|
import { Color, FontSize, TextStyle } from '@tiptap/extension-text-style';
|
|
5
6
|
import StarterKit from '@tiptap/starter-kit';
|
|
7
|
+
/**
|
|
8
|
+
* 링크를 걸 수 있는 이미지. 링크(mark)는 텍스트에만 붙고 블록 이미지는 받지 못하므로
|
|
9
|
+
* 이미지 노드에 `href`를 두고 저장 시 `<a href><img></a>`로 감싼다.
|
|
10
|
+
* 편집 화면은 리사이즈 노드뷰가 img만 그리므로 눌러도 이동하지 않고 선택만 된다.
|
|
11
|
+
*/
|
|
12
|
+
const LinkableImage = Image.extend({
|
|
13
|
+
addAttributes() {
|
|
14
|
+
return {
|
|
15
|
+
...this.parent?.(),
|
|
16
|
+
href: {
|
|
17
|
+
default: null,
|
|
18
|
+
// 붙여넣기·불러오기 때 이미지를 감싼 <a>의 주소를 읽는다
|
|
19
|
+
parseHTML: (element) => element.closest('a')?.getAttribute('href') ?? null,
|
|
20
|
+
// img 자체에는 href를 쓰지 않는다(아래 renderHTML에서 <a>로 감쌈)
|
|
21
|
+
renderHTML: () => ({}),
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
26
|
+
const img = [
|
|
27
|
+
'img',
|
|
28
|
+
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
|
|
29
|
+
];
|
|
30
|
+
const href = node.attrs.href;
|
|
31
|
+
return href
|
|
32
|
+
? [
|
|
33
|
+
'a',
|
|
34
|
+
{ href, target: '_blank', rel: 'noopener noreferrer nofollow' },
|
|
35
|
+
img,
|
|
36
|
+
]
|
|
37
|
+
: img;
|
|
38
|
+
},
|
|
39
|
+
});
|
|
6
40
|
export const createEditorExtensions = ({ resizableImage = true, resizableTable = true, } = {}) => [
|
|
7
41
|
// link·underline은 StarterKit에 포함돼 있다. 따로 등록하면 중복 경고가 난다.
|
|
8
42
|
StarterKit.configure({
|
|
@@ -27,7 +61,7 @@ export const createEditorExtensions = ({ resizableImage = true, resizableTable =
|
|
|
27
61
|
types: ['heading', 'paragraph', 'image'],
|
|
28
62
|
alignments: ['left', 'center', 'right', 'justify'],
|
|
29
63
|
}),
|
|
30
|
-
|
|
64
|
+
LinkableImage.configure({
|
|
31
65
|
inline: false,
|
|
32
66
|
allowBase64: true,
|
|
33
67
|
resize: resizableImage
|
|
@@ -7,6 +7,21 @@ export interface FileUploadOptions {
|
|
|
7
7
|
allowedExtensions?: TMimeType[];
|
|
8
8
|
maxFileCount?: number;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* 파일과 링크를 한 목록에 섞어 담는 첨부 한 건입니다.
|
|
12
|
+
* 링크는 서버가 이름과 주소로 나눠 받으므로 `label`·`url`을 따로 둡니다.
|
|
13
|
+
*/
|
|
14
|
+
export type FileUploadAttachment = {
|
|
15
|
+
type: 'file';
|
|
16
|
+
file: IFile;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'link';
|
|
19
|
+
label: string;
|
|
20
|
+
url: string;
|
|
21
|
+
};
|
|
22
|
+
type FileUploadLinkValue = Omit<Extract<FileUploadAttachment, {
|
|
23
|
+
type: 'link';
|
|
24
|
+
}>, 'type'>;
|
|
10
25
|
interface FileUploadContextValue {
|
|
11
26
|
recommendedSize?: {
|
|
12
27
|
width: number;
|
|
@@ -14,8 +29,10 @@ interface FileUploadContextValue {
|
|
|
14
29
|
};
|
|
15
30
|
maxSize: number;
|
|
16
31
|
allowedExtensions: TMimeType[];
|
|
32
|
+
/** 파일만 모은 목록. 파일 전용 조합에서는 `attachmentList`와 인덱스가 같다. */
|
|
17
33
|
fileList: IFile[];
|
|
18
|
-
|
|
34
|
+
/** 파일·링크가 섞인 전체 목록. 아래 함수들의 `index`는 이 목록 기준이다. */
|
|
35
|
+
attachmentList: FileUploadAttachment[];
|
|
19
36
|
maxFileCount: number;
|
|
20
37
|
disabled?: boolean;
|
|
21
38
|
readOnly?: boolean;
|
|
@@ -24,25 +41,32 @@ interface FileUploadContextValue {
|
|
|
24
41
|
replaceFile: (file: File, index: number, options?: FileUploadOptions) => Promise<void>;
|
|
25
42
|
deleteFile: (index: number) => Promise<void>;
|
|
26
43
|
addLink: () => Promise<void>;
|
|
27
|
-
changeLink: (index: number, value:
|
|
44
|
+
changeLink: (index: number, value: Partial<FileUploadLinkValue>) => Promise<void>;
|
|
28
45
|
deleteLink: (index: number) => Promise<void>;
|
|
46
|
+
moveAttachment: (from: number, to: number) => Promise<void>;
|
|
29
47
|
}
|
|
30
48
|
export declare const useFileUploadContext: () => FileUploadContextValue;
|
|
31
|
-
|
|
49
|
+
/** 파일만 다루는 조합(단일·목록·이미지 업로드)이 받는 상태입니다. */
|
|
50
|
+
export interface FileUploadFileListProps {
|
|
51
|
+
fileList: IFile[];
|
|
52
|
+
setFileList: Dispatch<SetStateAction<IFile[]>>;
|
|
53
|
+
onChangeFile: (files: IFile[]) => void | Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
export interface FileUploadBaseRootProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'onChange'>, Partial<FileUploadFileListProps> {
|
|
32
56
|
recommendedSize?: {
|
|
33
57
|
width: number;
|
|
34
58
|
height: number;
|
|
35
59
|
};
|
|
36
60
|
maxSize: number;
|
|
37
61
|
allowedExtensions?: TMimeType[];
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
62
|
+
/**
|
|
63
|
+
* 파일과 링크를 한 목록에 섞어 쓸 때 넘깁니다(`AttachmentList`·`Input type="link"`).
|
|
64
|
+
* 넘기면 `fileList` 계열 대신 이 배열로 상태를 주고받습니다.
|
|
65
|
+
*/
|
|
66
|
+
attachmentList?: FileUploadAttachment[];
|
|
67
|
+
setAttachmentList?: Dispatch<SetStateAction<FileUploadAttachment[]>>;
|
|
68
|
+
onChangeAttachment?: (attachments: FileUploadAttachment[]) => void | Promise<void>;
|
|
44
69
|
maxFileCount: number;
|
|
45
|
-
onChangeFile: (files: IFile[]) => void | Promise<void>;
|
|
46
70
|
onDeleteFile: (file: IFile) => Promise<boolean>;
|
|
47
71
|
disabled?: boolean;
|
|
48
72
|
readOnly?: boolean;
|
|
@@ -57,7 +81,7 @@ export interface FileUploadBaseInputProps extends Omit<InputHTMLAttributes<HTMLI
|
|
|
57
81
|
ref?: Ref<HTMLInputElement>;
|
|
58
82
|
}
|
|
59
83
|
export declare const FileUploadBase: {
|
|
60
|
-
Root: ({ recommendedSize, maxSize, allowedExtensions: allowedExtensionsProp, maxFileCount, fileList, setFileList,
|
|
84
|
+
Root: ({ recommendedSize, maxSize, allowedExtensions: allowedExtensionsProp, maxFileCount, fileList: fileListProp, setFileList, onChangeFile, attachmentList: attachmentListProp, setAttachmentList, onChangeAttachment, onDeleteFile, disabled, readOnly, children, ref, ...props }: FileUploadBaseRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
61
85
|
Input: ({ replaceIndex, options, onClick, onChange, disabled, ref, ...props }: FileUploadBaseInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
62
86
|
};
|
|
63
87
|
export default FileUploadBase;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileUploadBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/FileUploadBase.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,GAAG,EACR,KAAK,cAAc,EAEpB,MAAM,OAAO,CAAC;AAGf,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGL,KAAK,KAAK,EAKX,MAAM,cAAc,CAAC;AAEtB,wDAAwD;AACxD,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,SAAS,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,sBAAsB;IAC9B,eAAe,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,SAAS,EAAE,CAAC;IAC/B,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClB,
|
|
1
|
+
{"version":3,"file":"FileUploadBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/FileUploadBase.tsx"],"names":[],"mappings":"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"}
|
|
@@ -12,12 +12,26 @@ export const useFileUploadContext = () => {
|
|
|
12
12
|
}
|
|
13
13
|
return context;
|
|
14
14
|
};
|
|
15
|
-
const Root = ({ recommendedSize, maxSize, allowedExtensions: allowedExtensionsProp, maxFileCount, fileList, setFileList,
|
|
15
|
+
const Root = ({ recommendedSize, maxSize, allowedExtensions: allowedExtensionsProp, maxFileCount, fileList: fileListProp, setFileList, onChangeFile, attachmentList: attachmentListProp, setAttachmentList, onChangeAttachment, onDeleteFile, disabled, readOnly, children, ref, ...props }) => {
|
|
16
16
|
const allowedExtensions = allowedExtensionsProp?.length
|
|
17
17
|
? allowedExtensionsProp
|
|
18
18
|
: SUPPORTED_FILE_MIME_TYPES;
|
|
19
19
|
const locked = Boolean(disabled || readOnly);
|
|
20
|
-
|
|
20
|
+
// 파일 전용 조합도 같은 목록 연산을 쓰도록 파일을 첨부 형태로 감싼다.
|
|
21
|
+
const attachmentList = attachmentListProp ??
|
|
22
|
+
(fileListProp ?? []).map((file) => ({ type: 'file', file }));
|
|
23
|
+
const fileList = attachmentList.flatMap((item) => item.type === 'file' ? [item.file] : []);
|
|
24
|
+
// 바뀐 목록을 받은 쪽 형태 그대로 돌려준다. 파일 전용 조합에는 파일만 남긴 IFile[]을 준다.
|
|
25
|
+
const commit = async (next) => {
|
|
26
|
+
if (attachmentListProp) {
|
|
27
|
+
setAttachmentList?.(next);
|
|
28
|
+
await onChangeAttachment?.(next);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const files = next.flatMap((item) => item.type === 'file' ? [item.file] : []);
|
|
32
|
+
setFileList?.(files);
|
|
33
|
+
await onChangeFile?.(files);
|
|
34
|
+
};
|
|
21
35
|
// 인풋마다 허용 조건이 다를 수 있어, Root 값 위에 인풋이 준 옵션을 덮어쓴다.
|
|
22
36
|
const resolveOptions = (options) => ({
|
|
23
37
|
maxSize: options?.maxSize ?? maxSize,
|
|
@@ -68,47 +82,51 @@ const Root = ({ recommendedSize, maxSize, allowedExtensions: allowedExtensionsPr
|
|
|
68
82
|
const converted = await convertFiles(files, resolved);
|
|
69
83
|
if (!converted)
|
|
70
84
|
return;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
85
|
+
await commit([
|
|
86
|
+
...attachmentList,
|
|
87
|
+
...converted.map((file) => ({ type: 'file', file })),
|
|
88
|
+
]);
|
|
74
89
|
};
|
|
75
90
|
const replaceFile = async (file, index, options) => {
|
|
76
91
|
const [converted] = (await convertFiles([file], resolveOptions(options))) ?? [];
|
|
77
92
|
if (!converted)
|
|
78
93
|
return;
|
|
79
|
-
|
|
80
|
-
setFileList(next);
|
|
81
|
-
await onChangeFile(next);
|
|
94
|
+
await commit(attachmentList.map((item, itemIndex) => itemIndex === index ? { type: 'file', file: converted } : item));
|
|
82
95
|
};
|
|
83
96
|
const deleteFile = async (index) => {
|
|
84
|
-
const target =
|
|
85
|
-
if (
|
|
97
|
+
const target = attachmentList[index];
|
|
98
|
+
if (target?.type !== 'file')
|
|
86
99
|
return;
|
|
87
100
|
try {
|
|
88
|
-
if (!(await onDeleteFile(target)))
|
|
101
|
+
if (!(await onDeleteFile(target.file)))
|
|
89
102
|
return;
|
|
90
|
-
|
|
91
|
-
setFileList(next);
|
|
92
|
-
await onChangeFile(next);
|
|
103
|
+
await commit(attachmentList.filter((_, itemIndex) => itemIndex !== index));
|
|
93
104
|
}
|
|
94
105
|
catch {
|
|
95
106
|
LDToast.error('파일 삭제 중 문제가 발생했습니다. 잠시후 다시 시도해주세요.');
|
|
96
107
|
}
|
|
97
108
|
};
|
|
98
|
-
// 링크는 파일이 아니라 검증·변환 대상이 아니므로 목록 갱신만
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
109
|
+
// 링크는 파일이 아니라 검증·변환 대상이 아니므로 목록 갱신만 한다.
|
|
110
|
+
const addLink = () => commit([...attachmentList, { type: 'link', label: '', url: '' }]);
|
|
111
|
+
// 이름·주소 중 바뀐 쪽만 받아 해당 행에 합친다.
|
|
112
|
+
const changeLink = (index, value) => commit(attachmentList.map((item, itemIndex) => itemIndex === index && item.type === 'link'
|
|
113
|
+
? { ...item, ...value }
|
|
114
|
+
: item));
|
|
115
|
+
const deleteLink = (index) => commit(attachmentList.filter((_, itemIndex) => itemIndex !== index));
|
|
116
|
+
const moveAttachment = (from, to) => {
|
|
117
|
+
const next = [...attachmentList];
|
|
118
|
+
const [moved] = next.splice(from, 1);
|
|
119
|
+
if (!moved)
|
|
120
|
+
return Promise.resolve();
|
|
121
|
+
next.splice(to, 0, moved);
|
|
122
|
+
return commit(next);
|
|
102
123
|
};
|
|
103
|
-
const addLink = () => applyLinks([...linkList, '']);
|
|
104
|
-
const changeLink = (index, value) => applyLinks(linkList.map((item, itemIndex) => (itemIndex === index ? value : item)));
|
|
105
|
-
const deleteLink = (index) => applyLinks(linkList.filter((_, itemIndex) => itemIndex !== index));
|
|
106
124
|
return (_jsx(FileUploadContext, { value: {
|
|
107
125
|
recommendedSize,
|
|
108
126
|
maxSize,
|
|
109
127
|
allowedExtensions,
|
|
110
128
|
fileList,
|
|
111
|
-
|
|
129
|
+
attachmentList,
|
|
112
130
|
maxFileCount,
|
|
113
131
|
disabled,
|
|
114
132
|
readOnly,
|
|
@@ -119,6 +137,7 @@ const Root = ({ recommendedSize, maxSize, allowedExtensions: allowedExtensionsPr
|
|
|
119
137
|
addLink,
|
|
120
138
|
changeLink,
|
|
121
139
|
deleteLink,
|
|
140
|
+
moveAttachment,
|
|
122
141
|
}, children: _jsx("div", { ref: ref, ...props, children: children }) }));
|
|
123
142
|
};
|
|
124
143
|
const Input = ({ replaceIndex, options, onClick, onChange, disabled, ref, ...props }) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
2
|
import { type LDButtonProps } from '../../components/LDButton/LDButton.js';
|
|
3
|
-
import { type FileUploadBaseRootProps, type FileUploadOptions } from '../../components/LDFileUpload/FileUploadBase.js';
|
|
3
|
+
import { type FileUploadBaseRootProps, type FileUploadFileListProps, type FileUploadOptions } from '../../components/LDFileUpload/FileUploadBase.js';
|
|
4
4
|
export interface LDFileUploadClassNames {
|
|
5
5
|
root?: string;
|
|
6
6
|
input?: string;
|
|
@@ -25,12 +25,17 @@ export interface LDFileUploadCardListProps {
|
|
|
25
25
|
isExistUploadedAt?: boolean;
|
|
26
26
|
className?: string;
|
|
27
27
|
}
|
|
28
|
-
export interface
|
|
28
|
+
export interface LDFileUploadAttachmentListProps {
|
|
29
|
+
/** 링크 주소 입력칸 placeholder */
|
|
29
30
|
placeholder?: string;
|
|
31
|
+
/** 링크 이름 입력칸 placeholder */
|
|
32
|
+
labelPlaceholder?: string;
|
|
33
|
+
/** 파일 카드에 업로드 시각 라벨을 표시합니다. */
|
|
34
|
+
isExistUploadedAt?: boolean;
|
|
30
35
|
className?: string;
|
|
31
36
|
}
|
|
32
37
|
export type LDFileUploadDescriptionProps = HTMLAttributes<HTMLParagraphElement>;
|
|
33
|
-
export interface LDFileUploadProps extends Omit<LDFileUploadRootProps, 'children' | 'classNames' | 'maxFileCount'
|
|
38
|
+
export interface LDFileUploadProps extends Omit<LDFileUploadRootProps, 'children' | 'classNames' | 'maxFileCount' | keyof FileUploadFileListProps>, FileUploadFileListProps {
|
|
34
39
|
isExistDescription?: boolean;
|
|
35
40
|
/** 카드에 업로드 시각 라벨을 표시합니다. */
|
|
36
41
|
isExistUploadedAt?: boolean;
|
|
@@ -41,7 +46,7 @@ declare const LDFileUpload: {
|
|
|
41
46
|
Root: ({ className, classNames, children, ...props }: LDFileUploadRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
42
47
|
Input: ({ type, label, icon, options, className, ...props }: LDFileUploadInputProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
43
48
|
CardList: ({ type, isExistUploadedAt, className, }: LDFileUploadCardListProps) => import("react/jsx-runtime").JSX.Element;
|
|
44
|
-
|
|
49
|
+
AttachmentList: ({ placeholder, labelPlaceholder, isExistUploadedAt, className, }: LDFileUploadAttachmentListProps) => import("react/jsx-runtime").JSX.Element;
|
|
45
50
|
Description: ({ className, ...props }: LDFileUploadDescriptionProps) => import("react/jsx-runtime").JSX.Element;
|
|
46
51
|
};
|
|
47
52
|
export default LDFileUpload;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LDFileUpload.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDFileUpload.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LDFileUpload.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDFileUpload.tsx"],"names":[],"mappings":"AA8BA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAEf,OAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE9E,OAAuB,EAErB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EAEvB,MAAM,0CAA0C,CAAC;AAuFlD,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACrC;AAuBD,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAClD,aAAa,CAAC,QAAQ,CAAC,EACvB,MAAM,CACP;IACC,IAAI,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AA6FD,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAC3B,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyUD,MAAM,WAAW,+BAA+B;IAC9C,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyFD,MAAM,MAAM,4BAA4B,GAAG,cAAc,CAAC,oBAAoB,CAAC,CAAC;AA6BhF,MAAM,WAAW,iBACf,SACE,IAAI,CACF,qBAAqB,EACrB,UAAU,GAAG,YAAY,GAAG,cAAc,GAAG,MAAM,uBAAuB,CAC3E,EACD,uBAAuB;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4BAA4B;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,kCAAkC;AAClC,QAAA,MAAM,YAAY;qFAMf,iBAAiB;0DArlBjB,qBAAqB;iEAmCrB,sBAAsB;wDA+FtB,yBAAyB;uFAqVzB,+BAA+B;2CAiFY,4BAA4B;CA2DzE,CAAC;AAQF,eAAe,YAAY,CAAC"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { closestCenter, DndContext, KeyboardSensor, PointerSensor, useSensor, useSensors, } from '@dnd-kit/core';
|
|
4
|
+
import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
|
|
5
|
+
import { SortableContext, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy, } from '@dnd-kit/sortable';
|
|
6
|
+
import { CSS } from '@dnd-kit/utilities';
|
|
3
7
|
import dayjs from 'dayjs';
|
|
4
|
-
import { Images, Link2, Paperclip, Plus, Trash2, X } from 'lucide-react';
|
|
5
|
-
import { createContext, useContext, } from 'react';
|
|
8
|
+
import { GripVertical, Images, Link2, Paperclip, Plus, RefreshCw, Trash2, X, } from 'lucide-react';
|
|
9
|
+
import { createContext, useContext, useId, } from 'react';
|
|
6
10
|
import LDButton from '../../components/LDButton/LDButton.js';
|
|
7
11
|
import LDCarousel from '../../components/LDCarousel/LDCarousel.js';
|
|
8
12
|
import FileUploadBase, { useFileUploadContext, } from '../../components/LDFileUpload/FileUploadBase.js';
|
|
@@ -11,7 +15,7 @@ import RenderIcon from '../../components/RenderIcon/RenderIcon.js';
|
|
|
11
15
|
import Show from '../../components/Show/Show.js';
|
|
12
16
|
import { FILE_EXTENSIONS } from '../../constants/file.js';
|
|
13
17
|
import cn from '../../utils/cn.js';
|
|
14
|
-
import { getFileSizeUnit } from '../../utils/file.js';
|
|
18
|
+
import { getFileSizeUnit, isImageOrPdf } from '../../utils/file.js';
|
|
15
19
|
import tv from '../../utils/tv.js';
|
|
16
20
|
// disabled·readOnly·기본 상태의 커서는 서로 배타적이다. cursor-not-allowed 는 hover:cursor-pointer 와
|
|
17
21
|
// tailwind-merge 상 다른 그룹이어서 축만으로는 지워지지 않으므로, 겹치지 않게 compound 로 갈라 놓는다.
|
|
@@ -54,10 +58,12 @@ const imageCardDeleteVariants = tv({
|
|
|
54
58
|
base: 'absolute top-2 right-2 flex size-5 min-w-0 items-center justify-center rounded-sm bg-neutral-100 px-0 text-neutral700 opacity-0 ld-transition',
|
|
55
59
|
variants: { locked: { false: 'group-hover:opacity-100' } },
|
|
56
60
|
});
|
|
61
|
+
// 파일 카드는 누르면 파일을 연다. 보기는 readOnly에서도 되므로 disabled만 커서를 막는다.
|
|
57
62
|
const cardVariants = tv({
|
|
58
63
|
base: 'flex w-full flex-row items-center justify-between gap-md rounded-[10px] bg-tintBlue p-5',
|
|
59
|
-
variants:
|
|
60
|
-
|
|
64
|
+
variants: {
|
|
65
|
+
disabled: { true: 'cursor-not-allowed', false: 'hover:cursor-pointer' },
|
|
66
|
+
},
|
|
61
67
|
});
|
|
62
68
|
const cardDeleteVariants = tv({
|
|
63
69
|
base: 'flex size-4.5 min-w-0 items-center justify-center px-0 text-lb500 ld-transition',
|
|
@@ -72,7 +78,7 @@ const linkCardVariants = tv({
|
|
|
72
78
|
},
|
|
73
79
|
});
|
|
74
80
|
const linkFieldVariants = tv({
|
|
75
|
-
base: 'ld-input-field -my-2 h-full w-full min-w-0 border-0 bg-transparent px-0 py-2 display16 bold text-lb500 placeholder-
|
|
81
|
+
base: 'ld-input-field -my-2 h-full w-full min-w-0 border-0 bg-transparent px-0 py-2 display16 bold text-lb500 placeholder-neutral300 outline-none read-only:cursor-not-allowed',
|
|
76
82
|
variants: {
|
|
77
83
|
disabled: { true: 'cursor-not-allowed', false: '' },
|
|
78
84
|
},
|
|
@@ -134,24 +140,108 @@ const CardList = ({ type = 'default', isExistUploadedAt = true, className, }) =>
|
|
|
134
140
|
}
|
|
135
141
|
return (_jsx(LDCarousel, { className: cn(className, classNames.cardList), slidesPerView: "auto", gap: 8, arrowPosition: "none", showDots: false, slides: cards }));
|
|
136
142
|
}
|
|
137
|
-
return (_jsx("div", { className: cn('flex w-full flex-col gap-sm', className, classNames.cardList), children: fileList.map((file, index) => (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
return (_jsx("div", { className: cn('flex w-full flex-col gap-sm', className, classNames.cardList), children: fileList.map((file, index) => (_jsx(FileCard, { file: file, index: index, isExistUploadedAt: isExistUploadedAt }, `${file.fileName}_${index}`))) }));
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* 첨부 파일을 연다. 이미지·PDF는 새 탭에서 보이고, 나머지는 파일 이름 그대로 내려받는다.
|
|
147
|
+
* 새로 올린 파일은 data: URL인데 Chrome이 data: URL로의 새 탭 이동을 막으므로 Blob URL로 바꿔 연다.
|
|
148
|
+
*/
|
|
149
|
+
const openFile = async ({ src, fileName }) => {
|
|
150
|
+
const href = src.startsWith('data:')
|
|
151
|
+
? URL.createObjectURL(await (await fetch(src)).blob())
|
|
152
|
+
: src;
|
|
153
|
+
const anchor = document.createElement('a');
|
|
154
|
+
anchor.href = href;
|
|
155
|
+
anchor.target = '_blank';
|
|
156
|
+
anchor.rel = 'noopener noreferrer';
|
|
157
|
+
if (!isImageOrPdf(fileName))
|
|
158
|
+
anchor.download = fileName;
|
|
159
|
+
anchor.click();
|
|
160
|
+
// 새 탭이 Blob을 다 읽을 시간을 두고 해제한다
|
|
161
|
+
if (href !== src)
|
|
162
|
+
setTimeout(() => URL.revokeObjectURL(href), 60_000);
|
|
146
163
|
};
|
|
147
|
-
/**
|
|
148
|
-
const
|
|
149
|
-
const {
|
|
164
|
+
/** 파일 카드. 카드를 누르면 파일을 교체하고 X로 삭제한다. */
|
|
165
|
+
const FileCard = ({ file, index, isExistUploadedAt, handle, }) => {
|
|
166
|
+
const { disabled, locked, deleteFile } = useFileUploadContext();
|
|
150
167
|
const classNames = useContext(StyleContext);
|
|
151
|
-
return (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
168
|
+
return (
|
|
169
|
+
// 카드 어디를 눌러도 열리게 한다. 키보드는 파일 이름 버튼으로 같은 동작에 닿는다(클릭이 카드로 올라옴).
|
|
170
|
+
// 손잡이·교체·삭제는 각자 전파를 끊어 카드 열기와 겹치지 않게 한다.
|
|
171
|
+
_jsxs("div", { onClick: () => {
|
|
172
|
+
if (!disabled)
|
|
173
|
+
void openFile(file);
|
|
174
|
+
}, className: cardVariants({
|
|
175
|
+
disabled: !!disabled,
|
|
176
|
+
className: classNames.card,
|
|
177
|
+
}), children: [_jsxs("div", { className: "flex flex-row items-center gap-sm", children: [handle, _jsx(RenderIcon, { className: "size-5 text-lb500", children: _jsx(Paperclip, {}) }), _jsxs("div", { className: "flex items-center justify-center gap-sm mobile:flex-col mobile:items-start mobile:gap-2xs", children: [_jsx("button", { type: "button", disabled: disabled, "aria-label": `${file.fileName} 열기`, className: "cursor-pointer display16 bold text-lb500 disabled:cursor-not-allowed", children: file.fileName }), _jsx(Show, { when: isExistUploadedAt && file.uploadedAt, children: (uploadedAt) => (_jsxs("span", { className: "rounded-[5px] bg-blue200 px-1.5 py-0.75 display10 medium text-white", children: [dayjs(uploadedAt).format('YYYY-MM-DD HH:mm'), " \uB9C8\uC9C0\uB9C9 \uC5C5\uB85C\uB4DC"] })) })] })] }), _jsxs("div", { className: "flex flex-row items-center gap-sm", children: [_jsxs("label", { onClick: (event) => event.stopPropagation(), className: cardDeleteVariants({
|
|
178
|
+
locked,
|
|
179
|
+
className: 'cursor-pointer',
|
|
180
|
+
}), children: [_jsx(RefreshCw, { className: "size-4.5" }), _jsx(FileUploadBase.Input, { replaceIndex: index, "aria-label": `${file.fileName} 교체`,
|
|
181
|
+
// label이 대신 보낸 click이 카드까지 올라가 파일이 열리지 않게 한다
|
|
182
|
+
onClick: (event) => event.stopPropagation(), className: "sr-only" })] }), _jsx(LDButton, { onClick: async (event) => {
|
|
183
|
+
event.preventDefault();
|
|
184
|
+
event.stopPropagation();
|
|
185
|
+
await deleteFile(index);
|
|
186
|
+
}, "aria-label": `${file.fileName} 삭제`, disabled: locked, variant: "ghost", leftIcon: _jsx(X, { className: "size-4.5" }), color: "neutral", className: cardDeleteVariants({ locked }) })] })] }));
|
|
187
|
+
};
|
|
188
|
+
/** 링크 행. 이름과 주소를 그 자리에서 입력받는다. */
|
|
189
|
+
const LinkRow = ({ link, index, linkNumber, placeholder, labelPlaceholder, handle, }) => {
|
|
190
|
+
const { disabled, readOnly, locked, changeLink, deleteLink } = useFileUploadContext();
|
|
191
|
+
const classNames = useContext(StyleContext);
|
|
192
|
+
return (_jsxs(InputBase.Root, { block: true, className: linkCardVariants({
|
|
193
|
+
disabled: !!disabled,
|
|
194
|
+
className: classNames.card,
|
|
195
|
+
}), children: [handle, _jsx(RenderIcon, { className: "size-5 shrink-0 text-lb500", children: _jsx(Link2, {}) }), _jsx(InputBase.Field, { value: link.label, placeholder: labelPlaceholder, "aria-label": `링크 ${linkNumber} 이름`, disabled: disabled, readOnly: readOnly, onChange: (event) => changeLink(index, { label: event.target.value }), className: linkFieldVariants({
|
|
196
|
+
disabled: !!disabled,
|
|
197
|
+
className: 'w-40 shrink-0',
|
|
198
|
+
}) }), _jsx("span", { "aria-hidden": true, className: "shrink-0 text-blue200", children: "|" }), _jsx(InputBase.Field, { type: "url", value: link.url, placeholder: placeholder, "aria-label": `링크 ${linkNumber} 주소`, disabled: disabled, readOnly: readOnly, onChange: (event) => changeLink(index, { url: event.target.value }), className: linkFieldVariants({ disabled: !!disabled }) }), _jsx(LDButton, { onClick: () => deleteLink(index), "aria-label": `링크 ${linkNumber} 삭제`, disabled: locked, variant: "ghost", leftIcon: _jsx(X, { className: "size-4.5" }), color: "neutral", className: cardDeleteVariants({ locked }) })] }));
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* 드래그로 순서를 바꾸는 항목 래퍼.
|
|
202
|
+
* 파일 카드는 누르면 교체 창이 열리고 링크 행에는 입력칸이 있어, 카드 전체가 아니라 손잡이로만 끈다.
|
|
203
|
+
*/
|
|
204
|
+
const SortableAttachment = ({ id, name, children, }) => {
|
|
205
|
+
const { locked } = useFileUploadContext();
|
|
206
|
+
const { setNodeRef, setActivatorNodeRef, attributes, listeners, transform, transition, isDragging, isSorting, } = useSortable({ id, disabled: locked });
|
|
207
|
+
return (_jsx("div", { ref: setNodeRef, className: cn(isDragging && 'relative z-10 opacity-80'), style: {
|
|
208
|
+
transform: CSS.Transform.toString(transform),
|
|
209
|
+
// 인덱스를 id로 쓰므로 놓는 순간 같은 노드에 다른 항목이 들어간다. 그때 transition이 돌면
|
|
210
|
+
// 이전 자리에서 미끄러져 오는 것처럼 보이므로, 끄는 동안(isSorting)에만 애니메이션한다.
|
|
211
|
+
transition: isSorting && !isDragging ? transition : undefined,
|
|
212
|
+
}, children: children(_jsx("button", { type: "button", ref: setActivatorNodeRef, ...attributes, ...listeners, "aria-label": `${name} 순서 변경`, disabled: locked,
|
|
213
|
+
// 손잡이 클릭이 카드로 올라가면 파일이 열린다
|
|
214
|
+
onClick: (event) => event.stopPropagation(), className: "shrink-0 cursor-grab touch-none text-lb300 active:cursor-grabbing disabled:cursor-not-allowed", children: _jsx(GripVertical, { className: "size-5" }) })) }));
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* 파일과 링크가 섞인 첨부 목록입니다. 손잡이를 끌어 순서를 바꿉니다.
|
|
218
|
+
* Root에 `attachmentList`·`setAttachmentList`를 넘겨야 합니다.
|
|
219
|
+
*/
|
|
220
|
+
const AttachmentList = ({ placeholder = '링크를 입력해주세요', labelPlaceholder = '링크 이름', isExistUploadedAt = true, className, }) => {
|
|
221
|
+
const { attachmentList, moveAttachment } = useFileUploadContext();
|
|
222
|
+
const classNames = useContext(StyleContext);
|
|
223
|
+
// SSR에서 dnd-kit 접근성 id가 서버·클라이언트로 어긋나지 않게 고정한다.
|
|
224
|
+
const dndId = useId();
|
|
225
|
+
const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, {
|
|
226
|
+
coordinateGetter: sortableKeyboardCoordinates,
|
|
227
|
+
}));
|
|
228
|
+
// ponytail: 항목에 고유 id가 없어 인덱스를 id로 쓴다. 놓을 때는 애니메이션 없이 제자리에 붙는다(SortableAttachment). 놓을 때도 부드럽게 옮기려면 항목 id를 도입
|
|
229
|
+
const ids = attachmentList.map((_, index) => String(index));
|
|
230
|
+
const handleDragEnd = ({ active, over }) => {
|
|
231
|
+
if (!over || active.id === over.id)
|
|
232
|
+
return;
|
|
233
|
+
void moveAttachment(Number(active.id), Number(over.id));
|
|
234
|
+
};
|
|
235
|
+
return (_jsx(DndContext, { id: dndId, sensors: sensors, collisionDetection: closestCenter, modifiers: [restrictToVerticalAxis], onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: ids, strategy: verticalListSortingStrategy, children: _jsx("div", { className: cn('flex w-full flex-col gap-sm', className, classNames.cardList), children: attachmentList.map((item, index) => {
|
|
236
|
+
const id = String(index);
|
|
237
|
+
if (item.type === 'file') {
|
|
238
|
+
return (_jsx(SortableAttachment, { id: id, name: item.file.fileName, children: (handle) => (_jsx(FileCard, { file: item.file, index: index, isExistUploadedAt: isExistUploadedAt, handle: handle })) }, id));
|
|
239
|
+
}
|
|
240
|
+
const linkNumber = attachmentList
|
|
241
|
+
.slice(0, index + 1)
|
|
242
|
+
.filter((other) => other.type === 'link').length;
|
|
243
|
+
return (_jsx(SortableAttachment, { id: id, name: `링크 ${linkNumber}`, children: (handle) => (_jsx(LinkRow, { link: item, index: index, linkNumber: linkNumber, placeholder: placeholder, labelPlaceholder: labelPlaceholder, handle: handle })) }, id));
|
|
244
|
+
}) }) }) }));
|
|
155
245
|
};
|
|
156
246
|
/** 업로드 제한 조건을 안내합니다. */
|
|
157
247
|
const Description = ({ className, ...props }) => {
|
|
@@ -167,6 +257,6 @@ const LDFileUpload = ({ recommendedSize = { width: 1200, height: 800 }, isExistD
|
|
|
167
257
|
LDFileUpload.Root = Root;
|
|
168
258
|
LDFileUpload.Input = Input;
|
|
169
259
|
LDFileUpload.CardList = CardList;
|
|
170
|
-
LDFileUpload.
|
|
260
|
+
LDFileUpload.AttachmentList = AttachmentList;
|
|
171
261
|
LDFileUpload.Description = Description;
|
|
172
262
|
export default LDFileUpload;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type FileUploadFileListProps } from '../../components/LDFileUpload/FileUploadBase.js';
|
|
1
2
|
import { type LDFileUploadRootProps } from '../../components/LDFileUpload/LDFileUpload.js';
|
|
2
|
-
export interface LDFileUploadListProps extends Omit<LDFileUploadRootProps, 'children' | 'classNames'
|
|
3
|
+
export interface LDFileUploadListProps extends Omit<LDFileUploadRootProps, 'children' | 'classNames' | keyof FileUploadFileListProps>, FileUploadFileListProps {
|
|
3
4
|
isExistDescription?: boolean;
|
|
4
5
|
}
|
|
5
6
|
/** 여러 개의 일반 파일을 업로드하는 기본 조합입니다. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LDFileUploadList.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDFileUploadList.tsx"],"names":[],"mappings":"AAAA,OAAqB,EACnB,KAAK,qBAAqB,EAC3B,MAAM,wCAAwC,CAAC;AAEhD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"LDFileUploadList.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDFileUploadList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACxF,OAAqB,EACnB,KAAK,qBAAqB,EAC3B,MAAM,wCAAwC,CAAC;AAEhD,MAAM,WAAW,qBACf,SACE,IAAI,CACF,qBAAqB,EACrB,UAAU,GAAG,YAAY,GAAG,MAAM,uBAAuB,CAC1D,EACD,uBAAuB;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,mCAAmC;AACnC,QAAA,MAAM,gBAAgB,GAAI,qFAOvB,qBAAqB,4CAcvB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type FileUploadFileListProps } from '../../components/LDFileUpload/FileUploadBase.js';
|
|
1
2
|
import { type LDFileUploadClassNames, type LDFileUploadRootProps } from '../../components/LDFileUpload/LDFileUpload.js';
|
|
2
|
-
export interface LDImageUploadProps extends Omit<LDFileUploadRootProps, 'children' | 'maxFileCount'
|
|
3
|
+
export interface LDImageUploadProps extends Omit<LDFileUploadRootProps, 'children' | 'maxFileCount' | keyof FileUploadFileListProps>, FileUploadFileListProps {
|
|
3
4
|
isExistDescription?: boolean;
|
|
4
5
|
classNames?: LDFileUploadClassNames;
|
|
5
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LDImageUpload.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDImageUpload.tsx"],"names":[],"mappings":"AAAA,OAAqB,EACnB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,wCAAwC,CAAC;AAGhD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"LDImageUpload.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDImageUpload.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACxF,OAAqB,EACnB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,wCAAwC,CAAC;AAGhD,MAAM,WAAW,kBACf,SACE,IAAI,CACF,qBAAqB,EACrB,UAAU,GAAG,cAAc,GAAG,MAAM,uBAAuB,CAC5D,EACD,uBAAuB;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACrC;AAED,gCAAgC;AAChC,QAAA,MAAM,aAAa,GAAI,gFAMpB,kBAAkB,4CAiBpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type FileUploadFileListProps } from '../../components/LDFileUpload/FileUploadBase.js';
|
|
1
2
|
import { type LDFileUploadRootProps } from '../../components/LDFileUpload/LDFileUpload.js';
|
|
2
|
-
export interface LDImageUploadListProps extends Omit<LDFileUploadRootProps, 'children' | 'classNames'
|
|
3
|
+
export interface LDImageUploadListProps extends Omit<LDFileUploadRootProps, 'children' | 'classNames' | keyof FileUploadFileListProps>, FileUploadFileListProps {
|
|
3
4
|
isExistDescription?: boolean;
|
|
4
5
|
}
|
|
5
6
|
/** 여러 개의 이미지를 업로드하는 기본 조합입니다. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LDImageUploadList.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDImageUploadList.tsx"],"names":[],"mappings":"AAAA,OAAqB,EACnB,KAAK,qBAAqB,EAC3B,MAAM,wCAAwC,CAAC;AAGhD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"LDImageUploadList.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDImageUploadList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACxF,OAAqB,EACnB,KAAK,qBAAqB,EAC3B,MAAM,wCAAwC,CAAC;AAGhD,MAAM,WAAW,sBACf,SACE,IAAI,CACF,qBAAqB,EACrB,UAAU,GAAG,YAAY,GAAG,MAAM,uBAAuB,CAC1D,EACD,uBAAuB;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,iCAAiC;AACjC,QAAA,MAAM,iBAAiB,GAAI,wGAQxB,sBAAsB,4CAmBxB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
package/dist/index.css
CHANGED
|
@@ -3126,6 +3126,9 @@
|
|
|
3126
3126
|
.text-lb100 {
|
|
3127
3127
|
color: var(--color-lb100);
|
|
3128
3128
|
}
|
|
3129
|
+
.text-lb300 {
|
|
3130
|
+
color: var(--color-lb300);
|
|
3131
|
+
}
|
|
3129
3132
|
.text-lb500 {
|
|
3130
3133
|
color: var(--color-lb500);
|
|
3131
3134
|
}
|
|
@@ -3228,11 +3231,6 @@
|
|
|
3228
3231
|
.underline-offset-\[4px\] {
|
|
3229
3232
|
text-underline-offset: 4px;
|
|
3230
3233
|
}
|
|
3231
|
-
.placeholder-lb300 {
|
|
3232
|
-
&::placeholder {
|
|
3233
|
-
color: var(--color-lb300);
|
|
3234
|
-
}
|
|
3235
|
-
}
|
|
3236
3234
|
.placeholder-neutral300 {
|
|
3237
3235
|
&::placeholder {
|
|
3238
3236
|
color: var(--color-neutral300);
|
|
@@ -4102,6 +4100,11 @@
|
|
|
4102
4100
|
--tw-ring-inset: inset;
|
|
4103
4101
|
}
|
|
4104
4102
|
}
|
|
4103
|
+
.active\:cursor-grabbing {
|
|
4104
|
+
&:active {
|
|
4105
|
+
cursor: grabbing;
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4105
4108
|
.active\:bg-accept50 {
|
|
4106
4109
|
&:active {
|
|
4107
4110
|
background-color: var(--color-accept50);
|
|
@@ -5554,17 +5557,17 @@
|
|
|
5554
5557
|
padding: 0 !important;
|
|
5555
5558
|
line-height: calc(28 / 18) !important;
|
|
5556
5559
|
}
|
|
5557
|
-
prose h1, prose h2, prose h3 {
|
|
5560
|
+
.prose h1, .prose h2, .prose h3 {
|
|
5558
5561
|
margin-top: 0 !important;
|
|
5559
5562
|
margin-bottom: 0.5rem !important;
|
|
5560
5563
|
padding: 0 !important;
|
|
5561
5564
|
}
|
|
5562
|
-
prose ul, prose ol {
|
|
5565
|
+
.prose ul, .prose ol {
|
|
5563
5566
|
margin-top: 0 !important;
|
|
5564
5567
|
margin-bottom: 0.5rem !important;
|
|
5565
5568
|
padding: 0 20px !important;
|
|
5566
5569
|
}
|
|
5567
|
-
prose ul li::marker, prose ol li::marker {
|
|
5570
|
+
.prose ul li::marker, .prose ol li::marker {
|
|
5568
5571
|
color: #000 !important;
|
|
5569
5572
|
}
|
|
5570
5573
|
.prose :is(strong, b) {
|
package/dist/index.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export { type DrawerButton, default as LDDrawer, type LDDrawerBodyProps, type LD
|
|
|
26
26
|
export { default as LDEditor } from './components/LDEditor/LDEditor.js';
|
|
27
27
|
export { default as LDViewer } from './components/LDEditor/LDViewer.js';
|
|
28
28
|
export { type EmptySize, default as LDEmpty, type LDEmptyProps, } from './components/LDEmpty/LDEmpty.js';
|
|
29
|
-
export { type FileUploadOptions as LDFileUploadOptions } from './components/LDFileUpload/FileUploadBase.js';
|
|
30
|
-
export { default as LDFileUpload, type LDFileUploadCardListProps, type LDFileUploadClassNames, type LDFileUploadDescriptionProps, type LDFileUploadInputProps, type
|
|
29
|
+
export { type FileUploadAttachment as LDFileUploadAttachment, type FileUploadOptions as LDFileUploadOptions, } from './components/LDFileUpload/FileUploadBase.js';
|
|
30
|
+
export { default as LDFileUpload, type LDFileUploadAttachmentListProps, type LDFileUploadCardListProps, type LDFileUploadClassNames, type LDFileUploadDescriptionProps, type LDFileUploadInputProps, type LDFileUploadProps, type LDFileUploadRootProps, } from './components/LDFileUpload/LDFileUpload.js';
|
|
31
31
|
export { default as LDFileUploadList, type LDFileUploadListProps, } from './components/LDFileUpload/LDFileUploadList.js';
|
|
32
32
|
export { default as LDImageUpload, type LDImageUploadProps, } from './components/LDFileUpload/LDImageUpload.js';
|
|
33
33
|
export { default as LDImageUploadList, type LDImageUploadListProps, } from './components/LDFileUpload/LDImageUploadList.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,iBAAiB,EACtB,OAAO,IAAI,WAAW,EACtB,KAAK,gBAAgB,GACtB,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EACL,OAAO,IAAI,cAAc,EACzB,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACnC,KAAK,uBAAuB,EAC5B,KAAK,gCAAgC,EACrC,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,GAC7B,MAAM,4CAA4C,CAAC;AAGpD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EACL,OAAO,IAAI,gBAAgB,EAC3B,KAAK,qBAAqB,GAC3B,MAAM,wCAAwC,CAAC;AAGhD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAGlE,OAAO,EACL,OAAO,IAAI,YAAY,EACvB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,wCAAwC,CAAC;AAGhD,OAAO,EACL,OAAO,IAAI,QAAQ,EACnB,KAAK,aAAa,GACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,OAAO,IAAI,MAAM,EACjB,KAAK,WAAW,GACjB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,KAAK,gBAAgB,EACrB,OAAO,IAAI,UAAU,EACrB,KAAK,eAAe,GACrB,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAGxE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAG3E,OAAO,EACL,OAAO,IAAI,OAAO,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAG7F,OAAO,EACL,OAAO,IAAI,cAAc,EACzB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,GAC9B,MAAM,4CAA4C,CAAC;AAGpD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAGzF,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AAChG,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,sDAAsD,CAAC;AAGxG,OAAO,EACL,KAAK,iBAAiB,EACtB,OAAO,IAAI,gBAAgB,EAC3B,KAAK,qBAAqB,GAC3B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EACL,OAAO,IAAI,SAAS,EACpB,KAAK,cAAc,GACpB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EACL,KAAK,YAAY,EACjB,OAAO,IAAI,QAAQ,EACnB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAGrE,OAAO,EACL,KAAK,SAAS,EACd,OAAO,IAAI,OAAO,EAClB,KAAK,YAAY,GAClB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -11,23 +11,23 @@
|
|
|
11
11
|
line-height: calc(28 / 18) !important;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
prose h1,
|
|
15
|
-
prose h2,
|
|
16
|
-
prose h3 {
|
|
14
|
+
.prose h1,
|
|
15
|
+
.prose h2,
|
|
16
|
+
.prose h3 {
|
|
17
17
|
margin-top: 0 !important;
|
|
18
18
|
margin-bottom: 0.5rem !important;
|
|
19
19
|
padding: 0 !important;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
prose ul,
|
|
23
|
-
prose ol {
|
|
22
|
+
.prose ul,
|
|
23
|
+
.prose ol {
|
|
24
24
|
margin-top: 0 !important;
|
|
25
25
|
margin-bottom: 0.5rem !important;
|
|
26
26
|
padding: 0 20px !important;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
prose ul li::marker,
|
|
30
|
-
prose ol li::marker {
|
|
29
|
+
.prose ul li::marker,
|
|
30
|
+
.prose ol li::marker {
|
|
31
31
|
color: #000 !important;
|
|
32
32
|
}
|
|
33
33
|
|