@team-monolith/cds 1.47.0 → 1.47.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/patterns/LexicalEditor/LexicalCustomConfigContext.d.ts +1 -0
- package/dist/patterns/LexicalEditor/LexicalCustomConfigContext.js +1 -0
- package/dist/patterns/LexicalEditor/LexicalEditor.d.ts +2 -0
- package/dist/patterns/LexicalEditor/LexicalEditor.js +2 -2
- package/dist/patterns/LexicalEditor/Plugins.js +1 -1
- package/dist/patterns/LexicalEditor/nodes/LayoutContainerNode.js +1 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/InputComponent.js +3 -3
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView.js +1 -3
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectComponent.js +30 -30
- package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js +5 -5
- package/package.json +1 -1
- package/dist/patterns/LexicalEditor/plugins/LayoutPlugin/InsertLayoutDialog.d.ts +0 -17
- package/dist/patterns/LexicalEditor/plugins/LayoutPlugin/InsertLayoutDialog.js +0 -21
- /package/dist/patterns/LexicalEditor/plugins/LayoutPlugin/{LayoutPlugin.d.ts → index.d.ts} +0 -0
- /package/dist/patterns/LexicalEditor/plugins/LayoutPlugin/{LayoutPlugin.js → index.js} +0 -0
|
@@ -12,6 +12,8 @@ export interface LexicalEditorProps {
|
|
|
12
12
|
/** freeze. 문제 블록을 수정하지 못하도록 함
|
|
13
13
|
*/
|
|
14
14
|
freezeProblemNode?: boolean;
|
|
15
|
+
/** 퀴즈 정답이 공개되는지 여부. false가 default입니다. 공개하고자 하는곳에서 true로 설정해야 합니다. */
|
|
16
|
+
showQuizSolution?: boolean;
|
|
15
17
|
/** 퀴즈 노드가 허용되는지 여부. false가 디폴트이고, 전달하지 않아도 로컬스토리지 devMode로도 노출시킬 수 있습니다. */
|
|
16
18
|
isQuizEnabled?: boolean;
|
|
17
19
|
/** 외부에서 플러그인을 주입하는 경우 활용함 */
|
|
@@ -32,7 +32,7 @@ function validateValue(value) {
|
|
|
32
32
|
return true;
|
|
33
33
|
}
|
|
34
34
|
export function LexicalEditor(props) {
|
|
35
|
-
const { className, contentEditableClassName, value, onChange, editable = true, freezeProblemNode, isQuizEnabled = false, children, } = props;
|
|
35
|
+
const { className, contentEditableClassName, value, onChange, editable = true, showQuizSolution = false, freezeProblemNode = false, isQuizEnabled = false, children, } = props;
|
|
36
36
|
const theme = useTheme();
|
|
37
37
|
const initialConfig = {
|
|
38
38
|
namespace: "CodleLexicalEditor",
|
|
@@ -67,5 +67,5 @@ export function LexicalEditor(props) {
|
|
|
67
67
|
editorState: validateValue(value) ? JSON.stringify(value) : undefined,
|
|
68
68
|
editable: editable,
|
|
69
69
|
};
|
|
70
|
-
return (_jsx(LexicalCustomConfigContext.Provider, Object.assign({ value: { freezeProblemNode
|
|
70
|
+
return (_jsx(LexicalCustomConfigContext.Provider, Object.assign({ value: { freezeProblemNode, showQuizSolution } }, { children: _jsxs(LexicalComposer, Object.assign({ initialConfig: initialConfig }, { children: [_jsx(Plugins, { className: className, contentEditableClassName: contentEditableClassName, onChange: onChange, isQuizEnabled: isQuizEnabled }), _jsx(_Fragment, { children: children })] })) })));
|
|
71
71
|
}
|
|
@@ -29,7 +29,7 @@ import ListMaxIndentLevelPlugin from "./plugins/ListMaxIndentLevelPlugin";
|
|
|
29
29
|
import styled from "@emotion/styled";
|
|
30
30
|
import ProblemInputPlugin from "./plugins/ProblemInputPlugin";
|
|
31
31
|
import ProblemSelectPlugin from "./plugins/ProblemSelectPlugin";
|
|
32
|
-
import { LayoutPlugin } from "./plugins/LayoutPlugin
|
|
32
|
+
import { LayoutPlugin } from "./plugins/LayoutPlugin";
|
|
33
33
|
export default function Plugins(props) {
|
|
34
34
|
const { className, contentEditableClassName, onChange, isQuizEnabled } = props;
|
|
35
35
|
const isEditable = useLexicalEditable();
|
|
@@ -30,6 +30,7 @@ export class LayoutContainerNode extends ElementNode {
|
|
|
30
30
|
createDOM(config) {
|
|
31
31
|
const dom = document.createElement("div");
|
|
32
32
|
dom.style.display = "grid";
|
|
33
|
+
dom.style.gap = "24px";
|
|
33
34
|
dom.style.gridTemplateColumns = this.__templateColumns;
|
|
34
35
|
if (typeof config.theme.layoutContainer === "string") {
|
|
35
36
|
addClassNamesToElement(dom, config.theme.layoutContainer);
|
|
@@ -35,7 +35,7 @@ export function InputComponent(props) {
|
|
|
35
35
|
// SoT를 내부 State로 관리하고 EditorState를 따로 설정.
|
|
36
36
|
// 문제를 더 파악하고 추후 개선 필요.
|
|
37
37
|
const [answerInput, setAnswerInput] = useState(answer);
|
|
38
|
-
const
|
|
38
|
+
const { freezeProblemNode } = useContext(LexicalCustomConfigContext);
|
|
39
39
|
// "** ***" 같은 형태입니다.
|
|
40
40
|
const answerFormat = solutions[0].value;
|
|
41
41
|
const handleChange = (value) => {
|
|
@@ -51,9 +51,9 @@ export function InputComponent(props) {
|
|
|
51
51
|
// 학생 view
|
|
52
52
|
if (!isEditable) {
|
|
53
53
|
if (showCharacterNumber) {
|
|
54
|
-
return (_jsx(SegmentedInput, { readOnly:
|
|
54
|
+
return (_jsx(SegmentedInput, { readOnly: freezeProblemNode, isCorrect: isCorrect, answerFormat: answerFormat, placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: handleChange }));
|
|
55
55
|
}
|
|
56
|
-
return (_jsx(TextInput, { readOnly:
|
|
56
|
+
return (_jsx(TextInput, { readOnly: freezeProblemNode, isCorrect: isCorrect, size: "small", color: "default", placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: (e) => {
|
|
57
57
|
handleChange(e.target.value);
|
|
58
58
|
}, fullWidth: true }));
|
|
59
59
|
}
|
|
@@ -29,9 +29,7 @@ export function SelectBoxView(props) {
|
|
|
29
29
|
: undefined;
|
|
30
30
|
return (_jsx(SelectBoxComponent, { css: css `
|
|
31
31
|
width: 100%;
|
|
32
|
-
`, type: selectBoxType, index: selectBoxType ? TYPE_TO_INDEX_ICON(selectBoxType) : index, image: image, text: text,
|
|
33
|
-
// isAnswer가 존재하면 채점 후의 상태이므로 unclickable을 위해 onClick을 전달하지 않음
|
|
34
|
-
onClick: isAnswer === undefined ? onClick : undefined,
|
|
32
|
+
`, type: selectBoxType, index: selectBoxType ? TYPE_TO_INDEX_ICON(selectBoxType) : index, image: image, text: text, onClick: onClick,
|
|
35
33
|
// 선택되지 않았으나 정답일 때 정답 태그를 표시
|
|
36
34
|
endIcon: isAnswer &&
|
|
37
35
|
!isSelected && (_jsx(Tag, { label: "\uC815\uB2F5", icon: _jsx(CheckboxCircleFillIcon, {}), color: "green", css: css `
|
|
@@ -29,40 +29,40 @@ export function SelectComponent(props) {
|
|
|
29
29
|
const [editor] = useLexicalComposerContext();
|
|
30
30
|
const [settingOpen, setSettingOpen] = useState(false);
|
|
31
31
|
const isEditable = useLexicalEditable();
|
|
32
|
-
const
|
|
33
|
-
//
|
|
32
|
+
const { freezeProblemNode, showQuizSolution } = useContext(LexicalCustomConfigContext);
|
|
33
|
+
// view
|
|
34
34
|
if (!isEditable) {
|
|
35
35
|
return (_jsxs(_Fragment, { children: [hasMultipleAnswers && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
|
|
36
36
|
width: 14px;
|
|
37
37
|
height: 14px;
|
|
38
|
-
` }), "\uC9C8\uBB38\uC5D0 \uD574\uB2F9\uD558\uB294 \uB2F5\uC744 \uBAA8\uB450 \uACE0\uB974\uB294 \uBB38\uC81C\uC785\uB2C8\uB2E4."] })), selections.map((selection, index) => (_jsx(SelectBoxView, { index: index + 1, isAnswer: selection.isAnswer, isSelected: selected.includes(selection.value), image: selection.show.image, text: selection.show.text, onClick:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
38
|
+
` }), "\uC9C8\uBB38\uC5D0 \uD574\uB2F9\uD558\uB294 \uB2F5\uC744 \uBAA8\uB450 \uACE0\uB974\uB294 \uBB38\uC81C\uC785\uB2C8\uB2E4."] })), selections.map((selection, index) => (_jsx(SelectBoxView, { index: index + 1, isAnswer: showQuizSolution ? selection.isAnswer : undefined, isSelected: selected.includes(selection.value), image: selection.show.image, text: selection.show.text, onClick: freezeProblemNode
|
|
39
|
+
? undefined
|
|
40
|
+
: () => {
|
|
41
|
+
const isSelected = selected.includes(selection.value);
|
|
42
|
+
if (isSelected) {
|
|
43
|
+
editor.update(() => {
|
|
44
|
+
const node = $getNodeByKey(nodeKey);
|
|
45
|
+
if (!$isProblemSelectNode(node)) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
node.setSelected(selected.filter((v) => v !== selection.value));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
editor.update(() => {
|
|
53
|
+
const node = $getNodeByKey(nodeKey);
|
|
54
|
+
if (!$isProblemSelectNode(node)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (hasMultipleAnswers) {
|
|
58
|
+
node.setSelected([...selected, selection.value]);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
node.setSelected([selection.value]);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
} }, index)))] }));
|
|
66
66
|
}
|
|
67
67
|
// 교사 edit view
|
|
68
68
|
return (_jsxs(_Fragment, { children: [_jsxs("div", Object.assign({ css: css `
|
package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js
CHANGED
|
@@ -21,12 +21,12 @@ import * as ReactDOM from "react-dom";
|
|
|
21
21
|
import { css as cssToClassName } from "@emotion/css";
|
|
22
22
|
import { ComponentPickerMenuList } from "./ComponentPickerMenuList";
|
|
23
23
|
import { InsertImageDialog } from "../ImagesPlugin/InsertImageDialog";
|
|
24
|
-
import { TextIcon, H1Icon, H2Icon, H3Icon, ListUnorderedIcon, ListOrderedIcon, DoubleQuotesLIcon, CodeViewIcon, SeparatorIcon, ImageLineIcon, InputMethodLineIcon, ListRadioIcon, } from "../../../../icons";
|
|
24
|
+
import { TextIcon, H1Icon, H2Icon, H3Icon, ListUnorderedIcon, ListOrderedIcon, DoubleQuotesLIcon, CodeViewIcon, SeparatorIcon, ImageLineIcon, InputMethodLineIcon, ListRadioIcon, LayoutColumnLineIcon, } from "../../../../icons";
|
|
25
25
|
import { ZINDEX } from "../../../../utils/zIndex";
|
|
26
26
|
import { css, useTheme } from "@emotion/react";
|
|
27
27
|
import { INSERT_PROBLEM_INPUT_COMMAND } from "../ProblemInputPlugin";
|
|
28
28
|
import { INSERT_PROBLEM_SELECT_COMMAND } from "../ProblemSelectPlugin";
|
|
29
|
-
import { INSERT_LAYOUT_COMMAND } from "../LayoutPlugin
|
|
29
|
+
import { INSERT_LAYOUT_COMMAND } from "../LayoutPlugin";
|
|
30
30
|
// import useModal from "../../hooks/useModal";
|
|
31
31
|
// import catTypingGif from "../../images/cat-typing.gif";
|
|
32
32
|
// import { INSERT_IMAGE_COMMAND, InsertImageDialog } from "../ImagesPlugin";
|
|
@@ -197,11 +197,11 @@ export function getBaseOptions(props) {
|
|
|
197
197
|
onSelect: () => setImageOpen(true),
|
|
198
198
|
}),
|
|
199
199
|
];
|
|
200
|
-
// 로컬스토리지 devMode가 true이면 칼럼
|
|
200
|
+
// 로컬스토리지 devMode가 true이면 칼럼 컨텍스트 메뉴를 추가합니다.
|
|
201
201
|
const isDevMode = localStorage.getItem("devMode") === "true";
|
|
202
202
|
if (isDevMode) {
|
|
203
|
-
baseOptions.push(new ComponentPickerOption("칼럼
|
|
204
|
-
icon: _jsx(
|
|
203
|
+
baseOptions.push(new ComponentPickerOption("칼럼", {
|
|
204
|
+
icon: _jsx(LayoutColumnLineIcon, {}),
|
|
205
205
|
keywords: ["columns", "layout", "grid"],
|
|
206
206
|
onSelect: () => editor.dispatchCommand(INSERT_LAYOUT_COMMAND, "1fr 1fr"),
|
|
207
207
|
}));
|
package/package.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the MIT license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*
|
|
8
|
-
*/
|
|
9
|
-
import { LexicalEditor } from "lexical";
|
|
10
|
-
export declare const LAYOUTS: {
|
|
11
|
-
label: string;
|
|
12
|
-
value: string;
|
|
13
|
-
}[];
|
|
14
|
-
export default function InsertLayoutDialog({ activeEditor, onClose, }: {
|
|
15
|
-
activeEditor: LexicalEditor;
|
|
16
|
-
onClose: () => void;
|
|
17
|
-
}): JSX.Element;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
import { INSERT_LAYOUT_COMMAND } from "./LayoutPlugin";
|
|
4
|
-
import Button from "../../../../components/Button";
|
|
5
|
-
export const LAYOUTS = [
|
|
6
|
-
{ label: "2 columns (equal width)", value: "1fr 1fr" },
|
|
7
|
-
{ label: "2 columns (25% - 75%)", value: "1fr 3fr" },
|
|
8
|
-
{ label: "3 columns (equal width)", value: "1fr 1fr 1fr" },
|
|
9
|
-
{ label: "3 columns (25% - 50% - 25%)", value: "1fr 2fr 1fr" },
|
|
10
|
-
{ label: "4 columns (equal width)", value: "1fr 1fr 1fr 1fr" },
|
|
11
|
-
];
|
|
12
|
-
export default function InsertLayoutDialog({ activeEditor, onClose, }) {
|
|
13
|
-
var _a;
|
|
14
|
-
const [layout, setLayout] = useState(LAYOUTS[0].value);
|
|
15
|
-
const buttonLabel = (_a = LAYOUTS.find((item) => item.value === layout)) === null || _a === void 0 ? void 0 : _a.label;
|
|
16
|
-
const onClick = () => {
|
|
17
|
-
activeEditor.dispatchCommand(INSERT_LAYOUT_COMMAND, LAYOUTS[0].value);
|
|
18
|
-
onClose();
|
|
19
|
-
};
|
|
20
|
-
return (_jsx(_Fragment, { children: _jsx(Button, Object.assign({ onClick: onClick, color: "grey", size: "small", label: undefined }, { children: "Insert" })) }));
|
|
21
|
-
}
|
|
File without changes
|
|
File without changes
|