@team-monolith/cds 1.11.1 → 1.11.3

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.
@@ -2,7 +2,7 @@ import { Solution } from "./ProblemInputNode";
2
2
  import { NodeKey } from "lexical";
3
3
  export declare function InputComponent(props: {
4
4
  solutions: Solution[];
5
- showCharacterCount: boolean;
5
+ showCharacterNumber: boolean;
6
6
  placeholder: string;
7
7
  answer: string;
8
8
  nodeKey: NodeKey;
@@ -26,7 +26,7 @@ import TextInput from "./TextInput";
26
26
  import SegmentedInput from "./SegmentedInput";
27
27
  export function InputComponent(props) {
28
28
  const { answer } = props, settingFormProps = __rest(props, ["answer"]);
29
- const { solutions, showCharacterCount, placeholder, nodeKey } = settingFormProps;
29
+ const { solutions, showCharacterNumber, placeholder, nodeKey } = settingFormProps;
30
30
  const [editor] = useLexicalComposerContext();
31
31
  const [settingOpen, setSettingOpen] = useState(false);
32
32
  const isEditable = useLexicalEditable();
@@ -38,29 +38,23 @@ export function InputComponent(props) {
38
38
  const lexicalCustomConfig = useContext(LexicalCustomConfigContext);
39
39
  // "** ***" 같은 형태입니다.
40
40
  const answerFormat = solutions[0].value;
41
+ const handleChange = (value) => {
42
+ setAnswerInput(value);
43
+ editor.update(() => {
44
+ const node = $getNodeByKey(nodeKey);
45
+ if (!$isProblemInputNode(node)) {
46
+ return;
47
+ }
48
+ node.setAnswer(value);
49
+ });
50
+ };
41
51
  // 학생 view
42
52
  if (!isEditable) {
43
- if (showCharacterCount) {
44
- return (_jsx(SegmentedInput, { readOnly: lexicalCustomConfig.freezeProblemNode, answerFormat: answerFormat, placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: (value) => {
45
- setAnswerInput(value);
46
- editor.update(() => {
47
- const node = $getNodeByKey(nodeKey);
48
- if (!$isProblemInputNode(node)) {
49
- return;
50
- }
51
- node.setAnswer(value);
52
- });
53
- } }));
53
+ if (showCharacterNumber) {
54
+ return (_jsx(SegmentedInput, { readOnly: lexicalCustomConfig.freezeProblemNode, answerFormat: answerFormat, placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: handleChange }));
54
55
  }
55
56
  return (_jsx(TextInput, { readOnly: lexicalCustomConfig.freezeProblemNode, size: "small", color: "default", placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: (e) => {
56
- setAnswerInput(e.target.value);
57
- editor.update(() => {
58
- const node = $getNodeByKey(nodeKey);
59
- if (!$isProblemInputNode(node)) {
60
- return;
61
- }
62
- node.setAnswer(e.target.value);
63
- });
57
+ handleChange(e.target.value);
64
58
  }, fullWidth: true }));
65
59
  }
66
60
  // 교사 edit view
@@ -5,7 +5,7 @@ export interface Solution {
5
5
  value: string;
6
6
  }
7
7
  export interface ProblemInputPayload {
8
- showCharacterCount: boolean;
8
+ showCharacterNumber: boolean;
9
9
  placeholder: string;
10
10
  solutions: Solution[];
11
11
  answer: string;
@@ -18,26 +18,26 @@ export type SerializedProblemInputNode = Spread<ProblemInputPayload, SerializedL
18
18
  */
19
19
  export declare class ProblemInputNode extends DecoratorNode<ReactNode> {
20
20
  __solutions: Solution[];
21
- __showCharacterCount: boolean;
21
+ __showCharacterNumber: boolean;
22
22
  __placeholder: string;
23
23
  __answer: string;
24
24
  isInline(): boolean;
25
25
  static getType(): string;
26
26
  getSolutions(): Solution[];
27
- getShowCharacterCount(): boolean;
27
+ getShowCharacterNumber(): boolean;
28
28
  getPlaceholder(): string;
29
29
  getAnswer(): string;
30
30
  setSolutions(solutions: Solution[]): void;
31
- setShowCharacterCount(showCharacterCount: boolean): void;
31
+ setShowCharacterNumber(showCharacterNumber: boolean): void;
32
32
  setPlaceholder(placeholder: string): void;
33
33
  setAnswer(answer: string): void;
34
34
  static clone(node: ProblemInputNode): ProblemInputNode;
35
- constructor(showCharacterCount: boolean, placeholder: string, solutions: Solution[], answer: string, key?: NodeKey);
35
+ constructor(showCharacterNumber: boolean, placeholder: string, solutions: Solution[], answer: string, key?: NodeKey);
36
36
  createDOM(config: EditorConfig): HTMLElement;
37
37
  updateDOM(): boolean;
38
38
  static importJSON(serializedNode: SerializedProblemInputNode): ProblemInputNode;
39
39
  exportJSON(): SerializedProblemInputNode;
40
40
  decorate(): ReactNode;
41
41
  }
42
- export declare function $createProblemInputNode({ showCharacterCount, placeholder, solutions, answer, key, }: ProblemInputPayload): ProblemInputNode;
42
+ export declare function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer, key, }: ProblemInputPayload): ProblemInputNode;
43
43
  export declare function $isProblemInputNode(node: LexicalNode | null | undefined): node is ProblemInputNode;
@@ -16,8 +16,8 @@ export class ProblemInputNode extends DecoratorNode {
16
16
  getSolutions() {
17
17
  return this.__solutions;
18
18
  }
19
- getShowCharacterCount() {
20
- return this.__showCharacterCount;
19
+ getShowCharacterNumber() {
20
+ return this.__showCharacterNumber;
21
21
  }
22
22
  getPlaceholder() {
23
23
  return this.__placeholder;
@@ -29,9 +29,9 @@ export class ProblemInputNode extends DecoratorNode {
29
29
  const self = this.getWritable();
30
30
  self.__solutions = solutions;
31
31
  }
32
- setShowCharacterCount(showCharacterCount) {
32
+ setShowCharacterNumber(showCharacterNumber) {
33
33
  const self = this.getWritable();
34
- self.__showCharacterCount = showCharacterCount;
34
+ self.__showCharacterNumber = showCharacterNumber;
35
35
  }
36
36
  setPlaceholder(placeholder) {
37
37
  const self = this.getWritable();
@@ -42,11 +42,11 @@ export class ProblemInputNode extends DecoratorNode {
42
42
  self.__answer = answer;
43
43
  }
44
44
  static clone(node) {
45
- return new ProblemInputNode(node.__showCharacterCount, node.__placeholder, node.__solutions, node.__answer, node.__key);
45
+ return new ProblemInputNode(node.__showCharacterNumber, node.__placeholder, node.__solutions, node.__answer, node.__key);
46
46
  }
47
- constructor(showCharacterCount, placeholder, solutions, answer, key) {
47
+ constructor(showCharacterNumber, placeholder, solutions, answer, key) {
48
48
  super(key);
49
- this.__showCharacterCount = showCharacterCount;
49
+ this.__showCharacterNumber = showCharacterNumber;
50
50
  this.__placeholder = placeholder;
51
51
  this.__solutions = solutions;
52
52
  this.__answer = answer;
@@ -64,7 +64,7 @@ export class ProblemInputNode extends DecoratorNode {
64
64
  const node = $createProblemInputNode({
65
65
  key: serializedNode.key,
66
66
  solutions: serializedNode.solutions,
67
- showCharacterCount: serializedNode.showCharacterCount,
67
+ showCharacterNumber: serializedNode.showCharacterNumber,
68
68
  placeholder: serializedNode.placeholder,
69
69
  answer: serializedNode.answer,
70
70
  });
@@ -74,18 +74,18 @@ export class ProblemInputNode extends DecoratorNode {
74
74
  return {
75
75
  version: 1,
76
76
  type: "problem-input",
77
- showCharacterCount: this.__showCharacterCount,
77
+ showCharacterNumber: this.__showCharacterNumber,
78
78
  placeholder: this.__placeholder,
79
79
  solutions: this.__solutions,
80
80
  answer: this.__answer,
81
81
  };
82
82
  }
83
83
  decorate() {
84
- return (_jsx(InputComponent, { solutions: this.__solutions, showCharacterCount: this.__showCharacterCount, placeholder: this.__placeholder, answer: this.__answer, nodeKey: this.getKey() }));
84
+ return (_jsx(InputComponent, { solutions: this.__solutions, showCharacterNumber: this.__showCharacterNumber, placeholder: this.__placeholder, answer: this.__answer, nodeKey: this.getKey() }));
85
85
  }
86
86
  }
87
- export function $createProblemInputNode({ showCharacterCount, placeholder, solutions, answer, key, }) {
88
- return $applyNodeReplacement(new ProblemInputNode(showCharacterCount, placeholder, solutions, answer, key));
87
+ export function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer, key, }) {
88
+ return $applyNodeReplacement(new ProblemInputNode(showCharacterNumber, placeholder, solutions, answer, key));
89
89
  }
90
90
  export function $isProblemInputNode(node) {
91
91
  return node instanceof ProblemInputNode;
@@ -4,14 +4,6 @@ import { css } from "@emotion/react";
4
4
  import styled from "@emotion/styled";
5
5
  import { InputBase } from "../../../../components/InputBase";
6
6
  import { useRef, useState } from "react";
7
- function getDiffIndex(short, long) {
8
- for (let i = 0; i < short.length; i++) {
9
- if (short[i] !== long[i]) {
10
- return i;
11
- }
12
- }
13
- return short.length;
14
- }
15
7
  /**
16
8
  * SOT는 value이고, 그 value는 숨겨진 input에 작성됩니다.
17
9
  * 그리고 그 value는 split되어 segmented input에 표시됩니다.
@@ -29,28 +21,21 @@ export default function SegmentedInput(props) {
29
21
  const hiddenRef = useRef(null);
30
22
  return (_jsxs(Container, { children: [_jsx("input", { type: "input", ref: hiddenRef, value: splitedValues.join(""), readOnly: readOnly, onKeyDown: (e) => {
31
23
  if (e.key === "ArrowLeft") {
32
- if (focusedIndex === null || focusedIndex <= 0) {
33
- return;
34
- }
35
- else {
24
+ if (focusedIndex !== null && focusedIndex > 0) {
36
25
  setFocusedIndex(focusedIndex - 1);
37
26
  }
38
27
  }
39
28
  else if (e.key === "ArrowRight") {
40
- if (focusedIndex === null ||
41
- focusedIndex >= despacedFormat.length - 1) {
42
- return;
43
- }
44
- else {
29
+ if (focusedIndex !== null &&
30
+ focusedIndex < despacedFormat.length - 1) {
45
31
  setFocusedIndex(focusedIndex + 1);
46
32
  }
47
33
  }
48
34
  }, onChange: (event) => {
49
- const latestValue = splitedValues.join("");
50
- const eventValue = event.target.value;
51
- const diffIndex = getDiffIndex(latestValue, eventValue);
52
- onChange(eventValue);
53
- setFocusedIndex(diffIndex);
35
+ var _a;
36
+ onChange(event.target.value);
37
+ const selectionStart = (_a = hiddenRef.current) === null || _a === void 0 ? void 0 : _a.selectionStart;
38
+ setFocusedIndex(selectionStart ? selectionStart - 1 : null);
54
39
  }, onBlur: (e) => {
55
40
  setFocusedIndex(null);
56
41
  const eventValue = e.target.value;
@@ -68,6 +53,8 @@ export default function SegmentedInput(props) {
68
53
  readOnly,
69
54
  onFocus: () => {
70
55
  var _a, _b;
56
+ if (readOnly)
57
+ return;
71
58
  setFocusedIndex(i);
72
59
  (_a = hiddenRef.current) === null || _a === void 0 ? void 0 : _a.focus();
73
60
  (_b = hiddenRef.current) === null || _b === void 0 ? void 0 : _b.setSelectionRange(i, i);
@@ -1,7 +1,7 @@
1
1
  import { Control, UseFormTrigger } from "react-hook-form";
2
2
  import { ProblemInputPayload } from "../ProblemInputNode";
3
- export interface FormCharacterCountProps {
3
+ export interface FormCharacterNumberProps {
4
4
  control: Control<ProblemInputPayload, any>;
5
5
  trigger: UseFormTrigger<ProblemInputPayload>;
6
6
  }
7
- export declare function FormCharacterCount(props: FormCharacterCountProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function FormCharacterNumber(props: FormCharacterNumberProps): import("react/jsx-runtime").JSX.Element;
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Controller } from "react-hook-form";
3
3
  import { SegmentedControlButton, SegmentedControlGroup, } from "../../../../SegmentedControl";
4
- export function FormCharacterCount(props) {
4
+ export function FormCharacterNumber(props) {
5
5
  const { control, trigger } = props;
6
- return (_jsx(Controller, { name: "showCharacterCount", control: control, render: ({ field: { value, onChange } }) => {
6
+ return (_jsx(Controller, { name: "showCharacterNumber", control: control, render: ({ field: { value, onChange } }) => {
7
7
  return (_jsxs(SegmentedControlGroup, Object.assign({ size: "xsmall", value: value.toString(), onChange: (value) => {
8
8
  onChange(value === "true");
9
9
  trigger("solutions");
@@ -2,7 +2,7 @@ import { Solution } from "../ProblemInputNode";
2
2
  import { NodeKey } from "lexical";
3
3
  export interface SettingFormProps {
4
4
  solutions: Solution[];
5
- showCharacterCount: boolean;
5
+ showCharacterNumber: boolean;
6
6
  placeholder: string;
7
7
  nodeKey: NodeKey;
8
8
  onClose: () => void;
@@ -9,18 +9,18 @@ import { $isProblemInputNode, } from "../ProblemInputNode";
9
9
  import { FormSolution } from "./FormSolution";
10
10
  import Button from "../../../../../components/Button";
11
11
  import Tooltip from "../../../../../components/Tooltip";
12
- import { FormCharacterCount } from "./FormCharacterCount";
12
+ import { FormCharacterNumber } from "./FormCharacterNumber";
13
13
  import { FormPlaceholder } from "./FormPlaceholder";
14
14
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
15
15
  import { $getNodeByKey } from "lexical";
16
16
  export default function SettingForm(props) {
17
- const { solutions, showCharacterCount, placeholder, nodeKey, onClose } = props;
17
+ const { solutions, showCharacterNumber, placeholder, nodeKey, onClose } = props;
18
18
  const [editor] = useLexicalComposerContext();
19
19
  const { control, handleSubmit, watch, trigger } = useForm({
20
20
  mode: "all",
21
21
  defaultValues: {
22
22
  solutions,
23
- showCharacterCount,
23
+ showCharacterNumber,
24
24
  placeholder,
25
25
  },
26
26
  });
@@ -37,12 +37,12 @@ export default function SettingForm(props) {
37
37
  return;
38
38
  }
39
39
  node.setSolutions(data.solutions);
40
- node.setShowCharacterCount(data.showCharacterCount);
40
+ node.setShowCharacterNumber(data.showCharacterNumber);
41
41
  node.setPlaceholder(data.placeholder);
42
42
  });
43
43
  onClose();
44
44
  };
45
- const multipleSolutionsDisabled = watch("showCharacterCount");
45
+ const multipleSolutionsDisabled = watch("showCharacterNumber");
46
46
  return (_jsxs(Form, Object.assign({ onSubmit: handleSubmit(onSettingSubmit) }, { children: [_jsxs(Title, { children: [_jsx(InputMethodLineIcon, { css: css `
47
47
  width: 12px;
48
48
  height: 12px;
@@ -72,7 +72,7 @@ export default function SettingForm(props) {
72
72
  ` }), _jsxs(Label, { children: ["\uB744\uC5B4\uC4F0\uAE30, \uC54C\uD30C\uBCB3\uC758 \uB300\uC18C\uBB38\uC790 \uAD6C\uBD84\uAE4C\uC9C0 \uC77C\uCE58\uD574\uC57C \uC815\uB2F5\uC73C\uB85C \uCC98\uB9AC\uB429\uB2C8\uB2E4.", _jsx("br", {}), "\uAC00\uB2A5\uD55C \uC815\uB2F5\uC744 \uBAA8\uB450 \uCD94\uAC00\uD574\uC57C \uC6D0\uD65C\uD558\uAC8C \uC790\uB3D9 \uCC44\uC810\uD560 \uC218 \uC788\uC5B4\uC694."] })] }))] }), _jsxs(Right, { children: [_jsxs(FormArea, { children: [_jsxs(Label, { children: ["\uC785\uB825 \uCE78", _jsx(Tooltip, Object.assign({ text: _jsxs("span", { children: ["\uC608\uB97C \uB4E4\uC5B4 \uC815\uB2F5\uC774 '\uAE00\uC790 \uC218'\uC774\uACE0", _jsx("br", {}), _jsx("b", { children: "\uAE00\uC790 \uC218\uB300\uB85C" }), " \uC635\uC158\uC744 \uC120\uD0DD\uD588\uB2E4\uBA74", _jsx("br", {}), "\uC785\uB825 \uCE78\uC774 '\u2610\u2610 \u2610' \uCC98\uB7FC \uD45C\uC2DC\uB429\uB2C8\uB2E4."] }), placement: "top" }, { children: _jsx(QuestionFillIcon, { css: css `
73
73
  width: 12px;
74
74
  height: 12px;
75
- ` }) }))] }), _jsx(FormCharacterCount, { control: control, trigger: trigger })] }), _jsxs(FormArea, { children: [_jsxs(Label, { children: ["\uC790\uB9AC \uD45C\uC2DC\uC790", _jsx(Tooltip, Object.assign({ text: _jsx("span", { children: "\uC785\uB825 \uCE78\uC5D0 \uAE30\uBCF8\uC73C\uB85C \uB178\uCD9C\uB418\uB294 \uD14D\uC2A4\uD2B8\uC785\uB2C8\uB2E4." }), placement: "top" }, { children: _jsx(QuestionFillIcon, { css: css `
75
+ ` }) }))] }), _jsx(FormCharacterNumber, { control: control, trigger: trigger })] }), _jsxs(FormArea, { children: [_jsxs(Label, { children: ["\uC790\uB9AC \uD45C\uC2DC\uC790", _jsx(Tooltip, Object.assign({ text: _jsx("span", { children: "\uC785\uB825 \uCE78\uC5D0 \uAE30\uBCF8\uC73C\uB85C \uB178\uCD9C\uB418\uB294 \uD14D\uC2A4\uD2B8\uC785\uB2C8\uB2E4." }), placement: "top" }, { children: _jsx(QuestionFillIcon, { css: css `
76
76
  width: 12px;
77
77
  height: 12px;
78
78
  ` }) }))] }), _jsx(FormPlaceholder, { control: control })] })] })] }), _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" })] })] })));
@@ -1,4 +1,4 @@
1
1
  export * from "./FormSolution";
2
- export * from "./FormCharacterCount";
2
+ export * from "./FormCharacterNumber";
3
3
  export * from "./FormPlaceholder";
4
4
  export { default } from "./SettingForm";
@@ -1,4 +1,4 @@
1
1
  export * from "./FormSolution";
2
- export * from "./FormCharacterCount";
2
+ export * from "./FormCharacterNumber";
3
3
  export * from "./FormPlaceholder";
4
4
  export { default } from "./SettingForm";
@@ -44,9 +44,7 @@ const Index = styled.div(({ theme, isSelected }) => css `
44
44
  width: 20px;
45
45
  height: 20px;
46
46
  padding: 4px;
47
- // https://www.w3schools.com/howto/howto_css_disable_text_selection.asp
48
- -webkit-user-select: none; /* Safari */
49
- -ms-user-select: none; /* IE 10 and IE 11 */
47
+
50
48
  user-select: none; /* Standard syntax */
51
49
 
52
50
  justify-content: center;
@@ -78,7 +78,7 @@ function getQuizContextOptions(editor, theme) {
78
78
  value: "",
79
79
  },
80
80
  ],
81
- showCharacterCount: false,
81
+ showCharacterNumber: false,
82
82
  placeholder: "",
83
83
  answer: "",
84
84
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-monolith/cds",
3
- "version": "1.11.1",
3
+ "version": "1.11.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "sideEffects": false,
@@ -12,7 +12,7 @@
12
12
  "@mui/material": "^5.13.6",
13
13
  "@types/node": "^16.11.26",
14
14
  "@types/react": "^18.2.28",
15
- "@types/react-dom": "^18.2.13",
15
+ "@types/react-dom": "^18.2.13",
16
16
  "hex-to-css-filter": "^5.4.0",
17
17
  "lexical": "^0.12.4",
18
18
  "react": "^18.2.0",