@monolith-forensics/monolith-ui 1.9.1-dev.9 → 1.9.3-dev.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 (125) hide show
  1. package/dist/Charts/BarChart/BarChart.js +28 -14
  2. package/dist/Charts/BarChart/BarChart.styled.d.ts +7 -2
  3. package/dist/Charts/BarChart/BarChart.styled.js +5 -1
  4. package/dist/Charts/BarChart/BarChart.types.d.ts +13 -5
  5. package/dist/Charts/ChartUtils/chartSizing.d.ts +20 -0
  6. package/dist/Charts/ChartUtils/chartSizing.js +83 -0
  7. package/dist/Charts/ChartUtils/index.d.ts +1 -0
  8. package/dist/Charts/ChartUtils/index.js +1 -0
  9. package/dist/Charts/HeatMap/HeatMap.js +28 -7
  10. package/dist/Charts/HeatMap/HeatMap.styled.d.ts +6 -2
  11. package/dist/Charts/HeatMap/HeatMap.styled.js +3 -0
  12. package/dist/Charts/HeatMap/HeatMap.types.d.ts +7 -1
  13. package/dist/Charts/LineChart/LineChart.js +34 -15
  14. package/dist/Charts/LineChart/LineChart.styled.d.ts +7 -2
  15. package/dist/Charts/LineChart/LineChart.styled.js +5 -1
  16. package/dist/Charts/LineChart/LineChart.types.d.ts +13 -5
  17. package/dist/Charts/PieChart/PieChart.js +48 -33
  18. package/dist/Charts/PieChart/PieChart.styled.d.ts +7 -2
  19. package/dist/Charts/PieChart/PieChart.styled.js +6 -1
  20. package/dist/Charts/PieChart/PieChart.types.d.ts +7 -3
  21. package/dist/DropDownMenu/components/MenuItemList.js +32 -12
  22. package/dist/DropDownMenu/components/StyledContent.js +1 -1
  23. package/dist/DropDownMenu/components/StyledInnerItemContainer.js +1 -0
  24. package/dist/FieldLabel/FieldLabel.js +3 -18
  25. package/dist/FileViewer/FileViewer.js +32 -8
  26. package/dist/FileViewer/viewers/ImageViewer.d.ts +1 -0
  27. package/dist/FileViewer/viewers/ImageViewer.js +36 -15
  28. package/dist/MonolithUIProvider/MonolithUIProvider.d.ts +23 -0
  29. package/dist/RichTextEditor/Components/BubbleMenu.d.ts +3 -3
  30. package/dist/RichTextEditor/Components/BubbleMenu.js +190 -51
  31. package/dist/RichTextEditor/Components/CodeBlockBaseButton.d.ts +18 -0
  32. package/dist/RichTextEditor/Components/CodeBlockBaseButton.js +6 -0
  33. package/dist/RichTextEditor/Components/CodeBlockCopyButton.d.ts +9 -0
  34. package/dist/RichTextEditor/Components/CodeBlockCopyButton.js +42 -0
  35. package/dist/RichTextEditor/Components/CodeBlockFormatButton.d.ts +10 -0
  36. package/dist/RichTextEditor/Components/CodeBlockFormatButton.js +60 -0
  37. package/dist/RichTextEditor/Components/CodeBlockLanguageSelect.d.ts +9 -0
  38. package/dist/RichTextEditor/Components/CodeBlockLanguageSelect.js +30 -0
  39. package/dist/RichTextEditor/Components/CodeBlockNodeView.d.ts +3 -0
  40. package/dist/RichTextEditor/Components/CodeBlockNodeView.js +28 -0
  41. package/dist/RichTextEditor/Components/CodeBlockWrapButton.d.ts +10 -0
  42. package/dist/RichTextEditor/Components/CodeBlockWrapButton.js +17 -0
  43. package/dist/RichTextEditor/Components/LinkEditor.d.ts +8 -0
  44. package/dist/RichTextEditor/Components/LinkEditor.js +94 -0
  45. package/dist/RichTextEditor/Components/TableTools/TableCornerMenu.d.ts +2 -0
  46. package/dist/RichTextEditor/Components/TableTools/TableCornerMenu.js +19 -0
  47. package/dist/RichTextEditor/Components/TableTools/TableInsertControls.d.ts +2 -0
  48. package/dist/RichTextEditor/Components/TableTools/TableInsertControls.js +24 -0
  49. package/dist/RichTextEditor/Components/TableTools/TableRails.d.ts +2 -0
  50. package/dist/RichTextEditor/Components/TableTools/TableRails.js +180 -0
  51. package/dist/RichTextEditor/Components/TableTools/TableToolMenu.d.ts +5 -0
  52. package/dist/RichTextEditor/Components/TableTools/TableToolMenu.js +6 -0
  53. package/dist/RichTextEditor/Components/TableTools/TableTools.actions.d.ts +5 -0
  54. package/dist/RichTextEditor/Components/TableTools/TableTools.actions.js +183 -0
  55. package/dist/RichTextEditor/Components/TableTools/TableTools.commands.d.ts +16 -0
  56. package/dist/RichTextEditor/Components/TableTools/TableTools.commands.js +217 -0
  57. package/dist/RichTextEditor/Components/TableTools/TableTools.constants.d.ts +8 -0
  58. package/dist/RichTextEditor/Components/TableTools/TableTools.constants.js +11 -0
  59. package/dist/RichTextEditor/Components/TableTools/TableTools.d.ts +3 -0
  60. package/dist/RichTextEditor/Components/TableTools/TableTools.geometry.d.ts +23 -0
  61. package/dist/RichTextEditor/Components/TableTools/TableTools.geometry.js +75 -0
  62. package/dist/RichTextEditor/Components/TableTools/TableTools.js +3 -0
  63. package/dist/RichTextEditor/Components/TableTools/TableTools.selectors.d.ts +16 -0
  64. package/dist/RichTextEditor/Components/TableTools/TableTools.selectors.js +53 -0
  65. package/dist/RichTextEditor/Components/TableTools/TableTools.styled.d.ts +40 -0
  66. package/dist/RichTextEditor/Components/TableTools/TableTools.styled.js +167 -0
  67. package/dist/RichTextEditor/Components/TableTools/TableTools.types.d.ts +76 -0
  68. package/dist/RichTextEditor/Components/TableTools/TableTools.types.js +1 -0
  69. package/dist/RichTextEditor/Components/TableTools/TableTools.utils.d.ts +4 -0
  70. package/dist/RichTextEditor/Components/TableTools/TableTools.utils.js +4 -0
  71. package/dist/RichTextEditor/Components/TableTools/TableToolsPopover.d.ts +2 -0
  72. package/dist/RichTextEditor/Components/TableTools/TableToolsPopover.js +12 -0
  73. package/dist/RichTextEditor/Components/TableTools/index.d.ts +3 -0
  74. package/dist/RichTextEditor/Components/TableTools/index.js +2 -0
  75. package/dist/RichTextEditor/Enums/Controls.d.ts +7 -1
  76. package/dist/RichTextEditor/Enums/Controls.js +6 -0
  77. package/dist/RichTextEditor/Enums/Extensions.d.ts +4 -0
  78. package/dist/RichTextEditor/Enums/Extensions.js +4 -0
  79. package/dist/RichTextEditor/Enums/HighlightColors.d.ts +9 -0
  80. package/dist/RichTextEditor/Enums/HighlightColors.js +10 -0
  81. package/dist/RichTextEditor/Enums/SlashCommands.d.ts +4 -1
  82. package/dist/RichTextEditor/Enums/SlashCommands.js +3 -0
  83. package/dist/RichTextEditor/Extensions/SlashCommandList.js +0 -1
  84. package/dist/RichTextEditor/Extensions/getSlashCommand.d.ts +23 -3
  85. package/dist/RichTextEditor/Extensions/getSlashCommand.js +53 -7
  86. package/dist/RichTextEditor/Extensions/getTiptapExtensions.d.ts +15 -2
  87. package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +159 -24
  88. package/dist/RichTextEditor/Plugins/ImageActionsPlugin.js +4 -7
  89. package/dist/RichTextEditor/RichTextEditor.d.ts +9 -4
  90. package/dist/RichTextEditor/RichTextEditor.js +352 -14
  91. package/dist/RichTextEditor/Toolbar/Control.d.ts +6 -2
  92. package/dist/RichTextEditor/Toolbar/Control.js +13 -6
  93. package/dist/RichTextEditor/Toolbar/Controls.d.ts +6 -0
  94. package/dist/RichTextEditor/Toolbar/Controls.js +118 -1
  95. package/dist/RichTextEditor/Toolbar/ControlsGroup.js +17 -6
  96. package/dist/RichTextEditor/Toolbar/Labels.d.ts +1 -0
  97. package/dist/RichTextEditor/Toolbar/Labels.js +1 -0
  98. package/dist/RichTextEditor/Toolbar/Toolbar.d.ts +1 -2
  99. package/dist/RichTextEditor/Toolbar/Toolbar.js +32 -67
  100. package/dist/RichTextEditor/Utils/codeBlockUtils.d.ts +20 -0
  101. package/dist/RichTextEditor/Utils/codeBlockUtils.js +137 -0
  102. package/dist/RichTextEditor/Utils/codeUtils.d.ts +3 -0
  103. package/dist/RichTextEditor/Utils/codeUtils.js +12 -0
  104. package/dist/RichTextEditor/Utils/linkUtils.d.ts +19 -0
  105. package/dist/RichTextEditor/Utils/linkUtils.js +57 -0
  106. package/dist/RichTextEditor/Utils/tableUtils.d.ts +1 -0
  107. package/dist/RichTextEditor/Utils/tableUtils.js +1 -0
  108. package/dist/SegmentedControl/SegmentedControl.js +1 -1
  109. package/dist/SegmentedControl/SegmentedControl.styles.d.ts +1 -0
  110. package/dist/SegmentedControl/SegmentedControl.styles.js +30 -14
  111. package/dist/SegmentedControl/SegmentedControl.utils.d.ts +1 -0
  112. package/dist/SegmentedControl/SegmentedControl.utils.js +5 -2
  113. package/dist/Table/Table.js +4 -3
  114. package/dist/Table/TableComponents.d.ts +3 -0
  115. package/dist/Table/TableComponents.js +47 -0
  116. package/dist/Table/TableHeader.js +1 -1
  117. package/dist/Table/TableMenu/TableMenu.js +4 -3
  118. package/dist/Table/TableProvider.js +39 -0
  119. package/dist/Table/TableRow.js +1 -1
  120. package/dist/Table/types.d.ts +6 -0
  121. package/dist/Utilities/getImageTextContent.d.ts +78 -0
  122. package/dist/Utilities/getImageTextContent.js +222 -0
  123. package/dist/core/controlSizes.js +9 -9
  124. package/dist/theme/variants.js +46 -0
  125. package/package.json +8 -1
