@monolith-forensics/monolith-ui 1.9.3-dev.3 → 2.0.0

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 (33) hide show
  1. package/dist/Button/Button.js +11 -4
  2. package/dist/DropDownMenu/DropDownMenu.js +12 -2
  3. package/dist/DropDownMenu/components/MenuComponent.js +7 -1
  4. package/dist/DropDownMenu/components/MenuItem.js +4 -2
  5. package/dist/DropDownMenu/components/MenuItemList.d.ts +1 -0
  6. package/dist/DropDownMenu/components/MenuItemList.js +17 -7
  7. package/dist/DropDownMenu/components/SearchInput.js +2 -1
  8. package/dist/DropDownMenu/components/StyledContent.js +3 -2
  9. package/dist/DropDownMenu/constants.d.ts +4 -0
  10. package/dist/DropDownMenu/constants.js +4 -0
  11. package/dist/QueryFilter/DefaultOperators.d.ts +76 -0
  12. package/dist/QueryFilter/DefaultOperators.js +21 -0
  13. package/dist/QueryFilter/types.d.ts +66 -0
  14. package/dist/QueryFilter/types.js +1 -0
  15. package/dist/RichTextEditor/Enums/Controls.d.ts +2 -0
  16. package/dist/RichTextEditor/Enums/Controls.js +2 -0
  17. package/dist/RichTextEditor/Enums/Extensions.d.ts +1 -0
  18. package/dist/RichTextEditor/Enums/Extensions.js +1 -0
  19. package/dist/RichTextEditor/Enums/SlashCommands.d.ts +2 -0
  20. package/dist/RichTextEditor/Enums/SlashCommands.js +2 -0
  21. package/dist/RichTextEditor/Extensions/BubbleMenuExtension.d.ts +7 -0
  22. package/dist/RichTextEditor/Extensions/BubbleMenuExtension.js +157 -0
  23. package/dist/RichTextEditor/Extensions/getSlashCommand.js +19 -1
  24. package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +16 -1
  25. package/dist/RichTextEditor/RichTextEditor.js +65 -28
  26. package/dist/RichTextEditor/Toolbar/Controls.d.ts +14 -0
  27. package/dist/RichTextEditor/Toolbar/Controls.js +147 -3
  28. package/dist/RichTextEditor/Toolbar/Labels.d.ts +1 -0
  29. package/dist/RichTextEditor/Toolbar/Labels.js +1 -0
  30. package/dist/RichTextEditor/Toolbar/Toolbar.js +28 -2
  31. package/dist/Table/Utils/resizeHandler.d.ts +3 -0
  32. package/dist/Table/Utils/resizeHandler.js +84 -0
  33. package/package.json +4 -1
@@ -11,7 +11,7 @@ import { Extension } from "@tiptap/core";
11
11
  import Suggestion from "@tiptap/suggestion";
12
12
  import { ReactRenderer } from "@tiptap/react";
13
13
  import tippy from "tippy.js";
14
- import { Heading1, Heading2, Heading3, Heading4, List, ListOrdered, Text, TextQuote, Image as ImageIcon, Calendar, CodeIcon, ClockIcon, SquareCodeIcon, Table2Icon, } from "lucide-react";
14
+ import { Heading1, Heading2, Heading3, Heading4, List, ListOrdered, Text, TextQuote, Image as ImageIcon, Calendar, CodeIcon, ClockIcon, ListChecksIcon, SeparatorHorizontalIcon, SquareCodeIcon, Table2Icon, } from "lucide-react";
15
15
  import { startImageUpload, } from "../Plugins/UploadImagesPlugin.js";
16
16
  import { PluginKey } from "@tiptap/pm/state";
17
17
  import SlashCommandList from "./SlashCommandList";
@@ -116,6 +116,15 @@ const getCommandItems = (values, options) => {
116
116
  editor.chain().focus().deleteRange(range).toggleOrderedList().run();
117
117
  },
118
118
  },
119
+ {
120
+ title: SlashCommands.TaskList,
121
+ description: "Create a checklist with tasks.",
122
+ searchTerms: ["todo", "checklist", "checkbox"],
123
+ icon: ListChecksIcon,
124
+ command: ({ editor, range }) => {
125
+ editor.chain().focus().deleteRange(range).toggleTaskList().run();
126
+ },
127
+ },
119
128
  {
120
129
  title: SlashCommands.Code,
121
130
  description: "Start typing inline code.",
@@ -148,6 +157,15 @@ const getCommandItems = (values, options) => {
148
157
  editor.chain().focus().deleteRange(range).toggleBlockquote().run();
149
158
  },
150
159
  },
