@team-monolith/cds 1.119.3 → 1.119.5

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 (199) hide show
  1. package/@types/emotion.d.ts +160 -160
  2. package/README.md +37 -37
  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 +148 -148
  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 +15 -15
  130. package/dist/patterns/LexicalEditor/components/InsertVideoDialog/InsertVideoDialog.js +17 -17
  131. package/dist/patterns/LexicalEditor/components/UploadFileDialog/UploadFileDialog.js +2 -2
  132. package/dist/patterns/LexicalEditor/hr.svg +3 -3
  133. package/dist/patterns/LexicalEditor/nodes/FileNode/FileComponent.js +44 -44
  134. package/dist/patterns/LexicalEditor/nodes/FileNode/FileDownloadButton.js +25 -25
  135. package/dist/patterns/LexicalEditor/nodes/ImageNode/ImageComponent.js +8 -8
  136. package/dist/patterns/LexicalEditor/nodes/ImageNode/ImageResizer.js +60 -60
  137. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/InputComponent.js +19 -19
  138. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SegmentedInput.js +49 -49
  139. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/FormSolution.js +7 -7
  140. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/SettingForm.js +73 -73
  141. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/TextTypeDropdown.js +5 -5
  142. package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/TextInput.js +7 -7
  143. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxComponent.js +69 -69
  144. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxEdit.js +3 -3
  145. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox/SelectBoxView.js +15 -15
  146. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectComponent.js +28 -28
  147. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/FormSelection.js +54 -54
  148. package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/SettingForm.js +61 -61
  149. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/Evaluation.js +75 -75
  150. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/FormIconAndLabel/FormIconAndLabel.js +17 -17
  151. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/FormIconAndLabel/FormLabel.js +7 -7
  152. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/FormQuestion.js +28 -28
  153. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/Evaluation/SettingForm/SettingForm.js +52 -52
  154. package/dist/patterns/LexicalEditor/nodes/SelfEvaluationNode/EvaluationComponent/EvaluationComponent.js +7 -7
  155. package/dist/patterns/LexicalEditor/nodes/SheetInputNode/InputComponent.js +25 -25
  156. package/dist/patterns/LexicalEditor/nodes/SheetInputNode/SettingForm.js +53 -53
  157. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectBox/SelectBoxComponent.js +54 -54
  158. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectBox/SelectBoxView.js +5 -5
  159. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SelectComponent.js +21 -21
  160. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/FormSelection.js +42 -42
  161. package/dist/patterns/LexicalEditor/nodes/SheetSelectNode/SelectComponent/SettingForm/SettingForm.js +71 -71
  162. package/dist/patterns/LexicalEditor/nodes/VideoNode/VideoComponent.js +6 -6
  163. package/dist/patterns/LexicalEditor/nodes/index.d.ts +3 -0
  164. package/dist/patterns/LexicalEditor/nodes/index.js +3 -0
  165. package/dist/patterns/LexicalEditor/nodes/nodes.d.ts +4 -2
  166. package/dist/patterns/LexicalEditor/nodes/nodes.js +6 -0
  167. package/dist/patterns/LexicalEditor/nodes/toggleNodes/ToggleContainerNode.d.ts +32 -0
  168. package/dist/patterns/LexicalEditor/nodes/toggleNodes/ToggleContainerNode.js +131 -0
  169. package/dist/patterns/LexicalEditor/nodes/toggleNodes/ToggleContentNode.d.ts +23 -0
  170. package/dist/patterns/LexicalEditor/nodes/toggleNodes/ToggleContentNode.js +88 -0
  171. package/dist/patterns/LexicalEditor/nodes/toggleNodes/ToggleTitleNode.d.ts +24 -0
  172. package/dist/patterns/LexicalEditor/nodes/toggleNodes/ToggleTitleNode.js +105 -0
  173. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/ComponentAdder.js +51 -51
  174. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/ComponentAdderPlugin.js +11 -11
  175. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/menu.svg +7 -7
  176. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/plus.svg +2 -2
  177. package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/useContextMenuOptions.js +76 -12
  178. package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuItem.js +32 -32
  179. package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuList.js +32 -32
  180. package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js +38 -17
  181. package/dist/patterns/LexicalEditor/plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.js +49 -49
  182. package/dist/patterns/LexicalEditor/plugins/FloatingTextFormatToolbarPlugin/FloatingTextFormatPopup.js +36 -36
  183. package/dist/patterns/LexicalEditor/plugins/ParagraphPlaceholderPlugin/index.js +11 -2
  184. package/dist/patterns/LexicalEditor/plugins/TogglePlugin/index.d.ts +9 -0
  185. package/dist/patterns/LexicalEditor/plugins/TogglePlugin/index.js +198 -0
  186. package/dist/patterns/LexicalEditor/theme.d.ts +6 -0
  187. package/dist/patterns/LexicalEditor/theme.js +281 -243
  188. package/dist/patterns/LexicalEditor/utils/toggleUtils.d.ts +9 -0
  189. package/dist/patterns/LexicalEditor/utils/toggleUtils.js +18 -0
  190. package/dist/patterns/SegmentedControl/SegmentedControlButton.js +10 -10
  191. package/dist/patterns/SegmentedControl/SegmentedControlGroup.js +8 -8
  192. package/dist/patterns/SegmentedControl/SegmentedControlSquareButton.js +2 -2
  193. package/dist/patterns/Tabs.js +43 -43
  194. package/dist/patterns/ToggleButtonGroup/ToggleButton.js +40 -40
  195. package/dist/patterns/ToggleButtonGroup/ToggleButtonGroup.js +11 -11
  196. package/dist/utils/hover.js +12 -12
  197. package/dist/utils/reset.js +19 -19
  198. package/dist/utils/visuallyHidden.js +10 -10
  199. package/package.json +109 -109
