@team-monolith/cds 1.38.3 → 1.38.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.
@@ -5,5 +5,6 @@ export declare function InputComponent(props: {
5
5
  showCharacterNumber: boolean;
6
6
  placeholder: string;
7
7
  answer: string;
8
+ isCorrect?: boolean;
8
9
  nodeKey: NodeKey;
9
10
  }): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -25,7 +25,7 @@ import { LexicalCustomConfigContext } from "../../LexicalCustomConfigContext";
25
25
  import TextInput from "./TextInput";
26
26
  import SegmentedInput from "./SegmentedInput";
27
27
  export function InputComponent(props) {
28
- const { answer } = props, settingFormProps = __rest(props, ["answer"]);
28
+ const { answer, isCorrect } = props, settingFormProps = __rest(props, ["answer", "isCorrect"]);
29
29
  const { solutions, showCharacterNumber, placeholder, nodeKey } = settingFormProps;
30
30
  const [editor] = useLexicalComposerContext();
31
31
  const [settingOpen, setSettingOpen] = useState(false);
@@ -51,9 +51,9 @@ export function InputComponent(props) {
51
51
  // 학생 view
52
52
  if (!isEditable) {
53
53
  if (showCharacterNumber) {
54
- return (_jsx(SegmentedInput, { readOnly: lexicalCustomConfig.freezeProblemNode, answerFormat: answerFormat, placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: handleChange }));
54
+ return (_jsx(SegmentedInput, { readOnly: lexicalCustomConfig.freezeProblemNode, isCorrect: isCorrect, answerFormat: answerFormat, placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: handleChange }));
55
55
  }
56
- return (_jsx(TextInput, { readOnly: lexicalCustomConfig.freezeProblemNode, size: "small", color: "default", placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: (e) => {
56
+ return (_jsx(TextInput, { readOnly: lexicalCustomConfig.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
  }
@@ -11,6 +11,8 @@ export interface ProblemInputPayload {
11
11
  * (ex: "코들 입니다" => "** ***") */
12
12
  solutions: Solution[];
13
13
  answer: string;
14
+ /** FE에서만 사용하는 값. 문제의 정오답 여부를 주입하여 스타일을 변경합니다. */
15
+ isCorrect?: boolean;
14
16
  key?: NodeKey;
15
17
  }
16
18
  export type SerializedProblemInputNode = Spread<ProblemInputPayload, SerializedLexicalNode>;
@@ -23,6 +25,7 @@ export declare class ProblemInputNode extends DecoratorNode<ReactNode> {
23
25
  __showCharacterNumber: boolean;
24
26
  __placeholder: string;
25
27
  __answer: string;
28
+ __isCorrect?: boolean;
26
29
  isInline(): boolean;
27
30
  static getType(): string;
28
31
  getSolutions(): Solution[];
@@ -34,12 +37,12 @@ export declare class ProblemInputNode extends DecoratorNode<ReactNode> {
34
37
  setPlaceholder(placeholder: string): void;
35
38
  setAnswer(answer: string): void;
36
39
  static clone(node: ProblemInputNode): ProblemInputNode;
37
- constructor(showCharacterNumber: boolean, placeholder: string, solutions: Solution[], answer: string, key?: NodeKey);
40
+ constructor(showCharacterNumber: boolean, placeholder: string, solutions: Solution[], answer: string, isCorrect?: boolean, key?: NodeKey);
38
41
  createDOM(config: EditorConfig): HTMLElement;
39
42
  updateDOM(): boolean;
40
43
  static importJSON(serializedNode: SerializedProblemInputNode): ProblemInputNode;
41
44
  exportJSON(): SerializedProblemInputNode;
42
45
  decorate(): ReactNode;
43
46
  }
44
- export declare function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer, key, }: ProblemInputPayload): ProblemInputNode;
47
+ export declare function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer, isCorrect, key, }: ProblemInputPayload): ProblemInputNode;
45
48
  export declare function $isProblemInputNode(node: LexicalNode | null | undefined): node is ProblemInputNode;
@@ -42,14 +42,15 @@ export class ProblemInputNode extends DecoratorNode {
42
42
  self.__answer = answer;
43
43
  }
44
44
  static clone(node) {
45
- return new ProblemInputNode(node.__showCharacterNumber, node.__placeholder, node.__solutions, node.__answer, node.__key);
45
+ return new ProblemInputNode(node.__showCharacterNumber, node.__placeholder, node.__solutions, node.__answer, node.__isCorrect, node.__key);
46
46
  }
47
- constructor(showCharacterNumber, placeholder, solutions, answer, key) {
47
+ constructor(showCharacterNumber, placeholder, solutions, answer, isCorrect, key) {
48
48
  super(key);
49
49
  this.__showCharacterNumber = showCharacterNumber;
50
50
  this.__placeholder = placeholder;
51
51
  this.__solutions = solutions;
52
52
  this.__answer = answer;
53
+ this.__isCorrect = isCorrect;
53
54
  }
54
55
  createDOM(config) {
55
56
  // Define the DOM element here
@@ -67,6 +68,7 @@ export class ProblemInputNode extends DecoratorNode {
67
68
  showCharacterNumber: serializedNode.showCharacterNumber,
68
69
  placeholder: serializedNode.placeholder,
69
70
  answer: serializedNode.answer,
71
+ isCorrect: serializedNode.isCorrect,
70
72
  });
71
73
  return node;
72
74
  }
@@ -77,15 +79,16 @@ export class ProblemInputNode extends DecoratorNode {
77
79
  showCharacterNumber: this.__showCharacterNumber,
78
80
  placeholder: this.__placeholder,
79
81
  solutions: this.__solutions,
82
+ isCorrect: this.__isCorrect,
80
83
  answer: this.__answer,
81
84
  };
82
85
  }
83
86
  decorate() {
84
- return (_jsx(InputComponent, { solutions: this.__solutions, showCharacterNumber: this.__showCharacterNumber, placeholder: this.__placeholder, answer: this.__answer, nodeKey: this.getKey() }));
87
+ return (_jsx(InputComponent, { solutions: this.__solutions, showCharacterNumber: this.__showCharacterNumber, placeholder: this.__placeholder, answer: this.__answer, isCorrect: this.__isCorrect, nodeKey: this.getKey() }));
85
88
  }
86
89
  }
87
- export function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer, key, }) {
88
- return $applyNodeReplacement(new ProblemInputNode(showCharacterNumber, placeholder, solutions, answer, key));
90
+ export function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer, isCorrect, key, }) {
91
+ return $applyNodeReplacement(new ProblemInputNode(showCharacterNumber, placeholder, solutions, answer, isCorrect, key));
89
92
  }
90
93
  export function $isProblemInputNode(node) {
91
94
  return node instanceof ProblemInputNode;
@@ -1,5 +1,6 @@
1
1
  export interface SegmentedInputProps {
2
2
  readOnly: boolean;
3
+ isCorrect?: boolean;
3
4
  answerFormat: string;
4
5
  placeholder: string;
5
6
  value: string;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
2
2
  /** @jsxImportSource @emotion/react */
3
- import { css } from "@emotion/react";
3
+ import { css, useTheme } from "@emotion/react";
4
4
  import styled from "@emotion/styled";
5
5
  import { InputBase } from "../../../../components/InputBase";
6
6
  import { useRef, useState } from "react";
@@ -9,7 +9,8 @@ import { useRef, useState } from "react";
9
9
  * 그리고 그 value는 split되어 segmented input에 표시됩니다.
10
10
  */
11
11
  export default function SegmentedInput(props) {
12
- const { readOnly, answerFormat, placeholder, value, onChange } = props;
12
+ const { readOnly, isCorrect, answerFormat, placeholder, value, onChange } = props;
13
+ const theme = useTheme();
13
14
  // "** ***" => ["*", "*", " ", "*", "*", "*"]
14
15
  const splitedFormat = answerFormat.split("");
15
16
  // ["*", "*", " ", "*", "*", "*", " ", "*", "*"] => [2, 5]
@@ -58,7 +59,13 @@ export default function SegmentedInput(props) {
58
59
  display: flex;
59
60
  align-items: center;
60
61
  gap: 4px;
61
- ` }, { children: despacedFormat.map((_format, i) => (_jsx(SquareInput, { leftSpaced: leftSpacedIndexs.includes(i), size: "small", color: focusedIndex === i ? "activePrimary" : "default", inputProps: {
62
+ ` }, { children: despacedFormat.map((_format, i) => (_jsx(SquareInput, { leftSpaced: leftSpacedIndexs.includes(i), size: "small", color: isCorrect === true
63
+ ? "activeSuccess"
64
+ : isCorrect === false
65
+ ? "activeDanger"
66
+ : focusedIndex === i
67
+ ? "activePrimary"
68
+ : "default", inputProps: {
62
69
  readOnly,
63
70
  onFocus: () => {
64
71
  var _a, _b;
@@ -68,6 +75,9 @@ export default function SegmentedInput(props) {
68
75
  (_a = hiddenRef.current) === null || _a === void 0 ? void 0 : _a.focus();
69
76
  (_b = hiddenRef.current) === null || _b === void 0 ? void 0 : _b.setSelectionRange(i, i);
70
77
  },
78
+ color: isCorrect === false
79
+ ? theme.color.foreground.danger
80
+ : undefined,
71
81
  }, value: splitedValues[i] || "", onChange: () => { } }, i))) })), _jsx(InputMarker, {})] }), _jsx(Text, { children: placeholder })] }));
