@team-monolith/cds 1.84.8 → 1.84.10
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/patterns/LexicalEditor/LexicalCustomConfigContext.d.ts +1 -1
- package/dist/patterns/LexicalEditor/LexicalCustomConfigContext.js +1 -1
- package/dist/patterns/LexicalEditor/LexicalEditor.d.ts +1 -1
- package/dist/patterns/LexicalEditor/LexicalEditor.js +2 -2
- package/dist/patterns/LexicalEditor/Plugins.d.ts +1 -1
- package/dist/patterns/LexicalEditor/Plugins.js +2 -2
- package/dist/patterns/LexicalEditor/components/FileSelectInput.js +4 -4
- package/dist/patterns/LexicalEditor/components/UploadFileDialog/UploadFileDialog.js +0 -1
- package/dist/patterns/LexicalEditor/nodes/FileNode/FileDownloadButton.js +12 -4
- package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/ComponentAdderPlugin.d.ts +1 -1
- package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/ComponentAdderPlugin.js +3 -3
- package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/useContextMenuOptions.d.ts +1 -1
- package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/useContextMenuOptions.js +2 -2
- package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.d.ts +2 -2
- package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js +5 -5
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export type LexicalCustomConfig = {
|
|
3
3
|
freezeProblemNode: boolean;
|
|
4
4
|
showQuizSolution: boolean;
|
|
5
|
-
|
|
5
|
+
showFileUpload: boolean;
|
|
6
6
|
};
|
|
7
7
|
declare const LexicalCustomConfigContext: import("react").Context<LexicalCustomConfig>;
|
|
8
8
|
export { LexicalCustomConfigContext };
|
|
@@ -19,7 +19,7 @@ export interface LexicalEditorProps {
|
|
|
19
19
|
/** 퀴즈 노드가 허용되는지 여부. false가 디폴트이고, 전달하지 않아도 로컬스토리지 devMode로도 노출시킬 수 있습니다. */
|
|
20
20
|
isQuizEnabled?: boolean;
|
|
21
21
|
/** 렉시컬 플러그인의 파일 블록 노출의 유무, false가 디폴트이고, 전달하지 않아도 로컬스토리지 devMode로도 노출시킬 수 있습니다. */
|
|
22
|
-
|
|
22
|
+
showFileUpload?: boolean;
|
|
23
23
|
/** 외부에서 플러그인을 주입하는 경우 활용함 */
|
|
24
24
|
children?: JSX.Element | string | (JSX.Element | string)[];
|
|
25
25
|
}
|
|
@@ -39,7 +39,7 @@ function getCleanObject(obj) {
|
|
|
39
39
|
return newObj;
|
|
40
40
|
}
|
|
41
41
|
export function LexicalEditor(props) {
|
|
42
|
-
const { className, contentEditableClassName, value, onChange, editable = true, showQuizSolution = false, freezeProblemNode = false, isSheetEnabled = false, isQuizEnabled = false,
|
|
42
|
+
const { className, contentEditableClassName, value, onChange, editable = true, showQuizSolution = false, freezeProblemNode = false, isSheetEnabled = false, isQuizEnabled = false, showFileUpload = false, children, } = props;
|
|
43
43
|
const theme = useTheme();
|
|
44
44
|
const initialConfig = {
|
|
45
45
|
namespace: "CustomLexicalEditor",
|
|
@@ -62,5 +62,5 @@ export function LexicalEditor(props) {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
: undefined;
|
|
65
|
-
return (_jsx(LexicalCustomConfigContext.Provider, Object.assign({ value: { freezeProblemNode, showQuizSolution,
|
|
65
|
+
return (_jsx(LexicalCustomConfigContext.Provider, Object.assign({ value: { freezeProblemNode, showQuizSolution, showFileUpload } }, { children: _jsxs(LexicalComposer, Object.assign({ initialConfig: initialConfig }, { children: [_jsx(Plugins, { className: className, contentEditableClassName: contentEditableClassName, onChange: onChangeHandler, isSheetEnabled: isSheetEnabled, isQuizEnabled: isQuizEnabled, showFileUpload: showFileUpload }), _jsx(_Fragment, { children: children })] })) })));
|
|
66
66
|
}
|
|
@@ -10,6 +10,6 @@ export interface PluginsProps {
|
|
|
10
10
|
onChange?: (blocks: SerializedEditorState<SerializedLexicalNode>) => void;
|
|
11
11
|
isSheetEnabled: boolean;
|
|
12
12
|
isQuizEnabled: boolean;
|
|
13
|
-
|
|
13
|
+
showFileUpload: boolean;
|
|
14
14
|
}
|
|
15
15
|
export declare function Plugins(props: PluginsProps): ReactElement;
|
|
@@ -35,7 +35,7 @@ import { SheetInputPlugin } from "./plugins/SheetInputPlugin";
|
|
|
35
35
|
import { SelfEvaluationPlugin } from "./plugins/SelfEvaluationPlugin";
|
|
36
36
|
import { FilePlugin } from "./plugins/FilePlugin";
|
|
37
37
|
export function Plugins(props) {
|
|
38
|
-
const { className, contentEditableClassName, onChange, isSheetEnabled, isQuizEnabled,
|
|
38
|
+
const { className, contentEditableClassName, onChange, isSheetEnabled, isQuizEnabled, showFileUpload, } = props;
|
|
39
39
|
const isEditable = useLexicalEditable();
|
|
40
40
|
const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);
|
|
41
41
|
const [isLinkEditMode, setIsLinkEditMode] = useState(false);
|
|
@@ -48,7 +48,7 @@ export function Plugins(props) {
|
|
|
48
48
|
onChange === null || onChange === void 0 ? void 0 : onChange(editorState.toJSON());
|
|
49
49
|
},
|
|
50
50
|
// ignore 하지 않으면 Form에서 수정하지 않았는데 Dirty로 처리됨.
|
|
51
|
-
ignoreSelectionChange: true }), _jsx(AutoFocusPlugin, {}), isEditable && (_jsxs(_Fragment, { children: [_jsx(TabIndentationPlugin, {}), _jsx(ComponentPickerMenuPlugin, { isSheetEnabled: isSheetEnabled, isQuizEnabled: isQuizEnabled,
|
|
51
|
+
ignoreSelectionChange: true }), _jsx(AutoFocusPlugin, {}), isEditable && (_jsxs(_Fragment, { children: [_jsx(TabIndentationPlugin, {}), _jsx(ComponentPickerMenuPlugin, { isSheetEnabled: isSheetEnabled, isQuizEnabled: isQuizEnabled, showFileUpload: showFileUpload }), _jsx(MarkdownShortcutPlugin, { transformers: CUSTOM_TRANSFORMERS }), _jsx(HistoryPlugin, {})] })), floatingAnchorElem && isEditable && (_jsxs(_Fragment, { children: [_jsx(ComponentAdderPlugin, { anchorElem: floatingAnchorElem, isSheetEnabled: isSheetEnabled, isQuizEnabled: isQuizEnabled, showFileUpload: showFileUpload }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingLinkEditorPlugin, { anchorElem: floatingAnchorElem, isLinkEditMode: isLinkEditMode, setIsLinkEditMode: setIsLinkEditMode })] })), !isEditable && _jsx(ClickableLinkPlugin, {}), _jsx(ListPlugin, {}), _jsx(HorizontalRulePlugin, {}), _jsx(ImagesPlugin, {}), _jsx(FilePlugin, {}), _jsx(TablePlugin, {}), _jsx(LinkPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 5 }), _jsx(ProblemInputPlugin, {}), _jsx(ProblemSelectPlugin, {}), _jsx(LayoutPlugin, {}), _jsx(SheetSelectPlugin, {}), _jsx(SheetInputPlugin, {}), _jsx(SelfEvaluationPlugin, {})] }));
|
|
52
52
|
}
|
|
53
53
|
const ScrollArea = styled.div `
|
|
54
54
|
min-height: 150px;
|
|
@@ -44,10 +44,10 @@ export function FileSelectInput(props) {
|
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
if (accept) {
|
|
47
|
-
const isTypeValid = accept === "*" ||
|
|
48
|
-
|
|
49
|
-
accept.slice(1) === ((_b = file.name.split(".").pop()) === null || _b === void 0 ? void 0 : _b.toLowerCase())
|
|
50
|
-
|
|
47
|
+
const isTypeValid = accept === "*" ||
|
|
48
|
+
(accept.startsWith(".")
|
|
49
|
+
? accept.slice(1) === ((_b = file.name.split(".").pop()) === null || _b === void 0 ? void 0 : _b.toLowerCase())
|
|
50
|
+
: new RegExp(accept.replace("*", ".*")).test(file.type));
|
|
51
51
|
if (!isTypeValid) {
|
|
52
52
|
setErrorMessage(`업로드할 수 없는 파일입니다. ${typeStr}을 업로드해주세요.`);
|
|
53
53
|
event.target.value = "";
|
|
@@ -14,6 +14,7 @@ import { FileSize, getFileIcon, IconContainer } from "./FileComponent";
|
|
|
14
14
|
import { OverflowTooltip } from "../../../../components/OverflowTooltip";
|
|
15
15
|
import { useContext } from "react";
|
|
16
16
|
import { CdsContext } from "../../../../CdsProvider";
|
|
17
|
+
import { HOVER } from "../../../../utils/hover";
|
|
17
18
|
/**
|
|
18
19
|
* 파일 업로드 블록 내에서 삽입하기를 통해 렉시컬에 삽입된 파일블록을 표시하는 컴포넌트입니다. (ReadOnly)
|
|
19
20
|
* images/2025-02-05-10-53-19.png
|
|
@@ -29,23 +30,29 @@ export function FileDownloadButton({ fileName, fileSize, fileUrl, }) {
|
|
|
29
30
|
showFileError === null || showFileError === void 0 ? void 0 : showFileError("download", "다운로드 중 오류가 발생했어요");
|
|
30
31
|
return;
|
|
31
32
|
}
|
|
33
|
+
// fileUrl에 대해 GET 요청을 보냅니다.
|
|
32
34
|
const response = yield fetch(fileUrl, { method: "GET" });
|
|
33
35
|
if (!response.ok) {
|
|
34
36
|
showFileError === null || showFileError === void 0 ? void 0 : showFileError("download", "파일이 삭제되어 다운로드할 수 없어요.");
|
|
35
37
|
return;
|
|
36
38
|
}
|
|
39
|
+
// 요청이 성공하면 응답 데이터를 Blob(파일 데이터)로 변환
|
|
37
40
|
const blob = yield response.blob();
|
|
41
|
+
// Blob으로부터 임시 URL을 생성
|
|
38
42
|
const blobUrl = URL.createObjectURL(blob);
|
|
43
|
+
// 다운로드를 위해 anchor 요소를 생성
|
|
39
44
|
const link = document.createElement("a");
|
|
40
45
|
link.href = blobUrl;
|
|
46
|
+
// 다운로드할 때 사용할 파일명을 지정
|
|
41
47
|
link.download = fileName;
|
|
42
48
|
document.body.appendChild(link);
|
|
43
49
|
link.click();
|
|
44
50
|
document.body.removeChild(link);
|
|
51
|
+
// 생성된 Blob URL을 해제
|
|
45
52
|
URL.revokeObjectURL(blobUrl);
|
|
46
53
|
}
|
|
47
54
|
catch (_b) {
|
|
48
|
-
showFileError === null || showFileError === void 0 ? void 0 : showFileError("download", "
|
|
55
|
+
showFileError === null || showFileError === void 0 ? void 0 : showFileError("download", "다운로드 중 오류가 발생했어요");
|
|
49
56
|
}
|
|
50
57
|
});
|
|
51
58
|
return (_jsxs(ButtonContainer, Object.assign({ onClick: handleDownload, theme: theme }, { children: [_jsx(IconContainer, { children: getFileIcon(fileName) }), _jsx(FileNameLabel, { children: _jsx(OverflowTooltip, { text: fileName }) }), _jsxs(FileSize, { children: [(fileSize / (1024 * 1024)).toFixed(1), " MB"] })] })));
|
|
@@ -69,9 +76,10 @@ const ButtonContainer = styled.button(({ theme }) => css `
|
|
|
69
76
|
text-align: left;
|
|
70
77
|
overflow: hidden;
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
background
|
|
74
|
-
|
|
79
|
+
${HOVER(css `
|
|
80
|
+
background: ${theme.color.background.neutralAltActive};
|
|
81
|
+
color: ${theme.color.foreground.neutralBaseActive};
|
|
82
|
+
`)}
|
|
75
83
|
`);
|
|
76
84
|
const FileNameLabel = styled.div `
|
|
77
85
|
max-width: 152px;
|
|
@@ -8,7 +8,7 @@ export interface ComponentAdderPluginProps {
|
|
|
8
8
|
anchorElem: HTMLElement;
|
|
9
9
|
isSheetEnabled: boolean;
|
|
10
10
|
isQuizEnabled: boolean;
|
|
11
|
-
|
|
11
|
+
showFileUpload: boolean;
|
|
12
12
|
}
|
|
13
13
|
export declare const COMPONENT_ADDER_MENU_CLASSNAME = "component-adder-menu";
|
|
14
14
|
export declare function ComponentAdderPlugin(props: ComponentAdderPluginProps): JSX.Element | null;
|
|
@@ -57,7 +57,7 @@ function getTextUpToAnchor(selection) {
|
|
|
57
57
|
return anchorNode.getTextContent().slice(0, anchorOffset);
|
|
58
58
|
}
|
|
59
59
|
export function ComponentAdderPlugin(props) {
|
|
60
|
-
const { anchorElem, isSheetEnabled, isQuizEnabled,
|
|
60
|
+
const { anchorElem, isSheetEnabled, isQuizEnabled, showFileUpload } = props;
|
|
61
61
|
const theme = useTheme();
|
|
62
62
|
const [editor] = useLexicalComposerContext();
|
|
63
63
|
const [nodeKey, setNodeKey] = useState(null);
|
|
@@ -142,7 +142,7 @@ export function ComponentAdderPlugin(props) {
|
|
|
142
142
|
const getContextMenuOptions = useContextMenuOptions({
|
|
143
143
|
isSheetEnabled,
|
|
144
144
|
isQuizEnabled,
|
|
145
|
-
|
|
145
|
+
showFileUpload,
|
|
146
146
|
});
|
|
147
147
|
const filteredOptions = options.filter((option) => {
|
|
148
148
|
if (!query) {
|
|
@@ -210,7 +210,7 @@ export function ComponentAdderPlugin(props) {
|
|
|
210
210
|
isSheetEnabled,
|
|
211
211
|
isQuizEnabled,
|
|
212
212
|
setFileOpen,
|
|
213
|
-
|
|
213
|
+
showFileUpload,
|
|
214
214
|
});
|
|
215
215
|
setOptions(baseOptions);
|
|
216
216
|
setPlusOrMenu("plus");
|
|
@@ -6,5 +6,5 @@ import { ComponentDrawerOption, ComponentPickerOption } from "../ComponentPicker
|
|
|
6
6
|
export declare function useContextMenuOptions(props: {
|
|
7
7
|
isSheetEnabled: boolean;
|
|
8
8
|
isQuizEnabled: boolean;
|
|
9
|
-
|
|
9
|
+
showFileUpload: boolean;
|
|
10
10
|
}): (editor: LexicalEditor, node: LexicalNode, setImageOpen: (open: boolean) => void, setFileOpen: (open: boolean) => void) => (ComponentPickerOption | ComponentDrawerOption)[];
|
|
@@ -303,7 +303,7 @@ function getUploadFileContextMenuOptions(editor, node) {
|
|
|
303
303
|
];
|
|
304
304
|
}
|
|
305
305
|
export function useContextMenuOptions(props) {
|
|
306
|
-
const { isSheetEnabled, isQuizEnabled,
|
|
306
|
+
const { isSheetEnabled, isQuizEnabled, showFileUpload } = props;
|
|
307
307
|
const theme = useTheme();
|
|
308
308
|
return (editor, node, setImageOpen, setFileOpen) => {
|
|
309
309
|
if ($isProblemInputNode(node)) {
|
|
@@ -345,7 +345,7 @@ export function useContextMenuOptions(props) {
|
|
|
345
345
|
isSheetEnabled,
|
|
346
346
|
isQuizEnabled,
|
|
347
347
|
setFileOpen,
|
|
348
|
-
|
|
348
|
+
showFileUpload,
|
|
349
349
|
}),
|
|
350
350
|
new ComponentPickerOption("블록 삭제", {
|
|
351
351
|
icon: _jsx(CloseFillIcon, {}),
|
package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.d.ts
CHANGED
|
@@ -37,10 +37,10 @@ export declare function getBaseOptions(props: {
|
|
|
37
37
|
setFileOpen: (open: boolean) => void;
|
|
38
38
|
isSheetEnabled: boolean;
|
|
39
39
|
isQuizEnabled: boolean;
|
|
40
|
-
|
|
40
|
+
showFileUpload: boolean;
|
|
41
41
|
}): (ComponentPickerOption | ComponentDrawerOption)[];
|
|
42
42
|
export declare function ComponentPickerMenuPlugin(props: {
|
|
43
43
|
isSheetEnabled: boolean;
|
|
44
44
|
isQuizEnabled: boolean;
|
|
45
|
-
|
|
45
|
+
showFileUpload: boolean;
|
|
46
46
|
}): JSX.Element;
|
package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js
CHANGED
|
@@ -183,7 +183,7 @@ function getQuizContextOptions(editor, theme) {
|
|
|
183
183
|
];
|
|
184
184
|
}
|
|
185
185
|
export function getBaseOptions(props) {
|
|
186
|
-
const { editor, theme, setImageOpen, setFileOpen, isSheetEnabled, isQuizEnabled,
|
|
186
|
+
const { editor, theme, setImageOpen, setFileOpen, isSheetEnabled, isQuizEnabled, showFileUpload, } = props;
|
|
187
187
|
const baseOptions = [
|
|
188
188
|
new ComponentPickerOption("본문", {
|
|
189
189
|
icon: _jsx(TextIcon, {}),
|
|
@@ -285,8 +285,8 @@ export function getBaseOptions(props) {
|
|
|
285
285
|
onSelect: () => editor.dispatchCommand(INSERT_LAYOUT_COMMAND, "1fr 1fr"),
|
|
286
286
|
}));
|
|
287
287
|
}
|
|
288
|
-
//
|
|
289
|
-
if (
|
|
288
|
+
// showFileUpload 이면 파일블록을 추가합니다.
|
|
289
|
+
if (showFileUpload || isDevMode) {
|
|
290
290
|
baseOptions.push(new ComponentPickerOption("파일 게시", {
|
|
291
291
|
icon: _jsx(File3LineIcon, {}),
|
|
292
292
|
keywords: ["file", "upload"],
|
|
@@ -296,7 +296,7 @@ export function getBaseOptions(props) {
|
|
|
296
296
|
return baseOptions;
|
|
297
297
|
}
|
|
298
298
|
export function ComponentPickerMenuPlugin(props) {
|
|
299
|
-
const { isSheetEnabled, isQuizEnabled,
|
|
299
|
+
const { isSheetEnabled, isQuizEnabled, showFileUpload } = props;
|
|
300
300
|
const [editor] = useLexicalComposerContext();
|
|
301
301
|
const theme = useTheme();
|
|
302
302
|
const [queryString, setQueryString] = useState(null);
|
|
@@ -313,7 +313,7 @@ export function ComponentPickerMenuPlugin(props) {
|
|
|
313
313
|
isSheetEnabled,
|
|
314
314
|
isQuizEnabled,
|
|
315
315
|
setFileOpen,
|
|
316
|
-
|
|
316
|
+
showFileUpload,
|
|
317
317
|
});
|
|
318
318
|
if (!queryString) {
|
|
319
319
|
return baseOptions;
|