@@ -9,59 +9,59 @@ export const ComponentAdder = forwardRef(function ComponentAdder(props, ref) {
9
9
  const [editor] = useLexicalComposerContext();
10
10
  return (_jsxs(Container, { ref: ref, className: className, children: [_jsx(PlusContainer, { onClick: onPlusClick, children: editor._editable && _jsx(PlusIcon, {}) }), _jsx(MenuContainer, { draggable: true, onClick: onMenuClick, onDragStart: onMenuDragStart, onDragEnd: onMenuDragEnd, children: editor._editable && _jsx(MenuIcon, {}) })] }));
11
11
  });
12
- const Container = styled.div `
13
- display: flex;
14
- align-items: flex-start;
15
- gap: 3px;
16
-
17
- position: absolute;
18
- left: 0;
19
- top: 0;
20
- will-change: transform;
12
+ const Container = styled.div `
13
+ display: flex;
14
+ align-items: flex-start;
15
+ gap: 3px;
16
+
17
+ position: absolute;
18
+ left: 0;
19
+ top: 0;
20
+ will-change: transform;
21
21
  `;
22
- const PlusContainer = styled.div `
23
- display: flex;
24
- width: 26px;
25
- height: 26px;
26
- justify-content: center;
27
- align-items: center;
28
- border-radius: 5px;
29
- background: ${({ theme }) => theme.color.foreground.neutralAlt};
30
-
31
- cursor: pointer;
32
-
33
- &:hover {
34
- background-color: #eff2f5;
35
- }
22
+ const PlusContainer = styled.div `
23
+ display: flex;
24
+ width: 26px;
25
+ height: 26px;
26
+ justify-content: center;
27
+ align-items: center;
28
+ border-radius: 5px;
29
+ background: ${({ theme }) => theme.color.foreground.neutralAlt};
30
+
31
+ cursor: pointer;
32
+
33
+ &:hover {
34
+ background-color: #eff2f5;
35
+ }
36
36
  `;
37
- const PlusIcon = styled.div `
38
- width: 24px;
39
- height: 24px;
40
- // svg는 hover 이벤트를 path마다 받아서 불편함
41
- // Lexical에서 동일한 접근법을 사용하고 있음
42
- background-image: url(${plus});
37
+ const PlusIcon = styled.div `
38
+ width: 24px;
39
+ height: 24px;
40
+ // svg는 hover 이벤트를 path마다 받아서 불편함
41
+ // Lexical에서 동일한 접근법을 사용하고 있음
42
+ background-image: url(${plus});
43
43
  `;
44
- const MenuContainer = styled.div `
45
- display: flex;
46
- width: 26px;
47
- height: 26px;
48
- justify-content: center;
49
- align-items: center;
50
- border-radius: 5px;
51
- background: ${({ theme }) => theme.color.foreground.neutralAlt};
52
-
53
- cursor: grab;
54
-
55
- &:active {
56
- cursor: grabbing;
57
- }
58
-
59
- &:hover {
60
- background-color: #eff2f5;
61
- }
44
+ const MenuContainer = styled.div `
45
+ display: flex;
46
+ width: 26px;
47
+ height: 26px;
48
+ justify-content: center;
49
+ align-items: center;
50
+ border-radius: 5px;
51
+ background: ${({ theme }) => theme.color.foreground.neutralAlt};
52
+
53
+ cursor: grab;
54
+
55
+ &:active {
56
+ cursor: grabbing;
57
+ }
58
+
59
+ &:hover {
60
+ background-color: #eff2f5;
61
+ }
62
62
  `;
