@team-monolith/cds 1.9.6 → 1.9.7
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/nodes/ProblemInputNode/InputComponent.js +11 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/FormSelection.js +6 -2
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageDialog.d.ts +4 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageDialog.js +30 -20
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/SettingForm.js +5 -1
- package/package.json +1 -1
|
@@ -51,6 +51,17 @@ export function InputComponent(props) {
|
|
|
51
51
|
node.setAnswer(answerInput);
|
|
52
52
|
});
|
|
53
53
|
},
|
|
54
|
+
onKeyPress: (e) => {
|
|
55
|
+
if (e.key === "Enter") {
|
|
56
|
+
editor.update(() => {
|
|
57
|
+
const node = $getNodeByKey(nodeKey);
|
|
58
|
+
if (!$isProblemInputNode(node)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
node.setAnswer(answerInput);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
},
|
|
54
65
|
}, color: "default", fullWidth: true }));
|
|
55
66
|
}
|
|
56
67
|
}
|
|
@@ -13,9 +13,13 @@ export function FormSelection(props) {
|
|
|
13
13
|
const { index, control, field, update, rules, onDelete } = props;
|
|
14
14
|
const [imageOpen, setImageOpen] = useState(false);
|
|
15
15
|
const [inputFocused, setInputFocused] = useState(false);
|
|
16
|
-
return (_jsxs(_Fragment, { children: [_jsx(InsertImageDialog, { open: imageOpen, onClose: () => setImageOpen(false), updateImg: (props) => {
|
|
16
|
+
return (_jsxs(_Fragment, { children: [_jsx(InsertImageDialog, { title: field.show.image ? "이미지 바꾸기" : "이미지 삽입하기", open: imageOpen, onClose: () => setImageOpen(false), updateImg: (props) => {
|
|
17
17
|
update(index, Object.assign(Object.assign({}, field), { show: Object.assign(Object.assign({}, field.show), { image: props }) }));
|
|
18
|
-
}
|
|
18
|
+
}, deleteImg: field.show.image
|
|
19
|
+
? () => {
|
|
20
|
+
update(index, Object.assign(Object.assign({}, field), { show: Object.assign(Object.assign({}, field.show), { image: undefined }) }));
|
|
21
|
+
}
|
|
22
|
+
: undefined }), _jsxs(Container, { children: [_jsx(Index, { children: index + 1 }), _jsxs("div", Object.assign({ css: css `
|
|
19
23
|
display: flex;
|
|
20
24
|
flex: 1;
|
|
21
25
|
flex-direction: column;
|
package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageDialog.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { ImageProps } from "../ProblemSelectNode";
|
|
2
2
|
export interface InsertImageDialogProps {
|
|
3
|
+
title: string;
|
|
3
4
|
open: boolean;
|
|
4
5
|
onClose: () => void;
|
|
5
6
|
updateImg: (props: ImageProps) => void;
|
|
7
|
+
/** 전달하면 "이미지 삭제하기" 버튼이 생깁니다. */
|
|
8
|
+
deleteImg?: () => void;
|
|
6
9
|
}
|
|
7
|
-
export declare function InsertImageDialog(props: InsertImageDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function InsertImageDialog(props: InsertImageDialogProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageDialog.js
CHANGED
|
@@ -7,10 +7,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
|
|
11
|
+
/** @jsxImportSource @emotion/react */
|
|
11
12
|
import { useContext, useRef, useState } from "react";
|
|
12
13
|
import styled from "@emotion/styled";
|
|
13
|
-
import { useTheme } from "@emotion/react";
|
|
14
|
+
import { css, useTheme } from "@emotion/react";
|
|
14
15
|
import { ImageFillIcon, LinkIcon, UploadLineIcon } from "../../../../../icons";
|
|
15
16
|
import { AlertDialog, AlertDialogContent, AlertDialogTitle, } from "../../../../../components/AlertDialog";
|
|
16
17
|
import Button from "../../../../../components/Button";
|
|
@@ -18,7 +19,7 @@ import { CodleDesignSystemContext } from "../../../../../CodleDesignSystemProvid
|
|
|
18
19
|
import { InsertImageUriDialogBody } from "./InsertImageUriDialogBody";
|
|
19
20
|
import { InsertImageUploadedDialogBody } from "./InsertImageUploadedDialogBody";
|
|
20
21
|
export function InsertImageDialog(props) {
|
|
21
|
-
const { open, onClose, updateImg } = props;
|
|
22
|
+
const { title, open, onClose, updateImg, deleteImg } = props;
|
|
22
23
|
const theme = useTheme();
|
|
23
24
|
const [mode, setMode] = useState(null);
|
|
24
25
|
const inputRef = useRef(null);
|
|
@@ -35,20 +36,26 @@ export function InsertImageDialog(props) {
|
|
|
35
36
|
setAltText("");
|
|
36
37
|
onClose();
|
|
37
38
|
};
|
|
38
|
-
return (_jsxs(StyledAlertDialog, Object.assign({ icon: _jsx(ImageFillIcon, { color: theme.color.background.primary }), open: open, onClose: handleOnClose, disableIconPadding: true }, { children: [_jsx(StyledAlertDialogTitle, Object.assign({ onClose: handleOnClose }, { children:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
return (_jsxs(StyledAlertDialog, Object.assign({ icon: _jsx(ImageFillIcon, { color: theme.color.background.primary }), open: open, onClose: handleOnClose, disableIconPadding: true }, { children: [_jsx(StyledAlertDialogTitle, Object.assign({ onClose: handleOnClose }, { children: title })), !mode && (_jsx(AlertDialogContent, { children: _jsxs("div", Object.assign({ css: css `
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
gap: 16px;
|
|
43
|
+
// Actions가 없는 경우 하단이 디자인과 맞지 않는다
|
|
44
|
+
margin-bottom: -16px;
|
|
45
|
+
` }, { children: [_jsxs(Buttons, { children: [_jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uC774\uBBF8\uC9C0 URL\uC744 \uC54C\uACE0 \uC788\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "URL\uB85C \uC0BD\uC785\uD558\uAE30", startIcon: _jsx(LinkIcon, {}), onClick: () => setMode("url") })] }), _jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uAC16\uACE0 \uC788\uB294 \uC774\uBBF8\uC9C0\uB97C \uC0BD\uC785\uD558\uACE0 \uC2F6\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "\uD30C\uC77C \uC120\uD0DD\uD558\uAE30", startIcon: _jsx(UploadLineIcon, {}), onClick: () => {
|
|
46
|
+
var _a;
|
|
47
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
48
|
+
} }), _jsx(HiddenInput, { ref: inputRef, type: "file", accept: "image/*", onChange: (event) => __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
51
|
+
if (!file)
|
|
52
|
+
return;
|
|
53
|
+
const uploadByFile = (_b = cdsContext.lexical) === null || _b === void 0 ? void 0 : _b.uploadByFile;
|
|
54
|
+
if (uploadByFile) {
|
|
55
|
+
setSrc(yield uploadByFile(file));
|
|
56
|
+
setMode("file");
|
|
57
|
+
}
|
|
58
|
+
}) })] })] }), deleteImg && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(Button, { color: "textDanger", size: "medium", fullWidth: true, label: "\uC774\uBBF8\uC9C0 \uC0AD\uC81C\uD558\uAE30", onClick: deleteImg })] }))] })) })), mode === "url" && (_jsx(InsertImageUriDialogBody, { src: src, setSrc: setSrc, altText: altText, setAltText: setAltText, onClick: onClick })), mode === "file" && (_jsx(InsertImageUploadedDialogBody, { src: src, setSrc: setSrc, altText: altText, setAltText: setAltText, onClick: onClick }))] })));
|
|
52
59
|
}
|
|
53
60
|
const StyledAlertDialog = styled(AlertDialog) `
|
|
54
61
|
gap: 16px;
|
|
@@ -67,12 +74,15 @@ const StyledAlertDialogTitle = styled(AlertDialogTitle) `
|
|
|
67
74
|
`;
|
|
68
75
|
const Buttons = styled.div `
|
|
69
76
|
display: flex;
|
|
77
|
+
flex: 1;
|
|
70
78
|
align-items: flex-start;
|
|
71
79
|
gap: 8px;
|
|
72
|
-
|
|
73
|
-
// Actions가 없는 경우 하단이 디자인과 맞지 않는다
|
|
74
|
-
margin-bottom: -16px;
|
|
75
80
|
`;
|
|
81
|
+
const Divider = styled.div(({ theme }) => css `
|
|
82
|
+
width: 100%;
|
|
83
|
+
height: 1px;
|
|
84
|
+
background: ${theme.color.background.neutralAltActive};
|
|
85
|
+
`);
|
|
76
86
|
const ButtonAndDescription = styled.div `
|
|
77
87
|
display: flex;
|
|
78
88
|
flex-direction: column;
|
|
@@ -8,9 +8,12 @@ import shadows from "../../../../../foundation/shadows";
|
|
|
8
8
|
import { AddFillIcon, AlarmWarningFillIcon, ListRadioIcon, } from "../../../../../icons";
|
|
9
9
|
import Button from "../../../../../components/Button";
|
|
10
10
|
import { FormSelection } from "./FormSelection";
|
|
11
|
+
import Tooltip from "../../../../../components/Tooltip";
|
|
12
|
+
import { useState } from "react";
|
|
11
13
|
export default function SettingForm(props) {
|
|
12
14
|
const { control, handleSubmit, fields, append, remove, update, nodeKey, onClose, } = props;
|
|
13
15
|
const [editor] = useLexicalComposerContext();
|
|
16
|
+
const [tooltipOpen, setTooltipOpen] = useState(false);
|
|
14
17
|
const onSettingSubmit = (data) => {
|
|
15
18
|
editor.update(() => {
|
|
16
19
|
const node = $getNodeByKey(nodeKey);
|
|
@@ -32,6 +35,7 @@ export default function SettingForm(props) {
|
|
|
32
35
|
return `${duplicatedIndex + 1}번 선택지와 같은 내용입니다.`;
|
|
33
36
|
}
|
|
34
37
|
const hasMultipleAnswers = fields.filter((field) => field.isAnswer).length > 1;
|
|
38
|
+
const hasAnswer = fields.some((field) => field.isAnswer);
|
|
35
39
|
return (_jsxs(Form, Object.assign({ onSubmit: handleSubmit(onSettingSubmit) }, { children: [_jsxs(Title, { children: [_jsx(ListRadioIcon, { css: css `
|
|
36
40
|
width: 12px;
|
|
37
41
|
height: 12px;
|
|
@@ -53,7 +57,7 @@ export default function SettingForm(props) {
|
|
|
53
57
|
} }), hasMultipleAnswers && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
|
|
54
58
|
width: 14px;
|
|
55
59
|
height: 14px;
|
|
56
|
-
` }), "\uC815\uB2F5\uC774 \uC5EC\uB7EC \uAC1C\uC778 \uBB38\uC81C\uC5D0\uB294 \uC815\uB2F5\uC744 \uBAA8\uB450 \uC120\uD0DD\uD574\uC57C \uD55C\uB2E4\uB294 \uC548\uB0B4\uAC00 \uC81C\uACF5\uB429\uB2C8\uB2E4."] }))] }), _jsxs(Buttons, { children: [_jsx(Button, { color: "grey", size: "xsmall", label: "\uB2EB\uAE30", onClick: onClose }), _jsx(Button, { color: "primary", size: "xsmall", label: "\uC774\uB300\uB85C \uB123\uAE30", type: "submit" })] })] })));
|
|
60
|
+
` }), "\uC815\uB2F5\uC774 \uC5EC\uB7EC \uAC1C\uC778 \uBB38\uC81C\uC5D0\uB294 \uC815\uB2F5\uC744 \uBAA8\uB450 \uC120\uD0DD\uD574\uC57C \uD55C\uB2E4\uB294 \uC548\uB0B4\uAC00 \uC81C\uACF5\uB429\uB2C8\uB2E4."] }))] }), _jsxs(Buttons, { children: [_jsx(Button, { color: "grey", size: "xsmall", label: "\uB2EB\uAE30", onClick: onClose }), _jsx(Tooltip, Object.assign({ open: !hasAnswer && tooltipOpen, text: "\uC120\uD0DD\uC9C0 \uC911 \uC815\uB2F5\uC744 \uD45C\uC2DC\uD574\uC8FC\uC138\uC694.", onOpen: () => setTooltipOpen(true), onClose: () => setTooltipOpen(false), placement: "top-end" }, { children: _jsx("span", { children: _jsx(Button, { color: "primary", size: "xsmall", label: "\uC774\uB300\uB85C \uB123\uAE30", type: "submit", disabled: !hasAnswer }) }) }))] })] })));
|
|
57
61
|
}
|
|
58
62
|
const Form = styled.form(({ theme }) => css `
|
|
59
63
|
display: flex;
|