@@ -14,14 +14,73 @@ 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
18
  import { Toolbar } from "./Toolbar";
18
- import getTipTapExtensions from "./Extensions/getTiptapExtensions";
19
- import { Extensions, SlashCommands } from "./Enums";
19
+ import getTipTapExtensions, { resolveExtensions, } from "./Extensions/getTiptapExtensions";
20
+ import { Controls, Extensions, SlashCommands } from "./Enums";
20
21
  import { addImagePlaceholder, removeImagePlaceholder, startImageUpload, } from "./Plugins/UploadImagesPlugin";
21
22
  import SaveBadge from "./Components/SaveBadge";
22
23
  import BubbleMenuContent from "./Components/BubbleMenu";
24
+ import { TableRails } from "./Components/TableTools";
23
25
  import Fonts from "./Enums/Fonts";
24
26
  import RichTextEditorContext from "./Contexts/RichTextEditorContext";
27
+ import { getLinkAttributesAtPosition, getLinkRangeAtPosition, openLink, } from "./Utils/linkUtils";
28
+ import { TABLE_CELL_MIN_WIDTH } from "./Utils/tableUtils";
29
+ const codeBlockFallbacks = {
30
+ light: {
31
+ background: "#f6f8fa",
32
+ text: "#24292f",
33
+ border: "#d0d7de",
34
+ selection: "#0969da2e",
35
+ syntax: {
36
+ comment: "#6e7781",
37
+ punctuation: "#24292f",
38
+ property: "#0550ae",
39
+ selector: "#116329",
40
+ operator: "#cf222e",
41
+ keyword: "#cf222e",
42
+ string: "#0a3069",
43
+ number: "#0550ae",
44
+ function: "#8250df",
45
+ variable: "#953800",
46
+ tag: "#116329",
47
+ attribute: "#0550ae",
48
+ literal: "#0550ae",
49
+ deleted: "#82071e",
50
+ inserted: "#116329",
51
+ },
52
+ },
53
+ dark: {
54
+ background: "#0d1117",
55
+ text: "#c9d1d9",
56
+ border: "#30363d",
57
+ selection: "#1f6feb40",
58
+ syntax: {
59
+ comment: "#8b949e",
60
+ punctuation: "#c9d1d9",
61
+ property: "#79c0ff",
62
+ selector: "#7ee787",
63
+ operator: "#ff7b72",
64
+ keyword: "#ff7b72",
65
+ string: "#a5d6ff",
66
+ number: "#79c0ff",
67
+ function: "#d2a8ff",
68
+ variable: "#ffa657",
69
+ tag: "#7ee787",
70
+ attribute: "#79c0ff",
71
+ literal: "#79c0ff",
72
+ deleted: "#ffa198",
73
+ inserted: "#aff5b4",
74
+ },
75
+ },
76
+ };
77
+ const getCodeBlockTheme = (theme) => {
78
+ if (theme.palette.codeBlock)
79
+ return theme.palette.codeBlock;
80
+ return theme.palette.mode === "DARK"
81
+ ? codeBlockFallbacks.dark
82
+ : codeBlockFallbacks.light;
83
+ };
25
84
  const getImageFilesFromClipboard = (clipboardData) => {
26
85
  return Array.from(clipboardData.files).filter((file) => file.type.includes("image/"));
27
86
  };