63
- const MenuIcon = styled.div `
64
- width: 24px;
65
- height: 24px;
66
- background-image: url(${menu});
63
+ const MenuIcon = styled.div `
64
+ width: 24px;
65
+ height: 24px;
66
+ background-image: url(${menu});
67
67
  `;
@@ -171,8 +171,8 @@ export function ComponentAdderPlugin(props) {
171
171
  editor.dispatchCommand(INSERT_VIDEO_COMMAND, props);
172
172
  }, shouldReset: true }), _jsx(UploadFileDialog, { open: fileOpen, onClose: () => setFileOpen(false), onChange: (props) => {
173
173
  editor.dispatchCommand(UPLOAD_FILE_COMMAND, props);
174
- } }), _jsx(LexicalNodeMenuPlugin, { nodeKey: nodeKey, anchorClassName: cssToClassName `
175
- z-index: ${ZINDEX.DIALOG + 1};
174
+ } }), _jsx(LexicalNodeMenuPlugin, { nodeKey: nodeKey, anchorClassName: cssToClassName `
175
+ z-index: ${ZINDEX.DIALOG + 1};
176
176
  `, options: filteredOptions, menuRenderFn: (anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) => anchorElementRef.current && filteredOptions.length
177
177
  ? ReactDOM.createPortal(_jsx(ComponentPickerMenuList, { options: filteredOptions, selectedIndex: selectedIndex, selectOptionAndCleanUp: selectOptionAndCleanUp, setHighlightedIndex: setHighlightedIndex }), anchorElementRef.current)
178
178
  : null, onSelectOption: onSelectOption, onClose: () => {
@@ -263,13 +263,13 @@ export function ComponentAdderPlugin(props) {
263
263
  }));
264
264
  }), onMenuDragStart: onDragStart, onMenuDragEnd: onDragEnd }), _jsx(TargetLine, { ref: targetLineRef })] }), anchorElem)] }));
265
265
  }
