@team-monolith/cds 1.8.7 → 1.8.8

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.
@@ -32,7 +32,10 @@ export function InputComponent(props) {
32
32
  // 학생 view
33
33
  // TODO: "글자 수대로" 옵션시에 글자 수대로 입력칸을 표시해야 합니다.
34
34
  if (!isEditable) {
35
- return (_jsx(Input, { size: "small", placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: (e) => setAnswerInput(e.target.value), inputProps: {
35
+ return (_jsx(Input, { size: "small", placeholder: placeholder || "여기에 입력하세요.", value: answerInput, onChange: (e) => setAnswerInput(e.target.value),
36
+ // 한글 입력시에 onChange마다 update가 일어나는 것을 방지하기 위해 입력 완료후 onBlur시에 update하는 전략을 사용합니다.
37
+ // 이를 위해 answerInput을 state로 관리합니다.
38
+ inputProps: {
36
39
  onBlur: (_e) => {
37
40
  editor.update(() => {
38
41
  const node = $getNodeByKey(nodeKey);
@@ -1,9 +1,9 @@
1
1
  import { Control } from "react-hook-form";
2
2
  import { ProblemInputPayload } from "../ProblemInputNode";
3
- export interface FormAnswerProps {
3
+ export interface FormSolutionProps {
4
4
  index: number;
5
5
  control: Control<ProblemInputPayload, any>;
6
6
  rules?: any;
7
7
  onDelete?: () => void;
8
8
  }
9
- export declare function FormSolution(props: FormAnswerProps): import("@emotion/react/jsx-runtime").JSX.Element;
9
+ export declare function FormSolution(props: FormSolutionProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -2,39 +2,21 @@ import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
2
2
  /** @jsxImportSource @emotion/react */
3
3
  import { css, useTheme } from "@emotion/react";
4
4
  import { Controller } from "react-hook-form";
5
- import Dropdown from "../../../../Dropdown";
6
- import DropdownItem from "../../../../Dropdown/DropdownItem";
7
5
  import Input from "../../../../../components/Input";
8
6
  import { AlertFillIcon, DeleteBinLineIcon, ErrorWarningFillIcon, } from "../../../../../icons";
9
7
  import SquareButton from "../../../../../components/SquareButton";
10
8
  import Tooltip from "../../../../../components/Tooltip";
9
+ import TextTypeDropdown from "./TextTypeDropdown";
11
10
  export function FormSolution(props) {
12
11
  const { index, control, rules, onDelete } = props;
13
12
  const theme = useTheme();
14
- const TextTypeDropdown = (disabled) => (_jsx(Controller, { name: `solutions.${index}.textType`, control: control, render: ({ field: { value, onChange } }) => (_jsx(Dropdown, Object.assign({ label: value === "normal" ? "일반 텍스트" : "코드 텍스트", size: "xsmall", color: "textNeutral", closeOnItemClick: true, disabled: disabled, buttonCss: css `
15
- ${disabled && `color: ${theme.color.foreground.neutralAlt};`}
16
- > span {
17
- font-weight: 700;
18
- }
19
- `, menuProps: {
20
- anchorOrigin: {
21
- vertical: "bottom",
22
- horizontal: "center",
23
- },
24
- transformOrigin: {
25
- vertical: "top",
26
- horizontal: "center",
27
- },
28
- } }, { children: _jsx(DropdownItem, { index: 0, label: value === "normal" ? "코드 텍스트" : "일반 텍스트", onClick: () => {
29
- onChange(value === "normal" ? "code" : "normal");
30
- } }) }))) }));
31
13
  return (_jsx(Controller, { name: `solutions.${index}.value`, control: control, rules: rules, render: ({ field: { value, onChange }, fieldState: { invalid, error }, }) => {
32
- const disabled = (error === null || error === void 0 ? void 0 : error.type) === "multiAnswerDisabled";
14
+ const disabled = (error === null || error === void 0 ? void 0 : error.type) === "enabled";
33
15
  return (_jsx(Input, { size: "small", color: invalid ? "activeDanger" : "default", onChange: onChange, disabled: disabled, value: value, hintIcon: !disabled && invalid ? _jsx(ErrorWarningFillIcon, {}) : undefined, hintText: !disabled ? error === null || error === void 0 ? void 0 : error.message : undefined, placeholder: "\uC548\uB155\uD558\uC138\uC694", fullWidth: true, css: css `
34
16
  > div {
35
17
  padding: 4px 12px;
36
18
  }
37
- `, startIcon: TextTypeDropdown(disabled), endIcon: _jsxs("div", Object.assign({ css: css `
19
+ `, startIcon: _jsx(TextTypeDropdown, { index: index, control: control, disabled: disabled }), endIcon: _jsxs("div", Object.assign({ css: css `
38
20
  display: flex;
39
21
  gap: 4px;
40
22
  ` }, { children: [onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete })), 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 }) })))] })) }));
@@ -4,7 +4,7 @@ import { css, useTheme } from "@emotion/react";
4
4
  import styled from "@emotion/styled";
5
5
  import shadows from "../../../../../foundation/shadows";
6
6
  import { AddFillIcon, AlarmWarningFillIcon, InputMethodLineIcon, QuestionFillIcon, } from "../../../../../icons";
7
- import { useFieldArray, useForm, } from "react-hook-form";
7
+ import { useFieldArray, useForm } from "react-hook-form";
8
8
  import { $isProblemInputNode, } from "../ProblemInputNode";
9
9
  import { FormSolution } from "./FormSolution";
10
10
  import Button from "../../../../../components/Button";
@@ -42,15 +42,15 @@ export default function SettingForm(props) {
42
42
  });
43
43
  onClose();
44
44
  };
45
- const multiAnswerDisabled = watch("showCharacterCount");
45
+ const multipleSolutionsDisabled = watch("showCharacterCount");
46
46
  return (_jsxs(Form, Object.assign({ onSubmit: handleSubmit(onSettingSubmit) }, { children: [_jsxs(Title, { children: [_jsx(InputMethodLineIcon, { css: css `
47
47
  width: 12px;
48
48
  height: 12px;
49
49
  ` }), "\uC8FC\uAD00\uC2DD \uC785\uB825 \uCE78"] }), _jsxs(Content, { children: [_jsxs(Left, { children: [_jsxs(FormArea, { children: [_jsx(Label, { children: "\uC815\uB2F5" }), fields.map((field, index) => (_jsx(FormSolution, { index: index, control: control, rules: {
50
50
  validate: {
51
51
  // required 옵션보다 먼저 검증되어야 하는데 priority 옵션이 없어서 validate에서 통합해서 검증합니다.
52
- multiAnswerDisabled: () => index === 0 ||
53
- !multiAnswerDisabled ||
52
+ enabled: () => index === 0 ||
53
+ !multipleSolutionsDisabled ||
54
54
  "복수 정답이 불가능합니다.",
55
55
  required: (value) => value !== "" || "정답을 입력해주세요.",
56
56
  },
@@ -58,7 +58,7 @@ export default function SettingForm(props) {
58
58
  ? () => {
59
59
  remove(index);
60
60
  }
61
- : undefined }, field.uid)))] }), _jsx(Button, { color: "grey", size: "small", startIcon: _jsx(AddFillIcon, {}), label: "\uBCF5\uC218 \uC815\uB2F5 \uCD94\uAC00", disabled: multiAnswerDisabled, onClick: () => {
61
+ : undefined }, field.uid)))] }), _jsx(Button, { color: "grey", size: "small", startIcon: _jsx(AddFillIcon, {}), label: "\uBCF5\uC218 \uC815\uB2F5 \uCD94\uAC00", disabled: multipleSolutionsDisabled, onClick: () => {
62
62
  append({
63
63
  textType: "normal",
64
64
  value: "",
@@ -0,0 +1,7 @@
1
+ import { Control } from "react-hook-form";
2
+ import { ProblemInputPayload } from "../ProblemInputNode";
3
+ export default function TextTypeDropdown(props: {
4
+ index: number;
5
+ control: Control<ProblemInputPayload, any>;
6
+ disabled: boolean;
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Controller } from "react-hook-form";
3
+ import Dropdown from "../../../../Dropdown";
4
+ import { css, useTheme } from "@emotion/react";
5
+ import DropdownItem from "../../../../Dropdown/DropdownItem";
6
+ export default function TextTypeDropdown(props) {
7
+ const theme = useTheme();
8
+ const { index, control, disabled } = props;
9
+ return (_jsx(Controller, { name: `solutions.${index}.textType`, control: control, render: ({ field: { value, onChange } }) => (_jsx(Dropdown, Object.assign({ label: value === "normal" ? "일반 텍스트" : "코드 텍스트", size: "xsmall", color: "textNeutral", closeOnItemClick: true, disabled: disabled, buttonCss: css `
10
+ ${disabled && `color: ${theme.color.foreground.neutralAlt};`}
11
+ > span {
12
+ font-weight: 700;
13
+ }
14
+ `, menuProps: {
15
+ anchorOrigin: {
16
+ vertical: "bottom",
17
+ horizontal: "center",
18
+ },
19
+ transformOrigin: {
20
+ vertical: "top",
21
+ horizontal: "center",
22
+ },
23
+ } }, { children: _jsx(DropdownItem, { index: 0, label: value === "normal" ? "코드 텍스트" : "일반 텍스트", onClick: () => {
24
+ onChange(value === "normal" ? "code" : "normal");
25
+ } }) }))) }));
26
+ }
@@ -22,7 +22,7 @@ import ReactDOM, { createPortal } from "react-dom";
22
22
  import { LexicalNodeMenuPlugin } from "@lexical/react/LexicalNodeMenuPlugin";
23
23
  import { useDraggableBlockMenu } from "./useDraggableBlockMenu";
24
24
  import { css as cssToClassName } from "@emotion/css";
25
- import { ComponentPickerMenuList, getBaseOptions, ComponentDrawerOption, } from "../ComponentPickerMenuPlugin";
25
+ import { ComponentPickerOption, ComponentPickerMenuList, getBaseOptions, ComponentDrawerOption, } from "../ComponentPickerMenuPlugin";
26
26
  import { useFloatingMenu } from "./useFloatingMenu";
27
27
  import ComponentAdder from "./ComponentAdder";
28
28
  import styled from "@emotion/styled";
@@ -137,7 +137,7 @@ export function ComponentAdderPlugin(props) {
137
137
  return true;
138
138
  }
139
139
  const regex = new RegExp(query, "i");
140
- return (option.keywords &&
140
+ return (option instanceof ComponentPickerOption &&
141
141
  (regex.test(option.title) ||
142
142
  option.keywords.some((keyword) => regex.test(keyword))));
143
143
  });
@@ -13,8 +13,7 @@ import { Theme } from "@emotion/react";
13
13
  export declare class ComponentDrawerOption extends MenuOption {
14
14
  title: string;
15
15
  component: ReactElement;
16
- keywords?: Array<string>;
17
- constructor(title: string, component: ReactElement, keywords?: Array<string>);
16
+ constructor(title: string, component: ReactElement);
18
17
  }
19
18
  export declare class ComponentPickerOption extends MenuOption {
20
19
  title: string;
@@ -29,11 +29,10 @@ import { INSERT_PROBLEM_INPUT_COMMAND } from "../ProblemInputPlugin";
29
29
  // import catTypingGif from "../../images/cat-typing.gif";
30
30
  // import { INSERT_IMAGE_COMMAND, InsertImageDialog } from "../ImagesPlugin";
31
31
  export class ComponentDrawerOption extends MenuOption {
32
- constructor(title, component, keywords) {
32
+ constructor(title, component) {
33
33
  super(title);
34
34
  this.title = title;
35
35
  this.component = component;
36
- this.keywords = keywords;
37
36
  }
38
37
  }
39
38
  export class ComponentPickerOption extends MenuOption {
@@ -205,7 +204,7 @@ export function ComponentPickerMenuPlugin() {
205
204
  const regex = new RegExp(queryString, "i");
206
205
  return [
207
206
  ...getDynamicOptions(editor, queryString),
208
- ...baseOptions.filter((option) => option.keywords &&
207
+ ...baseOptions.filter((option) => option instanceof ComponentPickerOption &&
209
208
  (regex.test(option.title) ||
210
209
  option.keywords.some((keyword) => regex.test(keyword)))),
211
210
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-monolith/cds",
3
- "version": "1.8.7",
3
+ "version": "1.8.8",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "sideEffects": false,