@@ -275,25 +334,81 @@ const StyledContent = styled.div `
275
334
  word-break: break-word;
276
335
  text-rendering: optimizeLegibility;
277
336
 
337
+ .tableWrapper {
338
+ max-width: 100%;
339
+ overflow-x: auto;
340
+ padding: 5px 0px;
341
+ }
342
+
278
343
  table {
279
344
  border-collapse: collapse;
345
+ table-layout: fixed;
280
346
  width: 100%;
347
+ overflow: hidden;
281
348
 
282
349
  th,
283
350
  td {
284
351
  border: 1px solid ${({ theme }) => theme.palette.divider};
352
+ box-sizing: border-box;
285
353
  padding: 0.5rem;
286
- min-width: 100px;
354
+ min-width: ${TABLE_CELL_MIN_WIDTH}px;
355
+ position: relative;
356
+ vertical-align: top;
287
357
  }
288
358
 
289
359
  // for table header
290
360
  th {
291
361
  border: 1px solid ${({ theme }) => theme.palette.divider};
292
362
  padding: 0.5rem;
293
- min-width: 100px;
363
+ min-width: ${TABLE_CELL_MIN_WIDTH}px;
294
364
  background-color: ${({ theme }) => theme.palette.action.hover};
295
365
  font-weight: 500;
296
366
  }
367
+
368
+ [align="left"] {
369
+ text-align: left;
370
+ }
371
+
372
+ [align="center"] {
373
+ text-align: center;
374
+ }
375
+
376
+ [align="right"] {
377
+ text-align: right;
378
+ }
379
+ }
380
+
381
+ .column-resize-handle {
382
+ position: absolute;
383
+ top: 0;
384
+ right: -1px;
385
+ bottom: 0;
386
+ z-index: 20;
387
+ width: 2px;
388
+ background-color: ${({ theme }) => theme.palette.primary.main};
389
+ pointer-events: none;
390
+ }
391
+
392
+ &.resize-cursor {
393
+ cursor: col-resize;
394
+ }
395
+
396
+ .selectedCell::after {
397
+ position: absolute;
398
+ inset: 0;
399
+ z-index: 2;
400
+ background-color: ${({ theme }) => theme.palette.primary.main}22;
401
+ content: "";
402
+ pointer-events: none;
403
+ }
404
+
405
+ .monolith-table-rail-target::after {
406
+ position: absolute;
407
+ inset: 0;
408
+ z-index: 3;
409
+ background-color: ${({ theme }) => theme.palette.primary.main}18;
410
+ content: "";
411
+ pointer-events: none;
297
412
  }
298
413
 
299
414
  h1 {
@@ -320,6 +435,158 @@ const StyledContent = styled.div `
320
435
  margin: 0;
