@team-monolith/cds 1.38.2 → 1.38.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.
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/InputComponent.d.ts +0 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/InputComponent.js +3 -3
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/ProblemInputNode.d.ts +2 -5
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/ProblemInputNode.js +5 -8
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SegmentedInput.d.ts +0 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SegmentedInput.js +3 -13
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/TextInput.d.ts +0 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/TextInput.js +3 -19
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxComponent.d.ts +16 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxComponent.js +57 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxEdit.d.ts +1 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxEdit.js +6 -54
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/{SelectBoxView/SelectBoxView.d.ts → SelectBoxView.d.ts} +1 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView.js +104 -0
- package/package.json +1 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/SelectBoxView.js +0 -77
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/SubmittedBox/SelectedIndex.d.ts +0 -4
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/SubmittedBox/SelectedIndex.js +0 -38
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/SubmittedBox/SubmittedBox.d.ts +0 -10
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/SubmittedBox/SubmittedBox.js +0 -86
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/SubmittedBox/index.d.ts +0 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/SubmittedBox/index.js +0 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/index.d.ts +0 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/index.js +0 -1
|
@@ -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
|
|
28
|
+
const { answer } = props, settingFormProps = __rest(props, ["answer"]);
|
|
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,
|
|
54
|
+
return (_jsx(SegmentedInput, { readOnly: lexicalCustomConfig.freezeProblemNode, answerFormat: answerFormat, placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: handleChange }));
|
|
55
55
|
}
|
|
56
|
-
return (_jsx(TextInput, { readOnly: lexicalCustomConfig.freezeProblemNode,
|
|
56
|
+
return (_jsx(TextInput, { readOnly: lexicalCustomConfig.freezeProblemNode, size: "small", color: "default", placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: (e) => {
|
|
57
57
|
handleChange(e.target.value);
|
|
58
58
|
}, fullWidth: true }));
|
|
59
59
|
}
|
|
@@ -11,8 +11,6 @@ export interface ProblemInputPayload {
|
|
|
11
11
|
* (ex: "코들 입니다" => "** ***") */
|
|
12
12
|
solutions: Solution[];
|
|
13
13
|
answer: string;
|
|
14
|
-
/** FE에서만 사용하는 값. 문제의 정오답 여부를 주입하여 스타일을 변경합니다. */
|
|
15
|
-
isCorrect?: boolean;
|
|
16
14
|
key?: NodeKey;
|
|
17
15
|
}
|
|
18
16
|
export type SerializedProblemInputNode = Spread<ProblemInputPayload, SerializedLexicalNode>;
|
|
@@ -25,7 +23,6 @@ export declare class ProblemInputNode extends DecoratorNode<ReactNode> {
|
|
|
25
23
|
__showCharacterNumber: boolean;
|
|
26
24
|
__placeholder: string;
|
|
27
25
|
__answer: string;
|
|
28
|
-
__isCorrect?: boolean;
|
|
29
26
|
isInline(): boolean;
|
|
30
27
|
static getType(): string;
|
|
31
28
|
getSolutions(): Solution[];
|
|
@@ -37,12 +34,12 @@ export declare class ProblemInputNode extends DecoratorNode<ReactNode> {
|
|
|
37
34
|
setPlaceholder(placeholder: string): void;
|
|
38
35
|
setAnswer(answer: string): void;
|
|
39
36
|
static clone(node: ProblemInputNode): ProblemInputNode;
|
|
40
|
-
constructor(showCharacterNumber: boolean, placeholder: string, solutions: Solution[], answer: string,
|
|
37
|
+
constructor(showCharacterNumber: boolean, placeholder: string, solutions: Solution[], answer: string, key?: NodeKey);
|
|
41
38
|
createDOM(config: EditorConfig): HTMLElement;
|
|
42
39
|
updateDOM(): boolean;
|
|
43
40
|
static importJSON(serializedNode: SerializedProblemInputNode): ProblemInputNode;
|
|
44
41
|
exportJSON(): SerializedProblemInputNode;
|
|
45
42
|
decorate(): ReactNode;
|
|
46
43
|
}
|
|
47
|
-
export declare function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer,
|
|
44
|
+
export declare function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer, key, }: ProblemInputPayload): ProblemInputNode;
|
|
48
45
|
export declare function $isProblemInputNode(node: LexicalNode | null | undefined): node is ProblemInputNode;
|
|
@@ -42,15 +42,14 @@ 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.
|
|
45
|
+
return new ProblemInputNode(node.__showCharacterNumber, node.__placeholder, node.__solutions, node.__answer, node.__key);
|
|
46
46
|
}
|
|
47
|
-
constructor(showCharacterNumber, placeholder, solutions, answer,
|
|
47
|
+
constructor(showCharacterNumber, placeholder, solutions, answer, 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;
|
|
54
53
|
}
|
|
55
54
|
createDOM(config) {
|
|
56
55
|
// Define the DOM element here
|
|
@@ -68,7 +67,6 @@ export class ProblemInputNode extends DecoratorNode {
|
|
|
68
67
|
showCharacterNumber: serializedNode.showCharacterNumber,
|
|
69
68
|
placeholder: serializedNode.placeholder,
|
|
70
69
|
answer: serializedNode.answer,
|
|
71
|
-
isCorrect: serializedNode.isCorrect,
|
|
72
70
|
});
|
|
73
71
|
return node;
|
|
74
72
|
}
|
|
@@ -79,16 +77,15 @@ export class ProblemInputNode extends DecoratorNode {
|
|
|
79
77
|
showCharacterNumber: this.__showCharacterNumber,
|
|
80
78
|
placeholder: this.__placeholder,
|
|
81
79
|
solutions: this.__solutions,
|
|
82
|
-
isCorrect: this.__isCorrect,
|
|
83
80
|
answer: this.__answer,
|
|
84
81
|
};
|
|
85
82
|
}
|
|
86
83
|
decorate() {
|
|
87
|
-
return (_jsx(InputComponent, { solutions: this.__solutions, showCharacterNumber: this.__showCharacterNumber, placeholder: this.__placeholder, answer: this.__answer,
|
|
84
|
+
return (_jsx(InputComponent, { solutions: this.__solutions, showCharacterNumber: this.__showCharacterNumber, placeholder: this.__placeholder, answer: this.__answer, nodeKey: this.getKey() }));
|
|
88
85
|
}
|
|
89
86
|
}
|
|
90
|
-
export function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer,
|
|
91
|
-
return $applyNodeReplacement(new ProblemInputNode(showCharacterNumber, placeholder, solutions, answer,
|
|
87
|
+
export function $createProblemInputNode({ showCharacterNumber, placeholder, solutions, answer, key, }) {
|
|
88
|
+
return $applyNodeReplacement(new ProblemInputNode(showCharacterNumber, placeholder, solutions, answer, key));
|
|
92
89
|
}
|
|
93
90
|
export function $isProblemInputNode(node) {
|
|
94
91
|
return node instanceof ProblemInputNode;
|
|
@@ -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
|
|
3
|
+
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";
|
|
@@ -9,8 +9,7 @@ import { useRef, useState } from "react";
|
|
|
9
9
|
* 그리고 그 value는 split되어 segmented input에 표시됩니다.
|
|
10
10
|
*/
|
|
11
11
|
export default function SegmentedInput(props) {
|
|
12
|
-
const { readOnly,
|
|
13
|
-
const theme = useTheme();
|
|
12
|
+
const { readOnly, answerFormat, placeholder, value, onChange } = props;
|
|
14
13
|
// "** ***" => ["*", "*", " ", "*", "*", "*"]
|
|
15
14
|
const splitedFormat = answerFormat.split("");
|
|
16
15
|
// ["*", "*", " ", "*", "*", "*", " ", "*", "*"] => [2, 5]
|
|
@@ -59,13 +58,7 @@ export default function SegmentedInput(props) {
|
|
|
59
58
|
display: flex;
|
|
60
59
|
align-items: center;
|
|
61
60
|
gap: 4px;
|
|
62
|
-
` }, { children: despacedFormat.map((_format, i) => (_jsx(SquareInput, { leftSpaced: leftSpacedIndexs.includes(i), size: "small", color:
|
|
63
|
-
? "activeSuccess"
|
|
64
|
-
: isCorrect === false
|
|
65
|
-
? "activeDanger"
|
|
66
|
-
: focusedIndex === i
|
|
67
|
-
? "activePrimary"
|
|
68
|
-
: "default", inputProps: {
|
|
61
|
+
` }, { children: despacedFormat.map((_format, i) => (_jsx(SquareInput, { leftSpaced: leftSpacedIndexs.includes(i), size: "small", color: focusedIndex === i ? "activePrimary" : "default", inputProps: {
|
|
69
62
|
readOnly,
|
|
70
63
|
onFocus: () => {
|
|
71
64
|
var _a, _b;
|
|
@@ -75,9 +68,6 @@ export default function SegmentedInput(props) {
|
|
|
75
68
|
(_a = hiddenRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
76
69
|
(_b = hiddenRef.current) === null || _b === void 0 ? void 0 : _b.setSelectionRange(i, i);
|
|
77
70
|
},
|
|
78
|
-
color: isCorrect === false
|
|
79
|
-
? theme.color.foreground.danger
|
|
80
|
-
: undefined,
|
|
81
71
|
}, value: splitedValues[i] || "", onChange: () => { } }, i))) })), _jsx(InputMarker, {})] }), _jsx(Text, { children: placeholder })] }));
|
|
82
72
|
}
|
|
83
73
|
const Container = styled.div `
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { InputProps } from "../../../../components/Input";
|
|
2
2
|
export type TextInputProps = InputProps & {
|
|
3
3
|
readOnly: boolean;
|
|
4
|
-
isCorrect?: boolean;
|
|
5
4
|
};
|
|
6
5
|
/** 읽기모드/편집모드가 가능한 input 컴포넌트 */
|
|
7
6
|
export default function TextInput(props: TextInputProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -12,32 +12,16 @@ 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";
|
|
17
15
|
/** 읽기모드/편집모드가 가능한 input 컴포넌트 */
|
|
18
16
|
export default function TextInput(props) {
|
|
19
|
-
const { readOnly
|
|
17
|
+
const { readOnly } = props, InputOriginalProps = __rest(props, ["readOnly"]);
|
|
20
18
|
const [focus, setFocus] = useState(false);
|
|
21
|
-
const theme = useTheme();
|
|
22
19
|
if (readOnly) {
|
|
23
|
-
return (_jsx(Input, Object.assign({},
|
|
24
|
-
? "activeSuccess"
|
|
25
|
-
: isCorrect === false
|
|
26
|
-
? "activeDanger"
|
|
27
|
-
: inputOriginalProps.color, inputProps: {
|
|
20
|
+
return (_jsx(Input, Object.assign({}, InputOriginalProps, { inputProps: {
|
|
28
21
|
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,
|
|
38
22
|
} })));
|
|
39
23
|
}
|
|
40
|
-
return (_jsx(Input, Object.assign({},
|
|
24
|
+
return (_jsx(Input, Object.assign({}, InputOriginalProps, { color: focus ? "activePrimary" : "default", inputProps: {
|
|
41
25
|
onFocus: () => setFocus(true),
|
|
42
26
|
onBlur: () => setFocus(false),
|
|
43
27
|
} })));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ImageProps } from "../ProblemSelectNode";
|
|
3
|
+
/** 비지니스 로직과 무관한 SelectBox를 그리는 공통 컴포넌트입니다. */
|
|
4
|
+
export declare function SelectBoxComponent(props: {
|
|
5
|
+
className?: string;
|
|
6
|
+
indexClassName?: string;
|
|
7
|
+
contentClassName?: string;
|
|
8
|
+
/** 문제 번호 박스 내부를 그립니다. */
|
|
9
|
+
index: React.ReactNode;
|
|
10
|
+
image?: ImageProps | null;
|
|
11
|
+
text: React.ReactNode;
|
|
12
|
+
/** SelectBox content 우측에 표시될 부분 */
|
|
13
|
+
endIcon?: React.ReactNode;
|
|
14
|
+
/** 박스를 클릭할 때 실행될 콜백. 존재하지 않으면 cursor: pointer가 적용되지 않습니다. */
|
|
15
|
+
onClick?: () => void;
|
|
16
|
+
}): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
/** @jsxImportSource @emotion/react */
|
|
3
|
+
import { css } from "@emotion/react";
|
|
4
|
+
import styled from "@emotion/styled";
|
|
5
|
+
/** 비지니스 로직과 무관한 SelectBox를 그리는 공통 컴포넌트입니다. */
|
|
6
|
+
export function SelectBoxComponent(props) {
|
|
7
|
+
const { className, indexClassName, contentClassName, index, image, text, endIcon, onClick, } = props;
|
|
8
|
+
return (_jsxs(Container, Object.assign({ className: className, onClick: onClick }, { children: [_jsx(Index, Object.assign({ className: indexClassName }, { children: index })), _jsxs(Content, Object.assign({ className: contentClassName }, { children: [image && (_jsx("img", { src: image.src, alt: image.altText, css: css `
|
|
9
|
+
height: auto;
|
|
10
|
+
// 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
|
|
11
|
+
max-width: 100%;
|
|
12
|
+
width: fit-content;
|
|
13
|
+
border-radius: 6px;
|
|
14
|
+
` })), text] })), endIcon] })));
|
|
15
|
+
}
|
|
16
|
+
const Container = styled.div(({ theme, onClick }) => css `
|
|
17
|
+
${onClick && "cursor: pointer;"}
|
|
18
|
+
display: flex;
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
width: 400px;
|
|
21
|
+
padding: 12px;
|
|
22
|
+
gap: 12px;
|
|
23
|
+
border-radius: 8px;
|
|
24
|
+
background: ${theme.color.background.neutralAlt};
|
|
25
|
+
border: 1px solid transparent;
|
|
26
|
+
color: ${theme.color.foreground.neutralBase};
|
|
27
|
+
`);
|
|
28
|
+
const Index = styled.div(({ theme }) => css `
|
|
29
|
+
display: flex;
|
|
30
|
+
box-sizing: border-box;
|
|
31
|
+
width: 20px;
|
|
32
|
+
height: 20px;
|
|
33
|
+
padding: 4px;
|
|
34
|
+
|
|
35
|
+
user-select: none; /* Standard syntax */
|
|
36
|
+
|
|
37
|
+
justify-content: center;
|
|
38
|
+
align-items: center;
|
|
39
|
+
border-radius: 4px;
|
|
40
|
+
border: 1px solid ${theme.color.background.neutralAltActive};
|
|
41
|
+
background: ${theme.color.background.neutralBase};
|
|
42
|
+
color: ${theme.color.foreground.neutralBaseDisabled};
|
|
43
|
+
font-family: ${theme.fontFamily.ui};
|
|
44
|
+
font-size: 14px;
|
|
45
|
+
font-weight: 800;
|
|
46
|
+
line-height: 16px;
|
|
47
|
+
`);
|
|
48
|
+
const Content = styled.div(({ theme }) => css `
|
|
49
|
+
display: flex;
|
|
50
|
+
flex-direction: column;
|
|
51
|
+
gap: 12px;
|
|
52
|
+
flex: 1;
|
|
53
|
+
font-family: ${theme.fontFamily.ui};
|
|
54
|
+
font-size: 16px;
|
|
55
|
+
font-weight: 400;
|
|
56
|
+
line-height: 20px;
|
|
57
|
+
`);
|
|
@@ -4,6 +4,6 @@ export interface SelectBoxEditProps {
|
|
|
4
4
|
isAnswer: boolean;
|
|
5
5
|
image?: ImageProps | null;
|
|
6
6
|
text: string;
|
|
7
|
-
onClick
|
|
7
|
+
onClick: () => void;
|
|
8
8
|
}
|
|
9
9
|
export declare function SelectBoxEdit(props: SelectBoxEditProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -1,61 +1,13 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
2
|
/** @jsxImportSource @emotion/react */
|
|
3
|
-
import styled from "@emotion/styled";
|
|
4
3
|
import { css, useTheme } from "@emotion/react";
|
|
5
4
|
import { CheckboxCircleFillIcon } from "../../../../../icons";
|
|
5
|
+
import { SelectBoxComponent } from "./SelectBoxComponent";
|
|
6
6
|
export function SelectBoxEdit(props) {
|
|
7
7
|
const { index, isAnswer, image, text, onClick } = props;
|
|
8
8
|
const theme = useTheme();
|
|
9
|
-
return (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
width: fit-content;
|
|
14
|
-
border-radius: 6px;
|
|
15
|
-
` })), text] }), isAnswer && (_jsx(CheckboxCircleFillIcon, { color: theme.color.foreground.success, css: css `
|
|
16
|
-
width: 16px;
|
|
17
|
-
height: 16px;
|
|
18
|
-
` }))] })));
|
|
9
|
+
return (_jsx(SelectBoxComponent, { index: index, image: image, text: text, endIcon: isAnswer && (_jsx(CheckboxCircleFillIcon, { color: theme.color.foreground.success, css: css `
|
|
10
|
+
width: 16px;
|
|
11
|
+
height: 16px;
|
|
12
|
+
` })), onClick: onClick }));
|
|
19
13
|
}
|
|
20
|
-
const Container = styled.div(({ theme }) => css `
|
|
21
|
-
cursor: pointer;
|
|
22
|
-
display: flex;
|
|
23
|
-
box-sizing: border-box;
|
|
24
|
-
width: 400px;
|
|
25
|
-
padding: 12px;
|
|
26
|
-
gap: 12px;
|
|
27
|
-
border-radius: 8px;
|
|
28
|
-
background: ${theme.color.background.neutralAlt};
|
|
29
|
-
border: 1px solid transparent;
|
|
30
|
-
color: ${theme.color.foreground.neutralBase};
|
|
31
|
-
`);
|
|
32
|
-
const Index = styled.div(({ theme }) => css `
|
|
33
|
-
display: flex;
|
|
34
|
-
box-sizing: border-box;
|
|
35
|
-
width: 20px;
|
|
36
|
-
height: 20px;
|
|
37
|
-
padding: 4px;
|
|
38
|
-
|
|
39
|
-
user-select: none; /* Standard syntax */
|
|
40
|
-
|
|
41
|
-
justify-content: center;
|
|
42
|
-
align-items: center;
|
|
43
|
-
border-radius: 4px;
|
|
44
|
-
border: 1px solid ${theme.color.background.neutralAltActive};
|
|
45
|
-
background: ${theme.color.background.neutralBase};
|
|
46
|
-
color: ${theme.color.foreground.neutralBaseDisabled};
|
|
47
|
-
font-family: ${theme.fontFamily.ui};
|
|
48
|
-
font-size: 14px;
|
|
49
|
-
font-weight: 800;
|
|
50
|
-
line-height: 16px;
|
|
51
|
-
`);
|
|
52
|
-
const Content = styled.div(({ theme }) => css `
|
|
53
|
-
display: flex;
|
|
54
|
-
flex-direction: column;
|
|
55
|
-
gap: 12px;
|
|
56
|
-
flex: 1;
|
|
57
|
-
font-family: ${theme.fontFamily.ui};
|
|
58
|
-
font-size: 16px;
|
|
59
|
-
font-weight: 400;
|
|
60
|
-
line-height: 20px;
|
|
61
|
-
`);
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
+
/** @jsxImportSource @emotion/react */
|
|
3
|
+
import { css, useTheme } from "@emotion/react";
|
|
4
|
+
import { css as cssToClassName } from "@emotion/css";
|
|
5
|
+
import { CheckboxCircleFillIcon, CheckFillIcon, CloseCircleFillIcon, } from "../../../../../icons";
|
|
6
|
+
import { SelectBoxComponent } from "./SelectBoxComponent";
|
|
7
|
+
import Tag from "../../../../../components/Tag";
|
|
8
|
+
const getBoxStyle = (theme, isSelected, isAnswer) => {
|
|
9
|
+
if (isSelected) {
|
|
10
|
+
// 선택 박스
|
|
11
|
+
if (isAnswer === undefined) {
|
|
12
|
+
return css `
|
|
13
|
+
background: ${theme.color.container.primaryContainer};
|
|
14
|
+
border: 1px solid ${theme.color.foreground.primary};
|
|
15
|
+
color: ${theme.color.container.primaryOnContainer};
|
|
16
|
+
`;
|
|
17
|
+
}
|
|
18
|
+
// 정답 박스
|
|
19
|
+
if (isAnswer) {
|
|
20
|
+
return css `
|
|
21
|
+
background: ${theme.color.container.successContainer};
|
|
22
|
+
border: 1px solid ${theme.color.background.successActive};
|
|
23
|
+
color: ${theme.color.container.successOnContainer};
|
|
24
|
+
`;
|
|
25
|
+
}
|
|
26
|
+
// 오답 박스
|
|
27
|
+
return css `
|
|
28
|
+
background: ${theme.color.container.dangerContainer};
|
|
29
|
+
border: 1px solid ${theme.color.background.dangerActive};
|
|
30
|
+
color: ${theme.color.container.dangerOnContainer};
|
|
31
|
+
`;
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
};
|
|
35
|
+
const getIndexClassName = (theme, isSelected, isAnswer) => {
|
|
36
|
+
if (isSelected) {
|
|
37
|
+
// 선택 박스
|
|
38
|
+
if (isAnswer === undefined) {
|
|
39
|
+
return cssToClassName `
|
|
40
|
+
background: ${theme.color.background.primary};
|
|
41
|
+
border: 1px solid ${theme.color.background.primary};
|
|
42
|
+
color: ${theme.color.foreground.neutralAlt};
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
// 정답 박스
|
|
46
|
+
if (isAnswer) {
|
|
47
|
+
return cssToClassName `
|
|
48
|
+
background: ${theme.color.background.successActive};
|
|
49
|
+
border: 1px solid ${theme.color.background.successActive};
|
|
50
|
+
color: ${theme.color.foreground.neutralAlt};
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
// 오답 박스
|
|
54
|
+
return cssToClassName `
|
|
55
|
+
background: ${theme.color.background.dangerActive};
|
|
56
|
+
border: 1px solid ${theme.color.background.dangerActive};
|
|
57
|
+
color: ${theme.color.foreground.neutralAlt};
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
};
|
|
62
|
+
const getIndexComponent = (index, isSelected, isAnswer) => {
|
|
63
|
+
if (isSelected) {
|
|
64
|
+
// 선택 박스
|
|
65
|
+
if (isAnswer === undefined) {
|
|
66
|
+
return (_jsx(CheckFillIcon, { css: css `
|
|
67
|
+
width: 12px;
|
|
68
|
+
height: 12px;
|
|
69
|
+
` }));
|
|
70
|
+
}
|
|
71
|
+
// 정답 박스
|
|
72
|
+
if (isAnswer) {
|
|
73
|
+
return (_jsx(CheckboxCircleFillIcon, { css: css `
|
|
74
|
+
width: 12px;
|
|
75
|
+
height: 12px;
|
|
76
|
+
` }));
|
|
77
|
+
}
|
|
78
|
+
// 오답 박스
|
|
79
|
+
return (_jsx(CloseCircleFillIcon, { css: css `
|
|
80
|
+
width: 12px;
|
|
81
|
+
height: 12px;
|
|
82
|
+
` }));
|
|
83
|
+
}
|
|
84
|
+
return index;
|
|
85
|
+
};
|
|
86
|
+
export function SelectBoxView(props) {
|
|
87
|
+
const { index, isSelected, isAnswer, image, text, onClick } = props;
|
|
88
|
+
const theme = useTheme();
|
|
89
|
+
return (_jsx(SelectBoxComponent, { css: [
|
|
90
|
+
css `
|
|
91
|
+
width: 100%;
|
|
92
|
+
`,
|
|
93
|
+
getBoxStyle(theme, isSelected, isAnswer),
|
|
94
|
+
], indexClassName: getIndexClassName(theme, isSelected, isAnswer), index: getIndexComponent(index, isSelected, isAnswer), image: image, text: text,
|
|
95
|
+
// isAnswer가 존재하면 채점 후의 상태이므로 unclickable을 위해 onClick을 전달하지 않음
|
|
96
|
+
onClick: isAnswer === undefined ? onClick : undefined,
|
|
97
|
+
// 선택되지 않았으나 정답일 때 정답 태그를 표시
|
|
98
|
+
endIcon: isAnswer &&
|
|
99
|
+
!isSelected && (_jsx(Tag, { label: "\uC815\uB2F5", icon: _jsx(CheckboxCircleFillIcon, {}), color: "green", css: css `
|
|
100
|
+
span {
|
|
101
|
+
font-weight: 700;
|
|
102
|
+
}
|
|
103
|
+
` })) }));
|
|
104
|
+
}
|
package/package.json
CHANGED
package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/SelectBoxView.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
/** @jsxImportSource @emotion/react */
|
|
3
|
-
import styled from "@emotion/styled";
|
|
4
|
-
import { css } from "@emotion/react";
|
|
5
|
-
import { CheckFillIcon } from "../../../../../../icons";
|
|
6
|
-
import { SubmittedBox } from "./SubmittedBox";
|
|
7
|
-
export function SelectBoxView(props) {
|
|
8
|
-
const { index, isSelected, isAnswer, image, text, onClick } = props;
|
|
9
|
-
if (isAnswer !== undefined) {
|
|
10
|
-
return (_jsx(SubmittedBox, { index: index, isSelected: isSelected, isAnswer: isAnswer, image: image, text: text }));
|
|
11
|
-
}
|
|
12
|
-
// 채점 전의 객관식 선택지 view
|
|
13
|
-
return (_jsxs(Container, Object.assign({ isSelected: isSelected, onClick: onClick }, { children: [_jsx(Index, Object.assign({ isSelected: isSelected }, { children: isSelected ? (_jsx(CheckFillIcon, { css: css `
|
|
14
|
-
width: 12px;
|
|
15
|
-
height: 12px;
|
|
16
|
-
` })) : (index) })), _jsxs(Content, { children: [image && (_jsx("img", { src: image.src, alt: image.altText, css: css `
|
|
17
|
-
height: auto;
|
|
18
|
-
// 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
|
|
19
|
-
max-width: 100%;
|
|
20
|
-
width: fit-content;
|
|
21
|
-
border-radius: 6px;
|
|
22
|
-
` })), text] })] })));
|
|
23
|
-
}
|
|
24
|
-
const Container = styled.div(({ theme, isSelected }) => css `
|
|
25
|
-
cursor: pointer;
|
|
26
|
-
display: flex;
|
|
27
|
-
box-sizing: border-box;
|
|
28
|
-
width: 100%;
|
|
29
|
-
padding: 12px;
|
|
30
|
-
gap: 12px;
|
|
31
|
-
border-radius: 8px;
|
|
32
|
-
background: ${isSelected
|
|
33
|
-
? theme.color.container.primaryContainer
|
|
34
|
-
: theme.color.background.neutralAlt};
|
|
35
|
-
border: ${isSelected
|
|
36
|
-
? `1px solid ${theme.color.foreground.primary}`
|
|
37
|
-
: "1px solid transparent"};
|
|
38
|
-
color: ${isSelected
|
|
39
|
-
? theme.color.container.primaryOnContainer
|
|
40
|
-
: theme.color.foreground.neutralBase};
|
|
41
|
-
`);
|
|
42
|
-
const Index = styled.div(({ theme, isSelected }) => css `
|
|
43
|
-
display: flex;
|
|
44
|
-
box-sizing: border-box;
|
|
45
|
-
width: 20px;
|
|
46
|
-
height: 20px;
|
|
47
|
-
padding: 4px;
|
|
48
|
-
|
|
49
|
-
user-select: none; /* Standard syntax */
|
|
50
|
-
|
|
51
|
-
justify-content: center;
|
|
52
|
-
align-items: center;
|
|
53
|
-
border-radius: 4px;
|
|
54
|
-
border: ${isSelected
|
|
55
|
-
? "none"
|
|
56
|
-
: `1px solid ${theme.color.background.neutralAltActive}`};
|
|
57
|
-
background: ${isSelected
|
|
58
|
-
? theme.color.background.primary
|
|
59
|
-
: theme.color.background.neutralBase};
|
|
60
|
-
color: ${isSelected
|
|
61
|
-
? theme.color.foreground.neutralAlt
|
|
62
|
-
: theme.color.foreground.neutralBaseDisabled};
|
|
63
|
-
font-family: ${theme.fontFamily.ui};
|
|
64
|
-
font-size: 14px;
|
|
65
|
-
font-weight: 800;
|
|
66
|
-
line-height: 16px;
|
|
67
|
-
`);
|
|
68
|
-
const Content = styled.div(({ theme }) => css `
|
|
69
|
-
display: flex;
|
|
70
|
-
flex-direction: column;
|
|
71
|
-
gap: 12px;
|
|
72
|
-
flex: 1;
|
|
73
|
-
font-family: ${theme.fontFamily.ui};
|
|
74
|
-
font-size: 16px;
|
|
75
|
-
font-weight: 400;
|
|
76
|
-
line-height: 20px;
|
|
77
|
-
`);
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
-
/** @jsxImportSource @emotion/react */
|
|
3
|
-
import { css, useTheme } from "@emotion/react";
|
|
4
|
-
import styled from "@emotion/styled";
|
|
5
|
-
import { CheckboxCircleFillIcon, CloseCircleFillIcon, } from "../../../../../../../icons";
|
|
6
|
-
/** 선택된 상태로 제출된 객관식 선택지 문항 번호 컴포넌트입니다. */
|
|
7
|
-
export function SelectedIndex(props) {
|
|
8
|
-
const theme = useTheme();
|
|
9
|
-
if (props.isAnswer) {
|
|
10
|
-
return (_jsx(Index, Object.assign({ css: css `
|
|
11
|
-
background: ${theme.color.background.successActive};
|
|
12
|
-
border: 1px solid ${theme.color.background.successActive};
|
|
13
|
-
` }, { children: _jsx(CheckboxCircleFillIcon, { css: css `
|
|
14
|
-
width: 12px;
|
|
15
|
-
height: 12px;
|
|
16
|
-
`, color: theme.color.foreground.neutralAlt }) })));
|
|
17
|
-
}
|
|
18
|
-
return (_jsx(Index, Object.assign({ css: css `
|
|
19
|
-
background: ${theme.color.background.dangerActive};
|
|
20
|
-
border: 1px solid ${theme.color.background.dangerActive};
|
|
21
|
-
` }, { children: _jsx(CloseCircleFillIcon, { css: css `
|
|
22
|
-
width: 12px;
|
|
23
|
-
height: 12px;
|
|
24
|
-
`, color: theme.color.foreground.neutralAlt }) })));
|
|
25
|
-
}
|
|
26
|
-
const Index = styled.div `
|
|
27
|
-
display: flex;
|
|
28
|
-
box-sizing: border-box;
|
|
29
|
-
width: 20px;
|
|
30
|
-
height: 20px;
|
|
31
|
-
padding: 4px;
|
|
32
|
-
|
|
33
|
-
user-select: none; /* Standard syntax */
|
|
34
|
-
|
|
35
|
-
justify-content: center;
|
|
36
|
-
align-items: center;
|
|
37
|
-
border-radius: 4px;
|
|
38
|
-
`;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ImageProps } from "../../../ProblemSelectNode";
|
|
2
|
-
export interface SelectBoxViewGradedProps {
|
|
3
|
-
index: number;
|
|
4
|
-
isSelected: boolean;
|
|
5
|
-
isAnswer: boolean;
|
|
6
|
-
image?: ImageProps | null;
|
|
7
|
-
text: string;
|
|
8
|
-
}
|
|
9
|
-
/** 채점(제출) 후의 정답이 공개된(isAnswer가 존재하는) 객관식 선택지 view입니다. */
|
|
10
|
-
export declare function SubmittedBox(props: SelectBoxViewGradedProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
/** @jsxImportSource @emotion/react */
|
|
3
|
-
import styled from "@emotion/styled";
|
|
4
|
-
import { css, useTheme } from "@emotion/react";
|
|
5
|
-
import { CheckboxCircleFillIcon } from "../../../../../../../icons";
|
|
6
|
-
import Tag from "../../../../../../../components/Tag";
|
|
7
|
-
import { SelectedIndex } from "./SelectedIndex";
|
|
8
|
-
const SELECTD_CONTAINER_STYLE = (theme, isCorrect) => isCorrect
|
|
9
|
-
? css `
|
|
10
|
-
background: ${theme.color.container.successContainer};
|
|
11
|
-
border: 1px solid ${theme.color.background.successActive};
|
|
12
|
-
color: ${theme.color.container.successOnContainer};
|
|
13
|
-
`
|
|
14
|
-
: css `
|
|
15
|
-
background: ${theme.color.container.dangerContainer};
|
|
16
|
-
border: 1px solid ${theme.color.background.dangerActive};
|
|
17
|
-
color: ${theme.color.container.dangerOnContainer};
|
|
18
|
-
`;
|
|
19
|
-
/** 채점(제출) 후의 정답이 공개된(isAnswer가 존재하는) 객관식 선택지 view입니다. */
|
|
20
|
-
export function SubmittedBox(props) {
|
|
21
|
-
const { index, isSelected, isAnswer, image, text } = props;
|
|
22
|
-
const theme = useTheme();
|
|
23
|
-
// 선택된 상태일 때 : 정오답 여부에 따라 디자인이 다름
|
|
24
|
-
if (isSelected) {
|
|
25
|
-
return (_jsxs(Container, Object.assign({ css: SELECTD_CONTAINER_STYLE(theme, isAnswer) }, { children: [_jsx(SelectedIndex, { isAnswer: isAnswer }), _jsxs(Content, { children: [image && (_jsx("img", { src: image.src, alt: image.altText, css: css `
|
|
26
|
-
height: auto;
|
|
27
|
-
// 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
|
|
28
|
-
max-width: 100%;
|
|
29
|
-
width: fit-content;
|
|
30
|
-
border-radius: 6px;
|
|
31
|
-
` })), text] })] })));
|
|
32
|
-
}
|
|
33
|
-
// 선택되지 않은 상태일 때 : 정답이면 정답 태그를 표시
|
|
34
|
-
return (_jsxs(Container, { children: [_jsx(Index, { children: index }), _jsxs(Content, { children: [image && (_jsx("img", { src: image.src, alt: image.altText, css: css `
|
|
35
|
-
height: auto;
|
|
36
|
-
// 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
|
|
37
|
-
max-width: 100%;
|
|
38
|
-
width: fit-content;
|
|
39
|
-
border-radius: 6px;
|
|
40
|
-
` })), text] }), isAnswer && (_jsx(Tag, { label: "\uC815\uB2F5", icon: _jsx(CheckboxCircleFillIcon, {}), color: "green", css: css `
|
|
41
|
-
span {
|
|
42
|
-
font-weight: 700;
|
|
43
|
-
}
|
|
44
|
-
` }))] }));
|
|
45
|
-
}
|
|
46
|
-
const Container = styled.div(({ theme }) => css `
|
|
47
|
-
display: flex;
|
|
48
|
-
box-sizing: border-box;
|
|
49
|
-
width: 100%;
|
|
50
|
-
padding: 12px;
|
|
51
|
-
gap: 12px;
|
|
52
|
-
border-radius: 8px;
|
|
53
|
-
background: ${theme.color.background.neutralAlt};
|
|
54
|
-
border: 1px solid transparent;
|
|
55
|
-
color: ${theme.color.foreground.neutralBase};
|
|
56
|
-
`);
|
|
57
|
-
const Index = styled.div(({ theme }) => css `
|
|
58
|
-
display: flex;
|
|
59
|
-
box-sizing: border-box;
|
|
60
|
-
width: 20px;
|
|
61
|
-
height: 20px;
|
|
62
|
-
padding: 4px;
|
|
63
|
-
|
|
64
|
-
user-select: none; /* Standard syntax */
|
|
65
|
-
|
|
66
|
-
justify-content: center;
|
|
67
|
-
align-items: center;
|
|
68
|
-
border-radius: 4px;
|
|
69
|
-
border: 1px solid ${theme.color.background.neutralAltActive};
|
|
70
|
-
background: ${theme.color.background.neutralBase};
|
|
71
|
-
color: ${theme.color.foreground.neutralBaseDisabled};
|
|
72
|
-
font-family: ${theme.fontFamily.ui};
|
|
73
|
-
font-size: 14px;
|
|
74
|
-
font-weight: 800;
|
|
75
|
-
line-height: 16px;
|
|
76
|
-
`);
|
|
77
|
-
const Content = styled.div(({ theme }) => css `
|
|
78
|
-
display: flex;
|
|
79
|
-
flex-direction: column;
|
|
80
|
-
gap: 12px;
|
|
81
|
-
flex: 1;
|
|
82
|
-
font-family: ${theme.fontFamily.ui};
|
|
83
|
-
font-size: 16px;
|
|
84
|
-
font-weight: 400;
|
|
85
|
-
line-height: 20px;
|
|
86
|
-
`);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./SubmittedBox";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./SubmittedBox";
|
package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./SelectBoxView";
|
package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./SelectBoxView";
|