@team-monolith/cds 1.9.4 → 1.9.6

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.
@@ -2,6 +2,7 @@
2
2
  import { SerializedEditorState, SerializedLexicalNode } from "lexical";
3
3
  export interface LexicalEditorProps {
4
4
  className?: string;
5
+ contentEditableClassName?: string;
5
6
  value?: any;
6
7
  onChange?: (blocks: SerializedEditorState<SerializedLexicalNode>) => void;
7
8
  /** editable. 수정 모드 / 읽기 모드 여부
@@ -30,7 +30,7 @@ function validateValue(value) {
30
30
  return true;
31
31
  }
32
32
  export function LexicalEditor(props) {
33
- const { className, value, onChange, editable = true, freezeProblemNode, children, } = props;
33
+ const { className, contentEditableClassName, value, onChange, editable = true, freezeProblemNode, children, } = props;
34
34
  const theme = useTheme();
35
35
  const initialConfig = {
36
36
  namespace: "CodleLexicalEditor",
@@ -63,5 +63,5 @@ export function LexicalEditor(props) {
63
63
  editorState: validateValue(value) ? JSON.stringify(value) : undefined,
64
64
  editable: editable,
65
65
  };
66
- return (_jsx(LexicalCustomConfigContext.Provider, Object.assign({ value: { freezeProblemNode: freezeProblemNode !== null && freezeProblemNode !== void 0 ? freezeProblemNode : false } }, { children: _jsxs(LexicalComposer, Object.assign({ initialConfig: initialConfig }, { children: [_jsx(Plugins, { className: className, onChange: onChange }), _jsx(_Fragment, { children: children })] })) })));
66
+ return (_jsx(LexicalCustomConfigContext.Provider, Object.assign({ value: { freezeProblemNode: freezeProblemNode !== null && freezeProblemNode !== void 0 ? freezeProblemNode : false } }, { children: _jsxs(LexicalComposer, Object.assign({ initialConfig: initialConfig }, { children: [_jsx(Plugins, { className: className, contentEditableClassName: contentEditableClassName, onChange: onChange }), _jsx(_Fragment, { children: children })] })) })));
67
67
  }
@@ -6,6 +6,7 @@ import { ReactElement } from "react";
6
6
  import { SerializedEditorState, SerializedLexicalNode } from "lexical";
7
7
  export interface PluginsProps {
8
8
  className?: string;
9
+ contentEditableClassName?: string;
9
10
  onChange?: (blocks: SerializedEditorState<SerializedLexicalNode>) => void;
10
11
  }
11
12
  export default function Plugins(props: PluginsProps): ReactElement;
@@ -30,7 +30,7 @@ import styled from "@emotion/styled";
30
30
  import ProblemInputPlugin from "./plugins/ProblemInputPlugin";
31
31
  import ProblemSelectPlugin from "./plugins/ProblemSelectPlugin";
32
32
  export default function Plugins(props) {
33
- const { className, onChange } = props;
33
+ const { className, contentEditableClassName, onChange } = props;
34
34
  const isEditable = useLexicalEditable();
35
35
  const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);
36
36
  const [isLinkEditMode, setIsLinkEditMode] = useState(false);
@@ -39,7 +39,7 @@ export default function Plugins(props) {
39
39
  setFloatingAnchorElem(_floatingAnchorElem);
40
40
  }
41
41
  };
42
- return (_jsxs(_Fragment, { children: [_jsx(RichTextPlugin, { contentEditable: _jsx(ScrollArea, Object.assign({ className: className }, { children: _jsx(FloatingAnchor, Object.assign({ ref: onRef }, { children: _jsx(StyledContentEditable, { isEditable: isEditable }) })) })), placeholder: null, ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: (editorState) => {
42
+ return (_jsxs(_Fragment, { children: [_jsx(RichTextPlugin, { contentEditable: _jsx(ScrollArea, Object.assign({ className: className }, { children: _jsx(FloatingAnchor, Object.assign({ ref: onRef }, { children: _jsx(StyledContentEditable, { className: contentEditableClassName, isEditable: isEditable }) })) })), placeholder: null, ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: (editorState) => {
43
43
  onChange === null || onChange === void 0 ? void 0 : onChange(editorState.toJSON());
44
44
  },
45
45
  // ignore 하지 않으면 Form에서 수정하지 않았는데 Dirty로 처리됨.
@@ -22,7 +22,7 @@ import useLexicalEditable from "@lexical/react/useLexicalEditable";
22
22
  import { $isProblemInputNode } from "./ProblemInputNode";
23
23
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
24
24
  import { $getNodeByKey } from "lexical";
25
- import { LexicalCustomConfigContext, } from "../../LexicalCustomConfigContext";
25
+ import { LexicalCustomConfigContext } from "../../LexicalCustomConfigContext";
26
26
  export function InputComponent(props) {
27
27
  const { answer } = props, settingFormProps = __rest(props, ["answer"]);
28
28
  const { placeholder, nodeKey } = settingFormProps;
@@ -15,6 +15,7 @@ export interface Selection {
15
15
  export interface ProblemSelectPayload {
16
16
  selections: Selection[];
17
17
  selected: string[];
18
+ hasMultipleAnswers?: boolean;
18
19
  key?: NodeKey;
19
20
  }
20
21
  export type SerializedProblemSelectNode = Spread<ProblemSelectPayload, SerializedLexicalNode>;
@@ -25,6 +26,7 @@ export type SerializedProblemSelectNode = Spread<ProblemSelectPayload, Serialize
25
26
  export declare class ProblemSelectNode extends DecoratorNode<ReactNode> {
26
27
  __selections: Selection[];
27
28
  __selected: string[];
29
+ __hasMultipleAnswers: boolean | undefined;
28
30
  isInline(): boolean;
29
31
  static getType(): string;
30
32
  getSelections(): Selection[];
@@ -32,12 +34,12 @@ export declare class ProblemSelectNode extends DecoratorNode<ReactNode> {
32
34
  setSolutions(selections: Selection[]): void;
33
35
  setSelected(selected: string[]): void;
34
36
  static clone(node: ProblemSelectNode): ProblemSelectNode;
35
- constructor(selections: Selection[], selected: string[], key?: NodeKey);
37
+ constructor(selections: Selection[], selected: string[], hasMultipleAnswers?: boolean, key?: NodeKey);
36
38
  createDOM(config: EditorConfig): HTMLElement;
37
39
  updateDOM(): boolean;
38
40
  static importJSON(serializedNode: SerializedProblemSelectNode): ProblemSelectNode;
39
41
  exportJSON(): SerializedProblemSelectNode;
40
42
  decorate(): ReactNode;
41
43
  }
42
- export declare function $createProblemSelectNode({ selections, selected, key, }: ProblemSelectPayload): ProblemSelectNode;
44
+ export declare function $createProblemSelectNode({ selections, selected, hasMultipleAnswers, key, }: ProblemSelectPayload): ProblemSelectNode;
43
45
  export declare function $isProblemSelectNode(node: LexicalNode | null | undefined): node is ProblemSelectNode;
@@ -28,12 +28,13 @@ export class ProblemSelectNode extends DecoratorNode {
28
28
  self.__selected = selected;
29
29
  }
30
30
  static clone(node) {
31
- return new ProblemSelectNode(node.__selections, node.__selected, node.__key);
31
+ return new ProblemSelectNode(node.__selections, node.__selected, node.__hasMultipleAnswers, node.__key);
32
32
  }
33
- constructor(selections, selected, key) {
33
+ constructor(selections, selected, hasMultipleAnswers, key) {
34
34
  super(key);
35
35
  this.__selections = selections;
36
36
  this.__selected = selected;
37
+ this.__hasMultipleAnswers = hasMultipleAnswers;
37
38
  }
38
39
  createDOM(config) {
39
40
  // Define the DOM element here
@@ -49,6 +50,7 @@ export class ProblemSelectNode extends DecoratorNode {
49
50
  key: serializedNode.key,
50
51
  selections: serializedNode.selections,
51
52
  selected: serializedNode.selected,
53
+ hasMultipleAnswers: serializedNode.hasMultipleAnswers,
52
54
  });
53
55
  return node;
54
56
  }
@@ -61,11 +63,11 @@ export class ProblemSelectNode extends DecoratorNode {
61
63
  };
62
64
  }
63
65
  decorate() {
64
- return (_jsx(SelectComponent, { selections: this.__selections, selected: this.__selected, nodeKey: this.getKey() }));
66
+ return (_jsx(SelectComponent, { selections: this.__selections, selected: this.__selected, hasMultipleAnswers: this.__hasMultipleAnswers, nodeKey: this.getKey() }));
65
67
  }
66
68
  }
67
- export function $createProblemSelectNode({ selections, selected, key, }) {
68
- return $applyNodeReplacement(new ProblemSelectNode(selections, selected, key));
69
+ export function $createProblemSelectNode({ selections, selected, hasMultipleAnswers, key, }) {
70
+ return $applyNodeReplacement(new ProblemSelectNode(selections, selected, hasMultipleAnswers, key));
69
71
  }
70
72
  export function $isProblemSelectNode(node) {
71
73
  return node instanceof ProblemSelectNode;
@@ -5,7 +5,7 @@ export interface SelectBoxProps {
5
5
  isAnswer?: boolean;
6
6
  image?: ImageProps;
7
7
  text: string;
8
- onClick: () => void;
8
+ onClick?: () => void;
9
9
  fullWidth?: boolean;
10
10
  }
11
11
  export default function SelectBox(props: SelectBoxProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -4,5 +4,6 @@ import { Selection } from "./ProblemSelectNode";
4
4
  export declare function SelectComponent(props: {
5
5
  selections: Selection[];
6
6
  selected: string[];
7
+ hasMultipleAnswers?: boolean;
7
8
  nodeKey: NodeKey;
8
9
  }): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -1,18 +1,20 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
2
2
  /** @jsxImportSource @emotion/react */
3
3
  import { $getNodeByKey } from "lexical";
4
4
  import { $isProblemSelectNode, } from "./ProblemSelectNode";
5
5
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
6
- import { useState } from "react";
6
+ import { useContext, useState } from "react";
7
7
  import useLexicalEditable from "@lexical/react/useLexicalEditable";
8
8
  import { useFieldArray, useForm } from "react-hook-form";
9
9
  import SelectBox from "./SelectBox";
10
10
  import { css } from "@emotion/react";
11
11
  import SquareButton from "../../../../components/SquareButton";
12
- import { Settings3FillIcon } from "../../../../icons";
12
+ import { AlarmWarningFillIcon, Settings3FillIcon } from "../../../../icons";
13
13
  import SettingForm from "./SettingForm";
14
+ import styled from "@emotion/styled";
15
+ import { LexicalCustomConfigContext } from "../../LexicalCustomConfigContext";
14
16
  export function SelectComponent(props) {
15
- const { selections, selected, nodeKey } = props;
17
+ const { selections, selected, hasMultipleAnswers, nodeKey } = props;
16
18
  const [editor] = useLexicalComposerContext();
17
19
  const [settingOpen, setSettingOpen] = useState(false);
18
20
  const isEditable = useLexicalEditable();
@@ -28,34 +30,44 @@ export function SelectComponent(props) {
28
30
  name: "selections",
29
31
  keyName: "uid",
30
32
  });
33
+ const lexicalCustomConfig = useContext(LexicalCustomConfigContext);
31
34
  // 학생 view
32
35
  if (!isEditable) {
33
- return (_jsx(_Fragment, { children: fields.map((field, index) => (_jsx(SelectBox, { index: index + 1, isSelected: selected.includes(field.value), image: field.show.image, text: field.show.text, onClick: () => {
34
- const isSelected = selected.includes(field.value);
35
- if (isSelected) {
36
- editor.update(() => {
37
- const node = $getNodeByKey(nodeKey);
38
- if (!$isProblemSelectNode(node)) {
39
- return;
40
- }
41
- const newSelected = [...selected];
42
- const index = newSelected.indexOf(field.value);
43
- newSelected.splice(index, 1);
44
- node.setSelected(newSelected);
45
- });
46
- }
47
- else {
48
- editor.update(() => {
49
- const node = $getNodeByKey(nodeKey);
50
- if (!$isProblemSelectNode(node)) {
51
- return;
52
- }
53
- const newSelected = [...selected];
54
- newSelected.push(field.value);
55
- node.setSelected(newSelected);
56
- });
57
- }
58
- }, fullWidth: true }, index))) }));
36
+ if (lexicalCustomConfig.freezeProblemNode) {
37
+ return (_jsxs(_Fragment, { children: [hasMultipleAnswers && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
38
+ width: 14px;
39
+ height: 14px;
40
+ ` }), "\uC9C8\uBB38\uC5D0 \uD574\uB2F9\uD558\uB294 \uB2F5\uC744 \uBAA8\uB450 \uACE0\uB974\uB294 \uBB38\uC81C\uC785\uB2C8\uB2E4."] })), fields.map((field, index) => (_jsx(SelectBox, { index: index + 1, isSelected: selected.includes(field.value), image: field.show.image, text: field.show.text, fullWidth: true }, index)))] }));
41
+ }
42
+ return (_jsxs(_Fragment, { children: [hasMultipleAnswers && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
43
+ width: 14px;
44
+ height: 14px;
45
+ ` }), "\uC9C8\uBB38\uC5D0 \uD574\uB2F9\uD558\uB294 \uB2F5\uC744 \uBAA8\uB450 \uACE0\uB974\uB294 \uBB38\uC81C\uC785\uB2C8\uB2E4."] })), fields.map((field, index) => (_jsx(SelectBox, { index: index + 1, isSelected: selected.includes(field.value), image: field.show.image, text: field.show.text, onClick: () => {
46
+ const isSelected = selected.includes(field.value);
47
+ if (isSelected) {
48
+ editor.update(() => {
49
+ const node = $getNodeByKey(nodeKey);
50
+ if (!$isProblemSelectNode(node)) {
51
+ return;
52
+ }
53
+ const newSelected = [...selected];
54
+ const index = newSelected.indexOf(field.value);
55
+ newSelected.splice(index, 1);
56
+ node.setSelected(newSelected);
57
+ });
58
+ }
59
+ else {
60
+ editor.update(() => {
61
+ const node = $getNodeByKey(nodeKey);
62
+ if (!$isProblemSelectNode(node)) {
63
+ return;
64
+ }
65
+ const newSelected = [...selected];
66
+ newSelected.push(field.value);
67
+ node.setSelected(newSelected);
68
+ });
69
+ }
70
+ }, fullWidth: true }, index)))] }));
59
71
  }
60
72
  // 교사 edit view
61
73
  return (_jsxs(_Fragment, { children: [_jsxs("div", Object.assign({ css: css `
@@ -69,3 +81,15 @@ export function SelectComponent(props) {
69
81
  setSettingOpen(true);
70
82
  } })] })), settingOpen && (_jsx(SettingForm, { control: control, handleSubmit: handleSubmit, fields: fields, append: append, remove: remove, update: update, nodeKey: nodeKey, onClose: () => setSettingOpen(false) }))] }));
71
83
  }
84
+ const Alert = styled.div(({ theme }) => css `
85
+ display: flex;
86
+ gap: 4px;
87
+ margin-bottom: 12px;
88
+ color: ${theme.color.foreground.neutralBaseDisabled};
89
+ /* Default/Label/12px-Md */
90
+ font-family: ${theme.fontFamily.ui};
91
+ font-size: 12px;
92
+ font-style: normal;
93
+ font-weight: 500;
94
+ line-height: 16px; /* 133.333% */
95
+ `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-monolith/cds",
3
- "version": "1.9.4",
3
+ "version": "1.9.6",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "sideEffects": false,