@team-monolith/cds 1.9.3 → 1.9.4
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 +6 -0
- package/dist/patterns/LexicalEditor/LexicalCustomConfigContext.js +5 -0
- package/dist/patterns/LexicalEditor/LexicalEditor.d.ts +3 -0
- package/dist/patterns/LexicalEditor/LexicalEditor.js +3 -2
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/InputComponent.js +22 -15
- package/dist/patterns/LexicalEditor/plugins/ActionsPlugin/index.d.ts +9 -0
- package/dist/patterns/LexicalEditor/plugins/ActionsPlugin/index.js +24 -0
- package/package.json +1 -1
|
@@ -8,6 +8,9 @@ export interface LexicalEditorProps {
|
|
|
8
8
|
* initialConfig에 전달되므로 마운트 된 이후 수정해도 반영되지 않음
|
|
9
9
|
*/
|
|
10
10
|
editable?: boolean;
|
|
11
|
+
/** freeze. 문제 블록을 수정하지 못하도록 함
|
|
12
|
+
*/
|
|
13
|
+
freezeProblemNode?: boolean;
|
|
11
14
|
/** 외부에서 플러그인을 주입하는 경우 활용함 */
|
|
12
15
|
children?: JSX.Element | string | (JSX.Element | string)[];
|
|
13
16
|
}
|
|
@@ -11,6 +11,7 @@ import { getTheme } from "./theme";
|
|
|
11
11
|
import { useTheme } from "@emotion/react";
|
|
12
12
|
import Plugins from "./Plugins";
|
|
13
13
|
import { ColoredQuoteNode, ProblemInputNode } from "./nodes";
|
|
14
|
+
import { LexicalCustomConfigContext } from "./LexicalCustomConfigContext";
|
|
14
15
|
import { ProblemSelectNode } from "./nodes/ProblemSelectNode";
|
|
15
16
|
function validateValue(value) {
|
|
16
17
|
var _a, _b;
|
|
@@ -29,7 +30,7 @@ function validateValue(value) {
|
|
|
29
30
|
return true;
|
|
30
31
|
}
|
|
31
32
|
export function LexicalEditor(props) {
|
|
32
|
-
const { className, value, onChange, editable = true, children } = props;
|
|
33
|
+
const { className, value, onChange, editable = true, freezeProblemNode, children, } = props;
|
|
33
34
|
const theme = useTheme();
|
|
34
35
|
const initialConfig = {
|
|
35
36
|
namespace: "CodleLexicalEditor",
|
|
@@ -62,5 +63,5 @@ export function LexicalEditor(props) {
|
|
|
62
63
|
editorState: validateValue(value) ? JSON.stringify(value) : undefined,
|
|
63
64
|
editable: editable,
|
|
64
65
|
};
|
|
65
|
-
return (_jsxs(LexicalComposer, Object.assign({ initialConfig: initialConfig }, { children: [_jsx(Plugins, { className: className, onChange: onChange }), _jsx(_Fragment, { children: children })] })));
|
|
66
|
+
return (_jsx(LexicalCustomConfigContext.Provider, Object.assign({ value: { freezeProblemNode: freezeProblemNode !== null && freezeProblemNode !== void 0 ? freezeProblemNode : false } }, { children: _jsxs(LexicalComposer, Object.assign({ initialConfig: initialConfig }, { children: [_jsx(Plugins, { className: className, onChange: onChange }), _jsx(_Fragment, { children: children })] })) })));
|
|
66
67
|
}
|
|
@@ -12,7 +12,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
|
|
13
13
|
/** @jsxImportSource @emotion/react */
|
|
14
14
|
import { css } from "@emotion/react";
|
|
15
|
-
import { useState } from "react";
|
|
15
|
+
import { useContext, useState } from "react";
|
|
16
16
|
import Input from "../../../../components/Input";
|
|
17
17
|
import SquareButton from "../../../../components/SquareButton";
|
|
18
18
|
import { Settings3FillIcon } from "../../../../icons";
|
|
@@ -22,6 +22,7 @@ import useLexicalEditable from "@lexical/react/useLexicalEditable";
|
|
|
22
22
|
import { $isProblemInputNode } from "./ProblemInputNode";
|
|
23
23
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
24
24
|
import { $getNodeByKey } from "lexical";
|
|
25
|
+
import { LexicalCustomConfigContext, } from "../../LexicalCustomConfigContext";
|
|
25
26
|
export function InputComponent(props) {
|
|
26
27
|
const { answer } = props, settingFormProps = __rest(props, ["answer"]);
|
|
27
28
|
const { placeholder, nodeKey } = settingFormProps;
|
|
@@ -29,23 +30,29 @@ export function InputComponent(props) {
|
|
|
29
30
|
const [settingOpen, setSettingOpen] = useState(false);
|
|
30
31
|
const isEditable = useLexicalEditable();
|
|
31
32
|
const [answerInput, setAnswerInput] = useState(answer);
|
|
33
|
+
const lexicalCustomConfig = useContext(LexicalCustomConfigContext);
|
|
32
34
|
// 학생 view
|
|
33
35
|
// TODO: "글자 수대로" 옵션시에 글자 수대로 입력칸을 표시해야 합니다.
|
|
34
36
|
if (!isEditable) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
if (lexicalCustomConfig.freezeProblemNode) {
|
|
38
|
+
return (_jsx(Input, { size: "small", placeholder: placeholder || "여기에 입력하세요.", value: answerInput, color: "default", fullWidth: true, inputProps: { readOnly: true } }));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return (_jsx(Input, { size: "small", placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: (e) => setAnswerInput(e.target.value),
|
|
42
|
+
// 한글 입력시에 onChange마다 update가 일어나는 것을 방지하기 위해 입력 완료후 onBlur시에 update하는 전략을 사용합니다.
|
|
43
|
+
// 이를 위해 answerInput을 state로 관리합니다.
|
|
44
|
+
inputProps: {
|
|
45
|
+
onBlur: (_e) => {
|
|
46
|
+
editor.update(() => {
|
|
47
|
+
const node = $getNodeByKey(nodeKey);
|
|
48
|
+
if (!$isProblemInputNode(node)) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
node.setAnswer(answerInput);
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
}, color: "default", fullWidth: true }));
|
|
55
|
+
}
|
|
49
56
|
}
|
|
50
57
|
// 교사 edit view
|
|
51
58
|
return (_jsxs(_Fragment, { children: [_jsxs("div", Object.assign({ css: css `
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { ReactElement } from "react";
|
|
9
|
+
export default function ActionsPlugin(): ReactElement;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
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 { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
10
|
+
import { mergeRegister } from "@lexical/utils";
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
|
+
import { Button, LockFillIcon, LockUnlockFillIcon } from "../../../..";
|
|
13
|
+
export default function ActionsPlugin() {
|
|
14
|
+
const [editor] = useLexicalComposerContext();
|
|
15
|
+
const [isEditable, setIsEditable] = useState(() => editor.isEditable());
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
return mergeRegister(editor.registerEditableListener((editable) => {
|
|
18
|
+
setIsEditable(editable);
|
|
19
|
+
}));
|
|
20
|
+
}, [editor]);
|
|
21
|
+
return (_jsx(Button, { color: "primary", size: "small", startIcon: isEditable ? _jsx(LockFillIcon, {}) : _jsx(LockUnlockFillIcon, {}), onClick: () => {
|
|
22
|
+
editor.setEditable(!editor.isEditable());
|
|
23
|
+
}, title: "Read-Only Mode", label: `${!isEditable ? "수정 모드" : "읽기 모드"}로 변경`, "aria-label": `${!isEditable ? "Unlock" : "Lock"} read-only mode` }));
|
|
24
|
+
}
|