react-lite-rich-text-editor 1.1.1 → 1.1.2

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/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 FaYoutube = function FaYoutube(_ref15) {
530
+ var className = _ref15.className,
531
+ size = _ref15.size,
532
+ color = _ref15.color,
533
+ style = _ref15.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 576 512\" height=\"1em\" width=\"1em\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.781 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z\"></path></svg>"
545
+ }
546
+ });
547
+ };
548
+ var FaObjectGroup = function FaObjectGroup(_ref16) {
549
+ var className = _ref16.className,
550
+ size = _ref16.size,
551
+ color = _ref16.color,
552
+ style = _ref16.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 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>"
564
+ }
565
+ });
566
+ };
567
+ var FaTrash = function FaTrash(_ref17) {
568
+ var className = _ref17.className,
569
+ size = _ref17.size,
570
+ color = _ref17.color,
571
+ style = _ref17.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 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>"
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:24px;width:100%}.rte-modal-title{color:#111827;font-size:18px;font-weight:600;margin-bottom:4px}.rte-form-group{display:flex;flex-direction:column;gap:6px}.rte-label{color:#4b5563;font-size:14px;font-weight:500}.rte-input{border:1px solid #d1d5db;border-radius:8px;outline:none;padding:8px 12px;transition:all .15s ease;width:100%}.rte-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,.1)}.rte-modal-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:8px}.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)}.image-container:after{clear:both;content:\"\";display:table}";
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
- onBlur = _ref.onBlur,
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
+ youtubeModalOpen = _useState32[0],
773
+ setYoutubeModalOpen = _useState32[1];
774
+ var _useState33 = React.useState(""),
775
+ _useState34 = _slicedToArray(_useState33, 2),
776
+ youtubeUrl = _useState34[0],
777
+ setYoutubeUrl = _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;
@@ -748,6 +860,10 @@ function RichTextEditor(_ref) {
748
860
  }, [imageModalOpen]);