321
436
  line-height: 1.5rem;
322
437
  }
438
+ .editor-inline-code,
439
+ :not(pre) > code {
440
+ padding: 0.1rem 0.25rem;
441
+ border: 1px solid ${({ theme }) => theme.palette.divider};
442
+ border-radius: 4px;
443
+ background-color: ${({ theme }) => theme.palette.action.hover};
444
+ color: ${({ theme }) => theme.palette.text.secondary};
445
+ font-family:
446
+ ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Monaco, Consolas,
447
+ "Liberation Mono", "Courier New", monospace;
448
+ font-size: 0.9em;
449
+ box-decoration-break: clone;
450
+ }
451
+ .editor-code-block {
452
+ position: relative;
453
+ margin: 0.5rem 0;
454
+ padding: 1rem 0.875rem;
455
+ overflow-x: auto;
456
+ border: 1px solid ${({ theme }) => getCodeBlockTheme(theme).border};
457
+ border-radius: 6px;
458
+ background-color: ${({ theme }) => getCodeBlockTheme(theme).background};
459
+ color: ${({ theme }) => getCodeBlockTheme(theme).text};
460
+ font-family:
461
+ ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Monaco, Consolas,
462
+ "Liberation Mono", "Courier New", monospace;
463
+ font-size: 0.85rem;
464
+ line-height: 1.45rem;
465
+ white-space: pre;
466
+
467
+ ::selection {
468
+ background-color: ${({ theme }) => getCodeBlockTheme(theme).selection};
469
+ }
470
+
471
+ &[data-wrap="true"] {
472
+ white-space: pre-wrap;
473
+ word-break: break-word;
474
+ overflow-wrap: anywhere;
475
+ }
476
+
477
+ code {
478
+ display: block;
479
+ min-width: max-content;
480
+ padding: 0;
481
+ border: 0;
482
+ background-color: transparent;
483
+ color: inherit;
484
+ font: inherit;
485
+ }
486
+
487
+ &[data-wrap="true"] code {
488
+ min-width: 0;
489
+ white-space: inherit;
490
+ }
491
+
492
+ .editor-code-block-actions {
493
+ display: flex;
494
+ align-items: center;
495
+ position: absolute;
496
+ top: 0.4rem;
497
+ right: 0.4rem;
498
+ z-index: 1;
499
+ gap: 0.25rem;
500
+ opacity: 0;
501
+ transition: opacity 120ms ease-in-out;
502
+ }
503
+
504
+ &:hover .editor-code-block-actions,
505
+ &:focus-within .editor-code-block-actions {
506
+ opacity: 1;
507
+ }
508
+
509
+ .hljs-comment,
510
+ .hljs-quote {
511
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.comment};
512
+ }
513
+
514
+ .hljs-punctuation {
515
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.punctuation};
516
+ }
517
+
518
+ .hljs-property,
519
+ .hljs-attr,
520
+ .hljs-attribute,
521
+ .hljs-doctag {
522
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.property};
523
+ }
524
+
525
+ .hljs-selector-tag,
526
+ .hljs-selector-id,
527
+ .hljs-selector-class,
528
+ .hljs-selector-attr,
529
+ .hljs-selector-pseudo {
530
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.selector};
531
+ }
532
+
533
+ .hljs-operator,
534
+ .hljs-params {
535
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.operator};
536
+ }
537
+
538
+ .hljs-keyword,
539
+ .hljs-meta .hljs-keyword,
540
+ .hljs-template-tag,
541
+ .hljs-template-variable {
542
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.keyword};
543
+ }
544
+
545
+ .hljs-string,
546
+ .hljs-regexp {
547
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.string};
548
+ }
549
+
550
+ .hljs-number {
551
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.number};
552
+ }
553
+
554
+ .hljs-title,
555
+ .hljs-title.function_,
556
+ .hljs-title.class_ {
557
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.function};
558
+ }
559
+
560
+ .hljs-variable,
561
+ .hljs-name,
562
+ .hljs-section,
563
+ .hljs-symbol {
564
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.variable};
565
+ }
566
+
567
+ .hljs-tag {
568
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.tag};
569
+ }
570
+
571
+ .hljs-built_in,
572
+ .hljs-type,
573
+ .hljs-literal {
574
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.literal};
575
+ }
576
+
577
+ .hljs-meta,
578
+ .hljs-link {
579
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.attribute};
580
+ }
581
+
582
+ .hljs-deletion {
583
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.deleted};
584
+ }
585
+
586
+ .hljs-addition {
587
+ color: ${({ theme }) => getCodeBlockTheme(theme).syntax.inserted};
588
+ }
589
+ }
323
590
  ul {
324
591
  margin: 0;
325
592
  }
