@team-monolith/cds 1.113.2 → 1.114.1

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.
Files changed (200) hide show
  1. package/@types/emotion.d.ts +160 -160
  2. package/README.md +35 -35
  3. package/dist/CdsProvider.js +4 -4
  4. package/dist/components/AlertDialog/AlertDialog.js +54 -54
  5. package/dist/components/AlertDialog/AlertDialogActions.js +7 -7
  6. package/dist/components/AlertDialog/AlertDialogContent.js +8 -8
  7. package/dist/components/AlertDialog/AlertDialogTitle.js +34 -34
  8. package/dist/components/AnimatedButton.js +32 -32
  9. package/dist/components/Banner.js +51 -51
  10. package/dist/components/Book/Book.js +174 -174
  11. package/dist/components/Button.js +179 -179
  12. package/dist/components/CheckboxInput.js +100 -100
  13. package/dist/components/FileTypeAlertDialog.js +4 -4
  14. package/dist/components/Input.js +53 -53
  15. package/dist/components/InputBase.js +72 -72
  16. package/dist/components/Modal.js +4 -4
  17. package/dist/components/OverflowTooltip.js +4 -4
  18. package/dist/components/Pagination.js +56 -56
  19. package/dist/components/PinInput.js +64 -64
  20. package/dist/components/Popover.js +27 -27
  21. package/dist/components/RadioInput.js +73 -73
  22. package/dist/components/SquareButton.js +109 -109
  23. package/dist/components/Switch.js +69 -69
  24. package/dist/components/SwitchButton.js +107 -107
  25. package/dist/components/Tag.js +72 -72
  26. package/dist/components/Tooltip.js +19 -19
  27. package/dist/foundation/breakpoints.js +16 -16
  28. package/dist/icons/custom/colored/ai-helper.svg +4 -4
  29. package/dist/icons/custom/colored/ai-quiz-color.svg +20 -20
  30. package/dist/icons/custom/colored/badge-color.svg +4 -4
  31. package/dist/icons/custom/colored/badge-gold.svg +11 -11
  32. package/dist/icons/custom/colored/badge-green.svg +11 -11
  33. package/dist/icons/custom/colored/badge-silver.svg +11 -11
  34. package/dist/icons/custom/colored/basic-plus.svg +31 -31
  35. package/dist/icons/custom/colored/basic.svg +3 -3
  36. package/dist/icons/custom/colored/board-color.svg +5 -5
  37. package/dist/icons/custom/colored/cast-cloudy-color.svg +6 -6
  38. package/dist/icons/custom/colored/cast-partly-color.svg +7 -7
  39. package/dist/icons/custom/colored/cast-rainbow-color.svg +13 -13
  40. package/dist/icons/custom/colored/cast-sunny-color.svg +4 -4
  41. package/dist/icons/custom/colored/clap-bronze.svg +8 -8
  42. package/dist/icons/custom/colored/clap-gold.svg +8 -8
  43. package/dist/icons/custom/colored/clap-silver.svg +8 -8
  44. package/dist/icons/custom/colored/class.svg +13 -13
  45. package/dist/icons/custom/colored/codap-color.svg +13 -13
  46. package/dist/icons/custom/colored/ebook-color.svg +5 -5
  47. package/dist/icons/custom/colored/embedded-color.svg +38 -38
  48. package/dist/icons/custom/colored/emo-clap-color.svg +252 -252
  49. package/dist/icons/custom/colored/emo-good-color.svg +68 -68
  50. package/dist/icons/custom/colored/emo-great-color.svg +67 -67
  51. package/dist/icons/custom/colored/emo-heart-color.svg +239 -239
  52. package/dist/icons/custom/colored/emo-hundred-color.svg +194 -194
  53. package/dist/icons/custom/colored/emo-neutral-color.svg +76 -76
  54. package/dist/icons/custom/colored/emo-stars-color.svg +121 -121
  55. package/dist/icons/custom/colored/emo-thumbup-color.svg +238 -238
  56. package/dist/icons/custom/colored/empty.svg +1 -1
  57. package/dist/icons/custom/colored/entry-color.svg +4 -4
  58. package/dist/icons/custom/colored/filename-all-color.svg +4 -4
  59. package/dist/icons/custom/colored/filename-doc-color.svg +5 -5
  60. package/dist/icons/custom/colored/filename-hwp-color.svg +6 -6
  61. package/dist/icons/custom/colored/filename-img-color.svg +6 -6
  62. package/dist/icons/custom/colored/filename-mp4-color.svg +5 -5
  63. package/dist/icons/custom/colored/filename-pdf-color.svg +12 -12
  64. package/dist/icons/custom/colored/filename-ppt-color.svg +6 -6
  65. package/dist/icons/custom/colored/filename-xls-color.svg +5 -5
  66. package/dist/icons/custom/colored/filename-zip-color.svg +5 -5
  67. package/dist/icons/custom/colored/google.svg +13 -13
  68. package/dist/icons/custom/colored/hand-fill.svg +4 -4
  69. package/dist/icons/custom/colored/judge-color.svg +6 -6
  70. package/dist/icons/custom/colored/makecode-color.svg +4 -4
  71. package/dist/icons/custom/colored/master.svg +12 -12
  72. package/dist/icons/custom/colored/material.svg +6 -6
  73. package/dist/icons/custom/colored/medal-bronze.svg +9 -9
  74. package/dist/icons/custom/colored/medal-gold.svg +9 -9
  75. package/dist/icons/custom/colored/medal-silver.svg +9 -9
  76. package/dist/icons/custom/colored/pro.svg +4 -4
  77. package/dist/icons/custom/colored/problem.svg +7 -7
  78. package/dist/icons/custom/colored/python-color.svg +4 -4
  79. package/dist/icons/custom/colored/quiz-color.svg +12 -12
  80. package/dist/icons/custom/colored/resource-color.svg +13 -13
  81. package/dist/icons/custom/colored/scratch-color.svg +6 -6
  82. package/dist/icons/custom/colored/type-helper.svg +9 -9
  83. package/dist/icons/custom/colored/whale.svg +7 -7
  84. package/dist/icons/custom/colored/worksheet-color.svg +5 -5
  85. package/dist/icons/custom/default/ai-quiz.svg +8 -8
  86. package/dist/icons/custom/default/badge.svg +4 -4
  87. package/dist/icons/custom/default/board.svg +5 -5
  88. package/dist/icons/custom/default/cast-cloudy.svg +3 -3
  89. package/dist/icons/custom/default/cast-partly.svg +4 -4
  90. package/dist/icons/custom/default/cast-rainbow.svg +12 -12
  91. package/dist/icons/custom/default/cast-sunny.svg +3 -3
  92. package/dist/icons/custom/default/codap.svg +11 -11
  93. package/dist/icons/custom/default/ebook.svg +3 -3
  94. package/dist/icons/custom/default/embedded.svg +4 -4
  95. package/dist/icons/custom/default/emo-clap.svg +6 -6
  96. package/dist/icons/custom/default/emo-good.svg +12 -12
  97. package/dist/icons/custom/default/emo-great.svg +12 -12
  98. package/dist/icons/custom/default/emo-heart.svg +5 -5
  99. package/dist/icons/custom/default/emo-hundred.svg +3 -3
  100. package/dist/icons/custom/default/emo-neutral.svg +14 -14
  101. package/dist/icons/custom/default/emo-stars.svg +14 -14
  102. package/dist/icons/custom/default/emo-thumbup.svg +3 -3
  103. package/dist/icons/custom/default/entry.svg +4 -4
  104. package/dist/icons/custom/default/fab.svg +10 -10
  105. package/dist/icons/custom/default/grant-alt.svg +5 -5
  106. package/dist/icons/custom/default/grant.svg +4 -4
  107. package/dist/icons/custom/default/hand-line.svg +3 -3
  108. package/dist/icons/custom/default/judge.svg +3 -3
  109. package/dist/icons/custom/default/makecode.svg +5 -5
  110. package/dist/icons/custom/default/pdf.svg +3 -3
  111. package/dist/icons/custom/default/python.svg +7 -7
  112. package/dist/icons/custom/default/quiz.svg +4 -4
  113. package/dist/icons/custom/default/resource.svg +11 -11
  114. package/dist/icons/custom/default/scratch.svg +3 -3
  115. package/dist/icons/custom/default/scroll-alt.svg +5 -5
  116. package/dist/icons/custom/default/scroll-fill.svg +4 -4
  117. package/dist/icons/custom/default/scroll-line.svg +5 -5
  118. package/dist/icons/custom/default/symbol.svg +4 -4
  119. package/dist/icons/custom/default/worksheet.svg +4 -4
  120. package/dist/icons/custom/svgrColoredTemplate.js +26 -26
  121. package/dist/icons/custom/svgrDefaultTemplate.js +26 -26
  122. package/dist/patterns/Accordion.js +20 -20
  123. package/dist/patterns/Dropdown/DropdownItem/DropdownItem.js +60 -60
  124. package/dist/patterns/Dropdown/DropdownMenu/DropdownMenu.js +27 -27
  125. package/dist/patterns/Dropdown/DropdownMenu/style.js +19 -19
  126. package/dist/patterns/LexicalEditor/Plugins.js +38 -37
  127. package/dist/patterns/LexicalEditor/components/FileSelectInput.js +23 -23
  128. package/dist/patterns/LexicalEditor/components/InsertImageDialog/ImagePreview.js +4 -4
  129. package/dist/patterns/LexicalEditor/components/InsertImageDialog/InsertImageDialog.js +20 -17
  130. package/dist/patterns/LexicalEditor/components/InsertVideoDialog/InsertVideoDialog.d.ts +15 -0
  131. package/dist/patterns/LexicalEditor/components/InsertVideoDialog/InsertVideoDialog.js +83 -0
  132. package/dist/patterns/LexicalEditor/components/InsertVideoDialog/index.d.ts +1 -0
  133. package/dist/patterns/LexicalEditor/components/InsertVideoDialog/index.js +1 -0
  134. package/dist/patterns/LexicalEditor/components/UploadFileDialog/UploadFileDialog.js +2 -2
  135. package/dist/patterns/LexicalEditor/hr.svg +3 -3
  136. package/dist/patterns/LexicalEditor/nodes/FileNode/FileComponent.js +44 -44
  137. package/dist/patterns/LexicalEditor/nodes/FileNode/FileDownloadButton.js +25 -25
  138. package/dist/patterns/LexicalEditor/nodes/ImageNode/ImageComponent.js +8 -8
  139. package/dist/patterns/LexicalEditor/nodes/ImageNode/ImageResizer.js +60 -60
  140. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/InputComponent.js +19 -19
  141. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SegmentedInput.js +49 -49
  142. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/FormSolution.js +7 -7
  143. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/SettingForm.js +73 -73
  144. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/TextTypeDropdown.js +5 -5
  145. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/TextInput.js +7 -7
  146. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxComponent.js +69 -69
  147. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxEdit.js +3 -3
  148. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView.js +15 -15
  149. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectComponent.js +28 -28
  150. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/FormSelection.js +54 -54
  151. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/SettingForm.js +61 -61
  152. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/Evaluation.js +75 -75
  153. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/FormIconAndLabel/FormIconAndLabel.js +17 -17
  154. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/FormIconAndLabel/FormLabel.js +7 -7
  155. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/FormQuestion.js +28 -28
  156. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/SettingForm.js +52 -52
  157. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/EvaluationComponent.js +7 -7
  158. package/dist/patterns/LexicalEditor/nodes/SheetInputNode/InputComponent.js +25 -25
  159. package/dist/patterns/LexicalEditor/nodes/SheetInputNode/SettingForm.js +53 -53
  160. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectBox/SelectBoxComponent.js +54 -54
  161. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectBox/SelectBoxView.js +5 -5
  162. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectComponent.js +21 -21
  163. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/FormSelection.js +42 -42
  164. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/SettingForm.js +71 -71
  165. package/dist/patterns/LexicalEditor/nodes/VideoNode/VideoComponent.d.ts +7 -0
  166. package/dist/patterns/LexicalEditor/nodes/VideoNode/VideoComponent.js +53 -0
  167. package/dist/patterns/LexicalEditor/nodes/VideoNode/VideoNode.d.ts +23 -0
  168. package/dist/patterns/LexicalEditor/nodes/VideoNode/VideoNode.js +52 -0
  169. package/dist/patterns/LexicalEditor/nodes/VideoNode/index.d.ts +1 -0
  170. package/dist/patterns/LexicalEditor/nodes/VideoNode/index.js +1 -0
  171. package/dist/patterns/LexicalEditor/nodes/index.d.ts +1 -0
  172. package/dist/patterns/LexicalEditor/nodes/index.js +1 -0
  173. package/dist/patterns/LexicalEditor/nodes/nodes.d.ts +2 -1
  174. package/dist/patterns/LexicalEditor/nodes/nodes.js +2 -0
  175. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/ComponentAdder.js +51 -51
  176. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/ComponentAdderPlugin.js +18 -12
  177. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/menu.svg +7 -7
  178. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/plus.svg +2 -2
  179. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/useContextMenuOptions.d.ts +1 -1
  180. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/useContextMenuOptions.js +27 -12
  181. package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuItem.js +32 -32
  182. package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuList.js +32 -32
  183. package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.d.ts +1 -0
  184. package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js +30 -19
  185. package/dist/patterns/LexicalEditor/plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.js +49 -49
  186. package/dist/patterns/LexicalEditor/plugins/FloatingTextFormatToolbarPlugin/FloatingTextFormatPopup.js +36 -36
  187. package/dist/patterns/LexicalEditor/plugins/ParagraphPlaceholderPlugin/index.js +7 -7
  188. package/dist/patterns/LexicalEditor/plugins/VideosPlugin/index.d.ts +5 -0
  189. package/dist/patterns/LexicalEditor/plugins/VideosPlugin/index.js +20 -0
  190. package/dist/patterns/LexicalEditor/theme.js +243 -243
  191. package/dist/patterns/SegmentedControl/SegmentedControlButton.js +10 -10
  192. package/dist/patterns/SegmentedControl/SegmentedControlGroup.js +8 -8
  193. package/dist/patterns/SegmentedControl/SegmentedControlSquareButton.js +2 -2
  194. package/dist/patterns/Tabs.js +43 -43
  195. package/dist/patterns/ToggleButtonGroup/ToggleButton.js +40 -40
  196. package/dist/patterns/ToggleButtonGroup/ToggleButtonGroup.js +11 -11
  197. package/dist/utils/hover.js +12 -12
  198. package/dist/utils/reset.js +19 -19
  199. package/dist/utils/visuallyHidden.js +10 -10
  200. package/package.json +93 -92