160
+ {
161
+ title: SlashCommands.HorizontalRule,
162
+ description: "Insert a horizontal divider.",
163
+ searchTerms: ["divider", "line", "rule", "separator"],
164
+ icon: SeparatorHorizontalIcon,
165
+ command: ({ editor, range }) => {
166
+ editor.chain().focus().deleteRange(range).setHorizontalRule().run();
167
+ },
168
+ },
151
169
  {
152
170
  title: SlashCommands.CurrentDate,
153
171
  description: "Insert the current date.",
@@ -4,6 +4,8 @@ import { CodeBlockLowlight } from "@tiptap/extension-code-block-lowlight";
4
4
  import HorizontalRule from "@tiptap/extension-horizontal-rule";
5
5
  import TextAlign from "@tiptap/extension-text-align";
6
6
  import { Table, TableCell, TableHeader, TableRow, } from "@tiptap/extension-table";
7
+ import TaskList from "@tiptap/extension-task-list";
8
+ import TaskItem from "@tiptap/extension-task-item";
7
9
  import { Focus, Placeholder } from "@tiptap/extensions";
8
10
  import { Color } from "@tiptap/extension-color";
9
11
  import { Highlight } from "@tiptap/extension-highlight";
@@ -71,6 +73,7 @@ export const BASIC_EXTENSIONS = [
71
73
  Extensions.Strike,
72
74
  Extensions.Code,
73
75
  Extensions.Blockquote,
76
+ Extensions.HorizontalRule,
74
77
  Extensions.BulletList,
75
78
  Extensions.OrderedList,
76
79
  Extensions.TextStyle,
@@ -88,7 +91,7 @@ export const MINIMAL_EXTENSIONS = [
88
91
  export const FULL_EXTENSIONS = [
89
92
  ...BASIC_EXTENSIONS,
90
93
  Extensions.CodeBlock,
91
- Extensions.HorizontalRule,
94
+ Extensions.TaskList,
92
95
  Extensions.Table,
93
96
  Extensions.TableCell,
94
97
  Extensions.TableHeader,
@@ -269,6 +272,16 @@ const getTipTapExtensions = ({ disabledExtensions = [], extensions = [], slashCo
269
272
  name: Extensions.TableCell,
270
273
  extension: TableCell,
271
274
  },
275
+ {
276
+ name: Extensions.TaskList,
277
+ extension: TaskList,
278
+ },
279
+ {
280
+ name: "taskItem",
281
+ extension: TaskItem.configure({
282
+ nested: true,
283
+ }),
284
+ },
272
285
  {
273
286
  name: Extensions.Image,
274
287
  extension: CustomImage.configure({
@@ -314,6 +327,8 @@ const getTipTapExtensions = ({ disabledExtensions = [], extensions = [], slashCo
314
327
  .filter((ext) => {
315
328
  if (ext.name === "starterKit")
316
329
  return true;
330
+ if (ext.name === "taskItem")
331
+ return isEnabled(Extensions.TaskList);
317
332
  return isEnabled(ext.name);
318
333
  })
319
334
  .map((ext) => ext.extension);
@@ -14,7 +14,7 @@ import { EditorContent, useEditor } from "@tiptap/react";
14
14
  import { BubbleMenu as TiptapBubbleMenu, } from "@tiptap/react/menus";
15
15
  import { isTextSelection } from "@tiptap/core";
16
16
  import { DOMParser as ProseMirrorDOMParser } from "@tiptap/pm/model";
17
- import { TextSelection } from "@tiptap/pm/state";
17
+ import { NodeSelection, TextSelection } from "@tiptap/pm/state";
18
18
  import { Toolbar } from "./Toolbar";
19
19
  import getTipTapExtensions, { resolveExtensions, } from "./Extensions/getTiptapExtensions";
20
20
  import { Controls, Extensions, SlashCommands } from "./Enums";
@@ -26,6 +26,7 @@ import Fonts from "./Enums/Fonts";
26
26
  import RichTextEditorContext from "./Contexts/RichTextEditorContext";
27
27
  import { getLinkAttributesAtPosition, getLinkRangeAtPosition, openLink, } from "./Utils/linkUtils";
28
28
  import { TABLE_CELL_MIN_WIDTH } from "./Utils/tableUtils";
29
+ import { getControlSizeTokens } from "../core";
29
30
  const codeBlockFallbacks = {
30
31
  light: {
31
32
  background: "#f6f8fa",
@@ -74,6 +75,7 @@ const codeBlockFallbacks = {
74
75
  },
75
76
  },
76
77
  };
78
+ const TASK_CHECKBOX_SIZE = getControlSizeTokens("sm").checkboxIconSize;
77
79
  const getCodeBlockTheme = (theme) => {
78
80
  if (theme.palette.codeBlock)
79
81
  return theme.palette.codeBlock;
@@ -435,6 +437,12 @@ const StyledContent = styled.div `
435
437
  margin: 0;
436
438
  line-height: 1.5rem;
437
439
  }
440
+
441
+ hr {
442
+ border: 1px solid ${({ theme }) => theme.palette.action.hover};
443
+ margin: 1rem 0;
444
+ }
445
+
438
446
  .editor-inline-code,
439
447
  :not(pre) > code {
440
448
  padding: 0.1rem 0.25rem;
@@ -752,59 +760,77 @@ const StyledContent = styled.div `
752
760
 
753
761
  ul[data-type="taskList"] {
754
762
  list-style: none;
763
+ margin: 0.25rem 0;
755
764
  padding: 0;
756
765
 
757
766
  li {
758
767
  display: flex;
759
- align-items: center;
768
+ align-items: flex-start;
760
769
  margin: 0.25rem 0;
761
770
 
762
771
  > label {
772
+ display: inline-flex;
773
+ align-items: center;
774
+ justify-content: center;
763
775
  flex: 0 0 auto;
776
+ height: 1.5rem;
764
777
  margin-right: 0.5rem;
765
778
  user-select: none;
766
779
  }
767
780
 
768
781
  > div {
769
782
  flex: 1 1 auto;
783
+ min-width: 0;
784
+ }
785
+
786
+ > div > ul[data-type="taskList"] {
787
+ margin: 0.25rem 0 0;
770
788
  }
771
789
  }
772
790
 
773
791
  input[type="checkbox"] {
774
- cursor: pointer;
775
- margin: 0;
776
792
  -webkit-appearance: none;
777
793
  appearance: none;
778
- border: 2px solid ${({ theme }) => theme.palette.primary.main};
779
- border-radius: 0.125rem;
780
- background-color: ${({ theme }) => theme.palette.background.default};
781
- width: 1.25rem;
782
- height: 1.25rem;
783
- display: grid;
784
- place-content: center;
785
-
786
- &:hover {
787
- border-color: ${({ theme }) => theme.palette.primary.main};
794
+ position: relative;
795
+ display: inline-flex;
796
+ align-items: center;
797
+ justify-content: center;
798
+ box-sizing: border-box;
799
+ width: ${TASK_CHECKBOX_SIZE}px;
800
+ height: ${TASK_CHECKBOX_SIZE}px;
801
+ margin: 0;
802
+ border: 1px solid ${({ theme }) => theme.palette.text.secondary};
803
+ border-radius: 2px;
804
+ background-color: transparent;
805
+ cursor: pointer;
806
+
807
+ &::after {
808
+ content: "";
809
+ position: absolute;
810
+ left: 50%;
811
+ top: 45%;
812
+ width: 32%;
813
+ height: 56%;
814
+ border: solid
815
+ ${({ theme }) => (theme.name === "DARK" ? "#000000" : "#ffffff")};
816
+ border-width: 0 2px 2px 0;
817
+ opacity: 0;
818
+ transform: translate(-50%, -50%) rotate(45deg);
819
+ transform-origin: center;
788
820
  }
789
821
 
790
- &:active {
791
- background-color: ${({ theme }) => theme.palette.divider};
822
+ &:checked {
823
+ background-color: ${({ theme }) => theme.name === "DARK" ? "#cdcdcd" : "#646464"};
824
+ border-color: ${({ theme }) => theme.name === "DARK" ? "#cdcdcd" : "#646464"};
792
825
  }
793
826
 
794
- &::before {
795
- content: "";
796
- width: 0.75em;
797
- height: 0.75em;
798
- transform: scale(0);
799
- transition: 120ms transform ease-in-out;
800
- box-shadow: inset 1em 1em;
801
- transform-origin: center;
802
- clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
803
- color: ${({ theme }) => theme.palette.text.primary};
827
+ &:checked::after {
828
+ opacity: 1;
804
829
  }
805
830
 
806
- &:checked::before {
807
- transform: scale(1);
831
+ &:focus-visible {
832
+ outline: 2px solid ${({ theme }) => theme.palette.primary.main}40;
833
+ outline-offset: 2px;
808
834
  }
809
835
  }
810
836
  }
@@ -844,9 +870,15 @@ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = ""
844
870
  if (command === SlashCommands.Blockquote) {
845
871
  return resolvedExtensionSet.has(Extensions.Blockquote);
846
872
  }
873
+ if (command === SlashCommands.HorizontalRule) {
874
+ return resolvedExtensionSet.has(Extensions.HorizontalRule);
875
+ }
847
876
  if (command === SlashCommands.Table) {
848
877
  return resolvedExtensionSet.has(Extensions.Table);
849
878
  }
879
+ if (command === SlashCommands.TaskList) {
880
+ return resolvedExtensionSet.has(Extensions.TaskList);
881
+ }
850
882
  return true;
851
883
  }), [resolvedExtensionSet, slashCommands]);
852
884
  const resolvedToolbarOptions = useMemo(() => {
@@ -860,8 +892,10 @@ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = ""
860
892
  [Controls.CODE]: Extensions.Code,
861
893
  [Controls.CODE_BLOCK]: Extensions.CodeBlock,
862
894
  [Controls.BLOCKQUOTE]: Extensions.Blockquote,
895
+ [Controls.HORIZONTAL_RULE]: Extensions.HorizontalRule,
863
896
  [Controls.BULLET_LIST]: Extensions.BulletList,
864
897
  [Controls.ORDERED_LIST]: Extensions.OrderedList,
898
+ [Controls.TASK_LIST]: Extensions.TaskList,
865
899
  [Controls.COLOR]: Extensions.Color,
866
900
  [Controls.HIGHLIGHT]: Extensions.Highlight,
867
901
  [Controls.LINK]: Extensions.Link,
@@ -917,8 +951,11 @@ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = ""
917
951
  const hasEditorFocus = view.hasFocus() || isChildOfMenu;
918
952
  const selectedText = state.doc.textBetween(from, to).trim();
919
953
  const isEmptyTextBlock = !selectedText && isTextSelection(state.selection);
954
+ const isHorizontalRuleSelection = selection instanceof NodeSelection &&
955
+ selection.node.type.name === "horizontalRule";
920
956
  if (!hasEditorFocus ||
921
957
  selection.empty ||
958
+ isHorizontalRuleSelection ||
922
959
  isEmptyTextBlock ||
923
960
  !editor.isEditable) {
924
961
  return false;
@@ -2,6 +2,9 @@ import { Editor } from "@tiptap/react";
2
2
  interface ControlProps {
3
3
  editor: Editor | null;
4
4
  }
5
+ export type HeadingLevel = 1 | 2 | 3 | 4;
6
+ export type TextAlignment = "left" | "center" | "right" | "justify";
7
+ export type ListType = "bullet" | "ordered" | "task";
5
8
  export declare const UndoControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
6
9
  export declare const RedoControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
7
10
  export declare const FontControl: () => import("react/jsx-runtime").JSX.Element;
@@ -15,14 +18,25 @@ export declare const StrikeThroughControl: ({ editor }: ControlProps) => import(
15
18
  export declare const CodeControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
16
19
  export declare const CodeBlockControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
17
20
  export declare const BlockquoteControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
21
+ export declare const HorizontalRuleControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
18
22
  export declare const Heading1Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
19
23
  export declare const Heading2Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
20
24
  export declare const Heading3Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
21
25
  export declare const Heading4Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
26
+ export declare const HeadingControl: ({ editor, levels, }: ControlProps & {
27
+ levels?: HeadingLevel[];
28
+ }) => import("react/jsx-runtime").JSX.Element | null;
22
29
  export declare const BulletListControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
23
30
  export declare const OrderedListControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
31
+ export declare const TaskListControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
32
+ export declare const ListControl: ({ editor, listTypes, }: ControlProps & {
33
+ listTypes?: ListType[];
34
+ }) => import("react/jsx-runtime").JSX.Element | null;
24
35
  export declare const AlignLeftControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
25
36
  export declare const AlignRightControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
26
37
  export declare const AlignCenterControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
27
38
  export declare const AlignJustifiedControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
39
+ export declare const AlignmentControl: ({ editor, alignments, }: ControlProps & {
40
+ alignments?: TextAlignment[];
41
+ }) => import("react/jsx-runtime").JSX.Element | null;
28
42
  export {};
@@ -1,7 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { IconBold, IconItalic, IconUnderline, IconStrikethrough, IconH1, IconH2, IconH3, IconH4, IconList, IconListNumbers, IconAlignLeft, IconAlignRight, IconAlignCenter, IconAlignJustified, IconCornerUpLeft, IconCornerUpRight, IconBlockquote, } from "@tabler/icons-react";
3
- import { CodeIcon, HighlighterIcon, PaletteIcon, RemoveFormattingIcon, SquircleIcon, TypeIcon, } from "lucide-react";
4
- import { SquareCodeIcon } from "lucide-react";
2
+ import { IconBold, IconItalic, IconUnderline, IconStrikethrough, IconH1, IconH2, IconH3, IconH4, IconHeading, IconList, IconListNumbers, IconAlignLeft, IconAlignRight, IconAlignCenter, IconAlignJustified, IconCornerUpLeft, IconCornerUpRight, IconBlockquote, IconSeparatorHorizontal, } from "@tabler/icons-react";
3
+ import { CodeIcon, HighlighterIcon, ListChecksIcon, PaletteIcon, RemoveFormattingIcon, SquareCodeIcon, SquircleIcon, TypeIcon, } from "lucide-react";
5
4
  import { Control } from "./Control";
6
5
  import { hasInlineCode, toggleInlineCode } from "../Utils/codeUtils";
7
6
  import { hasSyntaxHighlightedCodeBlock, toggleCodeBlock, } from "../Utils/codeBlockUtils";
@@ -12,6 +11,38 @@ import RichTextEditorContext from "../Contexts/RichTextEditorContext";
12
11
  import Fonts from "../Enums/Fonts";
13
12
  import TextColors from "../Enums/TextColors";
14
13
  import HighlightColors from "../Enums/HighlightColors";
14
+ const headingControlOptions = [
15
+ { level: 1, label: "Heading 1", icon: IconH1 },
16
+ { level: 2, label: "Heading 2", icon: IconH2 },
17
+ { level: 3, label: "Heading 3", icon: IconH3 },
18
+ { level: 4, label: "Heading 4", icon: IconH4 },
19
+ ];
20
+ const alignmentControlOptions = [
21
+ { value: "left", label: "Align text: left", icon: IconAlignLeft },
22
+ { value: "center", label: "Align text: center", icon: IconAlignCenter },
23
+ { value: "right", label: "Align text: right", icon: IconAlignRight },
24
+ { value: "justify", label: "Align text: justify", icon: IconAlignJustified },
25
+ ];
26
+ const listControlOptions = [
27
+ {
28
+ value: "bullet",
29
+ label: "Bullet list",
30
+ nodeName: "bulletList",
31
+ icon: IconList,
32
+ },
33
+ {
34
+ value: "ordered",
35
+ label: "Ordered list",
36
+ nodeName: "orderedList",
37
+ icon: IconListNumbers,
38
+ },
39
+ {
40
+ value: "task",
41
+ label: "Task list",
42
+ nodeName: "taskList",
43
+ icon: ListChecksIcon,
44
+ },
45
+ ];
15
46
  export const UndoControl = ({ editor }) => {
16
47
  return (_jsx(Control, { editor: editor, label: "undoControlLabel", operation: {
17
48
  name: "undo",
@@ -163,6 +194,11 @@ export const BlockquoteControl = ({ editor }) => {
163
194
  name: "toggleBlockquote",
164
195
  }, icon: IconBlockquote }));
165
196
  };
197
+ export const HorizontalRuleControl = ({ editor }) => {
198
+ return (_jsx(Control, { editor: editor, label: "hrControlLabel", operation: {
199
+ name: "setHorizontalRule",
200
+ }, icon: IconSeparatorHorizontal }));
201
+ };
166
202
  export const Heading1Control = ({ editor }) => {
167
203
  return (_jsx(Control, { editor: editor, label: "h1ControlLabel", isActive: {
168
204
  name: "heading",
@@ -199,6 +235,37 @@ export const Heading4Control = ({ editor }) => {
199
235
  attributes: { level: 4 },
200
236
  }, icon: IconH4 }));
201
237
  };
238
+ export const HeadingControl = ({ editor, levels = [1, 2, 3, 4], }) => {
239
+ const options = headingControlOptions.filter((option) => levels.includes(option.level));
240
+ const currentHeading = headingControlOptions.find((option) => editor === null || editor === void 0 ? void 0 : editor.isActive("heading", { level: option.level }));
241
+ const selectedHeading = options.find((option) => option.level === (currentHeading === null || currentHeading === void 0 ? void 0 : currentHeading.level));
242
+ const ButtonIcon = (currentHeading === null || currentHeading === void 0 ? void 0 : currentHeading.icon) || IconHeading;
243
+ if (!options.length)
244
+ return null;
245
+ return (_jsx(DropDownMenu, { data: options.map((option) => ({
246
+ label: option.label,
247
+ value: option.level,
248
+ onClick: () => {
249
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().toggleHeading({ level: option.level }).run();
250
+ },
251
+ })), value: selectedHeading
252
+ ? [{ label: selectedHeading.label, value: selectedHeading.level }]
253
+ : [], enableSelectedOptionStyling: true, renderOption: (item) => {
254
+ const option = options.find((option) => option.level === item.value);
255
+ const Icon = (option === null || option === void 0 ? void 0 : option.icon) || IconH1;
256
+ return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [_jsx(Icon, { size: 14 }), item.label] }));
257
+ }, size: "xs", variant: "outlined", buttonProps: {
258
+ title: (currentHeading === null || currentHeading === void 0 ? void 0 : currentHeading.label) || "Heading",
259
+ "aria-label": "Heading",
260
+ disabled: !editor,
261
+ selected: Boolean(currentHeading),
262
+ style: { padding: "1px 6px" },
263
+ }, dropDownProps: {
264
+ style: {
265
+ width: 150,
266
+ },
267
+ }, children: _jsx(ButtonIcon, { size: 14 }) }));
268
+ };
202
269
  export const BulletListControl = ({ editor }) => {
203
270
  return (_jsx(Control, { editor: editor, label: "bulletListControlLabel", isActive: {
204
271
  name: "bulletList",
@@ -213,6 +280,51 @@ export const OrderedListControl = ({ editor }) => {
213
280
  name: "toggleOrderedList",
214
281
  }, icon: IconListNumbers }));
215
282
  };
283
+ export const TaskListControl = ({ editor }) => {
284
+ return (_jsx(Control, { editor: editor, label: "taskListControlLabel", isActive: {
285
+ name: "taskList",
286
+ }, operation: {
287
+ name: "toggleTaskList",
288
+ }, icon: ListChecksIcon }));
289
+ };
290
+ export const ListControl = ({ editor, listTypes = ["bullet", "ordered", "task"], }) => {
291
+ const options = listControlOptions.filter((option) => listTypes.includes(option.value));
292
+ const currentList = listControlOptions.find((option) => editor === null || editor === void 0 ? void 0 : editor.isActive(option.nodeName));
293
+ const selectedList = options.find((option) => option.value === (currentList === null || currentList === void 0 ? void 0 : currentList.value));
294
+ const fallbackList = options[0] || listControlOptions[0];
295
+ const ButtonIcon = (currentList === null || currentList === void 0 ? void 0 : currentList.icon) || fallbackList.icon;
296
+ if (!options.length)
297
+ return null;
298
+ return (_jsx(DropDownMenu, { data: options.map((option) => ({
299
+ label: option.label,
300
+ value: option.value,
301
+ onClick: () => {
302
+ const chain = editor === null || editor === void 0 ? void 0 : editor.chain().focus();
303
+ if (option.value === "bullet")
304
+ chain === null || chain === void 0 ? void 0 : chain.toggleBulletList().run();
305
+ if (option.value === "ordered")
306
+ chain === null || chain === void 0 ? void 0 : chain.toggleOrderedList().run();
307
+ if (option.value === "task")
308
+ chain === null || chain === void 0 ? void 0 : chain.toggleTaskList().run();
309
+ },
310
+ })), value: selectedList
311
+ ? [{ label: selectedList.label, value: selectedList.value }]
312
+ : [], enableSelectedOptionStyling: true, renderOption: (item) => {
313
+ const option = options.find((option) => option.value === item.value);
314
+ const Icon = (option === null || option === void 0 ? void 0 : option.icon) || IconList;
315
+ return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [_jsx(Icon, { size: 14 }), item.label] }));
316
+ }, size: "xs", variant: "outlined", buttonProps: {
317
+ title: (currentList === null || currentList === void 0 ? void 0 : currentList.label) || "List",
318
+ "aria-label": "List",
319
+ disabled: !editor,
320
+ selected: Boolean(currentList),
321
+ style: { padding: "1px 6px" },
322
+ }, dropDownProps: {
323
+ style: {
324
+ width: 150,
325
+ },
326
+ }, children: _jsx(ButtonIcon, { size: 14 }) }));
327
+ };
216
328
  export const AlignLeftControl = ({ editor }) => {
217
329
  return (_jsx(Control, { editor: editor, label: "alignLeftControlLabel", isActive: {
218
330
  name: { textAlign: "left" },
@@ -242,3 +354,35 @@ export const AlignJustifiedControl = ({ editor }) => {
242
354
  name: { textAlign: "justify" },
243
355
  }, operation: { name: "setTextAlign", attributes: "justify" }, icon: IconAlignJustified }));
244
356
  };
357
+ export const AlignmentControl = ({ editor, alignments = ["left", "center", "right", "justify"], }) => {
358
+ const options = alignmentControlOptions.filter((option) => alignments.includes(option.value));
359
+ const activeAlignment = alignmentControlOptions.find((option) => editor === null || editor === void 0 ? void 0 : editor.isActive({ textAlign: option.value }));
360
+ const currentAlignment = activeAlignment || alignmentControlOptions[0];
361
+ const selectedAlignment = options.find((option) => option.value === currentAlignment.value);
362
+ const ButtonIcon = currentAlignment.icon;
363
+ if (!options.length)
364
+ return null;
365
+ return (_jsx(DropDownMenu, { data: options.map((option) => ({
366
+ label: option.label,
367
+ value: option.value,
368
+ onClick: () => {
369
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().setTextAlign(option.value).run();
370
+ },
371
+ })), value: selectedAlignment
372
+ ? [{ label: selectedAlignment.label, value: selectedAlignment.value }]
373
+ : [], enableSelectedOptionStyling: true, renderOption: (item) => {
374
+ const option = options.find((option) => option.value === item.value);
375
+ const Icon = (option === null || option === void 0 ? void 0 : option.icon) || IconAlignLeft;
376
+ return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [_jsx(Icon, { size: 14 }), item.label] }));
377
+ }, size: "xs", variant: "outlined", buttonProps: {
378
+ title: currentAlignment.label,
379
+ "aria-label": "Text alignment",
380
+ disabled: !editor,
381
+ selected: Boolean(activeAlignment),
382
+ style: { padding: "1px 6px" },
383
+ }, dropDownProps: {
384
+ style: {
385
+ width: 170,
386
+ },
387
+ }, children: _jsx(ButtonIcon, { size: 14 }) }));
388
+ };
@@ -10,6 +10,7 @@ declare const Labels: {
10
10
  unlinkControlLabel: string;
11
11
  bulletListControlLabel: string;
12
12
  orderedListControlLabel: string;
13
+ taskListControlLabel: string;
13
14
  h1ControlLabel: string;
14
15
  h2ControlLabel: string;
15
16
  h3ControlLabel: string;
@@ -12,6 +12,7 @@ const Labels = {
12
12
  unlinkControlLabel: "Remove link",
13
13
  bulletListControlLabel: "Bullet list",
14
14
  orderedListControlLabel: "Ordered list",
15
+ taskListControlLabel: "Task list",
15
16
  h1ControlLabel: "Heading 1",
16
17
  h2ControlLabel: "Heading 2",
17
18
  h3ControlLabel: "Heading 3",
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import styled from "styled-components";
3
3
  import ControlsGroup from "./ControlsGroup";
4
- import { UndoControl, RedoControl, FontControl, TextColorControl, HighlightControl, BoldControl, ItalicControl, UnderlineControl, StrikeThroughControl, ClearFormattingControl, CodeControl, CodeBlockControl, BlockquoteControl, Heading1Control, Heading2Control, Heading3Control, Heading4Control, BulletListControl, OrderedListControl, AlignLeftControl, AlignCenterControl, AlignRightControl, AlignJustifiedControl, } from "./Controls";
4
+ import { UndoControl, RedoControl, FontControl, TextColorControl, HighlightControl, BoldControl, ItalicControl, UnderlineControl, StrikeThroughControl, ClearFormattingControl, CodeControl, CodeBlockControl, BlockquoteControl, HorizontalRuleControl, HeadingControl, ListControl, AlignmentControl, } from "./Controls";
5
5
  import { Controls } from "../Enums";
6
6
  import { DropDownMenu } from "../../DropDownMenu";
7
7
  import { useState } from "react";
@@ -10,6 +10,23 @@ import { Popover } from "../../Popover";
10
10
  import LinkEditor from "../Components/LinkEditor";
11
11
  import { TableToolsPopover } from "../Components/TableTools";
12
12
  import { LinkIcon } from "lucide-react";
13
+ const headingControlLevels = [
14
+ { control: Controls.HEADING_1, level: 1 },
15
+ { control: Controls.HEADING_2, level: 2 },
16
+ { control: Controls.HEADING_3, level: 3 },
17
+ { control: Controls.HEADING_4, level: 4 },
18
+ ];
19
+ const alignmentControls = [
20
+ { control: Controls.TEXT_ALIGN_LEFT, alignment: "left" },
21
+ { control: Controls.TEXT_ALIGN_CENTER, alignment: "center" },
22
+ { control: Controls.TEXT_ALIGN_RIGHT, alignment: "right" },
23
+ { control: Controls.TEXT_ALIGN_JUSTIFIED, alignment: "justify" },
24
+ ];
25
+ const listControls = [
26
+ { control: Controls.BULLET_LIST, listType: "bullet" },
27
+ { control: Controls.ORDERED_LIST, listType: "ordered" },
28
+ { control: Controls.TASK_LIST, listType: "task" },
29
+ ];
13
30
  const ToolbarContainer = styled.div `
14
31
  display: flex;
15
32
  flex-direction: row;
@@ -32,6 +49,15 @@ export const Toolbar = ({ editor, toolbarOptions }) => {
32
49
  var _a;
33
50
  const { controls } = toolbarOptions || {};
34
51
  const [linkPopoverOpen, setLinkPopoverOpen] = useState(false);
52
+ const headingLevels = headingControlLevels
53
+ .filter(({ control }) => controls === null || controls === void 0 ? void 0 : controls.includes(control))
54
+ .map(({ level }) => level);
55
+ const alignments = alignmentControls
56
+ .filter(({ control }) => controls === null || controls === void 0 ? void 0 : controls.includes(control))
57
+ .map(({ alignment }) => alignment);
58
+ const listTypes = listControls
59
+ .filter(({ control }) => controls === null || controls === void 0 ? void 0 : controls.includes(control))
60
+ .map(({ listType }) => listType);
35
61
  const customItems = controls === null || controls === void 0 ? void 0 : controls.filter((control) => typeof control !== "string" &&
36
62
  (control.type === "menu" || control.type === "button"));
37
63
  return (_jsxs(ToolbarContainer, { children: [(_a = customItems === null || customItems === void 0 ? void 0 : customItems.map) === null || _a === void 0 ? void 0 : _a.call(customItems, (item, index) => {
@@ -46,5 +72,5 @@ export const Toolbar = ({ editor, toolbarOptions }) => {
46
72
  },
47
73
  } }, item.options, { size: "xs", children: (_b = item === null || item === void 0 ? void 0 : item.options) === null || _b === void 0 ? void 0 : _b.label }), index));
48
74
  }
49
- }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDO)) && _jsx(UndoControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.REDO)) && _jsx(RedoControl, { editor: editor })] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.FONT)) && _jsx(FontControl, {}), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.COLOR)) && (_jsx(TextColorControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HIGHLIGHT)) && (_jsx(HighlightControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BOLD)) && _jsx(BoldControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.ITALIC)) && (_jsx(ItalicControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDERLINE)) && (_jsx(UnderlineControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.STRIKE)) && (_jsx(StrikeThroughControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_1)) && (_jsx(Heading1Control, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_2)) && (_jsx(Heading2Control, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_3)) && (_jsx(Heading3Control, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_4)) && (_jsx(Heading4Control, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BULLET_LIST)) && (_jsx(BulletListControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.ORDERED_LIST)) && (_jsx(OrderedListControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BLOCKQUOTE)) && (_jsx(BlockquoteControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_LEFT)) && (_jsx(AlignLeftControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_CENTER)) && (_jsx(AlignCenterControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_RIGHT)) && (_jsx(AlignRightControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_JUSTIFIED)) && (_jsx(AlignJustifiedControl, { editor: editor }))] }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.LINK)) && (_jsxs(Popover, { opened: linkPopoverOpen, onChange: setLinkPopoverOpen, position: "bottom", width: 330, trapFocus: true, children: [_jsx(Popover.Target, { children: _jsx(Button, { size: "xs", variant: "outlined", title: "Link", "aria-label": "Link", selected: linkPopoverOpen || Boolean(editor === null || editor === void 0 ? void 0 : editor.isActive("link")), disabled: !editor, style: { padding: "1px 6px" }, children: _jsx(LinkIcon, { size: 14 }) }) }), _jsx(Popover.Dropdown, { children: editor && (_jsx(LinkEditor, { editor: editor, autoFocus: linkPopoverOpen, onClose: () => setLinkPopoverOpen(false) })) })] })), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE)) && _jsx(CodeControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE_BLOCK)) && (_jsx(CodeBlockControl, { editor: editor }))] }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TABLE)) && (_jsx(TableToolsPopover, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CLEAR_FORMATTING)) && (_jsx(ClearFormattingControl, { editor: editor }))] }));
75
+ }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDO)) && _jsx(UndoControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.REDO)) && _jsx(RedoControl, { editor: editor })] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.FONT)) && _jsx(FontControl, {}), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.COLOR)) && (_jsx(TextColorControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HIGHLIGHT)) && (_jsx(HighlightControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BOLD)) && _jsx(BoldControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.ITALIC)) && (_jsx(ItalicControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDERLINE)) && (_jsx(UnderlineControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.STRIKE)) && (_jsx(StrikeThroughControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [headingLevels.length > 0 && (_jsx(HeadingControl, { editor: editor, levels: headingLevels })), alignments.length > 0 && (_jsx(AlignmentControl, { editor: editor, alignments: alignments })), listTypes.length > 0 && (_jsx(ListControl, { editor: editor, listTypes: listTypes })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BLOCKQUOTE)) && (_jsx(BlockquoteControl, { editor: editor }))] }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.LINK)) && (_jsxs(Popover, { opened: linkPopoverOpen, onChange: setLinkPopoverOpen, position: "bottom", width: 330, trapFocus: true, children: [_jsx(Popover.Target, { children: _jsx(Button, { size: "xs", variant: "outlined", title: "Link", "aria-label": "Link", selected: linkPopoverOpen || Boolean(editor === null || editor === void 0 ? void 0 : editor.isActive("link")), disabled: !editor, style: { padding: "1px 6px" }, children: _jsx(LinkIcon, { size: 14 }) }) }), _jsx(Popover.Dropdown, { children: editor && (_jsx(LinkEditor, { editor: editor, autoFocus: linkPopoverOpen, onClose: () => setLinkPopoverOpen(false) })) })] })), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE)) && _jsx(CodeControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE_BLOCK)) && (_jsx(CodeBlockControl, { editor: editor }))] }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TABLE)) && (_jsx(TableToolsPopover, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HORIZONTAL_RULE)) && (_jsx(HorizontalRuleControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CLEAR_FORMATTING)) && (_jsx(ClearFormattingControl, { editor: editor }))] }));
50
76
  };
@@ -0,0 +1,3 @@
1
+ import { ResizeHandlerProps } from "../types";
2
+ declare const resizeHandler: ({ event, columnId, columnProps, onResize, onResizeFinished, }: ResizeHandlerProps) => void;
3
+ export default resizeHandler;