749
861
  React.useEffect(function () {
750
862
  var handleClick = function handleClick(e) {
863
+ // Trigger selection update for toolbar reactivity
864
+ setSelectionVersion(function (v) {
865
+ return v + 1;
866
+ });
751
867
  var deleteBtn = e.target.closest('button[title="Remove image"]');
752
868
  if (deleteBtn && editable) {
753
869
  e.preventDefault();
@@ -824,21 +940,6 @@ function RichTextEditor(_ref) {
824
940
  var next = getCleanHtml();
825
941
  setHtml(next);
826
942
  }, []);
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
943
 
843
944
  // Detect if selection is inside a list (ol or ul)
844
945
  var detectListType = function detectListType() {
@@ -971,10 +1072,10 @@ function RichTextEditor(_ref) {
971
1072
  triggerChange();
972
1073
  focus();
973
1074
  };
974
- var _useState31 = React.useState("#000000"),
975
- _useState32 = _slicedToArray(_useState31, 2),
976
- fontColor = _useState32[0],
977
- setFontColor = _useState32[1];
1075
+ var _useState49 = React.useState("#000000"),
1076
+ _useState50 = _slicedToArray(_useState49, 2),
1077
+ fontColor = _useState50[0],
1078
+ setFontColor = _useState50[1];
978
1079
  var handleColorChange = function handleColorChange(color) {
979
1080
  setFontColor(color);
980
1081
  exec("foreColor", color);
@@ -994,6 +1095,177 @@ function RichTextEditor(_ref) {
994
1095
  setLinkModalOpen(true);
995
1096
  }
996
1097
  };
1098
+ var findParentTag = function findParentTag(node, tagName) {
1099
+ if (!node) return null;
1100
+ var curr = node;
1101
+ while (curr && curr !== editorRef.current) {
1102
+ if (curr.tagName === tagName) return curr;
1103
+ curr = curr.parentNode;
1104
+ }
1105
+ return null;
1106
+ };
1107
+ var tableAction = function tableAction(action) {
1108
+ var sel = window.getSelection();
1109
+ if (!sel || !sel.rangeCount) return;
1110
+ var cell = findParentTag(sel.anchorNode, 'TD') || findParentTag(sel.anchorNode, 'TH');
1111
+ if (!cell) return;
1112
+ var row = cell.parentNode;
1113
+ var table = row.parentNode.closest('table');
1114
+ switch (action) {
1115
+ case 'addRowAbove':
1116
+ var newRowAbove = table.insertRow(row.rowIndex);
1117
+ for (var i = 0; i < row.cells.length; i++) {
1118
+ var newCell = newRowAbove.insertCell(i);
1119
+ newCell.style.border = "1px solid #e5e7eb";
1120
+ newCell.style.padding = "12px";
1121
+ newCell.innerHTML = "&nbsp;";
1122
+ }
1123
+ break;
1124
+ case 'addRowBelow':
1125
+ var newRowBelow = table.insertRow(row.rowIndex + 1);
1126
+ for (var _i = 0; _i < row.cells.length; _i++) {
1127
+ var _newCell = newRowBelow.insertCell(_i);
1128
+ _newCell.style.border = "1px solid #e5e7eb";
1129
+ _newCell.style.padding = "12px";
1130
+ _newCell.innerHTML = "&nbsp;";
1131
+ }
1132
+ break;
1133
+ case 'addColBefore':
1134
+ var cellIndex = cell.cellIndex;
1135
+ for (var _i2 = 0; _i2 < table.rows.length; _i2++) {
1136
+ var _newCell2 = table.rows[_i2].insertCell(cellIndex);
1137
+ _newCell2.style.border = "1px solid #e5e7eb";
1138
+ _newCell2.style.padding = "12px";
1139
+ _newCell2.innerHTML = "&nbsp;";
1140
+ }
1141
+ break;
1142
+ case 'addColAfter':
1143
+ var cellIndexAfter = cell.cellIndex + 1;
1144
+ for (var _i3 = 0; _i3 < table.rows.length; _i3++) {
1145
+ var _newCell3 = table.rows[_i3].insertCell(cellIndexAfter);
1146
+ _newCell3.style.border = "1px solid #e5e7eb";
1147
+ _newCell3.style.padding = "12px";
1148
+ _newCell3.innerHTML = "&nbsp;";
1149
+ }
1150
+ break;
1151
+ case 'deleteRow':
1152
+ {
1153
+ var rowIndex = row.rowIndex;
1154
+ var _cellIndex = cell.cellIndex;
1155
+ table.deleteRow(rowIndex);
1156
+ if (table.rows.length === 0) {
1157
+ table.remove();
1158
+ } else {
1159
+ var targetRowIndex = Math.min(rowIndex, table.rows.length - 1);
1160
+ var targetRow = table.rows[targetRowIndex];
1161
+ var targetCell = targetRow.cells[Math.min(_cellIndex, targetRow.cells.length - 1)];
1162
+ if (targetCell) {
1163
+ var range = document.createRange();
1164
+ range.selectNodeContents(targetCell);
1165
+ range.collapse(true);
1166
+ sel.removeAllRanges();
1167
+ sel.addRange(range);
1168
+ setSelectionVersion(function (v) {
1169
+ return v + 1;
1170
+ });
1171
+ }
1172
+ }
1173
+ break;
1174
+ }
1175
+ case 'deleteCol':
1176
+ {
1177
+ var idx = cell.cellIndex;
1178
+ var _rowIndex = row.rowIndex;
1179
+ for (var _i4 = 0; _i4 < table.rows.length; _i4++) {
1180
+ table.rows[_i4].deleteCell(idx);
1181
+ }
1182
+ if (table.rows[0].cells.length === 0) {
1183
+ table.remove();
1184
+ } else {
1185
+ var _table$rows$_rowIndex;
1186
+ var targetColIndex = Math.min(idx, table.rows[0].cells.length - 1);
1187
+ 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];
1188
+ if (_targetCell) {
1189
+ var _range = document.createRange();
1190
+ _range.selectNodeContents(_targetCell);
1191
+ _range.collapse(true);
1192
+ sel.removeAllRanges();
1193
+ sel.addRange(_range);
1194
+ setSelectionVersion(function (v) {
1195
+ return v + 1;
1196
+ });
1197
+ }
1198
+ }
1199
+ break;
1200
+ }
1201
+ case 'mergeRight':
1202
+ if (cell.nextElementSibling) {
1203
+ var nextCell = cell.nextElementSibling;
1204
+ cell.colSpan = (cell.colSpan || 1) + (nextCell.colSpan || 1);
1205
+ nextCell.remove();
1206
+ }
1207
+ break;
1208
+ case 'deleteTable':
1209
+ table.remove();
1210
+ break;
1211
+ }
1212
+ triggerChange && triggerChange();
1213
+ };
1214
+ var insertTable = function insertTable() {
1215
+ var rows = parseInt(tableRows) || 3;
1216
+ var cols = parseInt(tableCols) || 3;
1217
+ var tableHtml = '<table style="width: 100%; border-collapse: collapse; border: 1px solid #e5e7eb; margin: 16px 0;"><tbody>';
1218
+ for (var i = 0; i < rows; i++) {
1219
+ tableHtml += '<tr>';
1220
+ for (var j = 0; j < cols; j++) {
1221
+ tableHtml += '<td style="border: 1px solid #e5e7eb; padding: 12px; min-height: 20px;">&nbsp;</td>';
1222
+ }
1223
+ tableHtml += '</tr>';
1224
+ }
1225
+ tableHtml += '</tbody></table><p>&nbsp;</p>';
1226
+ if (selectionRangeRef.current) {
1227
+ var sel = window.getSelection();
1228
+ sel.removeAllRanges();
1229
+ sel.addRange(selectionRangeRef.current);
1230
+ }
1231
+ document.execCommand("insertHTML", false, tableHtml);
1232
+ setTableModalOpen(false);
1233
+ triggerChange && triggerChange();
1234
+ };
1235
+ var insertYoutube = function insertYoutube() {
1236
+ var url = youtubeUrl.trim();
1237
+ // More robust regex for various YouTube formats
1238
+ var regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=|watch\?vi=|\&vi=)([^#\&\?]*).*/;
1239
+ var match = url.match(regExp);
1240
+ var videoId = match && match[2].length === 11 ? match[2] : null;
1241
+ if (videoId) {
1242
+ if (editorRef.current) {
1243
+ editorRef.current.focus();
1244
+ }
1245
+ if (selectionRangeRef.current) {
1246
+ var sel = window.getSelection();
1247
+ sel.removeAllRanges();
1248
+ sel.addRange(selectionRangeRef.current);
1249
+ }
1250
+ var embedHtml = "<div class=\"video-container\">\n <iframe \n src=\"https://www.youtube.com/embed/".concat(videoId, "\" \n frameborder=\"0\" \n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" \n allowfullscreen\n ></iframe>\n </div><p>&nbsp;</p>");
1251
+ try {
1252
+ document.execCommand("insertHTML", false, embedHtml);
1253
+ } catch (err) {
1254
+ console.error("Failed to insert YouTube HTML:", err);
1255
+ // Fallback: append to the end of the editor
1256
+ if (editorRef.current) {
1257
+ var div = document.createElement('div');
1258
+ div.innerHTML = embedHtml;
1259
+ editorRef.current.appendChild(div);
1260
+ }
1261
+ }
1262
+ } else {
1263
+ console.warn("Invalid YouTube URL or Video ID not found");
1264
+ }
1265
+ setYoutubeModalOpen(false);
1266
+ setYoutubeUrl("");
1267
+ triggerChange && triggerChange();
1268
+ };
997
1269
  var processExistingImages = function processExistingImages(container) {
998
1270
  if (!container) return;
999
1271
  container.querySelectorAll("img").forEach(function (img) {
@@ -1516,8 +1788,8 @@ function RichTextEditor(_ref) {
1516
1788
  var lastInsertedNode = null;
1517
1789
 
1518
1790
  // Iterate through the selected text nodes and wrap them in spans
1519
- for (var _i = 0, _nodesToStyle = nodesToStyle; _i < _nodesToStyle.length; _i++) {
1520
- var textNode = _nodesToStyle[_i];
1791
+ for (var _i5 = 0, _nodesToStyle = nodesToStyle; _i5 < _nodesToStyle.length; _i5++) {
1792
+ var textNode = _nodesToStyle[_i5];
1521
1793
  var parent = textNode.parentNode;
1522
1794
 
1523
1795
  // This is important: check if the parent is a block-level element
@@ -1614,6 +1886,9 @@ function RichTextEditor(_ref) {
1614
1886
  }
1615
1887
  }, [disabled]);
1616
1888
  var handleEditorClick = React.useCallback(function (e) {
1889
+ setSelectionVersion(function (v) {
1890
+ return v + 1;
1891
+ });
1617
1892
  // Check if the click is on a link
1618
1893
  var clickedLink = e.target.closest('a');
1619
1894
  if (clickedLink) {
@@ -1623,6 +1898,15 @@ function RichTextEditor(_ref) {
1623
1898
  return;
1624
1899
  }
1625
1900
 
1901
+ // NEW: Check if click is on an image for resizing
1902
+ var clickedImg = e.target.closest('img');
1903
+ if (clickedImg && !clickedImg.closest('.rte-modal')) {
1904
+ setSelectedImage(clickedImg);
1905
+ setResizeData({});
1906
+ } else if (!e.target.closest('.resize-handle')) {
1907
+ setSelectedImage(null);
1908
+ }
1909
+
1626
1910
  // If disabled is true, prevent editing
1627
1911
  if (disabled === true) {
1628
1912
  e.preventDefault();
@@ -1639,14 +1923,138 @@ function RichTextEditor(_ref) {
1639
1923
  }, 0);
1640
1924
  }
1641
1925
  }, [editable, disabled]);
1926
+ var startResize = function startResize(e, direction) {
1927
+ e.preventDefault();
1928
+ e.stopPropagation();
1929
+ var img = selectedImage;
1930
+ var startX = e.clientX;
1931
+ var startY = e.clientY;
1932
+ var startWidth = img.offsetWidth;
1933
+ var startHeight = img.offsetHeight;
1934
+ var onMouseMove = function onMouseMove(moveEvent) {
1935
+ var newWidth = startWidth;
1936
+ var newHeight = startHeight;
1937
+ if (direction.includes('e')) newWidth = startWidth + (moveEvent.clientX - startX);
1938
+ if (direction.includes('w')) newWidth = startWidth - (moveEvent.clientX - startX);
1939
+ if (direction.includes('s')) newHeight = startHeight + (moveEvent.clientY - startY);
1940
+ if (direction.includes('n')) newHeight = startHeight - (moveEvent.clientY - startY);
1941
+ img.style.width = "".concat(newWidth, "px");
1942
+ img.style.height = "".concat(newHeight, "px");
1943
+ setResizeData({}); // Force re-render of handles
1944
+ };
1945
+ var _onMouseUp = function onMouseUp() {
1946
+ document.removeEventListener('mousemove', onMouseMove);
1947
+ document.removeEventListener('mouseup', _onMouseUp);
1948
+ triggerChange();
1949
+ };
1950
+ document.addEventListener('mousemove', onMouseMove);
1951
+ document.addEventListener('mouseup', _onMouseUp);
1952
+ };
1953
+ var renderResizeHandles = function renderResizeHandles() {
1954
+ if (!selectedImage || !editorRef.current) return null;
1955
+ var editorRect = editorRef.current.getBoundingClientRect();
1956
+ var imgRect = selectedImage.getBoundingClientRect();
1957
+
1958
+ // Relative position within editorRef using the more robust BoundingClientRect
1959
+ var top = imgRect.top - editorRect.top + editorRef.current.scrollTop;
1960
+ var left = imgRect.left - editorRect.left + editorRef.current.scrollLeft;
1961
+ var width = imgRect.width;
1962
+ var height = imgRect.height;
1963
+ var handleStyles = {
1964
+ position: 'absolute',
1965
+ width: '10px',
1966
+ height: '10px',
1967
+ background: '#3b82f6',
1968
+ border: '2px solid white',
1969
+ borderRadius: '50%',
1970
+ zIndex: 100
1971
+ };
1972
+ var handles = [{
1973
+ id: 'nw',
1974
+ style: {
1975
+ top: top - 5,
1976
+ left: left - 5,
1977
+ cursor: 'nw-resize'
1978
+ }
1979
+ }, {
1980
+ id: 'ne',
1981
+ style: {
1982
+ top: top - 5,
1983
+ left: left + width - 5,
1984
+ cursor: 'ne-resize'
1985
+ }
1986
+ }, {
1987
+ id: 'sw',
1988
+ style: {
1989
+ top: top + height - 5,
1990
+ left: left - 5,
1991
+ cursor: 'sw-resize'
1992
+ }
1993
+ }, {
1994
+ id: 'se',
1995
+ style: {
1996
+ top: top + height - 5,
1997
+ left: left + width - 5,
1998
+ cursor: 'se-resize'
1999
+ }
2000
+ }];
2001
+ return /*#__PURE__*/React.createElement("div", {
2002
+ style: {
2003
+ position: 'absolute',
2004
+ top: 0,
2005
+ left: 0,
2006
+ width: '100%',
2007
+ height: '100%',
2008
+ pointerEvents: 'none'
2009
+ }
2010
+ }, /*#__PURE__*/React.createElement("div", {
2011
+ style: {
2012
+ position: 'absolute',
2013
+ top: top,
2014
+ left: left,
2015
+ width: width,
2016
+ height: height,
2017
+ border: '2px solid #3b82f6',
2018
+ pointerEvents: 'none'
2019
+ }
2020
+ }), handles.map(function (h) {
2021
+ return /*#__PURE__*/React.createElement("div", {
2022
+ key: h.id,
2023
+ className: "resize-handle",
2024
+ onMouseDown: function onMouseDown(e) {
2025
+ return startResize(e, h.id);
2026
+ },
2027
+ style: _objectSpread2(_objectSpread2(_objectSpread2({}, handleStyles), h.style), {}, {
2028
+ pointerEvents: 'auto'
2029
+ })
2030
+ });
2031
+ }));
2032
+ };
1642
2033
  return /*#__PURE__*/React.createElement("div", {
1643
2034
  className: "rte-main-wrapper",
1644
2035
  style: {
1645
- width: '100%'
2036
+ width: '100%',
2037
+ position: 'relative'
1646
2038
  }
1647
2039
  }, label && /*#__PURE__*/React.createElement(LabelComponent, null, label), /*#__PURE__*/React.createElement("div", {
2040
+ style: {
2041
+ position: 'relative'
2042
+ },
1648
2043
  className: !showBorder ? "" : "rte-container",
1649
2044
  onClick: handleEditorClick,
2045
+ onMouseOver: function onMouseOver(e) {
2046
+ var table = e.target.closest('table');
2047
+ if (table && editorRef.current.contains(table)) {
2048
+ setHoveredTable(table);
2049
+ }
2050
+ },
2051
+ onMouseOut: function onMouseOut(e) {
2052
+ var table = e.target.closest('table');
2053
+ var related = e.relatedTarget;
2054
+ if (table && (!related || !table.contains(related)) && !(related !== null && related !== void 0 && related.closest('.rte-table-delete-hover'))) {
2055
+ setHoveredTable(null);
2056
+ }
2057
+ },
1650
2058
  onDrop: handleDrop,
1651
2059
  onDragOver: function onDragOver(e) {
1652
2060
  e.preventDefault();
@@ -1661,7 +2069,7 @@ function RichTextEditor(_ref) {
1661
2069
  e.preventDefault();
1662
2070
  e.stopPropagation();
1663
2071
  document.execCommand("bold");
1664
- triggerChange();
2072
+ handleInput();
1665
2073
  focus();
1666
2074
  },
1667
2075
  className: "rte-toolbar-button ".concat(isBold ? "active" : "")
@@ -1674,7 +2082,7 @@ function RichTextEditor(_ref) {
1674
2082
  e.preventDefault();
1675
2083
  e.stopPropagation();
1676
2084
  document.execCommand("italic");
1677
- triggerChange();
2085
+ handleInput();
1678
2086
  focus();
1679
2087
  },
1680
2088
  className: "rte-toolbar-button ".concat(isItalic ? "active" : "")
@@ -1687,7 +2095,7 @@ function RichTextEditor(_ref) {
1687
2095
  e.preventDefault();
1688
2096
  e.stopPropagation();
1689
2097
  document.execCommand("underline");
1690
- triggerChange();
2098
+ handleInput();
1691
2099
  focus();
1692
2100
  },
1693
2101
  className: "rte-toolbar-button ".concat(isUnderline ? "active" : "")
@@ -1859,6 +2267,13 @@ function RichTextEditor(_ref) {
1859
2267
  backgroundColor: '#e5e7eb',
1860
2268
  margin: '0 4px'
1861
2269
  }
2270
+ }), /*#__PURE__*/React.createElement("div", {
2271
+ style: {
2272
+ width: '1px',
2273
+ height: '20px',
2274
+ backgroundColor: '#e5e7eb',
2275
+ margin: '0 4px'
2276
+ }
1862
2277
  }), /*#__PURE__*/React.createElement("button", {
1863
2278
  type: "button",
1864
2279
  title: "Add Link",
@@ -1899,7 +2314,151 @@ function RichTextEditor(_ref) {
1899
2314
  }
1900
2315
  }) : /*#__PURE__*/React.createElement(FaImage, {
1901
2316
  size: 14
1902
- }))), /*#__PURE__*/React.createElement("div", {
2317
+ })), /*#__PURE__*/React.createElement("div", {
2318
+ style: {
2319
+ width: '1px',
2320
+ height: '20px',
2321
+ backgroundColor: '#e5e7eb',
2322
+ margin: '0 4px'
2323
+ }
2324
+ }), /*#__PURE__*/React.createElement("button", {
2325
+ type: "button",
2326
+ title: "Insert Table",
2327
+ className: "rte-toolbar-button",
2328
+ onMouseDown: function onMouseDown(e) {
2329
+ e.preventDefault();
2330
+ var sel = window.getSelection();
2331
+ if (sel && sel.rangeCount > 0) {
2332
+ selectionRangeRef.current = sel.getRangeAt(0).cloneRange();
2333
+ }
2334
+ setTableModalOpen(true);
2335
+ }
2336
+ }, /*#__PURE__*/React.createElement(FaTable, {
2337
+ size: 14
2338
+ })), /*#__PURE__*/React.createElement("button", {
2339
+ type: "button",
2340
+ title: "Embed YouTube Video",
2341
+ className: "rte-toolbar-button",
2342
+ onMouseDown: function onMouseDown(e) {
2343
+ e.preventDefault();
2344
+ var sel = window.getSelection();
2345
+ if (sel && sel.rangeCount > 0) {
2346
+ selectionRangeRef.current = sel.getRangeAt(0).cloneRange();
2347
+ }
2348
+ setYoutubeModalOpen(true);
2349
+ }
2350
+ }, /*#__PURE__*/React.createElement(FaYoutube, {
2351
+ size: 14
2352
+ })), function () {
2353
+ if (typeof window === "undefined") return null;
2354
+ var sel = window.getSelection();
2355
+ // Robust check: inside cell OR the table itself is selected
2356
+ var isCell = sel && sel.rangeCount > 0 && sel.anchorNode && (findParentTag(sel.anchorNode, 'TD') || findParentTag(sel.anchorNode, 'TH'));
2357
+ var isTable = sel && sel.rangeCount > 0 && sel.anchorNode && findParentTag(sel.anchorNode, 'TABLE');
2358
+ if (isCell || isTable) {
2359
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
2360
+ style: {
2361
+ width: '1px',
2362
+ height: '20px',
2363
+ backgroundColor: '#e5e7eb',
2364
+ margin: '0 4px'
2365
+ }
2366
+ }), /*#__PURE__*/React.createElement("button", {
2367
+ type: "button",
2368
+ title: "Add Row Above",
2369
+ className: "rte-toolbar-button",
2370
+ onMouseDown: function onMouseDown(e) {
2371
+ e.preventDefault();
2372
+ tableAction('addRowAbove');
2373
+ }
2374
+ }, "+R\u2191"), /*#__PURE__*/React.createElement("button", {
2375
+ type: "button",
2376
+ title: "Add Row Below",
2377
+ className: "rte-toolbar-button",
2378
+ onMouseDown: function onMouseDown(e) {
2379
+ e.preventDefault();
2380
+ tableAction('addRowBelow');
2381
+ }
2382
+ }, "+R\u2193"), /*#__PURE__*/React.createElement("button", {
2383
+ type: "button",
2384
+ title: "Add Col Before",
2385
+ className: "rte-toolbar-button",
2386
+ onMouseDown: function onMouseDown(e) {
2387
+ e.preventDefault();
2388
+ tableAction('addColBefore');
2389
+ }
2390
+ }, "+C\u2190"), /*#__PURE__*/React.createElement("button", {
2391
+ type: "button",
2392
+ title: "Add Col After",
2393
+ className: "rte-toolbar-button",
2394
+ onMouseDown: function onMouseDown(e) {
2395
+ e.preventDefault();
2396
+ tableAction('addColAfter');
2397
+ }
2398
+ }, "+C\u2192"), /*#__PURE__*/React.createElement("div", {
2399
+ style: {
2400
+ width: '1px',
2401
+ height: '20px',
2402
+ backgroundColor: '#f3f4f6',
2403
+ margin: '0 4px'
2404
+ }
2405
+ }), /*#__PURE__*/React.createElement("button", {
2406
+ type: "button",
2407
+ title: "Merge Cells (Right)",
2408
+ className: "rte-toolbar-button",
2409
+ onMouseDown: function onMouseDown(e) {
2410
+ e.preventDefault();
2411
+ tableAction('mergeRight');
2412
+ }
2413
+ }, /*#__PURE__*/React.createElement(FaObjectGroup, {
2414
+ size: 14
2415
+ })), /*#__PURE__*/React.createElement("button", {
2416
+ type: "button",
2417
+ title: "Delete Row",
2418
+ className: "rte-toolbar-button rte-toolbar-button-danger ",
2419
+ onMouseDown: function onMouseDown(e) {
2420
+ e.preventDefault();
2421
+ tableAction('deleteRow');
2422
+ }
2423
+ }, /*#__PURE__*/React.createElement(FaTrash, {
2424
+ size: 12
2425
+ }), " ", /*#__PURE__*/React.createElement("span", {
2426
+ style: {
2427
+ fontSize: '10px'
2428
+ }
2429
+ }, "Row")), /*#__PURE__*/React.createElement("button", {
2430
+ type: "button",
2431
+ title: "Delete Column",
2432
+ className: "rte-toolbar-button rte-toolbar-button-danger",
2433
+ onMouseDown: function onMouseDown(e) {
2434
+ e.preventDefault();
2435
+ tableAction('deleteCol');
2436
+ }
2437
+ }, /*#__PURE__*/React.createElement(FaTrash, {
2438
+ size: 12
2439
+ }), " ", /*#__PURE__*/React.createElement("span", {
2440
+ style: {
2441
+ fontSize: '10px',
2442
+ marginRight: "5px"
2443
+ }
2444
+ }, "Col")), /*#__PURE__*/React.createElement("button", {
2445
+ type: "button",
2446
+ title: "Delete Table",
2447
+ className: "rte-toolbar-button rte-toolbar-button-danger",
2448
+ onMouseDown: function onMouseDown(e) {
2449
+ e.preventDefault();
2450
+ tableAction('deleteTable');
2451
+ }
2452
+ }, /*#__PURE__*/React.createElement(FaTrash, {
2453
+ size: 14
2454
+ }), " ", /*#__PURE__*/React.createElement("span", {
2455
+ style: {
2456
+ fontWeight: '600'
2457
+ }
2458
+ }, "Table")));
2459
+ }
2460
+ return null;
2461
+ }()), /*#__PURE__*/React.createElement("div", {
1903
2462
  ref: editorRef,
1904
2463
  contentEditable: editable && disabled !== true,
1905
2464
  suppressContentEditableWarning: true,
@@ -1920,7 +2479,23 @@ function RichTextEditor(_ref) {
1920
2479
  paddingLeft: paddingLeft || '12px'
1921
2480
  },
1922
2481
  className: "rte-content"
1923
- }), linkModalOpen && /*#__PURE__*/React.createElement("div", {
2482
+ }), renderResizeHandles(), /*#__PURE__*/React.createElement("div", {
2483
+ className: "rte-footer"
2484
+ }, function (_editorRef$current) {
2485
+ var text = ((_editorRef$current = editorRef.current) === null || _editorRef$current === void 0 ? void 0 : _editorRef$current.innerText) || "";
2486
+ var cleanText = text.replace(/[\n\r]/g, ' ').trim();
2487
+ var words = cleanText ? cleanText.split(/\s+/).length : 0;
2488
+ var chars = text.length;
2489
+ return /*#__PURE__*/React.createElement("div", {
2490
+ className: "rte-footer-content"
2491
+ }, /*#__PURE__*/React.createElement("span", {
2492
+ className: "rte-footer-item"
2493
+ }, /*#__PURE__*/React.createElement("b", null, words), " words"), /*#__PURE__*/React.createElement("span", {
2494
+ className: "rte-footer-separator"
2495
+ }, "\u2022"), /*#__PURE__*/React.createElement("span", {
2496
+ className: "rte-footer-item"
2497
+ }, /*#__PURE__*/React.createElement("b", null, chars), " characters"));
2498
+ }()), linkModalOpen && /*#__PURE__*/React.createElement("div", {
1924
2499
  className: "rte-modal-overlay",
1925
2500
  onClick: cancelLink
1926
2501
  }, /*#__PURE__*/React.createElement("div", {
@@ -1931,42 +2506,147 @@ function RichTextEditor(_ref) {
1931
2506
  }, /*#__PURE__*/React.createElement("h3", {
1932
2507
  className: "rte-modal-title"
1933
2508
  }, "Insert Link"), /*#__PURE__*/React.createElement("div", {
2509
+ className: "rte-modal-divider"
2510
+ }), /*#__PURE__*/React.createElement("div", {
2511
+ className: "rte-modal-body"
2512
+ }, /*#__PURE__*/React.createElement("div", {
2513
+ className: "rte-form-group"
2514
+ }, /*#__PURE__*/React.createElement("label", {
2515
+ className: "rte-label"
2516
+ }, "Link Text"), /*#__PURE__*/React.createElement("input", {
2517
+ type: "text",
2518
+ className: "rte-input",
2519
+ placeholder: "e.g. Google",
2520
+ value: linkText,
2521
+ onChange: function onChange(e) {
2522
+ return setLinkText(e.target.value);
2523
+ }
2524
+ })), /*#__PURE__*/React.createElement("div", {
1934
2525
  className: "rte-form-group"
1935
2526
  }, /*#__PURE__*/React.createElement("label", {
1936
2527
  className: "rte-label"
1937
2528
  }, "URL"), /*#__PURE__*/React.createElement("input", {
1938
- type: "url",
2529
+ type: "text",
1939
2530
  className: "rte-input",
2531
+ placeholder: "https://example.com",
1940
2532
  value: linkUrl,
1941
2533
  onChange: function onChange(e) {
1942
2534
  return setLinkUrl(e.target.value);
1943
2535
  },
1944
- autoFocus: true,
1945
- placeholder: "https://example.com"
2536
+ onKeyDown: function onKeyDown(e) {
2537
+ return e.key === 'Enter' && confirmLink();
2538
+ },
2539
+ autoFocus: true
2540
+ }))), /*#__PURE__*/React.createElement("div", {
2541
+ className: "rte-modal-divider",
2542
+ style: {
2543
+ margin: '8px 0 20px 0'
2544
+ }
2545
+ }), /*#__PURE__*/React.createElement("div", {
2546
+ className: "rte-modal-footer"
2547
+ }, /*#__PURE__*/React.createElement("button", {
2548
+ type: "button",
2549
+ className: "rte-btn rte-btn-secondary",
2550
+ onClick: cancelLink
2551
+ }, "Cancel"), /*#__PURE__*/React.createElement("button", {
2552
+ type: "button",
2553
+ className: "rte-btn rte-btn-primary",
2554
+ onClick: confirmLink,
2555
+ disabled: !linkUrl
2556
+ }, "Insert")))), tableModalOpen && /*#__PURE__*/React.createElement("div", {
2557
+ className: "rte-modal-overlay",
2558
+ onClick: function onClick() {
2559
+ return setTableModalOpen(false);
2560
+ }
2561
+ }, /*#__PURE__*/React.createElement("div", {
2562
+ className: "rte-modal",
2563
+ onClick: function onClick(e) {
2564
+ return e.stopPropagation();
2565
+ }
2566
+ }, /*#__PURE__*/React.createElement("h3", {
2567
+ className: "rte-modal-title"
2568
+ }, "Insert Table"), /*#__PURE__*/React.createElement("div", {
2569
+ className: "rte-form-group"
2570
+ }, /*#__PURE__*/React.createElement("label", {
2571
+ className: "rte-label"
2572
+ }, "Rows"), /*#__PURE__*/React.createElement("input", {
2573
+ type: "number",
2574
+ className: "rte-input",
2575
+ value: tableRows,
2576
+ onChange: function onChange(e) {
2577
+ return setTableRows(e.target.value);
2578
+ },
2579
+ min: "1",
2580
+ max: "10"
1946
2581
  })), /*#__PURE__*/React.createElement("div", {
1947
2582
  className: "rte-form-group"
1948
2583
  }, /*#__PURE__*/React.createElement("label", {
1949
2584
  className: "rte-label"
1950
- }, "Display Text"), /*#__PURE__*/React.createElement("input", {
2585
+ }, "Columns"), /*#__PURE__*/React.createElement("input", {
2586
+ type: "number",
2587
+ className: "rte-input",
2588
+ value: tableCols,
2589
+ onChange: function onChange(e) {
2590
+ return setTableCols(e.target.value);
2591
+ },
2592
+ min: "1",
2593
+ max: "10"
2594
+ })), /*#__PURE__*/React.createElement("div", {
2595
+ className: "rte-modal-actions"
2596
+ }, /*#__PURE__*/React.createElement("button", {
2597
+ type: "button",
2598
+ className: "rte-button rte-button-secondary",
2599
+ onClick: function onClick() {
2600
+ return setTableModalOpen(false);
2601
+ }
2602
+ }, "Cancel"), /*#__PURE__*/React.createElement("button", {
2603
+ type: "button",
2604
+ className: "rte-button rte-button-primary",
2605
+ onClick: insertTable
2606
+ }, "Insert")))), youtubeModalOpen && /*#__PURE__*/React.createElement("div", {
2607
+ className: "rte-modal-overlay",
2608
+ onClick: function onClick() {
2609
+ return setYoutubeModalOpen(false);
2610
+ }
2611
+ }, /*#__PURE__*/React.createElement("div", {
2612
+ className: "rte-modal",
2613
+ onClick: function onClick(e) {
2614
+ return e.stopPropagation();
2615
+ }
2616
+ }, /*#__PURE__*/React.createElement("div", {
2617
+ className: "rte-modal-header"
2618
+ }, /*#__PURE__*/React.createElement("h3", {
2619
+ className: "rte-modal-title"
2620
+ }, "Embed YouTube Video")), /*#__PURE__*/React.createElement("div", {
2621
+ className: "rte-form-group"
2622
+ }, /*#__PURE__*/React.createElement("label", {
2623
+ className: "rte-label"
2624
+ }, "Paste YouTube Video URL"), /*#__PURE__*/React.createElement("input", {
1951
2625
  type: "text",
1952
2626
  className: "rte-input",
1953
- value: linkText,
2627
+ value: youtubeUrl,
1954
2628
  onChange: function onChange(e) {
1955
- return setLinkText(e.target.value);
2629
+ return setYoutubeUrl(e.target.value);
1956
2630
  },
1957
- placeholder: "Link text"
2631
+ placeholder: "https://www.youtube.com/watch?v=...",
2632
+ autoFocus: true,
2633
+ onKeyDown: function onKeyDown(e) {
2634
+ if (e.key === 'Enter') insertYoutube();
2635
+ if (e.key === 'Escape') setYoutubeModalOpen(false);
2636
+ }
1958
2637
  })), /*#__PURE__*/React.createElement("div", {
1959
2638
  className: "rte-modal-actions"
1960
2639
  }, /*#__PURE__*/React.createElement("button", {
1961
2640
  type: "button",
1962
2641
  className: "rte-button rte-button-secondary",
1963
- onClick: cancelLink
2642
+ onClick: function onClick() {
2643
+ return setYoutubeModalOpen(false);
2644
+ }
1964
2645
  }, "Cancel"), /*#__PURE__*/React.createElement("button", {
1965
2646
  type: "button",
1966
2647
  className: "rte-button rte-button-primary",
1967
- onClick: confirmLink,
1968
- disabled: !linkUrl
1969
- }, "Insert")))), imageModalOpen && /*#__PURE__*/React.createElement("div", {
2648
+ onClick: insertYoutube
2649
+ }, "Embed Video")))), imageModalOpen && /*#__PURE__*/React.createElement("div", {
1970
2650
  className: "rte-modal-overlay",
1971
2651
  onClick: closeImageModal
1972
2652
  }, /*#__PURE__*/React.createElement("div", {
@@ -2006,7 +2686,7 @@ function RichTextEditor(_ref) {
2006
2686
  type: "button",
2007
2687
  className: "rte-button rte-button-primary",
2008
2688
  onClick: function onClick() {
2009
- handleChange && handleChange();
2689
+ onChange && onChange(html);
2010
2690
  setEditable(false);
2011
2691
  }
2012
2692
  }, "Save Changes")));