266
- const TargetLine = styled.div `
267
- pointer-events: none;
268
- background: deepskyblue;
269
- height: 4px;
270
- position: absolute;
271
- left: 0;
272
- top: 0;
273
- opacity: 0;
274
- will-change: transform;
266
+ const TargetLine = styled.div `
267
+ pointer-events: none;
268
+ background: deepskyblue;
269
+ height: 4px;
270
+ position: absolute;
271
+ left: 0;
272
+ top: 0;
273
+ opacity: 0;
274
+ will-change: transform;
275
275
  `;
@@ -1,8 +1,8 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
2
- <path d="M9.41002 7.29999H9.40002" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
3
- <path d="M14.6 7.29999H14.59" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
4
- <path d="M9.31004 12H9.30005" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
5
- <path d="M14.6 12H14.59" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
6
- <path d="M9.41002 16.7H9.40002" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
7
- <path d="M14.6 16.7H14.59" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
2
+ <path d="M9.41002 7.29999H9.40002" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
3
+ <path d="M14.6 7.29999H14.59" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
4
+ <path d="M9.31004 12H9.30005" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
5
+ <path d="M14.6 12H14.59" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
6
+ <path d="M9.41002 16.7H9.40002" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
7
+ <path d="M14.6 16.7H14.59" stroke="#363636" stroke-width="2.6" stroke-linecap="round"/>
8
8
  </svg>
@@ -1,3 +1,3 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
2
- <path d="M12 7V12M12 12V17M12 12H17M12 12H7" stroke="#363636" stroke-width="2" stroke-linecap="round"/>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
2
+ <path d="M12 7V12M12 12V17M12 12H17M12 12H7" stroke="#363636" stroke-width="2" stroke-linecap="round"/>
3
3
  </svg>
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  /**
3
3
  * Context Menu (:: 버튼)
4
4
  */
5
- import { $createParagraphNode, ParagraphNode, } from "lexical";
5
+ import { $createParagraphNode, $createTextNode, $isElementNode, ParagraphNode, } from "lexical";
6
6
  import { ComponentPickerOption, getBaseOptions, } from "../ComponentPickerMenuPlugin";
7
7
  import { $createHeadingNode, $createQuoteNode, HeadingNode, } from "@lexical/rich-text";
8
8
  import { $setBlocksType } from "@lexical/selection";
@@ -12,7 +12,8 @@ import { H1Icon, H2Icon, H3Icon, CloseFillIcon, ListUnorderedIcon, ListOrderedIc
12
12
  import { $isColoredQuoteNode, } from "../../nodes/ColoredQuoteNode";
13
13
  import { useTheme } from "@emotion/react";
14
14
  import { css } from "@emotion/css";
15
- import { $isFileNode, $isImageNode, $isVideoNode, $isProblemInputNode, } from "../../nodes";
15
+ import { $unwrapNode } from "@lexical/utils";
16
+ import { $isFileNode, $isImageNode, $isVideoNode, $isProblemInputNode, $isToggleContainerNode, $isToggleTitleNode, $isToggleContentNode, } from "../../nodes";
16
17
  import { $isProblemSelectNode, } from "../../nodes/ProblemSelectNode";
17
18
  import { $isSheetInputNode } from "../../nodes/SheetInputNode";
18
19
  import { $isSheetSelectNode, } from "../../nodes/SheetSelectNode";
@@ -163,6 +164,66 @@ function getListContextMenuOptions(editor, theme, node, t) {
163
164
  }),
164
165
  ];
165
166
  }
167
+ /**
168
+ * 토글 노드를 헤딩 노드로 변환하는 함수
169
+ * - 토글 컨테이너의 제목을 지정된 Heading 노드로 변환하고 (제목이 빈 경우 빈 텍스트 노드를 추가)
170
+ * - 본문과 컨테이너를 언랩하여 계층을 평탄화한다.
171
+ */
172
+ function convertToggleTitleToHeading(container, tag) {
173
+ const children = container.getChildren();
174
+ const titleNode = children.find($isToggleTitleNode);
175
+ if (!titleNode) {
176
+ return;
177
+ }
178
+ const contentNode = children.find($isToggleContentNode);
179
+ if (!contentNode) {
180
+ return;
181
+ }
182
+ const headingNode = $createHeadingNode(tag);
183
+ const nodesForHeading = titleNode
184
+ .getChildren()
185
+ .flatMap((child) => $isElementNode(child) ? child.getChildren() : [child]);
186
+ if (nodesForHeading.length > 0) {
187
+ headingNode.append(...nodesForHeading);
188
+ }
189
+ if (headingNode.getChildrenSize() === 0) {
190
+ headingNode.append($createTextNode(""));
191
+ }
192
+ titleNode.replace(headingNode);
193
+ $unwrapNode(contentNode);
194
+ $unwrapNode(container);
195
+ headingNode.selectStart();
196
+ }
197
+ function getToggleContextMenuOptions(editor, container, t) {
198
+ return [
199
+ ...[1, 2, 3].map((n) => {
200
+ const titleMap = {
201
+ 1: t("큰 제목", { context: "렉시컬 드롭다운 메뉴" }),
202
+ 2: t("중간 제목", { context: "렉시컬 드롭다운 메뉴" }),
203
+ 3: t("작은 제목", { context: "렉시컬 드롭다운 메뉴" }),
204
+ };
205
+ const iconMap = {
206
+ 1: _jsx(H1Icon, {}),
207
+ 2: _jsx(H2Icon, {}),
208
+ 3: _jsx(H3Icon, {}),
209
+ };
210
+ return new ComponentPickerOption(titleMap[n], {
211
+ icon: iconMap[n],
212
+ keywords: ["heading", "header", `h${n}`, titleMap[n]],
213
+ onSelect: () => editor.update(() => {
214
+ convertToggleTitleToHeading(container, `h${n}`);
215
+ }),
216
+ });
217
+ }),
218
+ new ComponentPickerOption(t("블록 삭제"), {
219
+ icon: _jsx(CloseFillIcon, {}),
220
+ keywords: [],
221
+ onSelect: () => {
222
+ container.remove();
223
+ },
224
+ }),
225
+ ];
226
+ }
166
227
  function getProblemInputContextMenuOptions(node, t) {
167
228
  return [
168
229
  new ComponentPickerOption(t("블록 삭제"), {
@@ -244,8 +305,8 @@ function getColoredQuoteContextMenuOptions(editor, theme, node, t) {
244
305
  return [
245
306
  new ComponentPickerOption(t("회색"), {
246
307
  icon: (_jsx(InputMethodLineIcon, { color: theme.color.container.marbleOnContainer })),
247
- iconContainerClassName: css `
248
- background: ${theme.color.container.marbleContainer};
308
+ iconContainerClassName: css `
309
+ background: ${theme.color.container.marbleContainer};
249
310
  `,