72
82
  }
73
83
  const Container = styled.div `
@@ -1,6 +1,7 @@
1
1
  import { InputProps } from "../../../../components/Input";
2
2
  export type TextInputProps = InputProps & {
3
3
  readOnly: boolean;
4
+ isCorrect?: boolean;
4
5
  };
5
6
  /** 읽기모드/편집모드가 가능한 input 컴포넌트 */
6
7
  export default function TextInput(props: TextInputProps): import("react/jsx-runtime").JSX.Element;
@@ -12,16 +12,32 @@ var __rest = (this && this.__rest) || function (s, e) {
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { useState } from "react";
14
14
  import Input from "../../../../components/Input";
15
+ import { css as cssToClassName } from "@emotion/css";
16
+ import { useTheme } from "@emotion/react";
15
17
  /** 읽기모드/편집모드가 가능한 input 컴포넌트 */
16
18
  export default function TextInput(props) {
17
- const { readOnly } = props, InputOriginalProps = __rest(props, ["readOnly"]);
19
+ const { readOnly, isCorrect } = props, inputOriginalProps = __rest(props, ["readOnly", "isCorrect"]);
18
20
  const [focus, setFocus] = useState(false);
21
+ const theme = useTheme();
19
22
  if (readOnly) {
20
- return (_jsx(Input, Object.assign({}, InputOriginalProps, { inputProps: {
23
+ return (_jsx(Input, Object.assign({}, inputOriginalProps, { color: isCorrect === true
24
+ ? "activeSuccess"
25
+ : isCorrect === false
26
+ ? "activeDanger"
27
+ : inputOriginalProps.color, inputProps: {
21
28
  readOnly: true,
29
+ className: isCorrect === false
30
+ ? cssToClassName `
31
+ color: ${theme.color.foreground.danger};
32
+ &::placeholder {
33
+ // inputComponent의 placeholder 스타일을 덮어쓰기 위해 부득이하게 !important 사용
34
+ color: ${theme.color.foreground.dangerDisabled} !important;
35
+ }
36
+ `
37
+ : undefined,
22
38
  } })));
23
39
  }
24
- return (_jsx(Input, Object.assign({}, InputOriginalProps, { color: focus ? "activePrimary" : "default", inputProps: {
40
+ return (_jsx(Input, Object.assign({}, inputOriginalProps, { color: focus ? "activePrimary" : inputOriginalProps.color, inputProps: {
25
41
  onFocus: () => setFocus(true),
26
42
  onBlur: () => setFocus(false),
27
43
  } })));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-monolith/cds",
3
- "version": "1.38.3",
3
+ "version": "1.38.4",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "sideEffects": false,