@team-monolith/cds 1.9.6 → 1.9.7

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.
@@ -51,6 +51,17 @@ export function InputComponent(props) {
51
51
  node.setAnswer(answerInput);
52
52
  });
53
53
  },
54
+ onKeyPress: (e) => {
55
+ if (e.key === "Enter") {
56
+ editor.update(() => {
57
+ const node = $getNodeByKey(nodeKey);
58
+ if (!$isProblemInputNode(node)) {
59
+ return;
60
+ }
61
+ node.setAnswer(answerInput);
62
+ });
63
+ }
64
+ },
54
65
  }, color: "default", fullWidth: true }));
55
66
  }
56
67
  }
@@ -13,9 +13,13 @@ export function FormSelection(props) {
13
13
  const { index, control, field, update, rules, onDelete } = props;
14
14
  const [imageOpen, setImageOpen] = useState(false);
15
15
  const [inputFocused, setInputFocused] = useState(false);
16
- return (_jsxs(_Fragment, { children: [_jsx(InsertImageDialog, { open: imageOpen, onClose: () => setImageOpen(false), updateImg: (props) => {
16
+ return (_jsxs(_Fragment, { children: [_jsx(InsertImageDialog, { title: field.show.image ? "이미지 바꾸기" : "이미지 삽입하기", open: imageOpen, onClose: () => setImageOpen(false), updateImg: (props) => {
17
17
  update(index, Object.assign(Object.assign({}, field), { show: Object.assign(Object.assign({}, field.show), { image: props }) }));
18
- } }), _jsxs(Container, { children: [_jsx(Index, { children: index + 1 }), _jsxs("div", Object.assign({ css: css `
18
+ }, deleteImg: field.show.image
19
+ ? () => {
20
+ update(index, Object.assign(Object.assign({}, field), { show: Object.assign(Object.assign({}, field.show), { image: undefined }) }));
21
+ }
22
+ : undefined }), _jsxs(Container, { children: [_jsx(Index, { children: index + 1 }), _jsxs("div", Object.assign({ css: css `
19
23
  display: flex;
20
24
  flex: 1;
21
25
  flex-direction: column;
@@ -1,7 +1,10 @@
1
1
  import { ImageProps } from "../ProblemSelectNode";
2
2
  export interface InsertImageDialogProps {
3
+ title: string;
3
4
  open: boolean;
4
5
  onClose: () => void;
5
6
  updateImg: (props: ImageProps) => void;
7
+ /** 전달하면 "이미지 삭제하기" 버튼이 생깁니다. */
8
+ deleteImg?: () => void;
6
9
  }
7
- export declare function InsertImageDialog(props: InsertImageDialogProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function InsertImageDialog(props: InsertImageDialogProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -7,10 +7,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
11
+ /** @jsxImportSource @emotion/react */
11
12
  import { useContext, useRef, useState } from "react";
12
13
  import styled from "@emotion/styled";
13
- import { useTheme } from "@emotion/react";
14
+ import { css, useTheme } from "@emotion/react";
14
15
  import { ImageFillIcon, LinkIcon, UploadLineIcon } from "../../../../../icons";
15
16
  import { AlertDialog, AlertDialogContent, AlertDialogTitle, } from "../../../../../components/AlertDialog";
16
17
  import Button from "../../../../../components/Button";
@@ -18,7 +19,7 @@ import { CodleDesignSystemContext } from "../../../../../CodleDesignSystemProvid
18
19
  import { InsertImageUriDialogBody } from "./InsertImageUriDialogBody";
19
20
  import { InsertImageUploadedDialogBody } from "./InsertImageUploadedDialogBody";
20
21
  export function InsertImageDialog(props) {
21
- const { open, onClose, updateImg } = props;
22
+ const { title, open, onClose, updateImg, deleteImg } = props;
22
23
  const theme = useTheme();
23
24
  const [mode, setMode] = useState(null);
24
25
  const inputRef = useRef(null);
@@ -35,20 +36,26 @@ export function InsertImageDialog(props) {
35
36
  setAltText("");
36
37
  onClose();
37
38
  };
38
- return (_jsxs(StyledAlertDialog, Object.assign({ icon: _jsx(ImageFillIcon, { color: theme.color.background.primary }), open: open, onClose: handleOnClose, disableIconPadding: true }, { children: [_jsx(StyledAlertDialogTitle, Object.assign({ onClose: handleOnClose }, { children: "\uC774\uBBF8\uC9C0 \uC0BD\uC785\uD558\uAE30" })), !mode && (_jsx(AlertDialogContent, { children: _jsxs(Buttons, { children: [_jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uC774\uBBF8\uC9C0 URL\uC744 \uC54C\uACE0 \uC788\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "URL\uB85C \uC0BD\uC785\uD558\uAE30", startIcon: _jsx(LinkIcon, {}), onClick: () => setMode("url") })] }), _jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uAC16\uACE0 \uC788\uB294 \uC774\uBBF8\uC9C0\uB97C \uC0BD\uC785\uD558\uACE0 \uC2F6\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "\uD30C\uC77C \uC120\uD0DD\uD558\uAE30", startIcon: _jsx(UploadLineIcon, {}), onClick: () => {
39
- var _a;
40
- (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
41
- } }), _jsx(HiddenInput, { ref: inputRef, type: "file", accept: "image/*", onChange: (event) => __awaiter(this, void 0, void 0, function* () {
42
- var _a, _b;
43
- const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
44
- if (!file)
45
- return;
46
- const uploadByFile = (_b = cdsContext.lexical) === null || _b === void 0 ? void 0 : _b.uploadByFile;
47
- if (uploadByFile) {
48
- setSrc(yield uploadByFile(file));
49
- setMode("file");
50
- }
51
- }) })] })] }) })), mode === "url" && (_jsx(InsertImageUriDialogBody, { src: src, setSrc: setSrc, altText: altText, setAltText: setAltText, onClick: onClick })), mode === "file" && (_jsx(InsertImageUploadedDialogBody, { src: src, setSrc: setSrc, altText: altText, setAltText: setAltText, onClick: onClick }))] })));
39
+ return (_jsxs(StyledAlertDialog, Object.assign({ icon: _jsx(ImageFillIcon, { color: theme.color.background.primary }), open: open, onClose: handleOnClose, disableIconPadding: true }, { children: [_jsx(StyledAlertDialogTitle, Object.assign({ onClose: handleOnClose }, { children: title })), !mode && (_jsx(AlertDialogContent, { children: _jsxs("div", Object.assign({ css: css `
40
+ display: flex;
41
+ flex-direction: column;
42
+ gap: 16px;
43
+ // Actions가 없는 경우 하단이 디자인과 맞지 않는다
44
+ margin-bottom: -16px;
45
+ ` }, { children: [_jsxs(Buttons, { children: [_jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uC774\uBBF8\uC9C0 URL\uC744 \uC54C\uACE0 \uC788\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "URL\uB85C \uC0BD\uC785\uD558\uAE30", startIcon: _jsx(LinkIcon, {}), onClick: () => setMode("url") })] }), _jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uAC16\uACE0 \uC788\uB294 \uC774\uBBF8\uC9C0\uB97C \uC0BD\uC785\uD558\uACE0 \uC2F6\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "\uD30C\uC77C \uC120\uD0DD\uD558\uAE30", startIcon: _jsx(UploadLineIcon, {}), onClick: () => {
46
+ var _a;
47
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
48
+ } }), _jsx(HiddenInput, { ref: inputRef, type: "file", accept: "image/*", onChange: (event) => __awaiter(this, void 0, void 0, function* () {
49
+ var _a, _b;
50
+ const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
51
+ if (!file)
52
+ return;
53
+ const uploadByFile = (_b = cdsContext.lexical) === null || _b === void 0 ? void 0 : _b.uploadByFile;
54
+ if (uploadByFile) {
55
+ setSrc(yield uploadByFile(file));
56
+ setMode("file");
57
+ }
58
+ }) })] })] }), deleteImg && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(Button, { color: "textDanger", size: "medium", fullWidth: true, label: "\uC774\uBBF8\uC9C0 \uC0AD\uC81C\uD558\uAE30", onClick: deleteImg })] }))] })) })), mode === "url" && (_jsx(InsertImageUriDialogBody, { src: src, setSrc: setSrc, altText: altText, setAltText: setAltText, onClick: onClick })), mode === "file" && (_jsx(InsertImageUploadedDialogBody, { src: src, setSrc: setSrc, altText: altText, setAltText: setAltText, onClick: onClick }))] })));
52
59
  }