250
311
  keywords: ["grey", "gray"],
251
312
  onSelect: () => {
@@ -256,8 +317,8 @@ function getColoredQuoteContextMenuOptions(editor, theme, node, t) {
256
317
  }),
257
318
  new ComponentPickerOption(t("빨간색"), {
258
319
  icon: (_jsx(InputMethodLineIcon, { color: theme.color.container.redOnContainer })),
259
- iconContainerClassName: css `
260
- background: ${theme.color.container.redContainer};
320
+ iconContainerClassName: css `
321
+ background: ${theme.color.container.redContainer};
261
322
  `,
262
323
  keywords: ["red"],
263
324
  onSelect: () => {
@@ -268,8 +329,8 @@ function getColoredQuoteContextMenuOptions(editor, theme, node, t) {
268
329
  }),
269
330
  new ComponentPickerOption(t("노란색"), {
270
331
  icon: (_jsx(InputMethodLineIcon, { color: theme.color.container.yellowOnContainer })),
271
- iconContainerClassName: css `
272
- background: ${theme.color.container.yellowContainer};
332
+ iconContainerClassName: css `
333
+ background: ${theme.color.container.yellowContainer};
273
334
  `,
274
335
  keywords: ["yellow"],
275
336
  onSelect: () => {
@@ -280,8 +341,8 @@ function getColoredQuoteContextMenuOptions(editor, theme, node, t) {
280
341
  }),
281
342
  new ComponentPickerOption(t("파란색"), {
282
343
  icon: (_jsx(InputMethodLineIcon, { color: theme.color.container.blueOnContainer })),
283
- iconContainerClassName: css `
284
- background: ${theme.color.container.blueContainer};
344
+ iconContainerClassName: css `
345
+ background: ${theme.color.container.blueContainer};
285
346
  `,
286
347
  keywords: ["blue"],
287
348
  onSelect: () => {
@@ -292,8 +353,8 @@ function getColoredQuoteContextMenuOptions(editor, theme, node, t) {
292
353
  }),
293
354
  new ComponentPickerOption(t("초록색"), {
294
355
  icon: (_jsx(InputMethodLineIcon, { color: theme.color.container.greenOnContainer })),
295
- iconContainerClassName: css `
296
- background: ${theme.color.container.greenContainer};
356
+ iconContainerClassName: css `
357
+ background: ${theme.color.container.greenContainer};
297
358
  `,
298
359
  keywords: ["green"],
299
360
  onSelect: () => {
@@ -361,6 +422,9 @@ export function useContextMenuOptions(props) {
361
422
  else if (node instanceof ListNode || node instanceof ListItemNode) {
362
423
  return getListContextMenuOptions(editor, theme, node, t);
363
424
  }
425
+ else if ($isToggleContainerNode(node)) {
426
+ return getToggleContextMenuOptions(editor, node, t);
427
+ }
364
428
  else if ($isColoredQuoteNode(node)) {
365
429
  return getColoredQuoteContextMenuOptions(editor, theme, node, t);
366
430
  }
@@ -4,38 +4,38 @@ export function ComponentPickerMenuItem(props) {
4
4
  const { index, isSelected, onClick, onMouseEnter, option } = props;
5
5
  return (_jsxs(ItemContainer, { tabIndex: -1, ref: option.setRefElement, role: "option", "aria-selected": isSelected, id: "typeahead-item-" + index, onMouseEnter: onMouseEnter, onClick: onClick, isSelected: isSelected, children: [_jsx(IconContainer, { className: option.iconContainerClassName, children: option.icon }), _jsx(Title, { children: option.title })] }, option.key));
6
6
  }
7
- const ItemContainer = styled.li `
8
- display: flex;
9
- padding: 3px 2px;
10
- align-items: center;
11
- gap: 10px;
12
- width: 100%;
13
- cursor: pointer;
14
-
15
- ${({ isSelected }) => isSelected && "background: #eee;"}
7
+ const ItemContainer = styled.li `
8
+ display: flex;
9
+ padding: 3px 2px;
10
+ align-items: center;
11
+ gap: 10px;
12
+ width: 100%;
13
+ cursor: pointer;
14
+
15
+ ${({ isSelected }) => isSelected && "background: #eee;"}
16
16
  `;
17
- const IconContainer = styled.div `
18
- display: flex;
19
- width: 26px;
20
- height: 26px;
21
- justify-content: center;
22
- align-items: center;
23
-
24
- border-radius: 5px;
25
-
26
- background: ${({ theme }) => theme.color.foreground.neutralAlt};
27
- box-shadow: 0px 0px 0px 1px rgba(201, 201, 204, 0.48);
28
-
29
- svg {
30
- width: 18px;
31
- height: 18px;
32
- }
17
+ const IconContainer = styled.div `
18
+ display: flex;
19
+ width: 26px;
20
+ height: 26px;
21
+ justify-content: center;
22
+ align-items: center;
23
+
24
+ border-radius: 5px;
25
+
26
+ background: ${({ theme }) => theme.color.foreground.neutralAlt};
27
+ box-shadow: 0px 0px 0px 1px rgba(201, 201, 204, 0.48);
28
+
29
+ svg {
30
+ width: 18px;
31
+ height: 18px;
32
+ }
33
33
  `;
34
- const Title = styled.span `
35
- color: ${({ theme }) => theme.color.foreground.neutralBase};
36
- font-family: ${({ theme }) => theme.fontFamily.ui};
37
- font-size: 14px;
38
- font-style: normal;
39
- font-weight: 500;
40
- line-height: 20px; /* 142.857% */
34
+ const Title = styled.span `
35
+ color: ${({ theme }) => theme.color.foreground.neutralBase};
36
+ font-family: ${({ theme }) => theme.fontFamily.ui};
37
+ font-size: 14px;
38
+ font-style: normal;
39
+ font-weight: 500;
40
+ line-height: 20px; /* 142.857% */
41
41
  `;
@@ -17,37 +17,37 @@ export function ComponentPickerMenuList(props) {
17
17
  }, option: option }, option.key));
18
18
  }) }) }));
19
19
  }
20
- const Container = styled.div `
21
- position: absolute;
22
-
23
- display: flex;
24
- width: 200px;
25
- padding: 4px;
26
- flex-direction: column;
27
- align-items: flex-start;
28
- gap: 5px;
29
-
30
- border-radius: 8px;
31
- border: 1px solid #e8e8eb;
32
- background: ${({ theme }) => theme.color.background.neutralBase};
33
- box-shadow: 0px 3px 15px -3px rgba(13, 20, 33, 0.13);
20
+ const Container = styled.div `
21
+ position: absolute;
22
+
23
+ display: flex;
24
+ width: 200px;
25
+ padding: 4px;
26
+ flex-direction: column;
27
+ align-items: flex-start;
28
+ gap: 5px;
29
+
30
+ border-radius: 8px;
31
+ border: 1px solid #e8e8eb;
32
+ background: ${({ theme }) => theme.color.background.neutralBase};
33
+ box-shadow: 0px 3px 15px -3px rgba(13, 20, 33, 0.13);
34
34
  `;
35
- const ListContainer = styled.ul `
36
- padding: 0;
37
- list-style: none;
38
- margin: 0;
39
-
40
- display: flex;
41
- flex-direction: column;
42
- align-items: flex-start;
43
- gap: 1px;
44
- align-self: stretch;
45
-
46
- overflow-y: scroll;
47
-
48
- scrollbar-width: none;
49
- -ms-overflow-style: none;
50
- &::-webkit-scrollbar {
51
- display: none;
52
- }
35
+ const ListContainer = styled.ul `
36
+ padding: 0;
37
+ list-style: none;
38
+ margin: 0;
39
+
40
+ display: flex;
41
+ flex-direction: column;
42
+ align-items: flex-start;
43
+ gap: 1px;
44
+ align-self: stretch;
45
+
46
+ overflow-y: scroll;
47
+
48
+ scrollbar-width: none;
49
+ -ms-overflow-style: none;
50
+ &::-webkit-scrollbar {
51
+ display: none;
52
+ }
53
53
  `;
@@ -15,12 +15,12 @@ import { LexicalTypeaheadMenuPlugin, MenuOption, useBasicTypeaheadTriggerMatch,
15
15
  import { $createHeadingNode, $createQuoteNode } from "@lexical/rich-text";
16
16
  import { $setBlocksType } from "@lexical/selection";
17
17
  import { INSERT_TABLE_COMMAND } from "@lexical/table";
18
- import { $createParagraphNode, $getSelection, $isRangeSelection, } from "lexical";
18
+ import { $createParagraphNode, $findMatchingParent, $getSelection, $isRangeSelection, } from "lexical";
19
19
  import { useCallback, useMemo, useState } from "react";
20
20
  import * as ReactDOM from "react-dom";
21
21
  import { css as cssToClassName } from "@emotion/css";
22
22
  import { ComponentPickerMenuList } from "./ComponentPickerMenuList";
23
- import { TextIcon, H1Icon, H2Icon, H3Icon, ListUnorderedIcon, ListOrderedIcon, DoubleQuotesLIcon, CodeViewIcon, SeparatorIcon, ImageLineIcon, VideoLineIcon, InputMethodLineIcon, ListRadioIcon, LayoutColumnLineIcon, FileList2LineIcon, EmojiStickerLineIcon, File3LineIcon, } from "../../../../icons";
23
+ import { TextIcon, H1Icon, H2Icon, H3Icon, ListUnorderedIcon, ListOrderedIcon, DoubleQuotesLIcon, CodeViewIcon, SeparatorIcon, ImageLineIcon, VideoLineIcon, InputMethodLineIcon, ListRadioIcon, LayoutColumnLineIcon, FileList2LineIcon, EmojiStickerLineIcon, File3LineIcon, PlayList2FillIcon, } from "../../../../icons";
24
24
  import { ZINDEX } from "../../../../utils/zIndex";
25
25
  import { css, useTheme } from "@emotion/react";
26
26
  import { INSERT_PROBLEM_INPUT_COMMAND } from "../ProblemInputPlugin";
@@ -37,6 +37,8 @@ import { UploadFileDialog } from "../../components/UploadFileDialog";
37
37
  import { UPLOAD_FILE_COMMAND } from "../FilePlugin";
38
38
  import { useTranslation } from "react-i18next";
39
39
  import { getTexts } from "../../../../texts";
40
+ import { INSERT_TOGGLE_COMMAND } from "../TogglePlugin";
41
+ import { $isToggleTitleNode } from "../../nodes";
40
42
  // import useModal from "../../hooks/useModal";
41
43
  // import catTypingGif from "../../images/cat-typing.gif";
42
44
  // import { INSERT_IMAGE_COMMAND, InsertImageDialog } from "../ImagesPlugin";
@@ -58,6 +60,16 @@ export class ComponentPickerOption extends MenuOption {
58
60
  this.onSelect = options.onSelect.bind(this);
59
61
  }
60
62
  }
63
+ function isSelectionInsideToggleTitle(editor) {
64
+ return editor.getEditorState().read(() => {
65
+ const selection = $getSelection();
66
+ if (!$isRangeSelection(selection)) {
67
+ return false;
68
+ }
69
+ const titleNode = $findMatchingParent(selection.anchor.getNode(), (node) => $isToggleTitleNode(node));
70
+ return Boolean(titleNode);
71
+ });
72
+ }
61
73
  function getDynamicOptions(editor, queryString) {
62
74
  const options = [];
63
75
  // Lexical 원본 코드를 가져왔기 때문에 코드 변경을 최소화하기위함
@@ -136,11 +148,11 @@ function getSheetContextOptions(editor, theme, t) {
136
148
  placeholder: "",
137
149
  }),
138
150
  }),
139
- new ComponentDrawerOption(t("활동지 메뉴구분선"), (_jsx("div", { css: css `
140
- width: 100%;
141
- height: 1px;
142
- background: ${theme.color.background.neutralAltActive};
143
- margin: 4px 0;
151
+ new ComponentDrawerOption(t("활동지 메뉴구분선"), (_jsx("div", { css: css `
152
+ width: 100%;
153
+ height: 1px;
154
+ background: ${theme.color.background.neutralAltActive};
155
+ margin: 4px 0;
144
156
  ` }))),
145
157
  ];
146
158
  }
@@ -184,11 +196,11 @@ function getQuizContextOptions(editor, theme, t) {
184
196
  });
185
197
  },
186
198
  }),