@@ -20,73 +20,73 @@ export const selectBoxClasses = {
20
20
  content: "SheetSelectNode-SelectBox-content",
21
21
  };
22
22
  const TYPE_TO_CONTAINER_STYLE = (theme, type) => ({
23
- primary: css `
24
- background: ${theme.color.container.blueContainer};
25
- border: 1px solid ${theme.color.foreground.primary};
26
- color: ${theme.color.container.blueOnContainer};
23
+ primary: css `
24
+ background: ${theme.color.container.blueContainer};
25
+ border: 1px solid ${theme.color.foreground.primary};
26
+ color: ${theme.color.container.blueOnContainer};
27
27
  `,
28
- normal: css `
29
- background: ${theme.color.background.neutralAlt};
30
- border: 1px solid transparent;
31
- color: ${theme.color.foreground.neutralBase};
28
+ normal: css `
29
+ background: ${theme.color.background.neutralAlt};
30
+ border: 1px solid transparent;
31
+ color: ${theme.color.foreground.neutralBase};
32
32
  `,
33
33
  })[type];
34
34
  const TYPE_TO_INDEX_STYLE = (theme, type) => ({
35
- primary: css `
36
- background: ${theme.color.background.primary};
37
- border: 1px solid ${theme.color.background.primary};
38
- color: ${theme.color.foreground.neutralAlt};
35
+ primary: css `
36
+ background: ${theme.color.background.primary};
37
+ border: 1px solid ${theme.color.background.primary};
38
+ color: ${theme.color.foreground.neutralAlt};
39
39
  `,
40
- normal: css `
41
- background: ${theme.color.background.neutralBase};
42
- border: 1px solid ${theme.color.background.neutralAltActive};
43
- color: ${theme.color.foreground.neutralBaseDisabled};
40
+ normal: css `
41
+ background: ${theme.color.background.neutralBase};
42
+ border: 1px solid ${theme.color.background.neutralAltActive};
43
+ color: ${theme.color.foreground.neutralBaseDisabled};
44
44
  `,
45
45
  })[type];
