@loword/loword-design-system 0.5.9 → 0.7.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.
@@ -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;AAkmBF,eAAe,QAAQ,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
- isLink: editor.isActive('link'),
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(editor.getAttributes('link').href || '');
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
- const chain = editor
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: () => editor.chain().focus().unsetLink().run(), 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) => {
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(editor.getAttributes('link').href || '');
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
- const chain = editor.chain().focus().extendMarkRange('link');
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":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,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
+ {"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
- Image.configure({
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
- linkList: string[];
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: string) => Promise<void>;
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
- export interface FileUploadBaseRootProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'onChange'> {
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
- fileList: IFile[];
39
- setFileList: Dispatch<SetStateAction<IFile[]>>;
40
- /** 첨부된 링크 목록입니다. `Input type="link"`·`LinkList`를 쓸 때 넘깁니다. */
41
- linkList?: string[];
42
- setLinkList?: Dispatch<SetStateAction<string[]>>;
43
- onChangeLink?: (links: string[]) => void | Promise<void>;
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, linkList: linkListProp, setLinkList, onChangeLink, onChangeFile, onDeleteFile, disabled, readOnly, children, ref, ...props }: FileUploadBaseRootProps) => import("react/jsx-runtime").JSX.Element;
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":"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"}
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, linkList: linkListProp, setLinkList, onChangeLink, onChangeFile, onDeleteFile, disabled, readOnly, children, ref, ...props }) => {
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
- const linkList = linkListProp ?? [];
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
- const next = [...fileList, ...converted];
72
- setFileList(next);
73
- await onChangeFile(next);
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
- const next = fileList.map((item, itemIndex) => itemIndex === index ? converted : item);
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 = fileList[index];
85
- if (!target)
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
- const next = fileList.filter((_, itemIndex) => itemIndex !== index);
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
- // 링크는 파일이 아니라 검증·변환 대상이 아니므로 목록 갱신만 하고 onChangeLink로 알린다.
99
- const applyLinks = async (next) => {
100
- setLinkList?.(next);
101
- await onChangeLink?.(next);
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
- linkList,
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,22 @@ export interface LDFileUploadCardListProps {
25
25
  isExistUploadedAt?: boolean;
26
26
  className?: string;
27
27
  }
28
- export interface LDFileUploadLinkListProps {
28
+ export interface LDFileUploadAttachmentListProps {
29
+ /** 링크 주소 입력칸 placeholder */
29
30
  placeholder?: string;
31
+ /** 링크 이름 입력칸 placeholder */
32
+ labelPlaceholder?: string;
33
+ /** 파일 카드에 업로드 시각 라벨을 표시합니다. */
34
+ isExistUploadedAt?: boolean;
35
+ /**
36
+ * 손잡이를 끌어 순서를 바꿀 수 있게 합니다. 서버가 첨부 순서를 저장하는 화면에서만 켭니다.
37
+ * @default false
38
+ */
39
+ sortable?: boolean;
30
40
  className?: string;
31
41
  }
32
42
  export type LDFileUploadDescriptionProps = HTMLAttributes<HTMLParagraphElement>;
33
- export interface LDFileUploadProps extends Omit<LDFileUploadRootProps, 'children' | 'classNames' | 'maxFileCount'> {
43
+ export interface LDFileUploadProps extends Omit<LDFileUploadRootProps, 'children' | 'classNames' | 'maxFileCount' | keyof FileUploadFileListProps>, FileUploadFileListProps {
34
44
  isExistDescription?: boolean;
35
45
  /** 카드에 업로드 시각 라벨을 표시합니다. */
36
46
  isExistUploadedAt?: boolean;
@@ -41,7 +51,7 @@ declare const LDFileUpload: {
41
51
  Root: ({ className, classNames, children, ...props }: LDFileUploadRootProps) => import("react/jsx-runtime").JSX.Element;
42
52
  Input: ({ type, label, icon, options, className, ...props }: LDFileUploadInputProps) => import("react/jsx-runtime").JSX.Element | null;
43
53
  CardList: ({ type, isExistUploadedAt, className, }: LDFileUploadCardListProps) => import("react/jsx-runtime").JSX.Element;
44
- LinkList: ({ placeholder, className, }: LDFileUploadLinkListProps) => import("react/jsx-runtime").JSX.Element;
54
+ AttachmentList: ({ placeholder, labelPlaceholder, isExistUploadedAt, sortable, className, }: LDFileUploadAttachmentListProps) => import("react/jsx-runtime").JSX.Element;
45
55
  Description: ({ className, ...props }: LDFileUploadDescriptionProps) => import("react/jsx-runtime").JSX.Element;
46
56
  };
47
57
  export default LDFileUpload;
@@ -1 +1 @@
1
- {"version":3,"file":"LDFileUpload.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDFileUpload.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAEf,OAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE9E,OAAuB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EAEvB,MAAM,0CAA0C,CAAC;AAqFlD,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;AA6HD,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwDD,MAAM,MAAM,4BAA4B,GAAG,cAAc,CAAC,oBAAoB,CAAC,CAAC;AA6BhF,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAC7C,qBAAqB,EACrB,UAAU,GAAG,YAAY,GAAG,cAAc,CAC3C;IACC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4BAA4B;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,kCAAkC;AAClC,QAAA,MAAM,YAAY;qFAMf,iBAAiB;0DAhWjB,qBAAqB;iEAmCrB,sBAAsB;wDA+FtB,yBAAyB;4CA+HzB,yBAAyB;2CAqDkB,4BAA4B;CAwDzE,CAAC;AAQF,eAAe,YAAY,CAAC"}
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;AA8UD,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;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoGD,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;0DA1mBjB,qBAAqB;iEAmCrB,sBAAsB;wDA+FtB,yBAAyB;iGAgWzB,+BAA+B;2CA2FY,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: cursorVariants,
60
- compoundVariants: cursorCompounds,
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-lb300 outline-none read-only:cursor-not-allowed',
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) => (_jsxs("label", { className: cardVariants({
138
- disabled: !!disabled,
139
- readOnly: !!readOnly,
140
- className: classNames.card,
141
- }), children: [_jsxs("div", { className: "flex flex-row items-center gap-sm", children: [_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("span", { className: "display16 bold text-lb500", 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"] })) })] })] }), _jsx(FileUploadBase.Input, { replaceIndex: index, "aria-label": `${file.fileName} 교체`, className: "sr-only" }), _jsx(LDButton, { onClick: async (event) => {
142
- event.preventDefault();
143
- event.stopPropagation();
144
- await deleteFile(index);
145
- }, disabled: locked, variant: "ghost", leftIcon: _jsx(X, { className: "size-4.5" }), color: "neutral", className: cardDeleteVariants({ locked }) })] }, `${file.fileName}_${index}`))) }));
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 LinkList = ({ placeholder = '링크를 입력해주세요', className, }) => {
149
- const { linkList, disabled, readOnly, locked, changeLink, deleteLink } = useFileUploadContext();
164
+ /** 파일 카드. 카드를 누르면 파일을 교체하고 X로 삭제한다. */
165
+ const FileCard = ({ file, index, isExistUploadedAt, handle, }) => {
166
+ const { disabled, locked, deleteFile } = useFileUploadContext();
150
167
  const classNames = useContext(StyleContext);
151
- return (_jsx("div", { className: cn('flex w-full flex-col gap-sm', className, classNames.cardList), children: linkList.map((link, index) => (_jsxs(InputBase.Root, { block: true, className: linkCardVariants({
152
- disabled: !!disabled,
153
- className: classNames.card,
154
- }), children: [_jsx(RenderIcon, { className: "size-5 shrink-0 text-lb500", children: _jsx(Link2, {}) }), _jsx(InputBase.Field, { type: "url", value: link, placeholder: placeholder, "aria-label": `링크 ${index + 1}`, disabled: disabled, readOnly: readOnly, onChange: (event) => changeLink(index, event.target.value), className: linkFieldVariants({ disabled: !!disabled }) }), _jsx(LDButton, { onClick: () => deleteLink(index), "aria-label": `링크 ${index + 1} 삭제`, disabled: locked, variant: "ghost", leftIcon: _jsx(X, { className: "size-4.5" }), color: "neutral", className: cardDeleteVariants({ locked }) })] }, index))) }));
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, sortable, children, }) => {
205
+ const { locked } = useFileUploadContext();
206
+ const { setNodeRef, setActivatorNodeRef, attributes, listeners, transform, transition, isDragging, isSorting, } = useSortable({ id, disabled: locked || !sortable });
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(sortable && (_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
+ * 파일과 링크가 섞인 첨부 목록입니다. `sortable`을 켜면 손잡이를 끌어 순서를 바꿉니다.
218
+ * Root에 `attachmentList`·`setAttachmentList`를 넘겨야 합니다.
219
+ */
220
+ const AttachmentList = ({ placeholder = '링크를 입력해주세요', labelPlaceholder = '링크 이름', isExistUploadedAt = true, sortable = false, 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, sortable: sortable, 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}`, sortable: sortable, 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.LinkList = LinkList;
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,qBAAsB,SAAQ,IAAI,CACjD,qBAAqB,EACrB,UAAU,GAAG,YAAY,CAC1B;IACC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,mCAAmC;AACnC,QAAA,MAAM,gBAAgB,GAAI,qFAOvB,qBAAqB,4CAcvB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
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,kBAAmB,SAAQ,IAAI,CAC9C,qBAAqB,EACrB,UAAU,GAAG,cAAc,CAC5B;IACC,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
+ {"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,sBAAuB,SAAQ,IAAI,CAClD,qBAAqB,EACrB,UAAU,GAAG,YAAY,CAC1B;IACC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,iCAAiC;AACjC,QAAA,MAAM,iBAAiB,GAAI,wGAQxB,sBAAsB,4CAmBxB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
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 LDFileUploadLinkListProps, type LDFileUploadProps, type LDFileUploadRootProps, } from './components/LDFileUpload/LDFileUpload.js';
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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loword/loword-design-system",
3
- "version": "0.5.9",
3
+ "version": "0.7.0",
4
4
  "description": "로워드 디자인 시스템 컴포넌트 패키지(Tailwind v4)",
5
5
  "keywords": [
6
6
  "react",
@@ -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