@@ -333,8 +600,6 @@ const StyledContent = styled.div `
333
600
  color: ${({ theme }) => theme.palette.text.primary};
334
601
  text-decoration: underline;
335
602
  cursor: pointer;
336
- // Set title attribute
337
- title: "Click to open link";
338
603
  }
339
604
  img {
340
605
  max-width: 100%;
@@ -352,6 +617,7 @@ const StyledContent = styled.div `
352
617
  color: #888;
353
618
  pointer-events: none;
354
619
  height: 0;
620
+ white-space: nowrap;
355
621
  }
356
622
  .ProseMirror .is-empty::before {
357
623
  content: attr(data-placeholder);
@@ -359,6 +625,7 @@ const StyledContent = styled.div `
359
625
  color: #888;
360
626
  pointer-events: none;
361
627
  height: 0;
628
+ white-space: nowrap;
362
629
  }
363
630
 
364
631
  .ProseMirror .monolith-image.uploading {
@@ -546,18 +813,69 @@ const StyledContent = styled.div `
546
813
  margin: 0 0.125rem;
547
814
  }
548
815
  `;
549
- export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = "", value, readOnly = false, font, showToolbar = true, saving = false, extensions = [], slashCommands = [], bubbleMenuOptions, toolbarOptions, autoFocus, onChange, handleImageUpload, handleImageUrlUpload, style, }) => {
816
+ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = "", value, readOnly = false, font, showToolbar = true, saving = false, disabledExtensions = [], extensionPreset = "basic", extensions = [], slashCommands = [], customSlashCommands = [], bubbleMenuOptions, toolbarOptions, autoFocus, onChange, handleImageUpload, handleImageUrlUpload, style, }) => {
817
+ const resolvedExtensions = useMemo(() => resolveExtensions({
818
+ disabledExtensions,
819
+ extensionPreset,
820
+ extensions,
821
+ }), [disabledExtensions, extensionPreset, extensions]);
822
+ const resolvedExtensionSet = useMemo(() => new Set(resolvedExtensions), [resolvedExtensions]);
823
+ const resolvedSlashCommands = useMemo(() => slashCommands.filter((command) => {
824
+ if (command === SlashCommands.Code) {
825
+ return resolvedExtensionSet.has(Extensions.Code);
826
+ }
827
+ if (command === SlashCommands.CodeBlock) {
828
+ return resolvedExtensionSet.has(Extensions.CodeBlock);
829
+ }
830
+ if (command === SlashCommands.Table) {
831
+ return resolvedExtensionSet.has(Extensions.Table);
832
+ }
833
+ return true;
834
+ }), [resolvedExtensionSet, slashCommands]);
835
+ const resolvedToolbarOptions = useMemo(() => {
836
+ if (!(toolbarOptions === null || toolbarOptions === void 0 ? void 0 : toolbarOptions.controls))
837
+ return toolbarOptions;
838
+ const controlExtensionMap = {
839
+ [Controls.BOLD]: Extensions.Bold,
840
+ [Controls.ITALIC]: Extensions.Italic,
841
+ [Controls.UNDERLINE]: Extensions.Underline,
842
+ [Controls.STRIKE]: Extensions.Strike,
843
+ [Controls.CODE]: Extensions.Code,
844
+ [Controls.CODE_BLOCK]: Extensions.CodeBlock,
845
+ [Controls.BULLET_LIST]: Extensions.BulletList,
846
+ [Controls.ORDERED_LIST]: Extensions.OrderedList,
847
+ [Controls.COLOR]: Extensions.Color,
848
+ [Controls.HIGHLIGHT]: Extensions.Highlight,
849
+ [Controls.LINK]: Extensions.Link,
850
+ [Controls.TEXT_ALIGN_LEFT]: Extensions.TextAlign,
851
+ [Controls.TEXT_ALIGN_CENTER]: Extensions.TextAlign,
852
+ [Controls.TEXT_ALIGN_RIGHT]: Extensions.TextAlign,
853
+ [Controls.TEXT_ALIGN_JUSTIFIED]: Extensions.TextAlign,
854
+ [Controls.TABLE]: Extensions.Table,
855
+ };
856
+ return Object.assign(Object.assign({}, toolbarOptions), { controls: toolbarOptions.controls.filter((control) => {
857
+ if (typeof control !== "string")
858
+ return true;
859
+ const extension = controlExtensionMap[control];
860
+ return !extension || resolvedExtensionSet.has(extension);
861
+ }) });
862
+ }, [resolvedExtensionSet, toolbarOptions]);
550
863
  const isControlled = value !== undefined;
551
- const hasImageExtension = extensions.includes(Extensions.Image);
552
- const hasSlashCommandExtension = extensions.includes(Extensions.SlashCommand);
553
- const hasBubbleMenuExtension = extensions.includes(Extensions.BubbleMenu);
554
- const hasImageSlashCommand = hasSlashCommandExtension && slashCommands.includes(SlashCommands.Image);
864
+ const hasImageExtension = resolvedExtensionSet.has(Extensions.Image);
865
+ const hasSlashCommandExtension = resolvedExtensionSet.has(Extensions.SlashCommand);
866
+ const hasBubbleMenuExtension = resolvedExtensionSet.has(Extensions.BubbleMenu);
867
+ const hasTableExtension = resolvedExtensionSet.has(Extensions.Table);
868
+ const hasImageSlashCommand = hasSlashCommandExtension &&
869
+ resolvedSlashCommands.includes(SlashCommands.Image);
555
870
  const onChangeRef = useRef(onChange);
871
+ const customSlashCommandsRef = useRef(customSlashCommands);
556
872
  const bubbleMenuPortalRef = useRef(null);
557
873
  const [fontState, setFontState] = useState(font || Fonts.DEFAULT);
874
+ customSlashCommandsRef.current = customSlashCommands;
558
875
  useEffect(() => {
559
876
  onChangeRef.current = onChange;
560
877
  }, [onChange]);
878
+ const getCustomSlashCommands = useCallback(() => customSlashCommandsRef.current, []);
561
879
  const getBubbleMenuPortalRoot = useCallback(() => {
562
880
  if (bubbleMenuPortalRef.current) {
563
881
  return bubbleMenuPortalRef.current;
@@ -609,11 +927,31 @@ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = ""
609
927
  editable: !readOnly,
610
928
  shouldRerenderOnTransaction: true,
611
929
  extensions: getTipTapExtensions({
612
- extensions,
613
- slashCommands,
930
+ disabledExtensions,
931
+ extensions: resolvedExtensions,
932
+ slashCommands: resolvedSlashCommands,
933
+ customSlashCommands,
934
+ getCustomSlashCommands,
614
935
  handleImageUpload,
615
936
  }),
616
937
  editorProps: {
938
+ handleClick: (view, pos, event) => {
939
+ const linkRange = getLinkRangeAtPosition(view.state, pos);
940
+ const linkAttributes = getLinkAttributesAtPosition(view.state, pos);
941
+ if (!linkRange || !(linkAttributes === null || linkAttributes === void 0 ? void 0 : linkAttributes.href))
942
+ return false;
943
+ const mouseEvent = event;
944
+ mouseEvent.preventDefault();
945
+ mouseEvent.stopPropagation();
946
+ const shouldOpenLink = mouseEvent.metaKey || mouseEvent.ctrlKey || !view.editable;
947
+ if (shouldOpenLink) {
948
+ openLink(linkAttributes.href);
949
+ return true;
950
+ }
951
+ view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, linkRange.from, linkRange.to)));
952
+ view.focus();
953
+ return true;
954
+ },
617
955
  handlePaste: (view, event) => {
618
956
  if (!hasImageExtension || !handleImageUpload)
619
957
  return false;
@@ -674,5 +1012,5 @@ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = ""
674
1012
  return (_jsx(StyledContent, { className: className, children: _jsxs(RichTextEditorContext.Provider, { value: {
675
1013
  font: fontState,
676
1014
  setFont: setFontState,
677
- }, children: [showToolbar && (_jsx(Toolbar, { editor: editor, toolbarOptions: toolbarOptions })), saving && _jsx(SaveBadge, {}), editor && hasBubbleMenuExtension && (_jsx(TiptapBubbleMenu, { editor: editor, pluginKey: "bubbleMenu", updateDelay: 150, appendTo: getBubbleMenuPortalRoot, shouldShow: shouldShowBubbleMenu, options: bubbleMenuPositionOptions, children: _jsx(BubbleMenuContent, { editor: editor, customMenuItems: bubbleMenuOptions === null || bubbleMenuOptions === void 0 ? void 0 : bubbleMenuOptions.customMenuItems }) })), _jsx(EditorContent, { className: "editor-content", editor: editor, "data-font": fontState || null, style: style })] }) }));
1015
+ }, children: [showToolbar && (_jsx(Toolbar, { editor: editor, toolbarOptions: resolvedToolbarOptions })), saving && _jsx(SaveBadge, {}), editor && hasBubbleMenuExtension && (_jsx(TiptapBubbleMenu, { editor: editor, pluginKey: "bubbleMenu", updateDelay: 200, appendTo: getBubbleMenuPortalRoot, shouldShow: shouldShowBubbleMenu, options: bubbleMenuPositionOptions, children: _jsx(BubbleMenuContent, { editor: editor, customMenuItems: bubbleMenuOptions === null || bubbleMenuOptions === void 0 ? void 0 : bubbleMenuOptions.customMenuItems }) })), editor && hasTableExtension && _jsx(TableRails, { editor: editor }), _jsx(EditorContent, { className: "editor-content", editor: editor, "data-font": fontState || null, style: style })] }) }));
678
1016
  };
@@ -1,13 +1,17 @@
1
1
  import { Editor } from "@tiptap/react";
2
+ import { ButtonProps } from "../../Button";
2
3
  export type ControlProps = {
3
4
  className?: string;
4
5
  editor: Editor | null;
5
6
  isActive?: any;
6
- operation: {
7
+ operation?: {
7
8
  name: string;
8
9
  attributes?: any;
9
10
  };
11
+ onClick?: (editor: Editor | null) => void;
12
+ disabled?: boolean;
10
13
  label: string;
11
14
  icon: any;
15
+ size?: ButtonProps["size"];
12
16
  };
13
- export declare const Control: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<ControlProps, never>> & string & Omit<({ className, editor, isActive, operation, label, icon: Icon, }: ControlProps) => import("react/jsx-runtime").JSX.Element, keyof import("react").Component<any, {}, any>>;
17
+ export declare const Control: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<ControlProps, never>> & string & Omit<({ className, editor, isActive, operation, onClick, disabled, label, icon: Icon, size, }: ControlProps) => import("react/jsx-runtime").JSX.Element, keyof import("react").Component<any, {}, any>>;
@@ -1,23 +1,30 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import styled from "styled-components";
3
3
  import Labels from "./Labels";
4
- export const Control = styled(({ className, editor, isActive, operation, label, icon: Icon, }) => {
4
+ import { Button } from "../../Button";
5
+ export const Control = styled(({ className, editor, isActive, operation, onClick, disabled, label, icon: Icon, size = "xs", }) => {
5
6
  var _a;
6
7
  const _label = Labels[label];
7
8
  const active = (isActive === null || isActive === void 0 ? void 0 : isActive.name)
8
9
  ? (_a = editor === null || editor === void 0 ? void 0 : editor.isActive) === null || _a === void 0 ? void 0 : _a.call(editor, isActive.name, isActive.attributes)
9
10
  : false;
10
- return (_jsx("button", { className: className + (active ? " active" : ""), "aria-label": _label, "data-active": active, title: _label, onClick: () => {
11
+ return (_jsx(Button, { className: className + (active ? " active" : ""), "aria-label": _label, "data-active": active, title: _label, disabled: disabled, onClick: () => {
12
+ if (onClick) {
13
+ onClick(editor);
14
+ return;
15
+ }
16
+ if (!operation)
17
+ return;
11
18
  const focus = editor === null || editor === void 0 ? void 0 : editor.chain().focus();
12
19
  focus[operation.name](operation.attributes).run();
13
- }, children: _jsx(Icon, { size: "16px" }) }));
20
+ }, size: size, children: _jsx(Icon, { size: "16px" }) }));
14
21
  }) `