53
60
  const StyledAlertDialog = styled(AlertDialog) `
54
61
  gap: 16px;
@@ -67,12 +74,15 @@ const StyledAlertDialogTitle = styled(AlertDialogTitle) `
67
74
  `;
68
75
  const Buttons = styled.div `
69
76
  display: flex;
77
+ flex: 1;
70
78
  align-items: flex-start;
71
79
  gap: 8px;
72
-
73
- // Actions가 없는 경우 하단이 디자인과 맞지 않는다
74
- margin-bottom: -16px;
75
80
  `;
81
+ const Divider = styled.div(({ theme }) => css `
82
+ width: 100%;
83
+ height: 1px;
84
+ background: ${theme.color.background.neutralAltActive};
85
+ `);
76
86
  const ButtonAndDescription = styled.div `
77
87
  display: flex;
78
88
  flex-direction: column;
@@ -8,9 +8,12 @@ import shadows from "../../../../../foundation/shadows";
8
8
  import { AddFillIcon, AlarmWarningFillIcon, ListRadioIcon, } from "../../../../../icons";
9
9
  import Button from "../../../../../components/Button";
10
10
  import { FormSelection } from "./FormSelection";
11
+ import Tooltip from "../../../../../components/Tooltip";
12
+ import { useState } from "react";
11
13
  export default function SettingForm(props) {
12
14
  const { control, handleSubmit, fields, append, remove, update, nodeKey, onClose, } = props;
13
15
  const [editor] = useLexicalComposerContext();
16
+ const [tooltipOpen, setTooltipOpen] = useState(false);
14
17
  const onSettingSubmit = (data) => {
15
18
  editor.update(() => {
16
19
  const node = $getNodeByKey(nodeKey);
@@ -32,6 +35,7 @@ export default function SettingForm(props) {
32
35
  return `${duplicatedIndex + 1}번 선택지와 같은 내용입니다.`;
33
36
  }
34
37
  const hasMultipleAnswers = fields.filter((field) => field.isAnswer).length > 1;
38
+ const hasAnswer = fields.some((field) => field.isAnswer);
35
39
  return (_jsxs(Form, Object.assign({ onSubmit: handleSubmit(onSettingSubmit) }, { children: [_jsxs(Title, { children: [_jsx(ListRadioIcon, { css: css `
36
40
  width: 12px;
37
41
  height: 12px;
@@ -53,7 +57,7 @@ export default function SettingForm(props) {
53
57
  } }), hasMultipleAnswers && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
54
58
  width: 14px;
55
59
  height: 14px;
56
- ` }), "\uC815\uB2F5\uC774 \uC5EC\uB7EC \uAC1C\uC778 \uBB38\uC81C\uC5D0\uB294 \uC815\uB2F5\uC744 \uBAA8\uB450 \uC120\uD0DD\uD574\uC57C \uD55C\uB2E4\uB294 \uC548\uB0B4\uAC00 \uC81C\uACF5\uB429\uB2C8\uB2E4."] }))] }), _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" })] })] })));
60
+ ` }), "\uC815\uB2F5\uC774 \uC5EC\uB7EC \uAC1C\uC778 \uBB38\uC81C\uC5D0\uB294 \uC815\uB2F5\uC744 \uBAA8\uB450 \uC120\uD0DD\uD574\uC57C \uD55C\uB2E4\uB294 \uC548\uB0B4\uAC00 \uC81C\uACF5\uB429\uB2C8\uB2E4."] }))] }), _jsxs(Buttons, { children: [_jsx(Button, { color: "grey", size: "xsmall", label: "\uB2EB\uAE30", onClick: onClose }), _jsx(Tooltip, Object.assign({ open: !hasAnswer && tooltipOpen, text: "\uC120\uD0DD\uC9C0 \uC911 \uC815\uB2F5\uC744 \uD45C\uC2DC\uD574\uC8FC\uC138\uC694.", onOpen: () => setTooltipOpen(true), onClose: () => setTooltipOpen(false), placement: "top-end" }, { children: _jsx("span", { children: _jsx(Button, { color: "primary", size: "xsmall", label: "\uC774\uB300\uB85C \uB123\uAE30", type: "submit", disabled: !hasAnswer }) }) }))] })] })));
57
61
  }
58
62
  const Form = styled.form(({ theme }) => css `
59
63
  display: flex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-monolith/cds",
3
- "version": "1.9.6",
3
+ "version": "1.9.7",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "sideEffects": false,