187
- new ComponentDrawerOption(t("퀴즈 메뉴구분선"), (_jsx("div", { css: css `
188
- width: 100%;
189
- height: 1px;
190
- background: ${theme.color.background.neutralAltActive};
191
- margin: 4px 0;
199
+ new ComponentDrawerOption(t("퀴즈 메뉴구분선"), (_jsx("div", { css: css `
200
+ width: 100%;
201
+ height: 1px;
202
+ background: ${theme.color.background.neutralAltActive};
203
+ margin: 4px 0;
192
204
  ` }))),
193
205
  ];
194
206
  }
@@ -238,6 +250,11 @@ export function getBaseOptions(props) {
238
250
  keywords: ["numbered list", "ordered list", "ol"],
239
251
  onSelect: () => editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined),
240
252
  }),
253
+ new ComponentPickerOption(t("토글 목록", { context: "렉시컬 드롭다운 메뉴" }), {
254
+ icon: _jsx(PlayList2FillIcon, {}),
255
+ keywords: ["toggle", "collapsible"],
256
+ onSelect: () => editor.dispatchCommand(INSERT_TOGGLE_COMMAND, undefined),
257
+ }),
241
258
  new ComponentPickerOption(t("인용 블록", { context: "렉시컬 드롭다운 메뉴" }), {
242
259
  icon: _jsx(DoubleQuotesLIcon, {}),
243
260
  keywords: ["block quote"],
@@ -321,9 +338,13 @@ export function ComponentPickerMenuPlugin(props) {
321
338
  const [imageOpen, setImageOpen] = useState(false);
322
339
  const [videoOpen, setVideoOpen] = useState(false);
323
340
  const [fileOpen, setFileOpen] = useState(false);
324
- const checkForTriggerMatch = useBasicTypeaheadTriggerMatch("/", {
325
- minLength: 0,
326
- });
341
+ const baseTrigger = useBasicTypeaheadTriggerMatch("/", { minLength: 0 });
342
+ const triggerFn = useCallback((text, editor) => {
343
+ if (isSelectionInsideToggleTitle(editor)) {
344
+ return null; // 메뉴를 열지 않음 → "/" 명령 무시
345
+ }
346
+ return baseTrigger(text, editor);
347
+ }, [baseTrigger]);
327
348
  const options = useMemo(() => {
328
349
  const baseOptions = getBaseOptions({
329
350
  editor,
@@ -368,8 +389,8 @@ export function ComponentPickerMenuPlugin(props) {
368
389
  editor.dispatchCommand(INSERT_VIDEO_COMMAND, props);
369
390
  }, onClose: () => setVideoOpen(false), shouldReset: true }), _jsx(UploadFileDialog, { open: fileOpen, onClose: () => setFileOpen(false), onChange: (props) => {
370
391
  editor.dispatchCommand(UPLOAD_FILE_COMMAND, props);
371
- } }), _jsx(LexicalTypeaheadMenuPlugin, { onQueryChange: setQueryString, onSelectOption: onSelectOption, triggerFn: checkForTriggerMatch, options: options, anchorClassName: cssToClassName `
372
- z-index: ${ZINDEX.DIALOG + 1};
392
+ } }), _jsx(LexicalTypeaheadMenuPlugin, { onQueryChange: setQueryString, onSelectOption: onSelectOption, triggerFn: triggerFn, options: options, anchorClassName: cssToClassName `
393
+ z-index: ${ZINDEX.DIALOG + 1};
373
394
  `, menuRenderFn: (anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) => anchorElementRef.current && options.length
374
395
  ? ReactDOM.createPortal(_jsx(ComponentPickerMenuList, { options: options, selectedIndex: selectedIndex, selectOptionAndCleanUp: selectOptionAndCleanUp, setHighlightedIndex: setHighlightedIndex }), anchorElementRef.current)
375
396
  : null })] }));