15
22
  display: flex;
16
23
  justify-content: center;
17
24
  align-items: center;
18
- width: 1.5rem;
19
- height: 1.5rem;
20
- padding: 0px;
25
+
26
+ padding: 5px;
27
+
21
28
  background-color: transparent;
22
29
  cursor: pointer;
23
30
  color: ${({ theme }) => theme.palette.text.primary};
@@ -4,10 +4,16 @@ interface ControlProps {
4
4
  }
5
5
  export declare const UndoControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
6
6
  export declare const RedoControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const FontControl: () => import("react/jsx-runtime").JSX.Element;
8
+ export declare const TextColorControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
9
+ export declare const HighlightControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
10
+ export declare const ClearFormattingControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
7
11
  export declare const BoldControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
8
12
  export declare const ItalicControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
9
13
  export declare const UnderlineControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
10
14
  export declare const StrikeThroughControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
15
+ export declare const CodeControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
16
+ export declare const CodeBlockControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
11
17
  export declare const Heading1Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
12
18
  export declare const Heading2Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
13
19
  export declare const Heading3Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,17 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { IconBold, IconItalic, IconUnderline, IconStrikethrough, IconH1, IconH2, IconH3, IconH4, IconList, IconListNumbers, IconAlignLeft, IconAlignRight, IconAlignCenter, IconAlignJustified, IconCornerUpLeft, IconCornerUpRight, } from "@tabler/icons-react";