46
46
  /** 비지니스 로직과 무관한 SelectBox를 그리는 공통 컴포넌트입니다. */
47
47
  export const SelectBoxComponent = forwardRef(function SelectBoxComponent(props, ref) {
48
48
  const { className, type, index, image, text, onClick } = props, restProps = __rest(props, ["className", "type", "index", "image", "text", "onClick"]);
49
49
  const theme = useTheme();
50
- return (_jsxs(Container, Object.assign({ className: `${className} ${selectBoxClasses.container}`, ref: ref }, restProps, { css: TYPE_TO_CONTAINER_STYLE(theme, type), onClick: onClick, children: [_jsx(Index, { className: selectBoxClasses.index, "aria-hidden": "true", css: TYPE_TO_INDEX_STYLE(theme, type), children: index }), _jsxs(Content, { className: selectBoxClasses.content, "aria-hidden": "true", children: [image && (_jsx("img", { "aria-hidden": "true", src: image.src, alt: image.altText, css: css `
51
- height: auto;
52
- // 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
53
- max-width: 100%;
54
- width: fit-content;
55
- border-radius: 6px;
50
+ return (_jsxs(Container, Object.assign({ className: `${className} ${selectBoxClasses.container}`, ref: ref }, restProps, { css: TYPE_TO_CONTAINER_STYLE(theme, type), onClick: onClick, children: [_jsx(Index, { className: selectBoxClasses.index, "aria-hidden": "true", css: TYPE_TO_INDEX_STYLE(theme, type), children: index }), _jsxs(Content, { className: selectBoxClasses.content, "aria-hidden": "true", children: [image && (_jsx("img", { "aria-hidden": "true", src: image.src, alt: image.altText, css: css `
51
+ height: auto;
52
+ // 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
53
+ max-width: 100%;
54
+ width: fit-content;
55
+ border-radius: 6px;
56
56
  ` })), text] })] })));
57
57
  });
58
- const Container = styled.div(({ onClick }) => css `
59
- ${onClick && "cursor: pointer;"}
60
- display: flex;
61
- width: 400px;
62
- padding: 12px;
63
- gap: 12px;
64
- border-radius: 8px;
58
+ const Container = styled.div(({ onClick }) => css `
59
+ ${onClick && "cursor: pointer;"}
60
+ display: flex;
61
+ width: 400px;
62
+ padding: 12px;
63
+ gap: 12px;
64
+ border-radius: 8px;
65
65
  `);
66
- const Index = styled.div(({ theme }) => css `
67
- display: flex;
68
- box-sizing: border-box;
69
- width: 20px;
70
- height: 20px;
71
- padding: 4px;
72
-
73
- user-select: none; /* Standard syntax */
74
-
75
- justify-content: center;
76
- align-items: center;
77
- border-radius: 4px;
78
- font-family: ${theme.fontFamily.ui};
79
- font-size: 14px;
80
- font-weight: 800;
81
- line-height: 16px;
66
+ const Index = styled.div(({ theme }) => css `
67
+ display: flex;
68
+ box-sizing: border-box;
69
+ width: 20px;
70
+ height: 20px;
71
+ padding: 4px;
72
+
73
+ user-select: none; /* Standard syntax */
74
+
75
+ justify-content: center;
76
+ align-items: center;
77
+ border-radius: 4px;
78
+ font-family: ${theme.fontFamily.ui};
79
+ font-size: 14px;
80
+ font-weight: 800;
81
+ line-height: 16px;
82
82
  `);
83
- const Content = styled.div(({ theme }) => css `
84
- display: flex;
85
- flex-direction: column;
86
- gap: 12px;
87
- flex: 1;
88
- font-family: ${theme.fontFamily.ui};
89
- font-size: 16px;
90
- font-weight: 400;
91
- line-height: 20px;
83
+ const Content = styled.div(({ theme }) => css `
84
+ display: flex;
85
+ flex-direction: column;
86
+ gap: 12px;
87
+ flex: 1;
88
+ font-family: ${theme.fontFamily.ui};
89
+ font-size: 16px;
90
+ font-weight: 400;
91
+ line-height: 20px;
92
92
  `);
@@ -7,9 +7,9 @@ import { useRef } from "react";
7
7
  import { useEventListener } from "usehooks-ts";
8
8
  function getIndexIcon(type, index) {
9
9
  return {
10
- primary: (_jsx(CheckFillIcon, { css: css `
11
- width: 12px;
12
- height: 12px;
10
+ primary: (_jsx(CheckFillIcon, { css: css `
11
+ width: 12px;
12
+ height: 12px;
13
13
  ` })),
14
14
  normal: index,
15
15
  }[type];
@@ -37,7 +37,7 @@ export function SelectBoxView(props) {
37
37
  useEventListener("keydown", handleKeyDown);
38
38
  // text가 있으면 text, 없으면 image의 altText, 없으면 index를 aria-label로 사용
39
39
  const ariaText = text || (image && image.altText) || index.toString() + "번 선택지";
40
- return (_jsx(SelectBoxComponent, { css: css `
41
- width: 100%;
40
+ return (_jsx(SelectBoxComponent, { css: css `
41
+ width: 100%;
42
42
  `, ref: boxRef, role: onClick ? "checkbox" : undefined, "aria-checked": isSelected, "aria-label": onClick ? ariaText + (isSelected ? " 선택됨" : " 선택하기") : ariaText, tabIndex: onClick ? 0 : -1, type: selectBoxType, index: getIndexIcon(selectBoxType, index), image: image, text: text, onClick: onClick }));
43
43
  }
@@ -20,9 +20,9 @@ export function SelectComponent(props) {
20
20
  const { freezeProblemNode } = useContext(LexicalCustomConfigContext);
21
21
  // view
22
22
  if (!isEditable) {
23
- return (_jsxs(_Fragment, { children: [allowMultipleAnswers && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
24
- width: 14px;
25
- height: 14px;
23
+ return (_jsxs(_Fragment, { children: [allowMultipleAnswers && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
24
+ width: 14px;
25
+ height: 14px;
26
26
  ` }), "\uC9C8\uBB38\uC5D0 \uD574\uB2F9\uD558\uB294 \uB2F5\uC744 \uBAA8\uB450 \uACE0\uB974\uB294 \uBB38\uD56D\uC785\uB2C8\uB2E4."] })), selections.map((selection, index) => (_jsx(SelectBoxView, { index: index + 1, isSelected: selected.includes(selection.value), image: selection.show.image, text: selection.show.text, onClick: freezeProblemNode
27
27
  ? undefined
28
28
  : () => {
@@ -53,13 +53,13 @@ export function SelectComponent(props) {
53
53
  } }, index)))] }));
54
54
  }
55
55
  // edit
56
- return (_jsxs(_Fragment, { children: [_jsxs("div", { css: css `
57
- display: flex;
58
- gap: 4px;
59
- `, children: [_jsx("div", { css: css `
60
- display: flex;
61
- flex-direction: column;
62
- gap: 4px;
56
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { css: css `
57
+ display: flex;
58
+ gap: 4px;
59
+ `, children: [_jsx("div", { css: css `
60
+ display: flex;
61
+ flex-direction: column;
62
+ gap: 4px;
63
63
  `, children: selections.map((selection, index) => (_jsx(SelectBoxEdit, { index: index + 1, image: selection.show.image, text: selection.show.text === "" && selection.show.image === null
64
64
  ? `${index + 1}번 선택지`
65
65
  : selection.show.text, onClick: () => setSettingOpen((open) => !open) }, index))) }), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => {
@@ -69,15 +69,15 @@ export function SelectComponent(props) {
69
69
  allowMultipleAnswers,
70
70
  }, nodeKey: nodeKey, onClose: () => setSettingOpen(false) }))] }));
71
71
  }
72
- const Alert = styled.div(({ theme }) => css `
73
- display: flex;
74
- gap: 4px;
75
- margin-bottom: 12px;
76
- color: ${theme.color.foreground.neutralBaseDisabled};
77
- /* Default/Label/12px-Md */
78
- font-family: ${theme.fontFamily.ui};
79
- font-size: 12px;
80
- font-style: normal;
81
- font-weight: 500;
82
- line-height: 16px; /* 133.333% */
72
+ const Alert = styled.div(({ theme }) => css `
73
+ display: flex;
74
+ gap: 4px;
75
+ margin-bottom: 12px;
76
+ color: ${theme.color.foreground.neutralBaseDisabled};
77
+ /* Default/Label/12px-Md */
78
+ font-family: ${theme.fontFamily.ui};
79
+ font-size: 12px;
80
+ font-style: normal;
81
+ font-weight: 500;
82
+ line-height: 16px; /* 133.333% */
83
83
  `);
@@ -17,21 +17,21 @@ export function FormSelection(props) {
17
17
  name: `selections.${index}.show`,
18
18
  rules,
19
19
  });
20
- return (_jsxs(Container, { children: [_jsx(Index, { children: index + 1 }), _jsxs("div", { css: css `
21
- display: flex;
22
- flex: 1;
23
- flex-direction: column;
24
- gap: 4px;
20
+ return (_jsxs(Container, { children: [_jsx(Index, { children: index + 1 }), _jsxs("div", { css: css `
21
+ display: flex;
22
+ flex: 1;
23
+ flex-direction: column;
24
+ gap: 4px;
25
25
  `, children: [_jsx(InsertImageDialog, { title: value.image ? "이미지 바꾸기" : "이미지 삽입하기", open: imageOpen, imageProps: (_a = value.image) !== null && _a !== void 0 ? _a : undefined, onClose: () => setImageOpen(false), onChange: (props) => onChange(Object.assign(Object.assign({}, value), { image: props })), onDelete: value.image
26
26
  ? () => {
27
27
  onChange(Object.assign(Object.assign({}, value), { image: null }));
28
28
  }
29
- : undefined }), value.image && (_jsx("img", { src: value.image.src, alt: value.image.altText, css: css `
30
- height: auto;
31
- // 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
32
- max-width: min(400px, 100%);
33
- width: fit-content;
34
- border-radius: 6px;
29
+ : undefined }), value.image && (_jsx("img", { src: value.image.src, alt: value.image.altText, css: css `
30
+ height: auto;
31
+ // 이미지로 인해 좌우로 스크롤이 생기는 것을 방지
32
+ max-width: min(400px, 100%);
33
+ width: fit-content;
34
+ border-radius: 6px;
35
35
  `, draggable: "false" })), _jsx(Input, { size: "small", color: invalid
36
36
  ? "activeDanger"
37
37
  : inputFocused
@@ -43,40 +43,40 @@ export function FormSelection(props) {
43
43
  onBlur: () => {
44
44
  setInputFocused(false);
45
45
  },
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 `
47
- flex: 1;
48
- ` })] }), _jsxs("div", { css: css `
49
- display: flex;
50
- // 이미지가 들어가서 container height가 커져도 높이가 유지되도록 설정
51
- height: 36px;
52
- gap: 8px;
53
- align-items: center;
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 `
47
+ flex: 1;
48
+ ` })] }), _jsxs("div", { css: css `
49
+ display: flex;
50
+ // 이미지가 들어가서 container height가 커져도 높이가 유지되도록 설정
51
+ height: 36px;
52
+ gap: 8px;
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
  }, "aria-label": value.image ? "이미지 바꾸기" : "이미지 삽입하기" }), onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete, "aria-label": "\uC0AD\uC81C" }))] })] }));
57
57
  }
58
- const Container = styled.div(({ theme }) => css `
59
- display: flex;
60
- padding: 4px 12px;
61
- gap: 8px;
62
- border-radius: 8px;
63
- background: ${theme.color.background.neutralAlt};
58
+ const Container = styled.div(({ theme }) => css `
59
+ display: flex;
60
+ padding: 4px 12px;
61
+ gap: 8px;
62
+ border-radius: 8px;
63
+ background: ${theme.color.background.neutralAlt};
64
64
  `);
65
- const Index = styled.div(({ theme }) => css `
66
- display: flex;
67
- box-sizing: border-box;
68
- width: 20px;
69
- height: 20px;
70
- padding: 4px;
71
- margin-top: 8px;
72
- justify-content: center;
73
- align-items: center;
74
- border-radius: 4px;
75
- border: 1px solid ${theme.color.background.neutralAltActive};
76
- background: ${theme.color.background.neutralBase};
77
- color: ${theme.color.foreground.neutralBaseDisabled};
78
- font-family: ${theme.fontFamily.ui};
79
- font-size: 14px;
80
- font-weight: 800;
81
- line-height: 16px;
65
+ const Index = styled.div(({ theme }) => css `
66
+ display: flex;
67
+ box-sizing: border-box;
68
+ width: 20px;
69
+ height: 20px;
70
+ padding: 4px;
71
+ margin-top: 8px;
72
+ justify-content: center;
73
+ align-items: center;
74
+ border-radius: 4px;
75
+ border: 1px solid ${theme.color.background.neutralAltActive};
76
+ background: ${theme.color.background.neutralBase};
77
+ color: ${theme.color.foreground.neutralBaseDisabled};
78
+ font-family: ${theme.fontFamily.ui};
79
+ font-size: 14px;
80
+ font-weight: 800;
81
+ line-height: 16px;
82
82
  `);
@@ -57,9 +57,9 @@ export function SettingForm(props) {
57
57
  .map((i) => i + 1)
58
58
  .join(",")}번 선택지가 같은 내용입니다.`;
59
59
  }
60
- return (_jsxs(Form, { onSubmit: handleSubmit(onSettingSubmit), children: [_jsxs(Title, { children: [_jsx(ListRadioIcon, { css: css `
61
- width: 12px;
62
- height: 12px;
60
+ return (_jsxs(Form, { onSubmit: handleSubmit(onSettingSubmit), children: [_jsxs(Title, { children: [_jsx(ListRadioIcon, { css: css `
61
+ width: 12px;
62
+ height: 12px;
63
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
64
  validate: {
65
65
  validateRequired,
@@ -81,82 +81,82 @@ export function SettingForm(props) {
81
81
  },
82
82
  value: uid(),
83
83
  });
84
- }, disabled: fields.length >= 9 })] }), _jsxs(Right, { children: [_jsxs(FormArea, { children: [_jsx(Label, { children: "\uB2E4\uC911 \uC120\uD0DD \uD5C8\uC6A9 \uC5EC\uBD80" }), _jsx(FormAllowMultipleAnswers, { control: control })] }), watch("allowMultipleAnswers") && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
85
- min-width: 14px;
86
- width: 14px;
87
- height: 14px;
84
+ }, disabled: fields.length >= 9 })] }), _jsxs(Right, { children: [_jsxs(FormArea, { children: [_jsx(Label, { children: "\uB2E4\uC911 \uC120\uD0DD \uD5C8\uC6A9 \uC5EC\uBD80" }), _jsx(FormAllowMultipleAnswers, { control: control })] }), watch("allowMultipleAnswers") && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
85
+ min-width: 14px;
86
+ width: 14px;
87
+ height: 14px;
88
88
  ` }), "\uB2E4\uC911 \uC120\uD0DD\uC744 \uD5C8\uC6A9\uD55C \uBB38\uD56D\uC5D0\uB294 \uC5EC\uB7EC \uC120\uD0DD\uC9C0\uB97C \uACE0\uB97C \uC218 \uC788\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", bold: true, type: "submit" })] })] }));
89
89
  }
90
- const Form = styled.form(({ theme }) => css `
91
- display: flex;
92
- width: 620px;
93
- flex-direction: column;
94
- border-radius: 6px;
95
- border: 1px solid ${theme.color.background.neutralAltActive};
96
- background: ${theme.color.background.neutralBase};
97
- box-shadow: ${shadows.shadow08};
90
+ const Form = styled.form(({ theme }) => css `
91
+ display: flex;
92
+ width: 620px;
93
+ flex-direction: column;
94
+ border-radius: 6px;
95
+ border: 1px solid ${theme.color.background.neutralAltActive};
96
+ background: ${theme.color.background.neutralBase};
97
+ box-shadow: ${shadows.shadow08};
98
98
  `);
99
- const Title = styled.div(({ theme }) => css `
100
- display: flex;
101
- padding: 8px 12px;
102
- gap: 4px;
103
- align-items: center;
104
- color: ${theme.color.foreground.neutralBase};
105
- /* Default/Label/12px-Md */
106
- font-family: ${theme.fontFamily.ui};
107
- font-size: 12px;
108
- font-style: normal;
109
- font-weight: 500;
110
- line-height: 16px; /* 133.333% */
99
+ const Title = styled.div(({ theme }) => css `
100
+ display: flex;
101
+ padding: 8px 12px;
102
+ gap: 4px;
103
+ align-items: center;
104
+ color: ${theme.color.foreground.neutralBase};
105
+ /* Default/Label/12px-Md */
106
+ font-family: ${theme.fontFamily.ui};
107
+ font-size: 12px;
108
+ font-style: normal;
109
+ font-weight: 500;
110
+ line-height: 16px; /* 133.333% */
111
111
  `);
112
- const Content = styled.div(({ theme }) => css `
113
- display: flex;
114
- border-top: 1px solid ${theme.color.background.neutralAltActive};
115
- border-bottom: 1px solid ${theme.color.background.neutralAltActive};
112
+ const Content = styled.div(({ theme }) => css `
113
+ display: flex;
114
+ border-top: 1px solid ${theme.color.background.neutralAltActive};
115
+ border-bottom: 1px solid ${theme.color.background.neutralAltActive};
116
116
  `);
117
- const Left = styled.div `
118
- flex: 1;
119
- display: flex;
120
- flex-direction: column;
121
- gap: 12px;
122
- padding: 12px;
117
+ const Left = styled.div `
118
+ flex: 1;
119
+ display: flex;
120
+ flex-direction: column;
121
+ gap: 12px;
122
+ padding: 12px;
123
123
  `;
124
- const Right = styled.div `
125
- width: 240px;
126
- display: flex;
127
- flex-direction: column;
128
- gap: 12px;
129
- padding: 12px;
124
+ const Right = styled.div `
125
+ width: 240px;
126
+ display: flex;
127
+ flex-direction: column;
128
+ gap: 12px;
129
+ padding: 12px;
130
130
  `;
131
- const FormArea = styled.div `
132
- display: flex;
133
- flex-direction: column;
134
- gap: 8px;
131
+ const FormArea = styled.div `
132
+ display: flex;
133
+ flex-direction: column;
134
+ gap: 8px;
135
135
  `;
136
- const Label = styled.div(({ theme }) => css `
137
- color: ${theme.color.foreground.neutralBaseDisabled};
138
- /* Default/Label/12px-Md */
139
- font-family: ${theme.fontFamily.ui};
140
- font-size: 12px;
141
- font-style: normal;
142
- font-weight: 500;
143
- line-height: 16px; /* 133.333% */
136
+ const Label = styled.div(({ theme }) => css `
137
+ color: ${theme.color.foreground.neutralBaseDisabled};
138
+ /* Default/Label/12px-Md */
139
+ font-family: ${theme.fontFamily.ui};
140
+ font-size: 12px;
141
+ font-style: normal;
142
+ font-weight: 500;
143
+ line-height: 16px; /* 133.333% */
144
144
  `);
145
- const Buttons = styled.div `
146
- display: flex;
147
- padding: 12px;
148
- justify-content: flex-end;
149
- align-items: center;
150
- gap: 8px;
145
+ const Buttons = styled.div `
146
+ display: flex;
147
+ padding: 12px;
148
+ justify-content: flex-end;
149
+ align-items: center;
150
+ gap: 8px;
151
151
  `;
152
- const Alert = styled.div(({ theme }) => css `
153
- display: flex;
154
- gap: 4px;
155
- color: ${theme.color.foreground.neutralBaseDisabled};
156
- /* Default/Label/12px-Md */
157
- font-family: ${theme.fontFamily.ui};
158
- font-size: 12px;
159
- font-style: normal;
160
- font-weight: 500;
161
- line-height: 16px; /* 133.333% */
152
+ const Alert = styled.div(({ theme }) => css `
153
+ display: flex;
154
+ gap: 4px;
155
+ color: ${theme.color.foreground.neutralBaseDisabled};
156
+ /* Default/Label/12px-Md */
157
+ font-family: ${theme.fontFamily.ui};
158
+ font-size: 12px;
159
+ font-style: normal;
160
+ font-weight: 500;
161
+ line-height: 16px; /* 133.333% */
162
162
  `);
@@ -0,0 +1,7 @@
1
+ /** @jsxImportSource @emotion/react */
2
+ import type { NodeKey } from "lexical";
3
+ export interface VideoComponentProps {
4
+ src: string;
5
+ nodeKey: NodeKey;
6
+ }
7
+ export declare function VideoComponent({ src, nodeKey, }: VideoComponentProps): JSX.Element;
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
2
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
3
+ import { $getNodeByKey } from "lexical";
4
+ import { useState } from "react";
5
+ import { $isVideoNode } from "./VideoNode";
6
+ import { SquareButton } from "../../../../components/SquareButton";
7
+ import { Settings3FillIcon } from "../../../../icons";
8
+ import styled from "@emotion/styled";
9
+ import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
10
+ import { InsertVideoDialog } from "../../components/InsertVideoDialog";
11
+ import ReactPlayer from "react-player";
12
+ import { css } from "@emotion/react";
13
+ function VideoPlayer(props) {
14
+ return (_jsx(ReactPlayer, { css: css `
15
+ background: black;
16
+ max-width: 1200px;
17
+ `, width: "100%", url: props.url, controls: true, config: {
18
+ file: {
19
+ hlsOptions: {
20
+ startLevel: 100,
21
+ },
22
+ },
23
+ } }));
24
+ }
25
+ export function VideoComponent({ src, nodeKey, }) {
26
+ const [open, setOpen] = useState(false);
27
+ const isEditable = useLexicalEditable();
28
+ const [editor] = useLexicalComposerContext();
29
+ const handleChange = (props) => {
30
+ editor.update(() => {
31
+ const node = $getNodeByKey(nodeKey);
32
+ if ($isVideoNode(node)) {
33
+ node.setSrc(props.src);
34
+ }
35
+ });
36
+ };
37
+ const handleDelete = () => {
38
+ editor.update(() => {
39
+ const node = $getNodeByKey(nodeKey);
40
+ if ($isVideoNode(node)) {
41
+ node.remove();
42
+ }
43
+ });
44
+ };
45
+ if (!isEditable) {
46
+ return _jsx(VideoPlayer, { url: src });
47
+ }
48
+ return (_jsxs(_Fragment, { children: [_jsxs(EditContainer, { children: [_jsx(VideoPlayer, { url: src }), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => setOpen(true), "aria-label": "\uB3D9\uC601\uC0C1 \uC218\uC815\uD558\uAE30" })] }), _jsx(InsertVideoDialog, { open: open, title: "\uB3D9\uC601\uC0C1 \uC218\uC815\uD558\uAE30", onClose: () => setOpen(false), videoProps: { src }, onChange: handleChange, onDelete: handleDelete })] }));
49
+ }
50
+ const EditContainer = styled.div `
51
+ display: flex;
52
+ gap: 4px;
53
+ `;
@@ -0,0 +1,23 @@
1
+ import type { EditorConfig, LexicalNode, NodeKey, SerializedLexicalNode, Spread, LexicalEditor } from "lexical";
2
+ import { DecoratorNode } from "lexical";
3
+ export interface VideoPayload {
4
+ /** 재생할 동영상의 URL */
5
+ src: string;
6
+ key?: NodeKey;
7
+ }
8
+ export type SerializedVideoNode = Spread<VideoPayload, SerializedLexicalNode>;
9
+ export declare class VideoNode extends DecoratorNode<JSX.Element> {
10
+ __src: string;
11
+ isInline(): boolean;
12
+ static getType(): string;
13
+ setSrc(src: string): void;
14
+ static clone(node: VideoNode): VideoNode;
15
+ constructor(src: string, key?: NodeKey);
16
+ static importJSON(serializedNode: SerializedVideoNode): VideoNode;
17
+ exportJSON(): SerializedVideoNode;
18
+ createDOM(config: EditorConfig): HTMLElement;
19
+ updateDOM(): false;
20
+ decorate(_editor: LexicalEditor): JSX.Element;
21
+ }
22
+ export declare function $createVideoNode({ src, key }: VideoPayload): VideoNode;
23
+ export declare function $isVideoNode(node: LexicalNode | null | undefined): node is VideoNode;
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { $applyNodeReplacement, DecoratorNode } from "lexical";
3
+ import React from "react";
4
+ const VideoComponent = React.lazy(() => import("./VideoComponent").then(({ VideoComponent }) => ({
5
+ default: VideoComponent,
6
+ })));
7
+ export class VideoNode extends DecoratorNode {
8
+ isInline() {
9
+ return false;
10
+ }
11
+ static getType() {
12
+ return "video";
13
+ }
14
+ setSrc(src) {
15
+ const writable = this.getWritable();
16
+ writable.__src = src;
17
+ }
18
+ static clone(node) {
19
+ return new VideoNode(node.__src, node.__key);
20
+ }
21
+ constructor(src, key) {
22
+ super(key);
23
+ this.__src = src;
24
+ }
25
+ static importJSON(serializedNode) {
26
+ return $createVideoNode({ src: serializedNode.src });
27
+ }
28
+ exportJSON() {
29
+ return { src: this.__src, type: "video", version: 1 };
30
+ }
31
+ createDOM(config) {
32
+ const span = document.createElement("span");
33
+ const theme = config.theme;
34
+ const className = theme.video;
35
+ if (className !== undefined) {
36
+ span.className = className;
37
+ }
38
+ return span;
39
+ }
40
+ updateDOM() {
41
+ return false;
42
+ }
43
+ decorate(_editor) {
44
+ return (_jsx(React.Suspense, { fallback: null, children: _jsx(VideoComponent, { src: this.__src, nodeKey: this.__key }) }));
45
+ }
46
+ }
47
+ export function $createVideoNode({ src, key }) {
48
+ return $applyNodeReplacement(new VideoNode(src, key));
49
+ }
50
+ export function $isVideoNode(node) {
51
+ return node instanceof VideoNode;
52
+ }
@@ -0,0 +1 @@
1
+ export * from "./VideoNode";
@@ -0,0 +1 @@
1
+ export * from "./VideoNode";
@@ -1,5 +1,6 @@
1
1
  export * from "./ColoredQuoteNode";
2
2
  export * from "./ImageNode";
3
+ export * from "./VideoNode";
3
4
  export * from "./FileNode";
4
5
  export * from "./ProblemInputNode";
5
6
  export * from "./ProblemSelectNode";
@@ -1,5 +1,6 @@
1
1
  export * from "./ColoredQuoteNode";
2
2
  export * from "./ImageNode";
3
+ export * from "./VideoNode";
3
4
  export * from "./FileNode";
4
5
  export * from "./ProblemInputNode";
5
6
  export * from "./ProblemSelectNode";