@team-monolith/cds 1.69.0 → 1.70.0
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/components/AlertDialog/AlertDialogTitle.js +4 -1
- package/dist/components/Banner.js +4 -1
- package/dist/components/SquareButton.d.ts +4 -2
- package/dist/patterns/LexicalEditor/nodes/ImageNode/ImageComponent.js +2 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/InputComponent.js +2 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/FormSolution.d.ts +1 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/FormSolution.js +5 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/ProblemSelectNode.js +0 -9
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectComponent.js +2 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/FormSelection.d.ts +1 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/FormSelection.js +9 -3
- package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/FormQuestion.d.ts +1 -1
- package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/FormQuestion.js +3 -1
- package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/EvaluationComponent.js +2 -0
- package/dist/patterns/LexicalEditor/nodes/SheetInputNode/InputComponent.js +3 -1
- package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectComponent.js +2 -0
- package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/FormSelection.d.ts +1 -1
- package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/FormSelection.js +8 -4
- package/package.json +1 -1
|
@@ -17,6 +17,7 @@ import SquareButton from "../SquareButton";
|
|
|
17
17
|
import { CloseFillIcon } from "../../icons";
|
|
18
18
|
import AlertDialogContext from "./AlertDialogContext";
|
|
19
19
|
import { MOBILE } from "../../foundation/breakpoints";
|
|
20
|
+
// eslint-disable-next-line react/display-name, @typescript-eslint/no-explicit-any
|
|
20
21
|
export const AlertDialogTitle = React.forwardRef((props, ref) => {
|
|
21
22
|
const { className, component: Component = "div", onClose, children } = props, other = __rest(props, ["className", "component", "onClose", "children"]);
|
|
22
23
|
const { icon } = React.useContext(AlertDialogContext);
|
|
@@ -51,5 +52,7 @@ export const AlertDialogTitle = React.forwardRef((props, ref) => {
|
|
|
51
52
|
height: 32px;
|
|
52
53
|
}
|
|
53
54
|
`)}
|
|
54
|
-
` }, { children: icon }))), children] })), onClose && (_jsx(SquareButton, { color: "icon", size: "small", icon: _jsx(CloseFillIcon, {}), onClick: onClose
|
|
55
|
+
` }, { children: icon }))), children] })), onClose && (_jsx(SquareButton, { color: "icon", size: "small", icon: _jsx(CloseFillIcon, {}), onClick: onClose, buttonProps: {
|
|
56
|
+
"aria-label": "닫기",
|
|
57
|
+
} }))] })) }));
|
|
55
58
|
});
|
|
@@ -47,6 +47,7 @@ const COLOR_PALETTE = (theme, color) => ({
|
|
|
47
47
|
/**
|
|
48
48
|
* [피그마](https://www.figma.com/file/yhrRFizzmhPoHdw9FbYow2/Codle-PD-Kit---Components?type=design&node-id=44-2847&t=bhnL1ombbddld3RQ-0)
|
|
49
49
|
*/
|
|
50
|
+
// eslint-disable-next-line react/display-name, @typescript-eslint/no-explicit-any
|
|
50
51
|
const Banner = React.forwardRef((props, ref) => {
|
|
51
52
|
const { className, component: Component = "div", headline, content, icon, color, buttonLabel, buttonClassName, onButtonClick, buttonProps, close, onClose, fullWidth } = props, other = __rest(props, ["className", "component", "headline", "content", "icon", "color", "buttonLabel", "buttonClassName", "onButtonClick", "buttonProps", "close", "onClose", "fullWidth"]);
|
|
52
53
|
const theme = useTheme();
|
|
@@ -80,7 +81,9 @@ const Banner = React.forwardRef((props, ref) => {
|
|
|
80
81
|
> button {
|
|
81
82
|
color: ${COLOR_PALETTE(theme, color).content};
|
|
82
83
|
}
|
|
83
|
-
`, color: "icon", size: "small", icon: _jsx(CloseFillIcon, {}), onClick: onClose
|
|
84
|
+
`, color: "icon", size: "small", icon: _jsx(CloseFillIcon, {}), onClick: onClose, buttonProps: {
|
|
85
|
+
"aria-label": "닫기",
|
|
86
|
+
} }))] })));
|
|
84
87
|
});
|
|
85
88
|
const IconDiv = styled.div `
|
|
86
89
|
display: flex;
|
|
@@ -24,8 +24,10 @@ export interface SquareButtonOwnProps<RootComponentType extends React.ElementTyp
|
|
|
24
24
|
loading?: boolean;
|
|
25
25
|
/** 버튼 클릭 시 호출될 콜백 함수 */
|
|
26
26
|
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
27
|
-
/** 버튼에 전달될 Props */
|
|
28
|
-
buttonProps
|
|
27
|
+
/** 버튼에 전달될 Props. 접근성을 위해 aria-label이 필수로 들어가야 합니다. */
|
|
28
|
+
buttonProps: {
|
|
29
|
+
"aria-label": string;
|
|
30
|
+
} & Partial<Omit<ButtonProps, "disabled" | "color" | "type" | "size" | "icon" | "label" | "loading" | "fullWidth" | "onClick" | "aria-label">>;
|
|
29
31
|
}
|
|
30
32
|
export type SquareButtonProps<RootComponentType extends React.ElementType = SquareButtonTypeMap["defaultComponent"]> = PolymorphicProps<SquareButtonTypeMap<RootComponentType>, RootComponentType>;
|
|
31
33
|
export interface SquareButtonTypeMap<RootComponentType extends React.ElementType = "span"> {
|
|
@@ -158,6 +158,8 @@ export default function ImageComponent({ src, altText, nodeKey, width, height, m
|
|
|
158
158
|
? `focused ${$isNodeSelection(selection) ? "draggable" : ""}`
|
|
159
159
|
: null, src: src, altText: altText, imageRef: imageRef, width: width, height: height, maxWidth: maxWidth }) })) })), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => {
|
|
160
160
|
setOpen(true);
|
|
161
|
+
}, buttonProps: {
|
|
162
|
+
"aria-label": "이미지 수정하기",
|
|
161
163
|
} })] }), _jsx(InsertImageDialog, { open: open, title: "\uC774\uBBF8\uC9C0 \uC218\uC815\uD558\uAE30", onClose: () => setOpen(false), imageProps: {
|
|
162
164
|
src,
|
|
163
165
|
altText,
|
|
@@ -64,6 +64,8 @@ export function InputComponent(props) {
|
|
|
64
64
|
gap: 4px;
|
|
65
65
|
` }, { children: [_jsx(VirtualInput, Object.assign({ onClick: () => setSettingOpen(true) }, { children: "\uC8FC\uAD00\uC2DD \uC785\uB825 \uCE78" })), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => {
|
|
66
66
|
setSettingOpen(true);
|
|
67
|
+
}, buttonProps: {
|
|
68
|
+
"aria-label": "입력 칸 설정",
|
|
67
69
|
} })] })), settingOpen && (_jsx(SettingForm, Object.assign({}, settingFormProps, { onClose: () => setSettingOpen(false) })))] }));
|
|
68
70
|
}
|
|
69
71
|
const VirtualInput = styled.div(({ theme }) => css `
|
|
@@ -2,7 +2,7 @@ import { Control } from "react-hook-form";
|
|
|
2
2
|
import { ProblemInputPayload } from "../ProblemInputNode";
|
|
3
3
|
export interface FormSolutionProps {
|
|
4
4
|
index: number;
|
|
5
|
-
control: Control<ProblemInputPayload
|
|
5
|
+
control: Control<ProblemInputPayload>;
|
|
6
6
|
rules?: any;
|
|
7
7
|
onDelete?: () => void;
|
|
8
8
|
}
|
|
@@ -19,6 +19,10 @@ export function FormSolution(props) {
|
|
|
19
19
|
`, startIcon: _jsx(TextTypeDropdown, { index: index, control: control, disabled: disabled }), endIcon: _jsxs("div", Object.assign({ css: css `
|
|
20
20
|
display: flex;
|
|
21
21
|
gap: 4px;
|
|
22
|
-
` }, { children: [onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete
|
|
22
|
+
` }, { children: [onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete, buttonProps: {
|
|
23
|
+
"aria-label": "삭제",
|
|
24
|
+
} })), disabled && (_jsx(Tooltip, Object.assign({ text: _jsxs("span", { children: ["\uC785\uB825 \uCE78 \uC124\uC815\uC774 '\uAE00\uC790 \uC218\uB300\uB85C'\uC778 \uACBD\uC6B0", _jsx("br", {}), "\uC815\uB2F5\uC744 \uD558\uB098\uB9CC \uB4F1\uB85D\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."] }) }, { children: _jsx(SquareButton, { color: "danger", size: "xsmall", icon: _jsx(AlertFillIcon, { color: theme.color.foreground.neutralAlt }), disabled: true, buttonProps: {
|
|
25
|
+
"aria-label": "정답 등록 불가",
|
|
26
|
+
} }) })))] })) }));
|
|
23
27
|
} }));
|
|
24
28
|
}
|
|
@@ -63,15 +63,6 @@ export class ProblemSelectNode extends DecoratorNode {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
exportJSON() {
|
|
66
|
-
// 서버에서 hasMultipleSolutions를 보내주지 않으면 없는 채로 내보냅니다.
|
|
67
|
-
if (this.__hasMultipleSolutions === undefined) {
|
|
68
|
-
return {
|
|
69
|
-
type: "problem-select",
|
|
70
|
-
version: 1,
|
|
71
|
-
selections: this.__selections,
|
|
72
|
-
selected: this.__selected,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
66
|
// 서버에서 hasMultipleSolutions를 보내주면 같이 내보냅니다.
|
|
76
67
|
return {
|
|
77
68
|
type: "problem-select",
|
|
@@ -69,6 +69,8 @@ export function SelectComponent(props) {
|
|
|
69
69
|
? `${index + 1}번 선택지`
|
|
70
70
|
: selection.show.text, onClick: () => setSettingOpen(true) }, index))) })), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => {
|
|
71
71
|
setSettingOpen(true);
|
|
72
|
+
}, buttonProps: {
|
|
73
|
+
"aria-label": "선택지 설정",
|
|
72
74
|
} })] })), settingOpen && (_jsx(SettingForm, { selections: selections, nodeKey: nodeKey, onClose: () => setSettingOpen(false) }))] }));
|
|
73
75
|
}
|
|
74
76
|
const Alert = styled.div(({ theme }) => css `
|
|
@@ -2,7 +2,7 @@ import { Control, RegisterOptions } from "react-hook-form";
|
|
|
2
2
|
import { SettingFormData } from "./SettingForm";
|
|
3
3
|
export interface FormSelectionProps {
|
|
4
4
|
index: number;
|
|
5
|
-
control: Control<SettingFormData
|
|
5
|
+
control: Control<SettingFormData>;
|
|
6
6
|
rules?: Omit<RegisterOptions<SettingFormData, `selections.${number}`>, "disabled" | "valueAsNumber" | "valueAsDate" | "setValueAs">;
|
|
7
7
|
onDelete?: () => void;
|
|
8
8
|
}
|
|
@@ -39,10 +39,10 @@ export function FormSelection(props) {
|
|
|
39
39
|
: inputFocused
|
|
40
40
|
? "activePrimary"
|
|
41
41
|
: "default", value: value.show.text, onChange: (e) => onChange(Object.assign(Object.assign({}, value), { show: Object.assign(Object.assign({}, value.show), { text: e.target.value }) })), inputProps: {
|
|
42
|
-
onFocus: (
|
|
42
|
+
onFocus: () => {
|
|
43
43
|
setInputFocused(true);
|
|
44
44
|
},
|
|
45
|
-
onBlur: (
|
|
45
|
+
onBlur: () => {
|
|
46
46
|
setInputFocused(false);
|
|
47
47
|
},
|
|
48
48
|
}, placeholder: `${index + 1}번 선택지`, hintIcon: invalid ? _jsx(ErrorWarningFillIcon, {}) : undefined, hintText: error === null || error === void 0 ? void 0 : error.message, multiline: true, fullWidth: true, css: css `
|
|
@@ -54,9 +54,15 @@ export function FormSelection(props) {
|
|
|
54
54
|
align-items: center;
|
|
55
55
|
` }, { children: [_jsx(SquareButton, { color: "icon", size: "xsmall", icon: value.show.image ? _jsx(ImageEditFillIcon, {}) : _jsx(ImageAddFillIcon, {}), onClick: () => {
|
|
56
56
|
setImageOpen(true);
|
|
57
|
+
}, buttonProps: {
|
|
58
|
+
"aria-label": value.show.image
|
|
59
|
+
? "이미지 바꾸기"
|
|
60
|
+
: "이미지 삽입하기",
|
|
57
61
|
} }), _jsxs(Answer, Object.assign({ onClick: () => {
|
|
58
62
|
onChange(Object.assign(Object.assign({}, value), { isAnswer: !value.isAnswer }));
|
|
59
|
-
} }, { children: ["\uC815\uB2F5", _jsx(Switch, { checked: Boolean(value.isAnswer), size: "small" })] })), onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete
|
|
63
|
+
} }, { children: ["\uC815\uB2F5", _jsx(Switch, { checked: Boolean(value.isAnswer), size: "small" })] })), onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete, buttonProps: {
|
|
64
|
+
"aria-label": "삭제",
|
|
65
|
+
} }))] }))] }));
|
|
60
66
|
}
|
|
61
67
|
const Container = styled.div(({ theme }) => css `
|
|
62
68
|
display: flex;
|
|
@@ -4,6 +4,6 @@ import { SettingFormData } from "./SettingForm";
|
|
|
4
4
|
/** 평가 항목을 설정하는 Form입니다. */
|
|
5
5
|
export declare function FormQuestion(props: {
|
|
6
6
|
index: number;
|
|
7
|
-
control: Control<SettingFormData
|
|
7
|
+
control: Control<SettingFormData>;
|
|
8
8
|
onDelete?: () => void;
|
|
9
9
|
}): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -8,7 +8,9 @@ export function FormQuestion(props) {
|
|
|
8
8
|
const { control, index, onDelete } = props;
|
|
9
9
|
return (_jsxs(Item, { children: [_jsx(Index, { children: index + 1 }), _jsx(FormInput, { control: control, name: `evaluations.${index}.question.text`, rules: {
|
|
10
10
|
required: "필수 입력 항목입니다.",
|
|
11
|
-
}, size: "small", placeholder: `${index + 1}번 평가 항목`, multiline: true, fullWidth: true }), onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete
|
|
11
|
+
}, size: "small", placeholder: `${index + 1}번 평가 항목`, multiline: true, fullWidth: true }), onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete, buttonProps: {
|
|
12
|
+
"aria-label": "삭제",
|
|
13
|
+
} }))] }));
|
|
12
14
|
}
|
|
13
15
|
const Item = styled.div(({ theme }) => css `
|
|
14
16
|
display: flex;
|
|
@@ -51,6 +51,8 @@ export function EvaluationComponent(props) {
|
|
|
51
51
|
width: ${EVALUATION_EDIT_WIDTH}px;
|
|
52
52
|
`, data: data, evaluations: evaluations, onClick: () => setSettingOpen((open) => !open) }), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => {
|
|
53
53
|
setSettingOpen((open) => !open);
|
|
54
|
+
}, buttonProps: {
|
|
55
|
+
"aria-label": "평가 칸 설정",
|
|
54
56
|
} })] })), settingOpen && (_jsx(SettingForm, { css: css `
|
|
55
57
|
width: ${EVALUATION_EDIT_WIDTH}px;
|
|
56
58
|
`, iconType: iconType, labels: labels, evaluations: evaluations, nodeKey: nodeKey, onClose: () => setSettingOpen(false) }))] }));
|
|
@@ -58,7 +58,9 @@ export function InputComponent(props) {
|
|
|
58
58
|
` }, { children: [_jsx(VirtualInput, Object.assign({ onClick: () => setSettingOpen((open) => !open), css: multiline &&
|
|
59
59
|
css `
|
|
60
60
|
height: ${TEXTAREA_HEIGHT + 2 * INPUT_VERTICAL_PADDING}px;
|
|
61
|
-
` }, { children: multiline ? "서술형 입력 칸" : "단답형 입력 칸" })), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => setSettingOpen((open) => !open)
|
|
61
|
+
` }, { children: multiline ? "서술형 입력 칸" : "단답형 입력 칸" })), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => setSettingOpen((open) => !open), buttonProps: {
|
|
62
|
+
"aria-label": "입력 칸 설정",
|
|
63
|
+
} })] })), settingOpen && (_jsx(SettingForm, { multiline: multiline, placeholder: placeholder, nodeKey: nodeKey, onClose: () => setSettingOpen(false) }))] }));
|
|
62
64
|
}
|
|
63
65
|
const VirtualInput = styled.div(({ theme }) => css `
|
|
64
66
|
box-sizing: border-box;
|
package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectComponent.js
CHANGED
|
@@ -64,6 +64,8 @@ export function SelectComponent(props) {
|
|
|
64
64
|
? `${index + 1}번 선택지`
|
|
65
65
|
: selection.show.text, onClick: () => setSettingOpen((open) => !open) }, index))) })), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => {
|
|
66
66
|
setSettingOpen((open) => !open);
|
|
67
|
+
}, buttonProps: {
|
|
68
|
+
"aria-label": "선택지 설정",
|
|
67
69
|
} })] })), settingOpen && (_jsx(SettingForm, { data: {
|
|
68
70
|
selections,
|
|
69
71
|
allowMultipleAnswers,
|
|
@@ -4,7 +4,7 @@ import { SettingFormData } from "./SettingForm";
|
|
|
4
4
|
/** SheetSelectNode SettingForm의 단일 선택지 폼입니다. */
|
|
5
5
|
export default function FormSelection(props: {
|
|
6
6
|
index: number;
|
|
7
|
-
control: Control<SettingFormData
|
|
7
|
+
control: Control<SettingFormData>;
|
|
8
8
|
rules?: Omit<RegisterOptions<SettingFormData, `selections.${number}.show`>, "disabled" | "valueAsNumber" | "valueAsDate" | "setValueAs">;
|
|
9
9
|
onDelete?: () => void;
|
|
10
10
|
}): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -5,7 +5,7 @@ import styled from "@emotion/styled";
|
|
|
5
5
|
import { css } from "@emotion/react";
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
import { DeleteBinLineIcon, ErrorWarningFillIcon, ImageAddFillIcon, ImageEditFillIcon, Input, SquareButton, } from "../../../../../..";
|
|
8
|
-
import { InsertImageDialog
|
|
8
|
+
import { InsertImageDialog } from "../../../../components/InsertImageDialog";
|
|
9
9
|
/** SheetSelectNode SettingForm의 단일 선택지 폼입니다. */
|
|
10
10
|
export default function FormSelection(props) {
|
|
11
11
|
var _a;
|
|
@@ -37,10 +37,10 @@ export default function FormSelection(props) {
|
|
|
37
37
|
: inputFocused
|
|
38
38
|
? "activePrimary"
|
|
39
39
|
: "default", value: value.text, onChange: (e) => onChange(Object.assign(Object.assign({}, value), { text: e.target.value })), inputProps: {
|
|
40
|
-
onFocus: (
|
|
40
|
+
onFocus: () => {
|
|
41
41
|
setInputFocused(true);
|
|
42
42
|
},
|
|
43
|
-
onBlur: (
|
|
43
|
+
onBlur: () => {
|
|
44
44
|
setInputFocused(false);
|
|
45
45
|
},
|
|
46
46
|
}, placeholder: `${index + 1}번 선택지`, hintIcon: invalid ? _jsx(ErrorWarningFillIcon, {}) : undefined, hintText: error === null || error === void 0 ? void 0 : error.message, multiline: true, fullWidth: true, css: css `
|
|
@@ -53,7 +53,11 @@ export default function FormSelection(props) {
|
|
|
53
53
|
align-items: center;
|
|
54
54
|
` }, { children: [_jsx(SquareButton, { color: "icon", size: "xsmall", icon: value.image ? _jsx(ImageEditFillIcon, {}) : _jsx(ImageAddFillIcon, {}), onClick: () => {
|
|
55
55
|
setImageOpen(true);
|
|
56
|
-
}
|
|
56
|
+
}, buttonProps: {
|
|
57
|
+
"aria-label": value.image ? "이미지 바꾸기" : "이미지 삽입하기",
|
|
58
|
+
} }), onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete, buttonProps: {
|
|
59
|
+
"aria-label": "삭제",
|
|
60
|
+
} }))] }))] }));
|
|
57
61
|
}
|
|
58
62
|
const Container = styled.div(({ theme }) => css `
|
|
59
63
|
display: flex;
|