@team-monolith/cds 1.52.1 → 1.52.2
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/InputBase.d.ts +2 -0
- package/dist/components/InputBase.js +4 -1
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxEdit.d.ts +1 -2
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectComponent.js +3 -2
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/FormSelection.d.ts +4 -9
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/FormSelection.js +36 -31
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/SettingForm.d.ts +3 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/SettingForm.js +18 -29
- package/dist/patterns/LexicalEditor/nodes/SheetInputNode/InputComponent.js +2 -8
- package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectBox/SelectBoxEdit.d.ts +1 -2
- package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectComponent.js +3 -2
- package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/FormSelection.d.ts +2 -3
- package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/FormSelection.js +33 -42
- package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/SettingForm.js +17 -29
- package/package.json +1 -1
|
@@ -45,6 +45,8 @@ interface InputBaseInputProps {
|
|
|
45
45
|
}
|
|
46
46
|
interface InputBaseTextAreaProps {
|
|
47
47
|
multiline: true;
|
|
48
|
+
/** MUI TextareaAutosize 사용 여부. 전달하지 않으면 사용합니다. */
|
|
49
|
+
disableAutosize?: boolean;
|
|
48
50
|
/** HTML input 태그에 전달될 ref */
|
|
49
51
|
inputRef?: ForwardedRef<HTMLTextAreaElement>;
|
|
50
52
|
/** HTML input 태그에 전달될 props */
|
|
@@ -62,7 +62,7 @@ const SIZE_TO_STYLES = (size, fullWidth) => ({
|
|
|
62
62
|
padding-bottom: 12px;
|
|
63
63
|
${!fullWidth && "max-width: 375px"};
|
|
64
64
|
`,
|
|
65
|
-
}[size]
|
|
65
|
+
})[size];
|
|
66
66
|
function InputComponent(props) {
|
|
67
67
|
const { placeholder, disabled = false, defaultValue, value } = props;
|
|
68
68
|
const theme = useTheme();
|
|
@@ -86,6 +86,9 @@ function InputComponent(props) {
|
|
|
86
86
|
`;
|
|
87
87
|
// Type Safety 때문에 코드의 중복을 허용합니다.
|
|
88
88
|
if (props.multiline) {
|
|
89
|
+
if (props.disableAutosize) {
|
|
90
|
+
return (_jsx("textarea", Object.assign({ css: style }, props.inputProps, { ref: props.inputRef, onChange: props.onChange, placeholder: placeholder, disabled: disabled, defaultValue: defaultValue, value: value })));
|
|
91
|
+
}
|
|
89
92
|
return (_jsx(TextareaAutosize, Object.assign({ css: style }, props.inputProps, { ref: props.inputRef, onChange: props.onChange, placeholder: placeholder, disabled: disabled, defaultValue: defaultValue, value: value })));
|
|
90
93
|
}
|
|
91
94
|
else {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { ImageProps } from "../../insertImageDialog";
|
|
2
|
-
import React from "react";
|
|
3
2
|
export interface SelectBoxEditProps {
|
|
4
3
|
index: number;
|
|
5
4
|
isAnswer: boolean;
|
|
6
5
|
image?: ImageProps | null;
|
|
7
|
-
text:
|
|
6
|
+
text: string;
|
|
8
7
|
onClick: () => void;
|
|
9
8
|
}
|
|
10
9
|
export declare function SelectBoxEdit(props: SelectBoxEditProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -65,8 +65,9 @@ export function SelectComponent(props) {
|
|
|
65
65
|
display: flex;
|
|
66
66
|
flex-direction: column;
|
|
67
67
|
gap: 4px;
|
|
68
|
-
` }, { children: selections.map((selection, index) => (_jsx(SelectBoxEdit, { index: index + 1, isAnswer: "isAnswer" in selection && selection.isAnswer, image: selection.show.image, text: selection.show.text
|
|
69
|
-
|
|
68
|
+
` }, { children: selections.map((selection, index) => (_jsx(SelectBoxEdit, { index: index + 1, isAnswer: "isAnswer" in selection && selection.isAnswer, image: selection.show.image, text: selection.show.text === "" && selection.show.image === null
|
|
69
|
+
? `${index + 1}번 선택지`
|
|
70
|
+
: selection.show.text, onClick: () => setSettingOpen(true) }, index))) })), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => {
|
|
70
71
|
setSettingOpen(true);
|
|
71
72
|
} })] })), settingOpen && (_jsx(SettingForm, { selections: selections, nodeKey: nodeKey, onClose: () => setSettingOpen(false) }))] }));
|
|
72
73
|
}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Control, RegisterOptions } from "react-hook-form";
|
|
2
|
+
import { SettingFormData } from "./SettingForm";
|
|
3
3
|
export interface FormSelectionProps {
|
|
4
4
|
index: number;
|
|
5
|
-
control: Control<
|
|
6
|
-
|
|
7
|
-
}, any>;
|
|
8
|
-
watch: UseFormWatch<{
|
|
9
|
-
selections: Selection[];
|
|
10
|
-
}>;
|
|
11
|
-
rules?: any;
|
|
5
|
+
control: Control<SettingFormData, any>;
|
|
6
|
+
rules?: Omit<RegisterOptions<SettingFormData, `selections.${number}`>, "disabled" | "valueAsNumber" | "valueAsDate" | "setValueAs">;
|
|
12
7
|
onDelete?: () => void;
|
|
13
8
|
}
|
|
14
9
|
export declare function FormSelection(props: FormSelectionProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
2
|
/** @jsxImportSource @emotion/react */
|
|
3
3
|
import styled from "@emotion/styled";
|
|
4
|
-
import {
|
|
4
|
+
import { useController } from "react-hook-form";
|
|
5
5
|
import { css } from "@emotion/react";
|
|
6
6
|
import Input from "../../../../../components/Input";
|
|
7
7
|
import { DeleteBinLineIcon, ErrorWarningFillIcon, ImageAddFillIcon, ImageEditFillIcon, } from "../../../../../icons";
|
|
@@ -10,43 +10,48 @@ import Switch from "../../../../../components/Switch";
|
|
|
10
10
|
import { useState } from "react";
|
|
11
11
|
import { InsertImageDialog } from "../../insertImageDialog";
|
|
12
12
|
export function FormSelection(props) {
|
|
13
|
-
const { index, control,
|
|
13
|
+
const { index, control, rules, onDelete } = props;
|
|
14
14
|
const [imageOpen, setImageOpen] = useState(false);
|
|
15
15
|
const [inputFocused, setInputFocused] = useState(false);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
16
|
+
const { field: { value, onChange }, fieldState: { invalid, error }, } = useController({
|
|
17
|
+
control,
|
|
18
|
+
name: `selections.${index}`,
|
|
19
|
+
rules,
|
|
20
|
+
});
|
|
21
|
+
return (_jsxs(Container, { children: [_jsx(Index, { children: index + 1 }), _jsxs("div", Object.assign({ css: css `
|
|
22
|
+
display: flex;
|
|
23
|
+
flex: 1;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
gap: 4px;
|
|
26
|
+
` }, { children: [_jsx(InsertImageDialog, { title: value.show.image ? "이미지 바꾸기" : "이미지 삽입하기", open: imageOpen, onClose: () => setImageOpen(false), updateImg: (props) => onChange(Object.assign(Object.assign({}, value), { show: Object.assign(Object.assign({}, value.show), { image: props }) })), deleteButton: Boolean(value.show.image) }), value.show.image && (_jsx("img", { src: value.show.image.src, alt: value.show.image.altText, css: css `
|
|
27
|
+
height: auto;
|
|
28
|
+
// 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
|
|
29
|
+
max-width: min(400px, 100%);
|
|
30
|
+
width: fit-content;
|
|
31
|
+
border-radius: 6px;
|
|
32
|
+
`, draggable: "false" })), _jsx(Input, { size: "small", color: invalid
|
|
33
|
+
? "activeDanger"
|
|
34
|
+
: inputFocused
|
|
35
|
+
? "activePrimary"
|
|
36
|
+
: "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: {
|
|
37
|
+
onFocus: (_e) => {
|
|
38
|
+
setInputFocused(true);
|
|
39
|
+
},
|
|
40
|
+
onBlur: (_e) => {
|
|
41
|
+
setInputFocused(false);
|
|
42
|
+
},
|
|
43
|
+
}, placeholder: `${index + 1}번 선택지`, hintIcon: invalid ? _jsx(ErrorWarningFillIcon, {}) : undefined, hintText: error === null || error === void 0 ? void 0 : error.message, multiline: true, fullWidth: true, css: css `
|
|
44
|
+
flex: 1;
|
|
45
|
+
` })] })), _jsxs("div", Object.assign({ css: css `
|
|
41
46
|
display: flex;
|
|
42
47
|
height: 36px;
|
|
43
48
|
gap: 8px;
|
|
44
49
|
align-items: center;
|
|
45
|
-
` }, { children: [_jsx(SquareButton, { color: "icon", size: "xsmall", icon:
|
|
50
|
+
` }, { children: [_jsx(SquareButton, { color: "icon", size: "xsmall", icon: value.show.image ? _jsx(ImageEditFillIcon, {}) : _jsx(ImageAddFillIcon, {}), onClick: () => {
|
|
46
51
|
setImageOpen(true);
|
|
47
|
-
} }),
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
} }), _jsxs(Answer, Object.assign({ onClick: () => {
|
|
53
|
+
onChange(Object.assign(Object.assign({}, value), { isAnswer: !value.isAnswer }));
|
|
54
|
+
} }, { children: ["\uC815\uB2F5", _jsx(Switch, { checked: Boolean(value.isAnswer), size: "small" })] })), onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete }))] }))] }));
|
|
50
55
|
}
|
|
51
56
|
const Container = styled.div(({ theme }) => css `
|
|
52
57
|
display: flex;
|
|
@@ -38,33 +38,25 @@ export default function SettingForm(props) {
|
|
|
38
38
|
});
|
|
39
39
|
onClose();
|
|
40
40
|
};
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
const selection = selections[index];
|
|
44
|
-
if (selection.show.image || selection.show.text)
|
|
41
|
+
function validateRequired(value) {
|
|
42
|
+
if (value.show.image || value.show.text)
|
|
45
43
|
return true;
|
|
46
44
|
return "필수 입력 항목입니다.";
|
|
47
45
|
}
|
|
48
|
-
function
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
.findIndex((selection) => {
|
|
57
|
-
var _a;
|
|
58
|
-
// text를 비교하고, text가 같은 경우 image도 비교합니다.
|
|
59
|
-
if (selection.show.text !== text)
|
|
60
|
-
return false;
|
|
61
|
-
if (((_a = selection.show.image) === null || _a === void 0 ? void 0 : _a.src) !== (image === null || image === void 0 ? void 0 : image.src))
|
|
62
|
-
return false;
|
|
63
|
-
return true;
|
|
46
|
+
function validateDuplicated(value, formValues) {
|
|
47
|
+
const shows = formValues.selections.map((selection) => selection.show);
|
|
48
|
+
const duplicatedIndexes = shows.flatMap((show, i) => {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
if (show.text === value.show.text &&
|
|
51
|
+
((_a = show.image) === null || _a === void 0 ? void 0 : _a.src) === ((_b = value.show.image) === null || _b === void 0 ? void 0 : _b.src))
|
|
52
|
+
return [i];
|
|
53
|
+
return [];
|
|
64
54
|
});
|
|
65
|
-
if (
|
|
55
|
+
if (duplicatedIndexes.length < 2)
|
|
66
56
|
return true;
|
|
67
|
-
return `${
|
|
57
|
+
return `${duplicatedIndexes
|
|
58
|
+
.map((i) => i + 1)
|
|
59
|
+
.join(",")}번 선택지가 같은 내용입니다.`;
|
|
68
60
|
}
|
|
69
61
|
const answersCount = watch("selections").filter((selection) => selection.isAnswer).length;
|
|
70
62
|
const hasMultipleAnswers = answersCount > 1;
|
|
@@ -72,13 +64,10 @@ export default function SettingForm(props) {
|
|
|
72
64
|
return (_jsxs(Form, Object.assign({ onSubmit: handleSubmit(onSettingSubmit) }, { children: [_jsxs(Title, { children: [_jsx(ListRadioIcon, { css: css `
|
|
73
65
|
width: 12px;
|
|
74
66
|
height: 12px;
|
|
75
|
-
` }), "\uAC1D\uAD00\uC2DD \uC785\uB825 \uCE78"] }), _jsxs(Content, { children: [_jsxs(FormArea, { children: [_jsx(Label, { children: "\uB2F5\uC548" }), fields.map((field, index) => (_jsx(FormSelection, { index: index, control: control,
|
|
76
|
-
validate:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return required;
|
|
80
|
-
}
|
|
81
|
-
return validateDuplicatedSelection(index);
|
|
67
|
+
` }), "\uAC1D\uAD00\uC2DD \uC785\uB825 \uCE78"] }), _jsxs(Content, { children: [_jsxs(FormArea, { children: [_jsx(Label, { children: "\uB2F5\uC548" }), fields.map((field, index) => (_jsx(FormSelection, { index: index, control: control, rules: {
|
|
68
|
+
validate: {
|
|
69
|
+
validateRequired,
|
|
70
|
+
validateDuplicated,
|
|
82
71
|
},
|
|
83
72
|
}, onDelete: index !== 0
|
|
84
73
|
? () => {
|
|
@@ -37,15 +37,9 @@ export function InputComponent(props) {
|
|
|
37
37
|
};
|
|
38
38
|
// view
|
|
39
39
|
if (!isEditable) {
|
|
40
|
-
return (_jsx(Input, { multiline: multiline, css: css `
|
|
40
|
+
return (_jsx(Input, { multiline: multiline, disableAutosize: true, css: css `
|
|
41
41
|
textarea {
|
|
42
|
-
|
|
43
|
-
max-height: ${TEXTAREA_HEIGHT}px;
|
|
44
|
-
min-height: ${TEXTAREA_HEIGHT}px;
|
|
45
|
-
// https://github.com/mui/material-ui/blob/next/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx
|
|
46
|
-
// MUI TextareaAutoSize는 overflow를 hidden으로 설정하는 로직이 있습니다.
|
|
47
|
-
// 그래서 부득이하게 !important를 사용합니다.
|
|
48
|
-
overflow: auto !important;
|
|
42
|
+
height: ${TEXTAREA_HEIGHT}px;
|
|
49
43
|
}
|
|
50
44
|
`, inputProps: freezeProblemNode
|
|
51
45
|
? { readOnly: true }
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { ImageProps } from "../../../insertImageDialog";
|
|
3
2
|
/** SheetSelectNode의 하나의 선택지 edit모드 컴포넌트입니다. */
|
|
4
3
|
export declare function SelectBoxEdit(props: {
|
|
5
4
|
index: number;
|
|
6
5
|
image?: ImageProps | null;
|
|
7
|
-
text:
|
|
6
|
+
text: string;
|
|
8
7
|
onClick: () => void;
|
|
9
8
|
}): import("react/jsx-runtime").JSX.Element;
|
package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectComponent.js
CHANGED
|
@@ -60,8 +60,9 @@ export function SelectComponent(props) {
|
|
|
60
60
|
display: flex;
|
|
61
61
|
flex-direction: column;
|
|
62
62
|
gap: 4px;
|
|
63
|
-
` }, { children: selections.map((selection, index) => (_jsx(SelectBoxEdit, { index: index + 1, image: selection.show.image, text: selection.show.text
|
|
64
|
-
|
|
63
|
+
` }, { children: selections.map((selection, index) => (_jsx(SelectBoxEdit, { index: index + 1, image: selection.show.image, text: selection.show.text === "" && selection.show.image === null
|
|
64
|
+
? `${index + 1}번 선택지`
|
|
65
|
+
: selection.show.text, onClick: () => setSettingOpen((open) => !open) }, index))) })), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => {
|
|
65
66
|
setSettingOpen((open) => !open);
|
|
66
67
|
} })] })), settingOpen && (_jsx(SettingForm, { data: {
|
|
67
68
|
selections,
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/** @jsxImportSource @emotion/react */
|
|
2
|
-
import { Control,
|
|
2
|
+
import { Control, RegisterOptions } from "react-hook-form";
|
|
3
3
|
import { SettingFormData } from "./SettingForm";
|
|
4
4
|
/** SheetSelectNode SettingForm의 단일 선택지 폼입니다. */
|
|
5
5
|
export default function FormSelection(props: {
|
|
6
6
|
index: number;
|
|
7
7
|
control: Control<SettingFormData, any>;
|
|
8
|
-
|
|
9
|
-
rules?: any;
|
|
8
|
+
rules?: Omit<RegisterOptions<SettingFormData, `selections.${number}.show`>, "disabled" | "valueAsNumber" | "valueAsDate" | "setValueAs">;
|
|
10
9
|
onDelete?: () => void;
|
|
11
10
|
}): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -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 {
|
|
3
|
+
import { useController } from "react-hook-form";
|
|
4
4
|
import styled from "@emotion/styled";
|
|
5
5
|
import { css } from "@emotion/react";
|
|
6
6
|
import { useState } from "react";
|
|
@@ -8,40 +8,45 @@ import { InsertImageDialog } from "../../../insertImageDialog";
|
|
|
8
8
|
import { DeleteBinLineIcon, ErrorWarningFillIcon, ImageAddFillIcon, ImageEditFillIcon, Input, SquareButton, } from "../../../../../..";
|
|
9
9
|
/** SheetSelectNode SettingForm의 단일 선택지 폼입니다. */
|
|
10
10
|
export default function FormSelection(props) {
|
|
11
|
-
const { index, control,
|
|
11
|
+
const { index, control, rules, onDelete } = props;
|
|
12
12
|
const [imageOpen, setImageOpen] = useState(false);
|
|
13
13
|
const [inputFocused, setInputFocused] = useState(false);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
14
|
+
const { field: { value, onChange }, fieldState: { invalid, error }, } = useController({
|
|
15
|
+
control,
|
|
16
|
+
name: `selections.${index}.show`,
|
|
17
|
+
rules,
|
|
18
|
+
});
|
|
19
|
+
return (_jsxs(Container, { children: [_jsx(Index, { children: index + 1 }), _jsxs("div", Object.assign({ css: css `
|
|
20
|
+
display: flex;
|
|
21
|
+
flex: 1;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
gap: 4px;
|
|
24
|
+
` }, { children: [_jsx(InsertImageDialog, { title: value.image ? "이미지 바꾸기" : "이미지 삽입하기", open: imageOpen, onClose: () => setImageOpen(false), updateImg: (props) => onChange(Object.assign(Object.assign({}, value), { image: props })), deleteButton: Boolean(value.image) }), value.image && (_jsx("img", { src: value.image.src, alt: value.image.altText, css: css `
|
|
25
|
+
height: auto;
|
|
26
|
+
// 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
|
|
27
|
+
max-width: min(400px, 100%);
|
|
28
|
+
width: fit-content;
|
|
29
|
+
border-radius: 6px;
|
|
30
|
+
`, draggable: "false" })), _jsx(Input, { size: "small", color: invalid
|
|
31
|
+
? "activeDanger"
|
|
32
|
+
: inputFocused
|
|
33
|
+
? "activePrimary"
|
|
34
|
+
: "default", value: value.text, onChange: (e) => onChange(Object.assign(Object.assign({}, value), { text: e.target.value })), inputProps: {
|
|
35
|
+
onFocus: (_e) => {
|
|
36
|
+
setInputFocused(true);
|
|
37
|
+
},
|
|
38
|
+
onBlur: (_e) => {
|
|
39
|
+
setInputFocused(false);
|
|
40
|
+
},
|
|
41
|
+
}, placeholder: `${index + 1}번 선택지`, hintIcon: invalid ? _jsx(ErrorWarningFillIcon, {}) : undefined, hintText: error === null || error === void 0 ? void 0 : error.message, multiline: true, fullWidth: true, css: css `
|
|
42
|
+
flex: 1;
|
|
43
|
+
` })] })), _jsxs("div", Object.assign({ css: css `
|
|
39
44
|
display: flex;
|
|
40
45
|
// 이미지가 들어가서 container height가 커져도 높이가 유지되도록 설정
|
|
41
46
|
height: 36px;
|
|
42
47
|
gap: 8px;
|
|
43
48
|
align-items: center;
|
|
44
|
-
` }, { children: [_jsx(SquareButton, { color: "icon", size: "xsmall", icon:
|
|
49
|
+
` }, { children: [_jsx(SquareButton, { color: "icon", size: "xsmall", icon: value.image ? _jsx(ImageEditFillIcon, {}) : _jsx(ImageAddFillIcon, {}), onClick: () => {
|
|
45
50
|
setImageOpen(true);
|
|
46
51
|
} }), onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete }))] }))] }));
|
|
47
52
|
}
|
|
@@ -70,17 +75,3 @@ const Index = styled.div(({ theme }) => css `
|
|
|
70
75
|
font-weight: 800;
|
|
71
76
|
line-height: 16px;
|
|
72
77
|
`);
|
|
73
|
-
const Answer = styled.div(({ theme }) => css `
|
|
74
|
-
display: flex;
|
|
75
|
-
align-items: center;
|
|
76
|
-
padding-right: 4px;
|
|
77
|
-
gap: 8px;
|
|
78
|
-
color: ${theme.color.foreground.neutralBase};
|
|
79
|
-
cursor: pointer;
|
|
80
|
-
/* Default/Label/14px-Md */
|
|
81
|
-
font-family: ${theme.fontFamily.ui};
|
|
82
|
-
font-size: 14px;
|
|
83
|
-
font-style: normal;
|
|
84
|
-
font-weight: 500;
|
|
85
|
-
line-height: 16px; /* 114.286% */
|
|
86
|
-
`);
|
package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/SettingForm.js
CHANGED
|
@@ -38,44 +38,32 @@ export function SettingForm(props) {
|
|
|
38
38
|
});
|
|
39
39
|
onClose();
|
|
40
40
|
};
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
const selection = selections[index];
|
|
44
|
-
if (selection.show.image || selection.show.text)
|
|
41
|
+
function validateRequired(value) {
|
|
42
|
+
if (value.image || value.text)
|
|
45
43
|
return true;
|
|
46
44
|
return "필수 입력 항목입니다.";
|
|
47
45
|
}
|
|
48
|
-
function
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
.slice(0, index)
|
|
56
|
-
.findIndex((selection) => {
|
|
57
|
-
var _a;
|
|
58
|
-
// text를 비교하고, text가 같은 경우 image도 비교합니다.
|
|
59
|
-
if (selection.show.text !== text)
|
|
60
|
-
return false;
|
|
61
|
-
if (((_a = selection.show.image) === null || _a === void 0 ? void 0 : _a.src) !== (image === null || image === void 0 ? void 0 : image.src))
|
|
62
|
-
return false;
|
|
63
|
-
return true;
|
|
46
|
+
function validateDuplicated(value, formValues) {
|
|
47
|
+
const shows = formValues.selections.map((selection) => selection.show);
|
|
48
|
+
const duplicatedIndexes = shows.flatMap((show, i) => {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
if (show.text === value.text && ((_a = show.image) === null || _a === void 0 ? void 0 : _a.src) === ((_b = value.image) === null || _b === void 0 ? void 0 : _b.src))
|
|
51
|
+
return [i];
|
|
52
|
+
return [];
|
|
64
53
|
});
|
|
65
|
-
if (
|
|
54
|
+
if (duplicatedIndexes.length < 2)
|
|
66
55
|
return true;
|
|
67
|
-
return `${
|
|
56
|
+
return `${duplicatedIndexes
|
|
57
|
+
.map((i) => i + 1)
|
|
58
|
+
.join(",")}번 선택지가 같은 내용입니다.`;
|
|
68
59
|
}
|
|
69
60
|
return (_jsxs(Form, Object.assign({ onSubmit: handleSubmit(onSettingSubmit) }, { children: [_jsxs(Title, { children: [_jsx(ListRadioIcon, { css: css `
|
|
70
61
|
width: 12px;
|
|
71
62
|
height: 12px;
|
|
72
|
-
` }), "\uC120\uD0DD\uD615 \uC785\uB825 \uCE78"] }), _jsxs(Content, { children: [_jsxs(Left, { children: [_jsxs(FormArea, { children: [_jsx(Label, { children: "\uC120\uD0DD\uC9C0" }), fields.map((field, index) => (_jsx(FormSelection, { index: index, control: control,
|
|
73
|
-
validate:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return required;
|
|
77
|
-
}
|
|
78
|
-
return validateDuplicatedSelection(index);
|
|
63
|
+
` }), "\uC120\uD0DD\uD615 \uC785\uB825 \uCE78"] }), _jsxs(Content, { children: [_jsxs(Left, { children: [_jsxs(FormArea, { children: [_jsx(Label, { children: "\uC120\uD0DD\uC9C0" }), fields.map((field, index) => (_jsx(FormSelection, { index: index, control: control, rules: {
|
|
64
|
+
validate: {
|
|
65
|
+
validateRequired,
|
|
66
|
+
validateDuplicated,
|
|
79
67
|
},
|
|
80
68
|
}, onDelete: index !== 0
|
|
81
69
|
? () => {
|