3
+ import { CodeIcon, HighlighterIcon, PaletteIcon, RemoveFormattingIcon, SquircleIcon, TypeIcon, } from "lucide-react";
4
+ import { SquareCodeIcon } from "lucide-react";
3
5
  import { Control } from "./Control";
6
+ import { hasInlineCode, toggleInlineCode } from "../Utils/codeUtils";
7
+ import { hasSyntaxHighlightedCodeBlock, toggleCodeBlock, } from "../Utils/codeBlockUtils";
8
+ import { useContext } from "react";
9
+ import { useTheme } from "styled-components";
10
+ import { DropDownMenu } from "../../DropDownMenu";
11
+ import RichTextEditorContext from "../Contexts/RichTextEditorContext";
12
+ import Fonts from "../Enums/Fonts";
13
+ import TextColors from "../Enums/TextColors";
14
+ import HighlightColors from "../Enums/HighlightColors";
4
15
  export const UndoControl = ({ editor }) => {
5
16
  return (_jsx(Control, { editor: editor, label: "undoControlLabel", operation: {
6
17
  name: "undo",
@@ -11,6 +22,102 @@ export const RedoControl = ({ editor }) => {
11
22
  name: "redo",
12
23
  }, icon: IconCornerUpRight }));
13
24
  };
25
+ export const FontControl = () => {
26
+ const { font, setFont } = useContext(RichTextEditorContext);
27
+ return (_jsx(DropDownMenu, { data: Object.values(Fonts).map((font) => ({
28
+ label: font,
29
+ value: font,
30
+ onClick: () => {
31
+ setFont(font);
32
+ },
33
+ })), size: "xs", variant: "outlined", dropDownProps: {
34
+ style: {
35
+ width: 135,
36
+ },
37
+ }, buttonProps: {
38
+ title: "Select Font",
39
+ leftSection: _jsx(TypeIcon, { size: 12 }),
40
+ }, children: (font || Fonts.DEFAULT) }));
41
+ };
42
+ export const TextColorControl = ({ editor }) => {
43
+ const theme = useTheme();
44
+ return (_jsx(DropDownMenu, { data: [
45
+ {
46
+ label: "Default",
47
+ value: "default",
48
+ onClick: () => {
49
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().unsetColor().run();
50
+ },
51
+ },
52
+ ...Object.keys(TextColors).map((color) => {
53
+ const colorKey = color;
54
+ return {
55
+ label: color,
56
+ value: TextColors[colorKey],
57
+ onClick: () => {
58
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().setColor(TextColors[colorKey]).run();
59
+ },
60
+ };
61
+ }),
62
+ ], renderOption: (item) => (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 5 }, children: [_jsx(SquircleIcon, { size: 12, color: item.value === "default"
63
+ ? theme.palette.text.primary
64
+ : item.value, style: {
65
+ backgroundColor: item.value === "default"
66
+ ? theme.palette.text.primary
67
+ : item.value,
68
+ borderRadius: "3px",
69
+ } }), item.label] })), size: "xs", variant: "outlined", buttonProps: {
70
+ title: "Select Color",
71
+ style: { padding: "1px 6px" },
72
+ }, dropDownProps: {
73
+ style: {
74
+ width: 120,
75
+ },
76
+ }, children: _jsx(PaletteIcon, { size: 14 }) }));
77
+ };
78
+ export const HighlightControl = ({ editor }) => {
79
+ const theme = useTheme();
80
+ return (_jsx(DropDownMenu, { data: [
81
+ {
82
+ label: "Default",
83
+ value: "default",
84
+ onClick: () => {
85
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().unsetHighlight().run();
86
+ },
87
+ },
88
+ ...Object.keys(HighlightColors).map((color) => {
89
+ const colorKey = color;
90
+ return {
91
+ label: color,
92
+ value: HighlightColors[colorKey],
93
+ onClick: () => {
94
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().setHighlight({ color: HighlightColors[colorKey] }).run();
95
+ },
96
+ };
97
+ }),
98
+ ], renderOption: (item) => (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 5 }, children: [_jsx(SquircleIcon, { size: 12, color: item.value === "default"
99
+ ? theme.palette.text.primary
100
+ : item.value, style: {
101
+ backgroundColor: item.value === "default"
102
+ ? "transparent"
103
+ : item.value,
104
+ borderRadius: "3px",
105
+ } }), item.label] })), size: "xs", variant: "outlined", buttonProps: {
106
+ title: "Select Highlight",
107
+ style: { padding: "1px 6px" },
108
+ }, dropDownProps: {
109
+ style: {
110
+ width: 100,
111
+ height: 210,
112
+ },
113
+ }, children: _jsx(HighlighterIcon, { size: 14 }) }));
114
+ };
115
+ export const ClearFormattingControl = ({ editor }) => {
116
+ return (_jsx(Control, { editor: editor, label: "clearFormattingControlLabel", onClick: (editor) => {
117
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().setParagraph().run();
118
+ editor === null || editor === void 0 ? void 0 : editor.chain().focus().unsetAllMarks().run();
119
+ }, icon: RemoveFormattingIcon }));
120
+ };
14
121
  export const BoldControl = ({ editor }) => {
15
122
  return (_jsx(Control, { editor: editor, label: "boldControlLabel", isActive: {
16
123
  name: "bold",
@@ -39,6 +146,16 @@ export const StrikeThroughControl = ({ editor }) => {
39
146
  name: "toggleStrike",
40
147
  }, icon: IconStrikethrough }));
41
148
  };
149
+ export const CodeControl = ({ editor }) => {
150
+ return (_jsx(Control, { editor: editor, label: "codeControlLabel", isActive: {
151
+ name: "code",
152
+ }, onClick: toggleInlineCode, disabled: !hasInlineCode(editor), icon: CodeIcon }));
153
+ };
154
+ export const CodeBlockControl = ({ editor }) => {
155
+ return (_jsx(Control, { editor: editor, label: "codeBlockControlLabel", isActive: {
156
+ name: "codeBlock",
157
+ }, onClick: toggleCodeBlock, disabled: !hasSyntaxHighlightedCodeBlock(editor), icon: SquareCodeIcon }));
158
+ };
42
159
  export const Heading1Control = ({ editor }) => {
43
160
  return (_jsx(Control, { editor: editor, label: "h1ControlLabel", isActive: {
44
161
  name: "heading",