react-lite-rich-text-editor 1.1.1 → 1.1.3
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.
- package/README.md +27 -10
- package/dist/index.cjs.js +754 -43
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +754 -43
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -507,6 +507,82 @@ var FaFont = function FaFont(_ref12) {
|
|
|
507
507
|
}
|
|
508
508
|
});
|
|
509
509
|
};
|
|
510
|
+
var FaTable = function FaTable(_ref14) {
|
|
511
|
+
var className = _ref14.className,
|
|
512
|
+
size = _ref14.size,
|
|
513
|
+
color = _ref14.color,
|
|
514
|
+
style = _ref14.style;
|
|
515
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
516
|
+
className: className,
|
|
517
|
+
style: _objectSpread2({
|
|
518
|
+
display: 'inline-flex',
|
|
519
|
+
alignItems: 'center',
|
|
520
|
+
justifyContent: 'center',
|
|
521
|
+
fontSize: size || '1em',
|
|
522
|
+
color: color || 'inherit'
|
|
523
|
+
}, style),
|
|
524
|
+
dangerouslySetInnerHTML: {
|
|
525
|
+
__html: "<svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 512 512\" height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M64 448c-35.3 0-64-28.7-64-64V128c0-35.3 28.7-64 64-64H448c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64zm96-288H64v64h96v-64zm0 96H64v64h96v-64zm0 96H64c0 17.7 14.3 32 32 32h64v-32zm128-192h-96v64h96v-64zm0 96h-96v64h96v-64zm0 96h-96v96h96v-96zm160-192h-96v64h96v-64zm0 96h-96v64h96v-64zm0 96h-96v64h64c17.7 0 32-14.3 32-32v-32z\"></path></svg>"
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
};
|
|
529
|
+
var FaObjectGroup = function FaObjectGroup(_ref16) {
|
|
530
|
+
var className = _ref16.className,
|
|
531
|
+
size = _ref16.size,
|
|
532
|
+
color = _ref16.color,
|
|
533
|
+
style = _ref16.style;
|
|
534
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
535
|
+
className: className,
|
|
536
|
+
style: _objectSpread2({
|
|
537
|
+
display: 'inline-flex',
|
|
538
|
+
alignItems: 'center',
|
|
539
|
+
justifyContent: 'center',
|
|
540
|
+
fontSize: size || '1em',
|
|
541
|
+
color: color || 'inherit'
|
|
542
|
+
}, style),
|
|
543
|
+
dangerouslySetInnerHTML: {
|
|
544
|
+
__html: "<svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 512 512\" height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M480 320h-48v48c0 17.7-14.3 32-32 32h-48v32c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V160c0-26.5 21.5-48 48-48h32v-48c0-17.7 14.3-32 32-32h48V0h32c26.5 0 48 21.5 48 48v48h48c17.7 0 32 14.3 32 32v48h32c26.5 0 48 21.5 48 48v128c0 26.5-21.5 48-48 48z\"></path></svg>"
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
};
|
|
548
|
+
var FaTrash = function FaTrash(_ref17) {
|
|
549
|
+
var className = _ref17.className,
|
|
550
|
+
size = _ref17.size,
|
|
551
|
+
color = _ref17.color,
|
|
552
|
+
style = _ref17.style;
|
|
553
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
554
|
+
className: className,
|
|
555
|
+
style: _objectSpread2({
|
|
556
|
+
display: 'inline-flex',
|
|
557
|
+
alignItems: 'center',
|
|
558
|
+
justifyContent: 'center',
|
|
559
|
+
fontSize: size || '1em',
|
|
560
|
+
color: color || 'inherit'
|
|
561
|
+
}, style),
|
|
562
|
+
dangerouslySetInnerHTML: {
|
|
563
|
+
__html: "<svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 448 512\" height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM53.2 467a48 48 0 0 0 47.9 45h245.8a48 48 0 0 0 47.9-45L416 128H32z\"></path></svg>"
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
};
|
|
567
|
+
var FaVideo = function FaVideo(_ref18) {
|
|
568
|
+
var className = _ref18.className,
|
|
569
|
+
size = _ref18.size,
|
|
570
|
+
color = _ref18.color,
|
|
571
|
+
style = _ref18.style;
|
|
572
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
573
|
+
className: className,
|
|
574
|
+
style: _objectSpread2({
|
|
575
|
+
display: 'inline-flex',
|
|
576
|
+
alignItems: 'center',
|
|
577
|
+
justifyContent: 'center',
|
|
578
|
+
fontSize: size || '1em',
|
|
579
|
+
color: color || 'inherit'
|
|
580
|
+
}, style),
|
|
581
|
+
dangerouslySetInnerHTML: {
|
|
582
|
+
__html: '<svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 576 512\" height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 128C0 92.7 28.7 64 64 64H320c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128zM559.1 99.8c10.4 5.6 16.9 16.3 16.9 28.2V384c0 11.9-6.5 22.6-16.9 28.2s-23 5-32.9-1.6l-96-64L416 337.1V174.9l14.2-9.5 96-64c9.9-6.6 22.6-7.1 32.9-1.6z\"></path></svg>'
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
};
|
|
510
586
|
|
|
511
587
|
// DraftJS helper stubs
|
|
512
588
|
// Since we are removing specific DraftJS dependencies for this package,
|
|
@@ -579,7 +655,7 @@ function styleInject(css, ref) {
|
|
|
579
655
|
}
|
|
580
656
|
}
|
|
581
657
|
|
|
582
|
-
var css_248z = ".rte-container{background-color:#fff;border:1px solid #e5e7eb;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,.05);overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1)}.rte-container:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,.1)}.rte-toolbar{align-items:center;background-color:#f9fafb;border-bottom:1px solid #f3f4f6;display:flex;flex-wrap:wrap;gap:4px;padding:8px}.rte-toolbar-button{align-items:center;background:transparent;border:none;border-radius:6px;color:#4b5563;cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:all .15s ease;width:32px}.rte-toolbar-button:hover{background-color:#f3f4f6;color:#111827}.rte-toolbar-button.active{background-color:#eff6ff;color:#2563eb}.rte-toolbar-button:disabled{cursor:not-allowed;opacity:.5}.rte-toolbar-select{background-color:#fff;border:1px solid #e5e7eb;border-radius:6px;color:#374151;cursor:pointer;font-size:14px;height:32px;outline:none;padding:0 8px;transition:border-color .15s ease}.rte-toolbar-select:hover{border-color:#d1d5db}.rte-toolbar-select:focus{border-color:#3b82f6}.rte-color-picker-label{align-items:center;border-radius:6px;cursor:pointer;display:flex;height:32px;justify-content:center;position:relative;transition:background-color .15s ease;width:32px}.rte-color-picker-label:hover{background-color:#f3f4f6}.rte-color-input{cursor:pointer;height:100%;inset:0;opacity:0;position:absolute;width:100%}.rte-content{color:#1f2937;font-family:inherit;font-size:16px;line-height:1.6;min-height:150px;outline:none;overflow-y:auto;padding:12px;word-break:break-word}.rte-content ul{list-style-type:disc;margin-left:1.5rem}.rte-content ol{list-style-type:decimal;margin-left:1.5rem}.rte-content img{border-radius:8px;height:auto;max-width:100%}.rte-modal-overlay{align-items:center;animation:rte-fade-in .2s ease-out;backdrop-filter:blur(4px);background-color:rgba(0,0,0,.5);display:flex;inset:0;justify-content:center;position:fixed;z-index:9999}.rte-modal{animation:rte-zoom-in .2s ease-out;background-color:#fff;border:1px solid #f3f4f6;border-radius:16px;box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);display:flex;flex-direction:column;gap:16px;max-width:400px;padding:
|
|
658
|
+
var css_248z = ".rte-container{background-color:#fff;border:1px solid #e5e7eb;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,.05);overflow:hidden;transition:all .2s cubic-bezier(.4,0,.2,1)}.rte-container:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,.1)}.rte-toolbar{align-items:center;background-color:#f9fafb;border-bottom:1px solid #f3f4f6;display:flex;flex-wrap:wrap;gap:4px;padding:8px}.rte-toolbar-button{align-items:center;background:transparent;border:none;border-radius:6px;color:#4b5563;cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;transition:all .15s ease;width:32px}.rte-toolbar-button:hover{background-color:#f3f4f6;color:#111827}.rte-toolbar-button.active{background-color:#eff6ff;color:#2563eb}.rte-toolbar-button:disabled{cursor:not-allowed;opacity:.5}.rte-toolbar-button-danger:hover{background-color:#fef2f2!important;color:#dc2626!important}.rte-toolbar-select{background-color:#fff;border:1px solid #e5e7eb;border-radius:6px;color:#374151;cursor:pointer;font-size:14px;height:32px;outline:none;padding:0 8px;transition:border-color .15s ease}.rte-toolbar-select:hover{border-color:#d1d5db}.rte-toolbar-select:focus{border-color:#3b82f6}.rte-color-picker-label{align-items:center;border-radius:6px;cursor:pointer;display:flex;height:32px;justify-content:center;position:relative;transition:background-color .15s ease;width:32px}.rte-color-picker-label:hover{background-color:#f3f4f6}.rte-color-input{cursor:pointer;height:100%;inset:0;opacity:0;position:absolute;width:100%}.rte-content{color:#1f2937;font-family:inherit;font-size:16px;line-height:1.6;min-height:150px;outline:none;overflow-y:auto;padding:12px;word-break:break-word}.rte-content ul{list-style-type:disc;margin-left:1.5rem}.rte-content ol{list-style-type:decimal;margin-left:1.5rem}.rte-content img{border-radius:8px;display:block;height:auto;max-width:100%}.rte-content table{border-collapse:collapse;margin:16px 0;width:100%}.rte-content td,.rte-content th{border:1px solid #e5e7eb;min-width:40px;padding:12px;word-break:break-word}.video-container{border-radius:12px;box-shadow:0 4px 6px -1px rgba(0,0,0,.1);height:0;margin:16px 0;overflow:hidden;padding-bottom:56.25%;position:relative}.video-container iframe{height:100%;left:0;position:absolute;top:0;width:100%}.rte-modal-overlay{align-items:center;animation:rte-fade-in .2s ease-out;backdrop-filter:blur(4px);background-color:rgba(0,0,0,.5);display:flex;inset:0;justify-content:center;position:fixed;z-index:9999}.rte-modal{animation:rte-zoom-in .2s ease-out;background-color:#fff;border:1px solid #f3f4f6;border-radius:16px;box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);display:flex;flex-direction:column;gap:16px;max-width:400px;padding:0;width:100%}.rte-modal-title{color:#111827;flex:1;font-size:18px;font-weight:600;margin:0;text-align:center}.rte-modal-header{align-items:center;border-bottom:1px solid #f3f4f6;display:flex;justify-content:space-between;padding:20px 24px 16px}.rte-form-group{display:flex;flex-direction:column;gap:8px;padding:16px 24px}.rte-label{color:#374151;font-size:14px;font-weight:600}.rte-input{border:1px solid #d1d5db;border-radius:8px;outline:none;padding:8px 12px;transition:all .15s ease;width:93%}.rte-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,.1)}.rte-modal-actions{border-top:1px solid #f3f4f6;display:flex;gap:12px;justify-content:flex-end;padding:16px 24px 20px}.rte-button{border:none;border-radius:8px;cursor:pointer;font-weight:500;padding:8px 16px;transition:all .15s ease}.rte-button-secondary{background-color:#f3f4f6;color:#4b5563}.rte-button-secondary:hover{background-color:#e5e7eb}.rte-button-primary{background-color:#2563eb;box-shadow:0 1px 2px rgba(0,0,0,.05);color:#fff}.rte-button-primary:hover{background-color:#1d4ed8}.rte-button-primary:disabled{cursor:not-allowed;opacity:.5}.rte-spinner-container{align-items:center;display:flex;justify-content:center;padding:16px}.rte-spinner{animation:rte-spin .8s linear infinite;border:3px solid #eff6ff;border-radius:50%;border-top-color:#3b82f6;height:32px;width:32px}@keyframes rte-spin{to{transform:rotate(1turn)}}@keyframes rte-fade-in{0%{opacity:0}to{opacity:1}}@keyframes rte-zoom-in{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.image-container{background:#f9fafb;border:1px solid #f3f4f6;border-radius:12px;box-sizing:border-box;margin:15px;max-width:100%;position:relative;transition:all .2s ease}.image-container.image-align-center{display:block;height:300px;margin:24px auto;width:100%}.image-container.image-align-left,.image-container.image-align-right{display:inline-block;height:300px;width:350px}.image-container.image-align-left{float:left;margin-right:24px}.image-container.image-align-right{float:right;margin-left:24px}.image-container img{background:#fff;border-radius:12px;display:block;height:100%;margin:0 auto;object-fit:contain;width:100%}.image-delete-button{align-items:center;background:#ef4444;border:3px solid #fff;border-radius:9999px;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);color:#fff;cursor:pointer;display:flex;font-size:18px;font-weight:700;height:26px;justify-content:center;line-height:1;padding:0;position:absolute;right:0;top:0;transform:translate(50%,-50%);transition:all .2s cubic-bezier(.4,0,.2,1);width:26px;z-index:50}.image-delete-button:hover{background:#b91c1c;box-shadow:0 10px 15px -3px rgba(0,0,0,.1);transform:translate(50%,-50%) scale(1.1)}.rte-table-delete-btn,.rte-table-delete-hover{align-items:center;display:flex;justify-content:center}.rte-table-delete-btn{background:#fff;border:1px solid #ef4444;border-radius:6px;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);color:#ef4444;cursor:pointer;height:28px;padding:0;transition:all .2s ease;width:28px}.rte-table-delete-btn:hover{background:#ef4444;color:#fff;transform:scale(1.1)}.rte-table-delete-btn:active{transform:scale(.95)}.image-container:after{clear:both;content:\"\";display:table}.rte-footer{background-color:#fcfcfd;border-top:1px solid #f3f4f6;display:flex;justify-content:flex-end;padding:6px 16px;user-select:none}.rte-footer-content{align-items:center;color:#9ca3af;display:flex;font-size:11px;gap:10px;letter-spacing:.025em}.rte-footer-separator{color:#e5e7eb;font-size:14px;line-height:1}.rte-footer-item b{color:#6b7280;font-weight:600}";
|
|
583
659
|
styleInject(css_248z);
|
|
584
660
|
|
|
585
661
|
// Helper functions for HTML escaping
|
|
@@ -595,9 +671,9 @@ var escapeAttr = function escapeAttr(str) {
|
|
|
595
671
|
var URL_REGEX = /(https?:\/\/[^\s]+)/g;
|
|
596
672
|
function RichTextEditor(_ref) {
|
|
597
673
|
var onChange = _ref.onChange,
|
|
598
|
-
showEditButton = _ref.showEditButton
|
|
599
|
-
|
|
600
|
-
_ref$disabled = _ref.disabled,
|
|
674
|
+
showEditButton = _ref.showEditButton;
|
|
675
|
+
_ref.onBlur;
|
|
676
|
+
var _ref$disabled = _ref.disabled,
|
|
601
677
|
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
602
678
|
_ref$editable = _ref.editable,
|
|
603
679
|
defaultEditable = _ref$editable === void 0 ? false : _ref$editable,
|
|
@@ -691,6 +767,42 @@ function RichTextEditor(_ref) {
|
|
|
691
767
|
_useState30 = _slicedToArray(_useState29, 2),
|
|
692
768
|
isUploading = _useState30[0],
|
|
693
769
|
setIsUploading = _useState30[1];
|
|
770
|
+
var _useState31 = React.useState(false),
|
|
771
|
+
_useState32 = _slicedToArray(_useState31, 2),
|
|
772
|
+
videoModalOpen = _useState32[0],
|
|
773
|
+
setVideoModalOpen = _useState32[1];
|
|
774
|
+
var _useState33 = React.useState(""),
|
|
775
|
+
_useState34 = _slicedToArray(_useState33, 2),
|
|
776
|
+
videoUrl = _useState34[0],
|
|
777
|
+
setVideoUrl = _useState34[1];
|
|
778
|
+
var _useState35 = React.useState(false),
|
|
779
|
+
_useState36 = _slicedToArray(_useState35, 2),
|
|
780
|
+
tableModalOpen = _useState36[0],
|
|
781
|
+
setTableModalOpen = _useState36[1];
|
|
782
|
+
var _useState37 = React.useState(null),
|
|
783
|
+
_useState38 = _slicedToArray(_useState37, 2);
|
|
784
|
+
_useState38[0];
|
|
785
|
+
var setHoveredTable = _useState38[1];
|
|
786
|
+
var _useState39 = React.useState(3),
|
|
787
|
+
_useState40 = _slicedToArray(_useState39, 2),
|
|
788
|
+
tableRows = _useState40[0],
|
|
789
|
+
setTableRows = _useState40[1];
|
|
790
|
+
var _useState41 = React.useState(3),
|
|
791
|
+
_useState42 = _slicedToArray(_useState41, 2),
|
|
792
|
+
tableCols = _useState42[0],
|
|
793
|
+
setTableCols = _useState42[1];
|
|
794
|
+
var _useState43 = React.useState(0),
|
|
795
|
+
_useState44 = _slicedToArray(_useState43, 2);
|
|
796
|
+
_useState44[0];
|
|
797
|
+
var setSelectionVersion = _useState44[1];
|
|
798
|
+
var _useState45 = React.useState(null),
|
|
799
|
+
_useState46 = _slicedToArray(_useState45, 2),
|
|
800
|
+
selectedImage = _useState46[0],
|
|
801
|
+
setSelectedImage = _useState46[1];
|
|
802
|
+
var _useState47 = React.useState(null),
|
|
803
|
+
_useState48 = _slicedToArray(_useState47, 2);
|
|
804
|
+
_useState48[0];
|
|
805
|
+
var setResizeData = _useState48[1];
|
|
694
806
|
var openImageModal = function openImageModal(url) {
|
|
695
807
|
if (editorRef.current) {
|
|
696
808
|
scrollTopRef.current = editorRef.current.scrollTop;
|
|
@@ -703,6 +815,13 @@ function RichTextEditor(_ref) {
|
|
|
703
815
|
setSelectedImageUrl("");
|
|
704
816
|
setZoomLevel(1);
|
|
705
817
|
};
|
|
818
|
+
var saveSelection = function saveSelection() {
|
|
819
|
+
if (typeof window === "undefined") return;
|
|
820
|
+
var sel = window.getSelection();
|
|
821
|
+
if (sel && sel.rangeCount > 0) {
|
|
822
|
+
selectionRangeRef.current = sel.getRangeAt(0).cloneRange();
|
|
823
|
+
}
|
|
824
|
+
};
|
|
706
825
|
var handleZoomIn = function handleZoomIn() {
|
|
707
826
|
setZoomLevel(function (prevZoom) {
|
|
708
827
|
return prevZoom + 0.1;
|
|
@@ -748,6 +867,10 @@ function RichTextEditor(_ref) {
|
|
|
748
867
|
}, [imageModalOpen]);
|
|
749
868
|
React.useEffect(function () {
|
|
750
869
|
var handleClick = function handleClick(e) {
|
|
870
|
+
// Trigger selection update for toolbar reactivity
|
|
871
|
+
setSelectionVersion(function (v) {
|
|
872
|
+
return v + 1;
|
|
873
|
+
});
|
|
751
874
|
var deleteBtn = e.target.closest('button[title="Remove image"]');
|
|
752
875
|
if (deleteBtn && editable) {
|
|
753
876
|
e.preventDefault();
|
|
@@ -824,21 +947,6 @@ function RichTextEditor(_ref) {
|
|
|
824
947
|
var next = getCleanHtml();
|
|
825
948
|
setHtml(next);
|
|
826
949
|
}, []);
|
|
827
|
-
var handleChange = function handleChange() {
|
|
828
|
-
if (!editorRef.current) return;
|
|
829
|
-
|
|
830
|
-
// Clone editor content
|
|
831
|
-
var tempDiv = document.createElement('div');
|
|
832
|
-
tempDiv.innerHTML = editorRef.current.innerHTML;
|
|
833
|
-
|
|
834
|
-
// Remove delete buttons from the clone
|
|
835
|
-
tempDiv.querySelectorAll('button[title="Remove image"]').forEach(function (btn) {
|
|
836
|
-
return btn.remove();
|
|
837
|
-
});
|
|
838
|
-
|
|
839
|
-
// Send cleaned HTML to onBlur
|
|
840
|
-
onBlur && onBlur(tempDiv.innerHTML);
|
|
841
|
-
};
|
|
842
950
|
|
|
843
951
|
// Detect if selection is inside a list (ol or ul)
|
|
844
952
|
var detectListType = function detectListType() {
|
|
@@ -971,10 +1079,10 @@ function RichTextEditor(_ref) {
|
|
|
971
1079
|
triggerChange();
|
|
972
1080
|
focus();
|
|
973
1081
|
};
|
|
974
|
-
var
|
|
975
|
-
|
|
976
|
-
fontColor =
|
|
977
|
-
setFontColor =
|
|
1082
|
+
var _useState49 = React.useState("#000000"),
|
|
1083
|
+
_useState50 = _slicedToArray(_useState49, 2),
|
|
1084
|
+
fontColor = _useState50[0],
|
|
1085
|
+
setFontColor = _useState50[1];
|
|
978
1086
|
var handleColorChange = function handleColorChange(color) {
|
|
979
1087
|
setFontColor(color);
|
|
980
1088
|
exec("foreColor", color);
|
|
@@ -994,6 +1102,198 @@ function RichTextEditor(_ref) {
|
|
|
994
1102
|
setLinkModalOpen(true);
|
|
995
1103
|
}
|
|
996
1104
|
};
|
|
1105
|
+
var findParentTag = function findParentTag(node, tagName) {
|
|
1106
|
+
if (!node) return null;
|
|
1107
|
+
var curr = node;
|
|
1108
|
+
while (curr && curr !== editorRef.current) {
|
|
1109
|
+
if (curr.tagName === tagName) return curr;
|
|
1110
|
+
curr = curr.parentNode;
|
|
1111
|
+
}
|
|
1112
|
+
return null;
|
|
1113
|
+
};
|
|
1114
|
+
var tableAction = function tableAction(action) {
|
|
1115
|
+
var sel = window.getSelection();
|
|
1116
|
+
if (!sel || !sel.rangeCount) return;
|
|
1117
|
+
var cell = findParentTag(sel.anchorNode, 'TD') || findParentTag(sel.anchorNode, 'TH');
|
|
1118
|
+
if (!cell) return;
|
|
1119
|
+
var row = cell.parentNode;
|
|
1120
|
+
var table = row.parentNode.closest('table');
|
|
1121
|
+
switch (action) {
|
|
1122
|
+
case 'addRowAbove':
|
|
1123
|
+
var newRowAbove = table.insertRow(row.rowIndex);
|
|
1124
|
+
for (var i = 0; i < row.cells.length; i++) {
|
|
1125
|
+
var newCell = newRowAbove.insertCell(i);
|
|
1126
|
+
newCell.style.border = "1px solid #e5e7eb";
|
|
1127
|
+
newCell.style.padding = "12px";
|
|
1128
|
+
newCell.innerHTML = " ";
|
|
1129
|
+
}
|
|
1130
|
+
break;
|
|
1131
|
+
case 'addRowBelow':
|
|
1132
|
+
var newRowBelow = table.insertRow(row.rowIndex + 1);
|
|
1133
|
+
for (var _i = 0; _i < row.cells.length; _i++) {
|
|
1134
|
+
var _newCell = newRowBelow.insertCell(_i);
|
|
1135
|
+
_newCell.style.border = "1px solid #e5e7eb";
|
|
1136
|
+
_newCell.style.padding = "12px";
|
|
1137
|
+
_newCell.innerHTML = " ";
|
|
1138
|
+
}
|
|
1139
|
+
break;
|
|
1140
|
+
case 'addColBefore':
|
|
1141
|
+
var cellIndex = cell.cellIndex;
|
|
1142
|
+
for (var _i2 = 0; _i2 < table.rows.length; _i2++) {
|
|
1143
|
+
var _newCell2 = table.rows[_i2].insertCell(cellIndex);
|
|
1144
|
+
_newCell2.style.border = "1px solid #e5e7eb";
|
|
1145
|
+
_newCell2.style.padding = "12px";
|
|
1146
|
+
_newCell2.innerHTML = " ";
|
|
1147
|
+
}
|
|
1148
|
+
break;
|
|
1149
|
+
case 'addColAfter':
|
|
1150
|
+
var cellIndexAfter = cell.cellIndex + 1;
|
|
1151
|
+
for (var _i3 = 0; _i3 < table.rows.length; _i3++) {
|
|
1152
|
+
var _newCell3 = table.rows[_i3].insertCell(cellIndexAfter);
|
|
1153
|
+
_newCell3.style.border = "1px solid #e5e7eb";
|
|
1154
|
+
_newCell3.style.padding = "12px";
|
|
1155
|
+
_newCell3.innerHTML = " ";
|
|
1156
|
+
}
|
|
1157
|
+
break;
|
|
1158
|
+
case 'deleteRow':
|
|
1159
|
+
{
|
|
1160
|
+
var rowIndex = row.rowIndex;
|
|
1161
|
+
var _cellIndex = cell.cellIndex;
|
|
1162
|
+
table.deleteRow(rowIndex);
|
|
1163
|
+
if (table.rows.length === 0) {
|
|
1164
|
+
table.remove();
|
|
1165
|
+
} else {
|
|
1166
|
+
var targetRowIndex = Math.min(rowIndex, table.rows.length - 1);
|
|
1167
|
+
var targetRow = table.rows[targetRowIndex];
|
|
1168
|
+
var targetCell = targetRow.cells[Math.min(_cellIndex, targetRow.cells.length - 1)];
|
|
1169
|
+
if (targetCell) {
|
|
1170
|
+
var range = document.createRange();
|
|
1171
|
+
range.selectNodeContents(targetCell);
|
|
1172
|
+
range.collapse(true);
|
|
1173
|
+
sel.removeAllRanges();
|
|
1174
|
+
sel.addRange(range);
|
|
1175
|
+
setSelectionVersion(function (v) {
|
|
1176
|
+
return v + 1;
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
break;
|
|
1181
|
+
}
|
|
1182
|
+
case 'deleteCol':
|
|
1183
|
+
{
|
|
1184
|
+
var idx = cell.cellIndex;
|
|
1185
|
+
var _rowIndex = row.rowIndex;
|
|
1186
|
+
for (var _i4 = 0; _i4 < table.rows.length; _i4++) {
|
|
1187
|
+
table.rows[_i4].deleteCell(idx);
|
|
1188
|
+
}
|
|
1189
|
+
if (table.rows[0].cells.length === 0) {
|
|
1190
|
+
table.remove();
|
|
1191
|
+
} else {
|
|
1192
|
+
var _table$rows$_rowIndex;
|
|
1193
|
+
var targetColIndex = Math.min(idx, table.rows[0].cells.length - 1);
|
|
1194
|
+
var _targetCell = ((_table$rows$_rowIndex = table.rows[_rowIndex]) === null || _table$rows$_rowIndex === void 0 ? void 0 : _table$rows$_rowIndex.cells[targetColIndex]) || table.rows[0].cells[targetColIndex];
|
|
1195
|
+
if (_targetCell) {
|
|
1196
|
+
var _range = document.createRange();
|
|
1197
|
+
_range.selectNodeContents(_targetCell);
|
|
1198
|
+
_range.collapse(true);
|
|
1199
|
+
sel.removeAllRanges();
|
|
1200
|
+
sel.addRange(_range);
|
|
1201
|
+
setSelectionVersion(function (v) {
|
|
1202
|
+
return v + 1;
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
break;
|
|
1207
|
+
}
|
|
1208
|
+
case 'mergeRight':
|
|
1209
|
+
if (cell.nextElementSibling) {
|
|
1210
|
+
var nextCell = cell.nextElementSibling;
|
|
1211
|
+
cell.colSpan = (cell.colSpan || 1) + (nextCell.colSpan || 1);
|
|
1212
|
+
nextCell.remove();
|
|
1213
|
+
}
|
|
1214
|
+
break;
|
|
1215
|
+
case 'deleteTable':
|
|
1216
|
+
table.remove();
|
|
1217
|
+
break;
|
|
1218
|
+
}
|
|
1219
|
+
triggerChange && triggerChange();
|
|
1220
|
+
};
|
|
1221
|
+
var insertTable = function insertTable() {
|
|
1222
|
+
var rows = parseInt(tableRows) || 3;
|
|
1223
|
+
var cols = parseInt(tableCols) || 3;
|
|
1224
|
+
var tableHtml = '<table style="width: 100%; border-collapse: collapse; border: 1px solid #e5e7eb; margin: 16px 0;"><tbody>';
|
|
1225
|
+
for (var i = 0; i < rows; i++) {
|
|
1226
|
+
tableHtml += '<tr>';
|
|
1227
|
+
for (var j = 0; j < cols; j++) {
|
|
1228
|
+
tableHtml += '<td style="border: 1px solid #e5e7eb; padding: 12px; min-height: 20px;"> </td>';
|
|
1229
|
+
}
|
|
1230
|
+
tableHtml += '</tr>';
|
|
1231
|
+
}
|
|
1232
|
+
tableHtml += '</tbody></table><p> </p>';
|
|
1233
|
+
if (selectionRangeRef.current) {
|
|
1234
|
+
var sel = window.getSelection();
|
|
1235
|
+
sel.removeAllRanges();
|
|
1236
|
+
sel.addRange(selectionRangeRef.current);
|
|
1237
|
+
}
|
|
1238
|
+
document.execCommand("insertHTML", false, tableHtml);
|
|
1239
|
+
setTableModalOpen(false);
|
|
1240
|
+
triggerChange && triggerChange();
|
|
1241
|
+
};
|
|
1242
|
+
var parseVideoUrl = function parseVideoUrl(url) {
|
|
1243
|
+
url = url.trim();
|
|
1244
|
+
if (!url) return null;
|
|
1245
|
+
|
|
1246
|
+
// YouTube
|
|
1247
|
+
var ytRegExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=|watch\?vi=|\&vi=)([^#\&\?]*).*/;
|
|
1248
|
+
var ytMatch = url.match(ytRegExp);
|
|
1249
|
+
if (ytMatch && ytMatch[2].length === 11) {
|
|
1250
|
+
return "https://www.youtube.com/embed/".concat(ytMatch[2]);
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// Vimeo
|
|
1254
|
+
var vimeoRegExp = /vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/;
|
|
1255
|
+
var vimeoMatch = url.match(vimeoRegExp);
|
|
1256
|
+
if (vimeoMatch && vimeoMatch[3]) {
|
|
1257
|
+
return "https://player.vimeo.com/video/".concat(vimeoMatch[3]);
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
// DailyMotion
|
|
1261
|
+
var dmRegExp = /dailymotion\.com\/video\/([a-zA-Z0-9]+)/;
|
|
1262
|
+
var dmMatch = url.match(dmRegExp);
|
|
1263
|
+
if (dmMatch && dmMatch[1]) {
|
|
1264
|
+
return "https://www.dailymotion.com/embed/video/".concat(dmMatch[1]);
|
|
1265
|
+
}
|
|
1266
|
+
return null;
|
|
1267
|
+
};
|
|
1268
|
+
var insertVideo = function insertVideo() {
|
|
1269
|
+
var embedUrl = parseVideoUrl(videoUrl);
|
|
1270
|
+
if (embedUrl) {
|
|
1271
|
+
if (editorRef.current) {
|
|
1272
|
+
editorRef.current.focus();
|
|
1273
|
+
}
|
|
1274
|
+
if (selectionRangeRef.current) {
|
|
1275
|
+
var sel = window.getSelection();
|
|
1276
|
+
sel.removeAllRanges();
|
|
1277
|
+
sel.addRange(selectionRangeRef.current);
|
|
1278
|
+
}
|
|
1279
|
+
var embedHtml = "<div class=\"video-container\">\n <iframe \n src=\"".concat(embedUrl, "\" \n frameborder=\"0\" \n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" \n allowfullscreen\n ></iframe>\n </div><p> </p>");
|
|
1280
|
+
try {
|
|
1281
|
+
document.execCommand("insertHTML", false, embedHtml);
|
|
1282
|
+
} catch (err) {
|
|
1283
|
+
console.error("Failed to insert Video HTML:", err);
|
|
1284
|
+
if (editorRef.current) {
|
|
1285
|
+
var div = document.createElement('div');
|
|
1286
|
+
div.innerHTML = embedHtml;
|
|
1287
|
+
editorRef.current.appendChild(div);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
setVideoModalOpen(false);
|
|
1291
|
+
setVideoUrl("");
|
|
1292
|
+
triggerChange && triggerChange();
|
|
1293
|
+
} else {
|
|
1294
|
+
console.warn("Invalid Video URL or Platform not supported");
|
|
1295
|
+
}
|
|
1296
|
+
};
|
|
997
1297
|
var processExistingImages = function processExistingImages(container) {
|
|
998
1298
|
if (!container) return;
|
|
999
1299
|
container.querySelectorAll("img").forEach(function (img) {
|
|
@@ -1516,8 +1816,8 @@ function RichTextEditor(_ref) {
|
|
|
1516
1816
|
var lastInsertedNode = null;
|
|
1517
1817
|
|
|
1518
1818
|
// Iterate through the selected text nodes and wrap them in spans
|
|
1519
|
-
for (var
|
|
1520
|
-
var textNode = _nodesToStyle[
|
|
1819
|
+
for (var _i5 = 0, _nodesToStyle = nodesToStyle; _i5 < _nodesToStyle.length; _i5++) {
|
|
1820
|
+
var textNode = _nodesToStyle[_i5];
|
|
1521
1821
|
var parent = textNode.parentNode;
|
|
1522
1822
|
|
|
1523
1823
|
// This is important: check if the parent is a block-level element
|
|
@@ -1614,6 +1914,9 @@ function RichTextEditor(_ref) {
|
|
|
1614
1914
|
}
|
|
1615
1915
|
}, [disabled]);
|
|
1616
1916
|
var handleEditorClick = React.useCallback(function (e) {
|
|
1917
|
+
setSelectionVersion(function (v) {
|
|
1918
|
+
return v + 1;
|
|
1919
|
+
});
|
|
1617
1920
|
// Check if the click is on a link
|
|
1618
1921
|
var clickedLink = e.target.closest('a');
|
|
1619
1922
|
if (clickedLink) {
|
|
@@ -1623,6 +1926,15 @@ function RichTextEditor(_ref) {
|
|
|
1623
1926
|
return;
|
|
1624
1927
|
}
|
|
1625
1928
|
|
|
1929
|
+
// NEW: Check if click is on an image for resizing
|
|
1930
|
+
var clickedImg = e.target.closest('img');
|
|
1931
|
+
if (clickedImg && !clickedImg.closest('.rte-modal')) {
|
|
1932
|
+
setSelectedImage(clickedImg);
|
|
1933
|
+
setResizeData({});
|
|
1934
|
+
} else if (!e.target.closest('.resize-handle')) {
|
|
1935
|
+
setSelectedImage(null);
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1626
1938
|
// If disabled is true, prevent editing
|
|
1627
1939
|
if (disabled === true) {
|
|
1628
1940
|
e.preventDefault();
|
|
@@ -1639,14 +1951,138 @@ function RichTextEditor(_ref) {
|
|
|
1639
1951
|
}, 0);
|
|
1640
1952
|
}
|
|
1641
1953
|
}, [editable, disabled]);
|
|
1954
|
+
var startResize = function startResize(e, direction) {
|
|
1955
|
+
e.preventDefault();
|
|
1956
|
+
e.stopPropagation();
|
|
1957
|
+
var img = selectedImage;
|
|
1958
|
+
var startX = e.clientX;
|
|
1959
|
+
var startY = e.clientY;
|
|
1960
|
+
var startWidth = img.offsetWidth;
|
|
1961
|
+
var startHeight = img.offsetHeight;
|
|
1962
|
+
var onMouseMove = function onMouseMove(moveEvent) {
|
|
1963
|
+
var newWidth = startWidth;
|
|
1964
|
+
var newHeight = startHeight;
|
|
1965
|
+
if (direction.includes('e')) newWidth = startWidth + (moveEvent.clientX - startX);
|
|
1966
|
+
if (direction.includes('w')) newWidth = startWidth - (moveEvent.clientX - startX);
|
|
1967
|
+
if (direction.includes('s')) newHeight = startHeight + (moveEvent.clientY - startY);
|
|
1968
|
+
if (direction.includes('n')) newHeight = startHeight - (moveEvent.clientY - startY);
|
|
1969
|
+
img.style.width = "".concat(newWidth, "px");
|
|
1970
|
+
img.style.height = "".concat(newHeight, "px");
|
|
1971
|
+
setResizeData({}); // Force re-render of handles
|
|
1972
|
+
};
|
|
1973
|
+
var _onMouseUp = function onMouseUp() {
|
|
1974
|
+
document.removeEventListener('mousemove', onMouseMove);
|
|
1975
|
+
document.removeEventListener('mouseup', _onMouseUp);
|
|
1976
|
+
triggerChange();
|
|
1977
|
+
};
|
|
1978
|
+
document.addEventListener('mousemove', onMouseMove);
|
|
1979
|
+
document.addEventListener('mouseup', _onMouseUp);
|
|
1980
|
+
};
|
|
1981
|
+
var renderResizeHandles = function renderResizeHandles() {
|
|
1982
|
+
if (!selectedImage || !editorRef.current) return null;
|
|
1983
|
+
var editorRect = editorRef.current.getBoundingClientRect();
|
|
1984
|
+
var imgRect = selectedImage.getBoundingClientRect();
|
|
1985
|
+
|
|
1986
|
+
// Relative position within editorRef using the more robust BoundingClientRect
|
|
1987
|
+
var top = imgRect.top - editorRect.top + editorRef.current.scrollTop;
|
|
1988
|
+
var left = imgRect.left - editorRect.left + editorRef.current.scrollLeft;
|
|
1989
|
+
var width = imgRect.width;
|
|
1990
|
+
var height = imgRect.height;
|
|
1991
|
+
var handleStyles = {
|
|
1992
|
+
position: 'absolute',
|
|
1993
|
+
width: '10px',
|
|
1994
|
+
height: '10px',
|
|
1995
|
+
background: '#3b82f6',
|
|
1996
|
+
border: '2px solid white',
|
|
1997
|
+
borderRadius: '50%',
|
|
1998
|
+
zIndex: 100
|
|
1999
|
+
};
|
|
2000
|
+
var handles = [{
|
|
2001
|
+
id: 'nw',
|
|
2002
|
+
style: {
|
|
2003
|
+
top: top - 5,
|
|
2004
|
+
left: left - 5,
|
|
2005
|
+
cursor: 'nw-resize'
|
|
2006
|
+
}
|
|
2007
|
+
}, {
|
|
2008
|
+
id: 'ne',
|
|
2009
|
+
style: {
|
|
2010
|
+
top: top - 5,
|
|
2011
|
+
left: left + width - 5,
|
|
2012
|
+
cursor: 'ne-resize'
|
|
2013
|
+
}
|
|
2014
|
+
}, {
|
|
2015
|
+
id: 'sw',
|
|
2016
|
+
style: {
|
|
2017
|
+
top: top + height - 5,
|
|
2018
|
+
left: left - 5,
|
|
2019
|
+
cursor: 'sw-resize'
|
|
2020
|
+
}
|
|
2021
|
+
}, {
|
|
2022
|
+
id: 'se',
|
|
2023
|
+
style: {
|
|
2024
|
+
top: top + height - 5,
|
|
2025
|
+
left: left + width - 5,
|
|
2026
|
+
cursor: 'se-resize'
|
|
2027
|
+
}
|
|
2028
|
+
}];
|
|
2029
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
2030
|
+
style: {
|
|
2031
|
+
position: 'absolute',
|
|
2032
|
+
top: 0,
|
|
2033
|
+
left: 0,
|
|
2034
|
+
width: '100%',
|
|
2035
|
+
height: '100%',
|
|
2036
|
+
pointerEvents: 'none'
|
|
2037
|
+
}
|
|
2038
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
2039
|
+
style: {
|
|
2040
|
+
position: 'absolute',
|
|
2041
|
+
top: top,
|
|
2042
|
+
left: left,
|
|
2043
|
+
width: width,
|
|
2044
|
+
height: height,
|
|
2045
|
+
border: '2px solid #3b82f6',
|
|
2046
|
+
pointerEvents: 'none'
|
|
2047
|
+
}
|
|
2048
|
+
}), handles.map(function (h) {
|
|
2049
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
2050
|
+
key: h.id,
|
|
2051
|
+
className: "resize-handle",
|
|
2052
|
+
onMouseDown: function onMouseDown(e) {
|
|
2053
|
+
return startResize(e, h.id);
|
|
2054
|
+
},
|
|
2055
|
+
style: _objectSpread2(_objectSpread2(_objectSpread2({}, handleStyles), h.style), {}, {
|
|
2056
|
+
pointerEvents: 'auto'
|
|
2057
|
+
})
|
|
2058
|
+
});
|
|
2059
|
+
}));
|
|
2060
|
+
};
|
|
1642
2061
|
return /*#__PURE__*/React.createElement("div", {
|
|
1643
2062
|
className: "rte-main-wrapper",
|
|
1644
2063
|
style: {
|
|
1645
|
-
width: '100%'
|
|
2064
|
+
width: '100%',
|
|
2065
|
+
position: 'relative'
|
|
1646
2066
|
}
|
|
1647
2067
|
}, label && /*#__PURE__*/React.createElement(LabelComponent, null, label), /*#__PURE__*/React.createElement("div", {
|
|
2068
|
+
style: {
|
|
2069
|
+
position: 'relative'
|
|
2070
|
+
},
|
|
1648
2071
|
className: !showBorder ? "" : "rte-container",
|
|
1649
2072
|
onClick: handleEditorClick,
|
|
2073
|
+
onMouseOver: function onMouseOver(e) {
|
|
2074
|
+
var table = e.target.closest('table');
|
|
2075
|
+
if (table && editorRef.current.contains(table)) {
|
|
2076
|
+
setHoveredTable(table);
|
|
2077
|
+
}
|
|
2078
|
+
},
|
|
2079
|
+
onMouseOut: function onMouseOut(e) {
|
|
2080
|
+
var table = e.target.closest('table');
|
|
2081
|
+
var related = e.relatedTarget;
|
|
2082
|
+
if (table && (!related || !table.contains(related)) && !(related !== null && related !== void 0 && related.closest('.rte-table-delete-hover'))) {
|
|
2083
|
+
setHoveredTable(null);
|
|
2084
|
+
}
|
|
2085
|
+
},
|
|
1650
2086
|
onDrop: handleDrop,
|
|
1651
2087
|
onDragOver: function onDragOver(e) {
|
|
1652
2088
|
e.preventDefault();
|
|
@@ -1661,7 +2097,7 @@ function RichTextEditor(_ref) {
|
|
|
1661
2097
|
e.preventDefault();
|
|
1662
2098
|
e.stopPropagation();
|
|
1663
2099
|
document.execCommand("bold");
|
|
1664
|
-
|
|
2100
|
+
handleInput();
|
|
1665
2101
|
focus();
|
|
1666
2102
|
},
|
|
1667
2103
|
className: "rte-toolbar-button ".concat(isBold ? "active" : "")
|
|
@@ -1674,7 +2110,7 @@ function RichTextEditor(_ref) {
|
|
|
1674
2110
|
e.preventDefault();
|
|
1675
2111
|
e.stopPropagation();
|
|
1676
2112
|
document.execCommand("italic");
|
|
1677
|
-
|
|
2113
|
+
handleInput();
|
|
1678
2114
|
focus();
|
|
1679
2115
|
},
|
|
1680
2116
|
className: "rte-toolbar-button ".concat(isItalic ? "active" : "")
|
|
@@ -1687,7 +2123,7 @@ function RichTextEditor(_ref) {
|
|
|
1687
2123
|
e.preventDefault();
|
|
1688
2124
|
e.stopPropagation();
|
|
1689
2125
|
document.execCommand("underline");
|
|
1690
|
-
|
|
2126
|
+
handleInput();
|
|
1691
2127
|
focus();
|
|
1692
2128
|
},
|
|
1693
2129
|
className: "rte-toolbar-button ".concat(isUnderline ? "active" : "")
|
|
@@ -1859,6 +2295,13 @@ function RichTextEditor(_ref) {
|
|
|
1859
2295
|
backgroundColor: '#e5e7eb',
|
|
1860
2296
|
margin: '0 4px'
|
|
1861
2297
|
}
|
|
2298
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
2299
|
+
style: {
|
|
2300
|
+
width: '1px',
|
|
2301
|
+
height: '20px',
|
|
2302
|
+
backgroundColor: '#e5e7eb',
|
|
2303
|
+
margin: '0 4px'
|
|
2304
|
+
}
|
|
1862
2305
|
}), /*#__PURE__*/React.createElement("button", {
|
|
1863
2306
|
type: "button",
|
|
1864
2307
|
title: "Add Link",
|
|
@@ -1899,7 +2342,145 @@ function RichTextEditor(_ref) {
|
|
|
1899
2342
|
}
|
|
1900
2343
|
}) : /*#__PURE__*/React.createElement(FaImage, {
|
|
1901
2344
|
size: 14
|
|
1902
|
-
}))
|
|
2345
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
2346
|
+
style: {
|
|
2347
|
+
width: '1px',
|
|
2348
|
+
height: '20px',
|
|
2349
|
+
backgroundColor: '#e5e7eb',
|
|
2350
|
+
margin: '0 4px'
|
|
2351
|
+
}
|
|
2352
|
+
}), /*#__PURE__*/React.createElement("button", {
|
|
2353
|
+
type: "button",
|
|
2354
|
+
title: "Insert Table",
|
|
2355
|
+
className: "rte-toolbar-button",
|
|
2356
|
+
onMouseDown: function onMouseDown(e) {
|
|
2357
|
+
e.preventDefault();
|
|
2358
|
+
var sel = window.getSelection();
|
|
2359
|
+
if (sel && sel.rangeCount > 0) {
|
|
2360
|
+
selectionRangeRef.current = sel.getRangeAt(0).cloneRange();
|
|
2361
|
+
}
|
|
2362
|
+
setTableModalOpen(true);
|
|
2363
|
+
}
|
|
2364
|
+
}, /*#__PURE__*/React.createElement(FaTable, {
|
|
2365
|
+
size: 14
|
|
2366
|
+
})), /*#__PURE__*/React.createElement("button", {
|
|
2367
|
+
type: "button",
|
|
2368
|
+
title: "Embed Video (YouTube, Vimeo, etc.)",
|
|
2369
|
+
className: "rte-toolbar-button ".concat(videoModalOpen ? 'active' : ''),
|
|
2370
|
+
onMouseDown: function onMouseDown(e) {
|
|
2371
|
+
e.preventDefault();
|
|
2372
|
+
saveSelection();
|
|
2373
|
+
setVideoModalOpen(true);
|
|
2374
|
+
}
|
|
2375
|
+
}, /*#__PURE__*/React.createElement(FaVideo, {
|
|
2376
|
+
size: 14
|
|
2377
|
+
})), function () {
|
|
2378
|
+
if (typeof window === "undefined") return null;
|
|
2379
|
+
var sel = window.getSelection();
|
|
2380
|
+
// Robust check: inside cell OR the table itself is selected
|
|
2381
|
+
var isCell = sel && sel.rangeCount > 0 && sel.anchorNode && (findParentTag(sel.anchorNode, 'TD') || findParentTag(sel.anchorNode, 'TH'));
|
|
2382
|
+
var isTable = sel && sel.rangeCount > 0 && sel.anchorNode && findParentTag(sel.anchorNode, 'TABLE');
|
|
2383
|
+
if (isCell || isTable) {
|
|
2384
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
2385
|
+
style: {
|
|
2386
|
+
width: '1px',
|
|
2387
|
+
height: '20px',
|
|
2388
|
+
backgroundColor: '#e5e7eb',
|
|
2389
|
+
margin: '0 4px'
|
|
2390
|
+
}
|
|
2391
|
+
}), /*#__PURE__*/React.createElement("button", {
|
|
2392
|
+
type: "button",
|
|
2393
|
+
title: "Add Row Above",
|
|
2394
|
+
className: "rte-toolbar-button",
|
|
2395
|
+
onMouseDown: function onMouseDown(e) {
|
|
2396
|
+
e.preventDefault();
|
|
2397
|
+
tableAction('addRowAbove');
|
|
2398
|
+
}
|
|
2399
|
+
}, "+R\u2191"), /*#__PURE__*/React.createElement("button", {
|
|
2400
|
+
type: "button",
|
|
2401
|
+
title: "Add Row Below",
|
|
2402
|
+
className: "rte-toolbar-button",
|
|
2403
|
+
onMouseDown: function onMouseDown(e) {
|
|
2404
|
+
e.preventDefault();
|
|
2405
|
+
tableAction('addRowBelow');
|
|
2406
|
+
}
|
|
2407
|
+
}, "+R\u2193"), /*#__PURE__*/React.createElement("button", {
|
|
2408
|
+
type: "button",
|
|
2409
|
+
title: "Add Col Before",
|
|
2410
|
+
className: "rte-toolbar-button",
|
|
2411
|
+
onMouseDown: function onMouseDown(e) {
|
|
2412
|
+
e.preventDefault();
|
|
2413
|
+
tableAction('addColBefore');
|
|
2414
|
+
}
|
|
2415
|
+
}, "+C\u2190"), /*#__PURE__*/React.createElement("button", {
|
|
2416
|
+
type: "button",
|
|
2417
|
+
title: "Add Col After",
|
|
2418
|
+
className: "rte-toolbar-button",
|
|
2419
|
+
onMouseDown: function onMouseDown(e) {
|
|
2420
|
+
e.preventDefault();
|
|
2421
|
+
tableAction('addColAfter');
|
|
2422
|
+
}
|
|
2423
|
+
}, "+C\u2192"), /*#__PURE__*/React.createElement("button", {
|
|
2424
|
+
type: "button",
|
|
2425
|
+
title: "Merge Cells (Right)",
|
|
2426
|
+
className: "rte-toolbar-button",
|
|
2427
|
+
onMouseDown: function onMouseDown(e) {
|
|
2428
|
+
e.preventDefault();
|
|
2429
|
+
tableAction('mergeRight');
|
|
2430
|
+
}
|
|
2431
|
+
}, /*#__PURE__*/React.createElement(FaObjectGroup, {
|
|
2432
|
+
size: 14
|
|
2433
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
2434
|
+
style: {
|
|
2435
|
+
display: 'flex',
|
|
2436
|
+
gap: '10px'
|
|
2437
|
+
}
|
|
2438
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
2439
|
+
type: "button",
|
|
2440
|
+
title: "Delete Row",
|
|
2441
|
+
className: "rte-toolbar-button rte-toolbar-button-danger",
|
|
2442
|
+
onMouseDown: function onMouseDown(e) {
|
|
2443
|
+
e.preventDefault();
|
|
2444
|
+
tableAction('deleteRow');
|
|
2445
|
+
}
|
|
2446
|
+
}, /*#__PURE__*/React.createElement(FaTrash, {
|
|
2447
|
+
size: 12
|
|
2448
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
2449
|
+
style: {
|
|
2450
|
+
fontSize: '10px'
|
|
2451
|
+
}
|
|
2452
|
+
}, "Row")), /*#__PURE__*/React.createElement("button", {
|
|
2453
|
+
type: "button",
|
|
2454
|
+
title: "Delete Column",
|
|
2455
|
+
className: "rte-toolbar-button rte-toolbar-button-danger",
|
|
2456
|
+
onMouseDown: function onMouseDown(e) {
|
|
2457
|
+
e.preventDefault();
|
|
2458
|
+
tableAction('deleteCol');
|
|
2459
|
+
}
|
|
2460
|
+
}, /*#__PURE__*/React.createElement(FaTrash, {
|
|
2461
|
+
size: 12
|
|
2462
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
2463
|
+
style: {
|
|
2464
|
+
fontSize: '10px'
|
|
2465
|
+
}
|
|
2466
|
+
}, "Col")), /*#__PURE__*/React.createElement("button", {
|
|
2467
|
+
type: "button",
|
|
2468
|
+
title: "Delete Table",
|
|
2469
|
+
className: "rte-toolbar-button rte-toolbar-button-danger",
|
|
2470
|
+
onMouseDown: function onMouseDown(e) {
|
|
2471
|
+
e.preventDefault();
|
|
2472
|
+
tableAction('deleteTable');
|
|
2473
|
+
}
|
|
2474
|
+
}, /*#__PURE__*/React.createElement(FaTrash, {
|
|
2475
|
+
size: 12
|
|
2476
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
2477
|
+
style: {
|
|
2478
|
+
fontSize: '10px'
|
|
2479
|
+
}
|
|
2480
|
+
}, "Table"))));
|
|
2481
|
+
}
|
|
2482
|
+
return null;
|
|
2483
|
+
}()), /*#__PURE__*/React.createElement("div", {
|
|
1903
2484
|
ref: editorRef,
|
|
1904
2485
|
contentEditable: editable && disabled !== true,
|
|
1905
2486
|
suppressContentEditableWarning: true,
|
|
@@ -1920,7 +2501,23 @@ function RichTextEditor(_ref) {
|
|
|
1920
2501
|
paddingLeft: paddingLeft || '12px'
|
|
1921
2502
|
},
|
|
1922
2503
|
className: "rte-content"
|
|
1923
|
-
}),
|
|
2504
|
+
}), renderResizeHandles(), /*#__PURE__*/React.createElement("div", {
|
|
2505
|
+
className: "rte-footer"
|
|
2506
|
+
}, function (_editorRef$current) {
|
|
2507
|
+
var text = ((_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.innerText) || "";
|
|
2508
|
+
var cleanText = text.replace(/[\n\r]/g, ' ').trim();
|
|
2509
|
+
var words = cleanText ? cleanText.split(/\s+/).length : 0;
|
|
2510
|
+
var chars = text.length;
|
|
2511
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
2512
|
+
className: "rte-footer-content"
|
|
2513
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
2514
|
+
className: "rte-footer-item"
|
|
2515
|
+
}, /*#__PURE__*/React.createElement("b", null, words), " words"), /*#__PURE__*/React.createElement("span", {
|
|
2516
|
+
className: "rte-footer-separator"
|
|
2517
|
+
}, "\u2022"), /*#__PURE__*/React.createElement("span", {
|
|
2518
|
+
className: "rte-footer-item"
|
|
2519
|
+
}, /*#__PURE__*/React.createElement("b", null, chars), " characters"));
|
|
2520
|
+
}()), linkModalOpen && /*#__PURE__*/React.createElement("div", {
|
|
1924
2521
|
className: "rte-modal-overlay",
|
|
1925
2522
|
onClick: cancelLink
|
|
1926
2523
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -1931,42 +2528,156 @@ function RichTextEditor(_ref) {
|
|
|
1931
2528
|
}, /*#__PURE__*/React.createElement("h3", {
|
|
1932
2529
|
className: "rte-modal-title"
|
|
1933
2530
|
}, "Insert Link"), /*#__PURE__*/React.createElement("div", {
|
|
2531
|
+
className: "rte-modal-divider"
|
|
2532
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
2533
|
+
className: "rte-modal-body"
|
|
2534
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
2535
|
+
className: "rte-form-group"
|
|
2536
|
+
}, /*#__PURE__*/React.createElement("label", {
|
|
2537
|
+
className: "rte-label"
|
|
2538
|
+
}, "Link Text"), /*#__PURE__*/React.createElement("input", {
|
|
2539
|
+
type: "text",
|
|
2540
|
+
className: "rte-input",
|
|
2541
|
+
placeholder: "e.g. Google",
|
|
2542
|
+
value: linkText,
|
|
2543
|
+
onChange: function onChange(e) {
|
|
2544
|
+
return setLinkText(e.target.value);
|
|
2545
|
+
}
|
|
2546
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
1934
2547
|
className: "rte-form-group"
|
|
1935
2548
|
}, /*#__PURE__*/React.createElement("label", {
|
|
1936
2549
|
className: "rte-label"
|
|
1937
2550
|
}, "URL"), /*#__PURE__*/React.createElement("input", {
|
|
1938
|
-
type: "
|
|
2551
|
+
type: "text",
|
|
1939
2552
|
className: "rte-input",
|
|
2553
|
+
placeholder: "https://example.com",
|
|
1940
2554
|
value: linkUrl,
|
|
1941
2555
|
onChange: function onChange(e) {
|
|
1942
2556
|
return setLinkUrl(e.target.value);
|
|
1943
2557
|
},
|
|
1944
|
-
|
|
1945
|
-
|
|
2558
|
+
onKeyDown: function onKeyDown(e) {
|
|
2559
|
+
return e.key === 'Enter' && confirmLink();
|
|
2560
|
+
},
|
|
2561
|
+
autoFocus: true
|
|
2562
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
2563
|
+
className: "rte-modal-divider",
|
|
2564
|
+
style: {
|
|
2565
|
+
margin: '8px 0 20px 0'
|
|
2566
|
+
}
|
|
2567
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
2568
|
+
className: "rte-modal-footer"
|
|
2569
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
2570
|
+
type: "button",
|
|
2571
|
+
className: "rte-btn rte-btn-secondary",
|
|
2572
|
+
onClick: cancelLink
|
|
2573
|
+
}, "Cancel"), /*#__PURE__*/React.createElement("button", {
|
|
2574
|
+
type: "button",
|
|
2575
|
+
className: "rte-btn rte-btn-primary",
|
|
2576
|
+
onClick: confirmLink,
|
|
2577
|
+
disabled: !linkUrl
|
|
2578
|
+
}, "Insert")))), tableModalOpen && /*#__PURE__*/React.createElement("div", {
|
|
2579
|
+
className: "rte-modal-overlay",
|
|
2580
|
+
onClick: function onClick() {
|
|
2581
|
+
return setTableModalOpen(false);
|
|
2582
|
+
}
|
|
2583
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
2584
|
+
className: "rte-modal",
|
|
2585
|
+
onClick: function onClick(e) {
|
|
2586
|
+
return e.stopPropagation();
|
|
2587
|
+
}
|
|
2588
|
+
}, /*#__PURE__*/React.createElement("h3", {
|
|
2589
|
+
className: "rte-modal-title"
|
|
2590
|
+
}, "Insert Table"), /*#__PURE__*/React.createElement("div", {
|
|
2591
|
+
className: "rte-form-group"
|
|
2592
|
+
}, /*#__PURE__*/React.createElement("label", {
|
|
2593
|
+
className: "rte-label"
|
|
2594
|
+
}, "Rows"), /*#__PURE__*/React.createElement("input", {
|
|
2595
|
+
type: "number",
|
|
2596
|
+
className: "rte-input",
|
|
2597
|
+
value: tableRows,
|
|
2598
|
+
onChange: function onChange(e) {
|
|
2599
|
+
return setTableRows(e.target.value);
|
|
2600
|
+
},
|
|
2601
|
+
min: "1",
|
|
2602
|
+
max: "10"
|
|
2603
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
2604
|
+
className: "rte-form-group"
|
|
2605
|
+
}, /*#__PURE__*/React.createElement("label", {
|
|
2606
|
+
className: "rte-label"
|
|
2607
|
+
}, "Columns"), /*#__PURE__*/React.createElement("input", {
|
|
2608
|
+
type: "number",
|
|
2609
|
+
className: "rte-input",
|
|
2610
|
+
value: tableCols,
|
|
2611
|
+
onChange: function onChange(e) {
|
|
2612
|
+
return setTableCols(e.target.value);
|
|
2613
|
+
},
|
|
2614
|
+
min: "1",
|
|
2615
|
+
max: "10"
|
|
1946
2616
|
})), /*#__PURE__*/React.createElement("div", {
|
|
2617
|
+
className: "rte-modal-actions"
|
|
2618
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
2619
|
+
type: "button",
|
|
2620
|
+
className: "rte-button rte-button-secondary",
|
|
2621
|
+
onClick: function onClick() {
|
|
2622
|
+
return setTableModalOpen(false);
|
|
2623
|
+
}
|
|
2624
|
+
}, "Cancel"), /*#__PURE__*/React.createElement("button", {
|
|
2625
|
+
type: "button",
|
|
2626
|
+
className: "rte-button rte-button-primary",
|
|
2627
|
+
onClick: insertTable
|
|
2628
|
+
}, "Insert")))), videoModalOpen && /*#__PURE__*/React.createElement("div", {
|
|
2629
|
+
className: "rte-modal-overlay",
|
|
2630
|
+
onClick: function onClick() {
|
|
2631
|
+
return setVideoModalOpen(false);
|
|
2632
|
+
}
|
|
2633
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
2634
|
+
className: "rte-modal",
|
|
2635
|
+
onClick: function onClick(e) {
|
|
2636
|
+
return e.stopPropagation();
|
|
2637
|
+
}
|
|
2638
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
2639
|
+
className: "rte-modal-header"
|
|
2640
|
+
}, /*#__PURE__*/React.createElement("h3", {
|
|
2641
|
+
className: "rte-modal-title"
|
|
2642
|
+
}, "Embed Video")), /*#__PURE__*/React.createElement("div", {
|
|
1947
2643
|
className: "rte-form-group"
|
|
1948
2644
|
}, /*#__PURE__*/React.createElement("label", {
|
|
1949
2645
|
className: "rte-label"
|
|
1950
|
-
}, "
|
|
2646
|
+
}, "Paste Video URL (YouTube, Vimeo...) ", /*#__PURE__*/React.createElement("span", {
|
|
2647
|
+
style: {
|
|
2648
|
+
color: '#ef4444'
|
|
2649
|
+
}
|
|
2650
|
+
}, "*")), /*#__PURE__*/React.createElement("input", {
|
|
1951
2651
|
type: "text",
|
|
1952
2652
|
className: "rte-input",
|
|
1953
|
-
value:
|
|
2653
|
+
value: videoUrl,
|
|
1954
2654
|
onChange: function onChange(e) {
|
|
1955
|
-
return
|
|
2655
|
+
return setVideoUrl(e.target.value);
|
|
1956
2656
|
},
|
|
1957
|
-
placeholder: "
|
|
2657
|
+
placeholder: "Paste URL here...",
|
|
2658
|
+
autoFocus: true,
|
|
2659
|
+
onKeyDown: function onKeyDown(e) {
|
|
2660
|
+
if (e.key === 'Enter' && videoUrl.trim()) insertVideo();
|
|
2661
|
+
if (e.key === 'Escape') setVideoModalOpen(false);
|
|
2662
|
+
}
|
|
1958
2663
|
})), /*#__PURE__*/React.createElement("div", {
|
|
1959
2664
|
className: "rte-modal-actions"
|
|
1960
2665
|
}, /*#__PURE__*/React.createElement("button", {
|
|
1961
2666
|
type: "button",
|
|
1962
2667
|
className: "rte-button rte-button-secondary",
|
|
1963
|
-
onClick:
|
|
2668
|
+
onClick: function onClick() {
|
|
2669
|
+
return setVideoModalOpen(false);
|
|
2670
|
+
}
|
|
1964
2671
|
}, "Cancel"), /*#__PURE__*/React.createElement("button", {
|
|
1965
2672
|
type: "button",
|
|
1966
2673
|
className: "rte-button rte-button-primary",
|
|
1967
|
-
onClick:
|
|
1968
|
-
|
|
1969
|
-
|
|
2674
|
+
onClick: function onClick() {
|
|
2675
|
+
if (videoUrl.trim()) {
|
|
2676
|
+
insertVideo();
|
|
2677
|
+
}
|
|
2678
|
+
},
|
|
2679
|
+
disabled: !videoUrl.trim()
|
|
2680
|
+
}, "Embed Video")))), imageModalOpen && /*#__PURE__*/React.createElement("div", {
|
|
1970
2681
|
className: "rte-modal-overlay",
|
|
1971
2682
|
onClick: closeImageModal
|
|
1972
2683
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -2006,7 +2717,7 @@ function RichTextEditor(_ref) {
|
|
|
2006
2717
|
type: "button",
|
|
2007
2718
|
className: "rte-button rte-button-primary",
|
|
2008
2719
|
onClick: function onClick() {
|
|
2009
|
-
|
|
2720
|
+
onChange && onChange(html);
|
|
2010
2721
|
setEditable(false);
|
|
2011
2722
|
}
|
|
2012
2723
|
}, "Save Changes")));
|