@meenainwal/rich-text-editor 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,8 +34,8 @@ class b {
34
34
  try {
35
35
  const n = this.getNodeByPath(t.startPath, e), i = this.getNodeByPath(t.endPath, e);
36
36
  if (n && i) {
37
- const o = document.createRange();
38
- o.setStart(n, Math.min(t.startOffset, n.textContent?.length || 0)), o.setEnd(i, Math.min(t.endOffset, i.textContent?.length || 0)), this.restoreSelection(o);
37
+ const s = document.createRange();
38
+ s.setStart(n, Math.min(t.startOffset, n.textContent?.length || 0)), s.setEnd(i, Math.min(t.endOffset, i.textContent?.length || 0)), this.restoreSelection(s);
39
39
  }
40
40
  } catch (n) {
41
41
  console.warn("Failed to restore selection path:", n);
@@ -45,8 +45,8 @@ class b {
45
45
  const n = [];
46
46
  let i = e;
47
47
  for (; i !== t && i.parentElement; ) {
48
- const o = Array.from(i.parentElement.childNodes).indexOf(i);
49
- n.unshift(o), i = i.parentElement;
48
+ const s = Array.from(i.parentElement.childNodes).indexOf(i);
49
+ n.unshift(s), i = i.parentElement;
50
50
  }
51
51
  return n;
52
52
  }
@@ -132,11 +132,11 @@ class y {
132
132
  const t = this.editor.selection.getRange();
133
133
  if (t && this.activeContainer.contains(t.commonAncestorContainer)) {
134
134
  e.preventDefault();
135
- const n = this.activeContainer.querySelector("img"), i = n?.getAttribute("data-image-id"), o = n?.src, s = this.editor.getOptions();
136
- s.onImageDelete && s.onImageDelete(i || void 0, o), i && s.imageEndpoints?.delete && fetch(s.imageEndpoints.delete, {
135
+ const n = this.activeContainer.querySelector("img"), i = n?.getAttribute("data-image-id"), s = n?.src, o = this.editor.getOptions();
136
+ o.onImageDelete && o.onImageDelete(i || void 0, s), i && o.imageEndpoints?.delete && fetch(o.imageEndpoints.delete, {
137
137
  method: "DELETE",
138
138
  headers: { "Content-Type": "application/json" },
139
- body: JSON.stringify({ id: i, url: o })
139
+ body: JSON.stringify({ id: i, url: s })
140
140
  }).catch((a) => console.error("Failed to notify server of image deletion", a)), this.activeContainer.remove(), this.activeContainer = null, this.editor.el.dispatchEvent(new Event("input", { bubbles: !0 }));
141
141
  }
142
142
  }
@@ -160,8 +160,8 @@ class y {
160
160
  handleResize(e) {
161
161
  if (!this.activeContainer || !this.isResizing) return;
162
162
  const t = this.activeContainer.querySelector("img"), n = e.clientX - this.startX, i = e.clientY - this.startY;
163
- let o = this.startWidth, s = this.startHeight;
164
- this.currentHandle?.includes("right") ? o = this.startWidth + n : this.currentHandle?.includes("left") ? o = this.startWidth - n : this.currentHandle?.includes("bottom") ? o = this.startWidth + i * this.aspectRatio : this.currentHandle?.includes("top") && (o = this.startWidth - i * this.aspectRatio), s = o / this.aspectRatio, o > 50 && o < this.editor.el.clientWidth && (t.style.width = `${o}px`, t.style.height = `${s}px`);
163
+ let s = this.startWidth, o = this.startHeight;
164
+ this.currentHandle?.includes("right") ? s = this.startWidth + n : this.currentHandle?.includes("left") ? s = this.startWidth - n : this.currentHandle?.includes("bottom") ? s = this.startWidth + i * this.aspectRatio : this.currentHandle?.includes("top") && (s = this.startWidth - i * this.aspectRatio), o = s / this.aspectRatio, s > 50 && s < this.editor.el.clientWidth && (t.style.width = `${s}px`, t.style.height = `${o}px`);
165
165
  }
166
166
  stopResize() {
167
167
  this.isResizing = !1, this.currentHandle = null, document.body.style.cursor = "", this.editor.el.dispatchEvent(new Event("input", { bubbles: !0 }));
@@ -220,7 +220,7 @@ const w = {
220
220
  title: "Redo",
221
221
  command: "redo",
222
222
  icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 7v6h-6"></path><path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7"></path></svg>'
223
- }, k = {
223
+ }, L = {
224
224
  type: "select",
225
225
  title: "Heading",
226
226
  command: "formatBlock",
@@ -234,7 +234,7 @@ const w = {
234
234
  { label: "Heading 5", value: "H5" },
235
235
  { label: "Heading 6", value: "H6" }
236
236
  ]
237
- }, L = {
237
+ }, k = {
238
238
  type: "select",
239
239
  title: "Font",
240
240
  command: "fontFamily",
@@ -347,12 +347,12 @@ const w = {
347
347
  title: "Bulleted List",
348
348
  command: "insertUnorderedList",
349
349
  icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line></svg>'
350
- }, O = {
350
+ }, B = {
351
351
  type: "button",
352
352
  title: "Numbered List",
353
353
  command: "insertOrderedList",
354
354
  icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="10" y1="6" x2="21" y2="6"></line><line x1="10" y1="12" x2="21" y2="12"></line><line x1="10" y1="18" x2="21" y2="18"></line><path d="M4 6h1v4"></path><path d="M4 10h2"></path><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"></path></svg>'
355
- }, B = {
355
+ }, O = {
356
356
  type: "button",
357
357
  title: "Outdent",
358
358
  command: "outdent",
@@ -367,12 +367,12 @@ const w = {
367
367
  title: "Horizontal Rule",
368
368
  command: "insertHorizontalRule",
369
369
  icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line></svg>'
370
- }, W = {
370
+ }, q = {
371
371
  type: "button",
372
372
  title: "Clear Formatting",
373
373
  command: "removeFormat",
374
374
  icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7V4h16v3"></path><path d="M5 20h6"></path><path d="M13 4 8 20"></path><path d="m15 15 5 5"></path><path d="m20 15-5 5"></path></svg>'
375
- }, q = {
375
+ }, W = {
376
376
  type: "button",
377
377
  title: "Insert Emoji",
378
378
  command: "insertEmoji",
@@ -396,8 +396,8 @@ const w = {
396
396
  { ...w, id: "undo" },
397
397
  { ...x, id: "redo" },
398
398
  m,
399
- { ...k, id: "heading" },
400
- { ...L, id: "font-family" },
399
+ { ...L, id: "heading" },
400
+ { ...k, id: "font-family" },
401
401
  { ...C, id: "font-size" },
402
402
  { ...S, id: "line-height" },
403
403
  m,
@@ -415,16 +415,16 @@ const w = {
415
415
  { ...D, id: "align-justify" },
416
416
  m,
417
417
  { ...z, id: "bullet-list" },
418
- { ...O, id: "ordered-list" },
419
- { ...B, id: "outdent" },
418
+ { ...B, id: "ordered-list" },
419
+ { ...O, id: "outdent" },
420
420
  { ...U, id: "indent" },
421
421
  m,
422
422
  { ...F, id: "horizontal-rule" },
423
- { ...q, id: "emoji" },
423
+ { ...W, id: "emoji" },
424
424
  { ..._, id: "link" },
425
425
  { ...$, id: "image" },
426
426
  { ...V, id: "table" },
427
- { ...W, id: "clear-formatting" }
427
+ { ...q, id: "clear-formatting" }
428
428
  ];
429
429
  class g {
430
430
  container;
@@ -433,55 +433,55 @@ class g {
433
433
  dark;
434
434
  theme;
435
435
  fields;
436
- constructor(e, t, n, i, o, s) {
437
- this.fields = t, this.onConfirm = n, this.onClose = i, this.theme = o, this.dark = s, this.container = this.createModalElement(e, t), this.setupEvents();
436
+ constructor(e, t, n, i, s, o) {
437
+ this.fields = t, this.onConfirm = n, this.onClose = i, this.theme = s, this.dark = o, this.container = this.createModalElement(e, t), this.setupEvents();
438
438
  }
439
439
  createModalElement(e, t) {
440
440
  const n = document.createElement("div");
441
441
  n.classList.add("te-modal"), this.theme && this.applyTheme(n, this.theme), this.dark && n.classList.add("te-dark");
442
442
  const i = document.createElement("div");
443
443
  i.classList.add("te-modal-header"), i.textContent = e, n.appendChild(i);
444
- const o = document.createElement("div");
445
- o.classList.add("te-modal-body"), t.forEach((l) => {
444
+ const s = document.createElement("div");
445
+ s.classList.add("te-modal-body"), t.forEach((l) => {
446
446
  const d = document.createElement("div");
447
447
  d.classList.add("te-modal-field");
448
448
  const c = document.createElement("label");
449
449
  c.setAttribute("for", l.id), c.textContent = l.label;
450
450
  const h = document.createElement("input");
451
- h.type = l.type, h.id = l.id, h.classList.add("te-modal-input"), l.placeholder && (h.placeholder = l.placeholder), l.defaultValue && (h.value = l.defaultValue), l.min && (h.min = l.min), l.max && (h.max = l.max), d.appendChild(c), d.appendChild(h), o.appendChild(d);
452
- }), n.appendChild(o);
453
- const s = document.createElement("div");
454
- s.classList.add("te-modal-footer");
451
+ h.type = l.type, h.id = l.id, h.classList.add("te-modal-input"), l.placeholder && (h.placeholder = l.placeholder), l.defaultValue && (h.value = l.defaultValue), l.min && (h.min = l.min), l.max && (h.max = l.max), d.appendChild(c), d.appendChild(h), s.appendChild(d);
452
+ }), n.appendChild(s);
453
+ const o = document.createElement("div");
454
+ o.classList.add("te-modal-footer");
455
455
  const a = document.createElement("button");
456
456
  a.classList.add("te-modal-btn", "te-modal-btn-cancel"), a.textContent = "Cancel";
457
457
  const r = document.createElement("button");
458
- return r.classList.add("te-modal-btn", "te-modal-btn-confirm"), r.textContent = "Insert", s.appendChild(a), s.appendChild(r), n.appendChild(s), n;
458
+ return r.classList.add("te-modal-btn", "te-modal-btn-confirm"), r.textContent = "Insert", o.appendChild(a), o.appendChild(r), n.appendChild(o), n;
459
459
  }
460
460
  setupEvents() {
461
461
  const e = this.container.querySelector(".te-modal-btn-cancel"), t = this.container.querySelector(".te-modal-btn-confirm");
462
462
  e.addEventListener("click", () => this.close()), t.addEventListener("click", () => {
463
- const o = {};
464
- this.fields.forEach((s) => {
465
- const a = this.container.querySelector(`#${s.id}`);
466
- o[s.id] = a.value;
467
- }), this.onConfirm(o), this.close();
463
+ const s = {};
464
+ this.fields.forEach((o) => {
465
+ const a = this.container.querySelector(`#${o.id}`);
466
+ s[o.id] = a.value;
467
+ }), this.onConfirm(s), this.close();
468
468
  });
469
- const n = (o) => {
470
- o.key === "Escape" && this.close(), o.key === "Enter" && t.click();
469
+ const n = (s) => {
470
+ s.key === "Escape" && this.close(), s.key === "Enter" && t.click();
471
471
  };
472
472
  this.container.addEventListener("keydown", n);
473
- const i = (o) => {
474
- this.container.contains(o.target) || (this.close(), document.removeEventListener("mousedown", i));
473
+ const i = (s) => {
474
+ this.container.contains(s.target) || (this.close(), document.removeEventListener("mousedown", i));
475
475
  };
476
476
  setTimeout(() => document.addEventListener("mousedown", i), 0);
477
477
  }
478
478
  show(e) {
479
479
  document.body.appendChild(this.container);
480
480
  const t = e.getBoundingClientRect(), n = 260;
481
- let i = t.bottom + window.scrollY + 10, o = t.left + window.scrollX;
482
- o + n > window.innerWidth && (o = window.innerWidth - n - 20), this.container.style.top = `${i}px`, this.container.style.left = `${o}px`;
483
- const s = this.container.querySelector("input");
484
- s && s.focus();
481
+ let i = t.bottom + window.scrollY + 10, s = t.left + window.scrollX;
482
+ s + n > window.innerWidth && (s = window.innerWidth - n - 20), this.container.style.top = `${i}px`, this.container.style.left = `${s}px`;
483
+ const o = this.container.querySelector("input");
484
+ o && o.focus();
485
485
  }
486
486
  close() {
487
487
  this.container.parentElement && (this.container.remove(), this.onClose());
@@ -507,9 +507,9 @@ class g {
507
507
  shadowMd: "--te-shadow-md",
508
508
  shadowLg: "--te-shadow-lg"
509
509
  };
510
- for (const [i, o] of Object.entries(n)) {
511
- const s = t[i];
512
- s && e.style.setProperty(o, s);
510
+ for (const [i, s] of Object.entries(n)) {
511
+ const o = t[i];
512
+ o && e.style.setProperty(s, o);
513
513
  }
514
514
  }
515
515
  }
@@ -527,10 +527,10 @@ class G {
527
527
  e.className = "te-floating-toolbar te-glass", e.style.display = "none", e.style.position = "absolute", e.style.zIndex = "2000";
528
528
  const t = ["heading", "bold", "italic", "underline", "strikethrough", "highlight-color", "link", "clear-formatting"];
529
529
  return v.filter((i) => i.id && t.includes(i.id)).forEach((i) => {
530
- const o = document.createElement("button");
531
- o.className = "te-floating-btn", o.title = i.title, o.innerHTML = i.icon || i.title, o.onclick = (s) => {
532
- s.preventDefault(), s.stopPropagation(), this.handleCommand(i);
533
- }, e.appendChild(o);
530
+ const s = document.createElement("button");
531
+ s.className = "te-floating-btn", s.title = i.title, s.innerHTML = i.icon || i.title, s.onclick = (o) => {
532
+ o.preventDefault(), o.stopPropagation(), this.handleCommand(i);
533
+ }, e.appendChild(s);
534
534
  }), e;
535
535
  }
536
536
  handleCommand(e) {
@@ -558,7 +558,9 @@ class G {
558
558
  const e = () => {
559
559
  setTimeout(() => this.updatePosition(), 50);
560
560
  };
561
- this.editor.el.addEventListener("mouseup", e), this.editor.el.addEventListener("keyup", e), window.addEventListener("mousedown", (t) => {
561
+ this.editor.el.addEventListener("mouseup", e), this.editor.el.addEventListener("keyup", e), this.editor.el.addEventListener("scroll", () => {
562
+ this.isVisible && !this.activeModal && this.hide();
563
+ }, !0), window.addEventListener("mousedown", (t) => {
562
564
  !this.container.contains(t.target) && !this.editor.el.contains(t.target) && this.hide();
563
565
  }), window.addEventListener("resize", () => {
564
566
  this.isVisible && this.updatePosition();
@@ -575,11 +577,13 @@ class G {
575
577
  this.hide();
576
578
  return;
577
579
  }
578
- const n = t.getBoundingClientRect();
580
+ const n = t.getBoundingClientRect(), s = (this.container.offsetParent || document.documentElement).getBoundingClientRect();
579
581
  this.container.style.display = "flex", this.isVisible = !0;
580
- const i = this.container.offsetWidth, o = this.container.offsetHeight;
581
- let s = n.top + window.scrollY - o - 10, a = n.left + window.scrollX + n.width / 2 - i / 2;
582
- s < window.scrollY && (s = n.bottom + window.scrollY + 10), a < 10 && (a = 10), a + i > window.innerWidth - 10 && (a = window.innerWidth - i - 10), this.container.style.top = `${s}px`, this.container.style.left = `${a}px`, this.container.classList.add("te-floating-visible");
582
+ const o = this.container.offsetWidth, a = this.container.offsetHeight;
583
+ let r = n.top - s.top - a - 10, l = n.left - s.left + n.width / 2 - o / 2;
584
+ n.top - a - 15 < 0 && (r = n.bottom - s.top + 10);
585
+ const d = 10 - s.left, c = window.innerWidth - 10 - s.left - o;
586
+ l < d && (l = d), l > c && (l = c), this.container.style.top = `${r}px`, this.container.style.left = `${l}px`, this.container.classList.add("te-floating-visible");
583
587
  }
584
588
  hide() {
585
589
  this.container.style.display = "none", this.container.classList.remove("te-floating-visible"), this.isVisible = !1;
@@ -599,25 +603,25 @@ class f {
599
603
  return new Promise((n, i) => {
600
604
  if (e.size <= t * 1024 * 1024 && e.type === "image/webp")
601
605
  return n(e);
602
- const o = new Image();
603
- o.src = URL.createObjectURL(e), o.onload = () => {
604
- const s = document.createElement("canvas");
605
- let a = o.width, r = o.height;
606
+ const s = new Image();
607
+ s.src = URL.createObjectURL(e), s.onload = () => {
608
+ const o = document.createElement("canvas");
609
+ let a = s.width, r = s.height;
606
610
  const l = 2e3;
607
- (a > l || r > l) && (a > r ? (r = Math.round(r * l / a), a = l) : (a = Math.round(a * l / r), r = l)), s.width = a, s.height = r;
608
- const d = s.getContext("2d");
611
+ (a > l || r > l) && (a > r ? (r = Math.round(r * l / a), a = l) : (a = Math.round(a * l / r), r = l)), o.width = a, o.height = r;
612
+ const d = o.getContext("2d");
609
613
  if (!d)
610
614
  return i(new Error("Failed to get canvas context"));
611
- d.drawImage(o, 0, 0, a, r), s.toBlob(
615
+ d.drawImage(s, 0, 0, a, r), o.toBlob(
612
616
  (c) => {
613
617
  c ? n(c) : i(new Error("Canvas toBlob failed"));
614
618
  },
615
619
  "image/webp",
616
620
  0.8
617
621
  // 80% quality is professional standard
618
- ), URL.revokeObjectURL(o.src);
619
- }, o.onerror = () => {
620
- URL.revokeObjectURL(o.src), i(new Error("Failed to load image for compression"));
622
+ ), URL.revokeObjectURL(s.src);
623
+ }, s.onerror = () => {
624
+ URL.revokeObjectURL(s.src), i(new Error("Failed to load image for compression"));
621
625
  };
622
626
  });
623
627
  }
@@ -630,27 +634,27 @@ class f {
630
634
  const i = new FormData();
631
635
  i.append("file", e, n);
632
636
  try {
633
- const o = await fetch(t.imageEndpoints.upload, {
637
+ const s = await fetch(t.imageEndpoints.upload, {
634
638
  method: "POST",
635
639
  body: i
636
640
  });
637
- if (o.ok) {
638
- const s = await o.json();
641
+ if (s.ok) {
642
+ const o = await s.json();
639
643
  return {
640
- imageUrl: s.imageUrl,
641
- imageId: s.imageId
644
+ imageUrl: o.imageUrl,
645
+ imageId: o.imageId
642
646
  };
643
647
  }
644
648
  console.warn("Custom upload endpoint returned an error, falling back.");
645
- } catch (o) {
646
- console.error("Custom upload failed:", o);
649
+ } catch (s) {
650
+ console.error("Custom upload failed:", s);
647
651
  }
648
652
  }
649
653
  if (t.cloudinaryFallback) {
650
- const { cloudName: i, uploadPreset: o } = t.cloudinaryFallback, s = `https://api.cloudinary.com/v1_1/${i}/image/upload`, a = new FormData();
651
- a.append("file", e, n), a.append("upload_preset", o);
654
+ const { cloudName: i, uploadPreset: s } = t.cloudinaryFallback, o = `https://api.cloudinary.com/v1_1/${i}/image/upload`, a = new FormData();
655
+ a.append("file", e, n), a.append("upload_preset", s);
652
656
  try {
653
- const r = await fetch(s, {
657
+ const r = await fetch(o, {
654
658
  method: "POST",
655
659
  body: a
656
660
  });
@@ -712,9 +716,9 @@ class K {
712
716
  shadowMd: "--te-shadow-md",
713
717
  shadowLg: "--te-shadow-lg"
714
718
  };
715
- for (const [i, o] of Object.entries(n)) {
716
- const s = e[i];
717
- s && t.style.setProperty(o, s);
719
+ for (const [i, s] of Object.entries(n)) {
720
+ const o = e[i];
721
+ o && t.style.setProperty(s, o);
718
722
  }
719
723
  }
720
724
  /**
@@ -733,7 +737,12 @@ class K {
733
737
  }
734
738
  checkPlaceholder() {
735
739
  if (!this.editableElement) return;
736
- this.editableElement.textContent?.trim() === "" && !this.editableElement.querySelector("img") && !this.editableElement.querySelector("table") && !this.editableElement.querySelector("ul") && !this.editableElement.querySelector("ol") ? this.editableElement.classList.add("is-empty") : this.editableElement.classList.remove("is-empty");
740
+ if (this.editableElement.textContent?.trim() === "" && !this.editableElement.querySelector("img") && !this.editableElement.querySelector("table") && !this.editableElement.querySelector("ul") && !this.editableElement.querySelector("ol") && !this.editableElement.querySelector("hr") && !this.editableElement.querySelector("figure") && !this.editableElement.querySelector("blockquote") && !this.editableElement.querySelector("pre")) {
741
+ this.editableElement.classList.add("is-empty");
742
+ const t = this.editableElement.firstElementChild;
743
+ t && (this.editableElement.style.textAlign = t.style.textAlign);
744
+ } else
745
+ this.editableElement.classList.remove("is-empty"), this.editableElement.style.textAlign = "";
737
746
  }
738
747
  addEventListener(e, t, n, i) {
739
748
  e.addEventListener(t, n, i), this.eventListeners.push({ target: e, type: t, handler: n });
@@ -744,8 +753,8 @@ class K {
744
753
  t.addedNodes.forEach((n) => {
745
754
  if (n.nodeType === Node.ELEMENT_NODE) {
746
755
  const i = n;
747
- i.tagName === "IMG" && !i.closest(".te-image-container") ? this.wrapImage(i) : i.querySelectorAll("img:not(.te-image)").forEach((s) => {
748
- s.closest(".te-image-container") || this.wrapImage(s);
756
+ i.tagName === "IMG" && !i.closest(".te-image-container") ? this.wrapImage(i) : i.querySelectorAll("img:not(.te-image)").forEach((o) => {
757
+ o.closest(".te-image-container") || this.wrapImage(o);
749
758
  });
750
759
  }
751
760
  });
@@ -765,11 +774,11 @@ class K {
765
774
  n.classList.add("te-image-container"), n.setAttribute("contenteditable", "false");
766
775
  const i = document.createElement("img");
767
776
  i.src = e.src, i.alt = e.alt || "", e.width && (i.style.width = `${e.width}px`), e.height && (i.style.height = `${e.height}px`), i.classList.add("te-image");
768
- const o = document.createElement("figcaption");
769
- if (o.classList.add("te-image-caption"), o.setAttribute("contenteditable", "true"), o.setAttribute("data-placeholder", "Type caption..."), ["top-left", "top-right", "bottom-left", "bottom-right"].forEach((a) => {
777
+ const s = document.createElement("figcaption");
778
+ if (s.classList.add("te-image-caption"), s.setAttribute("contenteditable", "true"), s.setAttribute("data-placeholder", "Type caption..."), ["top-left", "top-right", "bottom-left", "bottom-right"].forEach((a) => {
770
779
  const r = document.createElement("div");
771
780
  r.classList.add("te-image-resizer", `te-resizer-${a}`), n.appendChild(r);
772
- }), n.appendChild(i), n.appendChild(o), t.replaceChild(n, e), !n.nextElementSibling) {
781
+ }), n.appendChild(i), n.appendChild(s), t.replaceChild(n, e), !n.nextElementSibling) {
773
782
  const a = document.createElement("p");
774
783
  a.innerHTML = "<br>", n.after(a);
775
784
  }
@@ -781,14 +790,14 @@ class K {
781
790
  if (!t) return;
782
791
  e.preventDefault();
783
792
  const n = document.createElement("span");
784
- for (const [o, s] of Object.entries(this.pendingStyles))
785
- n.style.setProperty(o, s);
793
+ for (const [s, o] of Object.entries(this.pendingStyles))
794
+ n.style.setProperty(s, o);
786
795
  n.textContent = t;
787
796
  const i = this.selection.getRange();
788
797
  if (i) {
789
798
  i.deleteContents(), i.insertNode(n);
790
- const o = document.createRange();
791
- o.setStart(n.firstChild, t.length), o.setEnd(n.firstChild, t.length), this.selection.restoreSelection(o), this.pendingStyles = {}, this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
799
+ const s = document.createRange();
800
+ s.setStart(n.firstChild, t.length), s.setEnd(n.firstChild, t.length), this.selection.restoreSelection(s), this.pendingStyles = {}, this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
792
801
  }
793
802
  }
794
803
  }), this.addEventListener(this.editableElement, "input", () => {
@@ -904,7 +913,7 @@ class K {
904
913
  if (!n) return;
905
914
  const i = document.createElement("table");
906
915
  i.classList.add("te-table");
907
- for (let s = 0; s < e; s++) {
916
+ for (let o = 0; o < e; o++) {
908
917
  const a = document.createElement("tr");
909
918
  for (let r = 0; r < t; r++) {
910
919
  const l = document.createElement("td");
@@ -913,10 +922,10 @@ class K {
913
922
  i.appendChild(a);
914
923
  }
915
924
  n.deleteContents(), n.insertNode(i);
916
- const o = i.nextElementSibling;
917
- if (!o || o.tagName !== "P") {
918
- const s = document.createElement("p");
919
- s.innerHTML = "<br>", i.after(s), o && o.tagName === "BR" && o.remove();
925
+ const s = i.nextElementSibling;
926
+ if (!s || s.tagName !== "P") {
927
+ const o = document.createElement("p");
928
+ o.innerHTML = "<br>", i.after(o), s && s.tagName === "BR" && s.remove();
920
929
  }
921
930
  this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
922
931
  }
@@ -929,9 +938,9 @@ class K {
929
938
  const t = document.createElement("tr");
930
939
  t.style.borderBottom = "1px solid var(--te-border-color)";
931
940
  const n = e.rows[0].cells.length;
932
- for (let o = 0; o < n; o++) {
933
- const s = document.createElement("td");
934
- s.innerHTML = "<br>", t.appendChild(s);
941
+ for (let s = 0; s < n; s++) {
942
+ const o = document.createElement("td");
943
+ o.innerHTML = "<br>", t.appendChild(o);
935
944
  }
936
945
  const i = this.getSelectedTd();
937
946
  i ? i.parentElement?.after(t) : e.appendChild(t), this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
@@ -944,10 +953,10 @@ class K {
944
953
  if (e && e.parentElement) {
945
954
  const t = e.parentElement, n = t.parentElement;
946
955
  if (n.rows.length > 1) {
947
- const i = t.rowIndex, o = n.rows[i + 1] || n.rows[i - 1], s = e.cellIndex;
948
- if (t.remove(), o && o.cells[s]) {
956
+ const i = t.rowIndex, s = n.rows[i + 1] || n.rows[i - 1], o = e.cellIndex;
957
+ if (t.remove(), s && s.cells[o]) {
949
958
  const a = document.createRange();
950
- a.selectNodeContents(o.cells[s]), a.collapse(!0), this.selection.restoreSelection(a);
959
+ a.selectNodeContents(s.cells[o]), a.collapse(!0), this.selection.restoreSelection(a);
951
960
  }
952
961
  this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
953
962
  }
@@ -961,8 +970,8 @@ class K {
961
970
  if (!e) return;
962
971
  const t = this.getSelectedTd(), n = t ? t.cellIndex : -1;
963
972
  for (let i = 0; i < e.rows.length; i++) {
964
- const o = e.rows[i], s = document.createElement("td");
965
- s.innerHTML = "<br>", n !== -1 ? o.cells[n].after(s) : o.appendChild(s);
973
+ const s = e.rows[i], o = document.createElement("td");
974
+ o.innerHTML = "<br>", n !== -1 ? s.cells[n].after(o) : s.appendChild(o);
966
975
  }
967
976
  this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
968
977
  }
@@ -977,11 +986,11 @@ class K {
977
986
  const n = e.cellIndex;
978
987
  if (t.rows[0].cells.length > 1) {
979
988
  const i = e.nextElementSibling || e.previousElementSibling;
980
- for (let o = 0; o < t.rows.length; o++)
981
- t.rows[o].cells[n].remove();
989
+ for (let s = 0; s < t.rows.length; s++)
990
+ t.rows[s].cells[n].remove();
982
991
  if (i) {
983
- const o = document.createRange();
984
- o.selectNodeContents(i), o.collapse(!0), this.selection.restoreSelection(o);
992
+ const s = document.createRange();
993
+ s.selectNodeContents(i), s.collapse(!0), this.selection.restoreSelection(s);
985
994
  }
986
995
  this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
987
996
  }
@@ -1029,45 +1038,45 @@ class K {
1029
1038
  return this.pendingStyles[e] = t, n;
1030
1039
  if (["line-height"].includes(e))
1031
1040
  return this.setBlockStyle(e, t, n);
1032
- let o = n.commonAncestorContainer;
1033
- o.nodeType === Node.TEXT_NODE && (o = o.parentElement);
1034
- let s = null;
1035
- if (o.tagName === "SPAN" && o.children.length === 0 && o.textContent === n.toString())
1036
- o.style.setProperty(e, t), s = n.cloneRange();
1041
+ let s = n.commonAncestorContainer;
1042
+ s.nodeType === Node.TEXT_NODE && (s = s.parentElement);
1043
+ let o = null;
1044
+ if (s.tagName === "SPAN" && s.children.length === 0 && s.textContent === n.toString())
1045
+ s.style.setProperty(e, t), o = n.cloneRange();
1037
1046
  else {
1038
1047
  const a = document.createElement("span");
1039
1048
  a.style.setProperty(e, t);
1040
1049
  try {
1041
- const r = o.tagName === "SPAN" ? o : null, l = n.extractContents();
1050
+ const r = s.tagName === "SPAN" ? s : null, l = n.extractContents();
1042
1051
  this.clearStyleRecursive(l, e), a.appendChild(l), n.insertNode(a), r && r.innerHTML === "" && r.remove();
1043
1052
  const d = document.createRange();
1044
- d.selectNodeContents(a), s = d;
1053
+ d.selectNodeContents(a), o = d;
1045
1054
  const c = window.getSelection();
1046
1055
  c && c.rangeCount > 0 && (c.removeAllRanges(), c.addRange(d));
1047
1056
  } catch (r) {
1048
1057
  console.warn("Failed to apply style:", r);
1049
1058
  }
1050
1059
  }
1051
- return this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 })), s;
1060
+ return this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 })), o;
1052
1061
  }
1053
1062
  /**
1054
1063
  * Applies a style to the block-level containers within the range.
1055
1064
  */
1056
1065
  setBlockStyle(e, t, n) {
1057
- const i = ["P", "H1", "H2", "H3", "H4", "H5", "H6", "LI", "TD", "TH", "DIV", "BLOCKQUOTE"], o = /* @__PURE__ */ new Set();
1066
+ const i = ["P", "H1", "H2", "H3", "H4", "H5", "H6", "LI", "TD", "TH", "DIV", "BLOCKQUOTE"], s = /* @__PURE__ */ new Set();
1058
1067
  if (Array.from(this.editableElement.querySelectorAll(i.join(","))).forEach((a) => {
1059
- n.intersectsNode(a) && o.add(a);
1060
- }), o.size === 0) {
1068
+ n.intersectsNode(a) && s.add(a);
1069
+ }), s.size === 0) {
1061
1070
  let a = n.commonAncestorContainer;
1062
1071
  for (; a && a !== this.editableElement.parentElement; ) {
1063
1072
  if (a.nodeType === Node.ELEMENT_NODE && i.includes(a.tagName)) {
1064
- o.add(a);
1073
+ s.add(a);
1065
1074
  break;
1066
1075
  }
1067
1076
  a = a.parentNode;
1068
1077
  }
1069
1078
  }
1070
- return o.forEach((a) => {
1079
+ return s.forEach((a) => {
1071
1080
  a.style.setProperty(e, t);
1072
1081
  }), this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 })), n;
1073
1082
  }
@@ -1084,19 +1093,19 @@ class K {
1084
1093
  !/^https?:\/\//i.test(e) && !/^mailto:/i.test(e) && !e.startsWith("#") && (n ? e = "mailto:" + e : e = "https://" + e);
1085
1094
  const i = window.getSelection();
1086
1095
  if (i && i.rangeCount > 0) {
1087
- const o = i.getRangeAt(0);
1088
- if (o.collapsed) {
1089
- const s = document.createTextNode(e);
1090
- o.insertNode(s);
1096
+ const s = i.getRangeAt(0);
1097
+ if (s.collapsed) {
1098
+ const o = document.createTextNode(e);
1099
+ s.insertNode(o);
1091
1100
  const a = document.createRange();
1092
- a.selectNodeContents(s), i.removeAllRanges(), i.addRange(a);
1101
+ a.selectNodeContents(o), i.removeAllRanges(), i.addRange(a);
1093
1102
  }
1094
1103
  }
1095
1104
  if (document.execCommand("createLink", !1, e), i && i.rangeCount > 0) {
1096
- let s = i.getRangeAt(0).commonAncestorContainer;
1097
- s.nodeType === Node.TEXT_NODE && (s = s.parentElement);
1105
+ let o = i.getRangeAt(0).commonAncestorContainer;
1106
+ o.nodeType === Node.TEXT_NODE && (o = o.parentElement);
1098
1107
  let a = null;
1099
- s.tagName === "A" ? a = s : a = s.querySelector("a"), a && (a.setAttribute("target", "_blank"), a.setAttribute("rel", "noopener noreferrer"));
1108
+ o.tagName === "A" ? a = o : a = o.querySelector("a"), a && (a.setAttribute("target", "_blank"), a.setAttribute("rel", "noopener noreferrer"));
1100
1109
  }
1101
1110
  this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 }));
1102
1111
  }
@@ -1107,19 +1116,19 @@ class K {
1107
1116
  this.focus();
1108
1117
  const i = this.selection.getRange();
1109
1118
  if (!i) return null;
1110
- const o = document.createElement("figure");
1111
- o.classList.add("te-image-container"), o.setAttribute("contenteditable", "false"), n && o.classList.add("is-loading");
1112
- const s = document.createElement("img");
1113
- s.src = e, s.classList.add("te-image"), t && s.setAttribute("data-image-id", t);
1119
+ const s = document.createElement("figure");
1120
+ s.classList.add("te-image-container"), s.setAttribute("contenteditable", "false"), n && s.classList.add("is-loading");
1121
+ const o = document.createElement("img");
1122
+ o.src = e, o.classList.add("te-image"), t && o.setAttribute("data-image-id", t);
1114
1123
  const a = document.createElement("figcaption");
1115
1124
  a.classList.add("te-image-caption"), a.setAttribute("contenteditable", "true"), a.setAttribute("data-placeholder", "Type caption..."), ["top-left", "top-right", "bottom-left", "bottom-right"].forEach((c) => {
1116
1125
  const h = document.createElement("div");
1117
- h.classList.add("te-image-resizer", `te-resizer-${c}`), o.appendChild(h);
1118
- }), o.appendChild(s), o.appendChild(a), i.deleteContents(), i.insertNode(o);
1126
+ h.classList.add("te-image-resizer", `te-resizer-${c}`), s.appendChild(h);
1127
+ }), s.appendChild(o), s.appendChild(a), i.deleteContents(), i.insertNode(s);
1119
1128
  const l = document.createElement("p");
1120
- l.innerHTML = "<br>", o.after(l);
1129
+ l.innerHTML = "<br>", s.after(l);
1121
1130
  const d = document.createRange();
1122
- return d.setStart(l, 0), d.setEnd(l, 0), this.selection.restoreSelection(d), this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 })), this.save(), o;
1131
+ return d.setStart(l, 0), d.setEnd(l, 0), this.selection.restoreSelection(d), this.editableElement.dispatchEvent(new Event("input", { bubbles: !0 })), this.save(), s;
1123
1132
  }
1124
1133
  /**
1125
1134
  * Returns the clean and optimized HTML content of the editor.
@@ -1135,21 +1144,22 @@ class K {
1135
1144
  let n = null, i = null;
1136
1145
  if (t && this.editableElement.contains(t.commonAncestorContainer)) {
1137
1146
  n = document.createElement("span"), n.id = "te-selection-start", n.style.display = "none", i = document.createElement("span"), i.id = "te-selection-end", i.style.display = "none";
1138
- const s = t.cloneRange();
1139
- s.collapse(!0), s.insertNode(n);
1147
+ const o = t.cloneRange();
1148
+ o.collapse(!0), o.insertNode(n);
1140
1149
  const a = t.cloneRange();
1141
1150
  a.collapse(!1), a.insertNode(i);
1142
1151
  }
1143
- const o = this.normalizeHTML(this.editableElement.innerHTML);
1144
- if (o !== e || n) {
1145
- this.editableElement.innerHTML = o;
1146
- const s = this.editableElement.querySelector("#te-selection-start"), a = this.editableElement.querySelector("#te-selection-end");
1147
- if (s && a) {
1152
+ const s = this.normalizeHTML(this.editableElement.innerHTML);
1153
+ if (s !== e || n) {
1154
+ this.editableElement.innerHTML = s;
1155
+ const o = this.editableElement.querySelector("#te-selection-start"), a = this.editableElement.querySelector("#te-selection-end");
1156
+ if (o && a) {
1148
1157
  const r = document.createRange();
1149
- r.setStartAfter(s), r.setEndBefore(a), this.selection.restoreSelection(r);
1158
+ r.setStartAfter(o), r.setEndBefore(a), this.selection.restoreSelection(r);
1150
1159
  }
1151
1160
  this.editableElement.querySelectorAll("#te-selection-start, #te-selection-end").forEach((r) => r.remove());
1152
1161
  }
1162
+ this.checkPlaceholder();
1153
1163
  }
1154
1164
  normalizationContainer = null;
1155
1165
  /**
@@ -1241,12 +1251,12 @@ class K {
1241
1251
  a.replaceWith(r);
1242
1252
  } else a.innerHTML.trim() === "" && a.remove();
1243
1253
  });
1244
- const s = Array.from(t.querySelectorAll("p"));
1245
- s.forEach((a) => {
1254
+ const o = Array.from(t.querySelectorAll("p"));
1255
+ o.forEach((a) => {
1246
1256
  a.innerHTML.trim() === "" && t.childNodes.length > 1 && a !== t.lastElementChild && a.remove();
1247
1257
  });
1248
- for (let a = s.length - 1; a >= 0; a--) {
1249
- const r = s[a], l = r.innerHTML.trim() === "" || r.innerHTML.trim() === "<br>", d = r === t.lastElementChild;
1258
+ for (let a = o.length - 1; a >= 0; a--) {
1259
+ const r = o[a], l = r.innerHTML.trim() === "" || r.innerHTML.trim() === "<br>", d = r === t.lastElementChild;
1250
1260
  if (l && d && t.children.length > 1)
1251
1261
  r.remove();
1252
1262
  else
@@ -1259,23 +1269,23 @@ class K {
1259
1269
  e.preventDefault();
1260
1270
  let t = (e.clipboardData || window.clipboardData).getData("text/plain"), n = (e.clipboardData || window.clipboardData).getData("text/html");
1261
1271
  if (e.clipboardData && e.clipboardData.items) {
1262
- const o = [];
1263
- for (let s = 0; s < e.clipboardData.items.length; s++) {
1264
- const a = e.clipboardData.items[s];
1272
+ const s = [];
1273
+ for (let o = 0; o < e.clipboardData.items.length; o++) {
1274
+ const a = e.clipboardData.items[o];
1265
1275
  if (a.type.startsWith("image/")) {
1266
1276
  const r = a.getAsFile();
1267
- r && o.push(r);
1277
+ r && s.push(r);
1268
1278
  }
1269
1279
  }
1270
- if (o.length > 0) {
1271
- this.handleFiles(o);
1280
+ if (s.length > 0) {
1281
+ this.handleFiles(s);
1272
1282
  return;
1273
1283
  }
1274
1284
  }
1275
1285
  const i = /<([a-z1-6]+)\b[^>]*>[\s\S]*<\/\1>/i.test(t) || /^\s*<[a-z1-6]+\b[^>]*>/i.test(t);
1276
1286
  if (!n && t && i && (n = t.replace(/(\r\n|\n|\r)/gm, " ").replace(/>\s+</g, "><").trim()), n) {
1277
- const o = this.sanitize(n);
1278
- this.execute("insertHTML", o);
1287
+ const s = this.sanitize(n);
1288
+ this.execute("insertHTML", s);
1279
1289
  } else
1280
1290
  this.execute("insertText", t);
1281
1291
  }
@@ -1312,18 +1322,18 @@ class K {
1312
1322
  continue;
1313
1323
  }
1314
1324
  this.options.onSaving && this.options.onSaving();
1315
- const o = URL.createObjectURL(n);
1316
- i = this.insertImage(o, void 0, !0);
1317
- const s = await f.compressImage(n, t), a = URL.createObjectURL(s);
1325
+ const s = URL.createObjectURL(n);
1326
+ i = this.insertImage(s, void 0, !0);
1327
+ const o = await f.compressImage(n, t), a = URL.createObjectURL(o);
1318
1328
  if (i) {
1319
1329
  const l = i.querySelector("img");
1320
1330
  l && (l.src = a);
1321
1331
  }
1322
- if (s.size > t * 1024 * 1024) {
1332
+ if (o.size > t * 1024 * 1024) {
1323
1333
  alert(`Image "${n.name}" exceeds the ${t}MB limit even after compression.`), i?.remove();
1324
1334
  continue;
1325
1335
  }
1326
- const r = await f.uploadFile(s, this.options);
1336
+ const r = await f.uploadFile(o, this.options);
1327
1337
  if (r)
1328
1338
  if (i) {
1329
1339
  const l = i.querySelector("img");
@@ -1339,10 +1349,10 @@ class K {
1339
1349
  h && (h.src = c), i.classList.remove("is-loading");
1340
1350
  } else
1341
1351
  this.insertImage(c);
1342
- }, l.readAsDataURL(s);
1352
+ }, l.readAsDataURL(o);
1343
1353
  }
1344
- } catch (o) {
1345
- console.error("Image handling failed", o), i?.remove();
1354
+ } catch (s) {
1355
+ console.error("Image handling failed", s), i?.remove();
1346
1356
  } finally {
1347
1357
  this.options.onSave && this.save();
1348
1358
  }
@@ -1399,10 +1409,10 @@ class X {
1399
1409
  return;
1400
1410
  }
1401
1411
  this.searchInput.value.length > 0 ? this.renderGridItems(e) : ["Smileys", "Symbols", "Hands", "Animals", "Food", "Travel", "Objects", "Activities"].forEach((i) => {
1402
- const o = e.filter((s) => s.category === i);
1403
- if (o.length > 0) {
1404
- const s = document.createElement("div");
1405
- s.classList.add("te-emoji-category-title"), s.textContent = i, this.emojiGrid.appendChild(s), this.renderGridItems(o);
1412
+ const s = e.filter((o) => o.category === i);
1413
+ if (s.length > 0) {
1414
+ const o = document.createElement("div");
1415
+ o.classList.add("te-emoji-category-title"), o.textContent = i, this.emojiGrid.appendChild(o), this.renderGridItems(s);
1406
1416
  }
1407
1417
  });
1408
1418
  }
@@ -1435,16 +1445,16 @@ class X {
1435
1445
  shadowMd: "--te-shadow-md",
1436
1446
  shadowLg: "--te-shadow-lg"
1437
1447
  };
1438
- for (const [i, o] of Object.entries(n)) {
1439
- const s = t[i];
1440
- s && e.style.setProperty(o, s);
1448
+ for (const [i, s] of Object.entries(n)) {
1449
+ const o = t[i];
1450
+ o && e.style.setProperty(s, o);
1441
1451
  }
1442
1452
  }
1443
1453
  show(e) {
1444
1454
  document.body.appendChild(this.container);
1445
1455
  const t = e.getBoundingClientRect(), n = 280;
1446
- let i = t.bottom + window.scrollY + 5, o = t.left + window.scrollX;
1447
- o + n > window.innerWidth && (o = window.innerWidth - n - 10), this.container.style.top = `${i}px`, this.container.style.left = `${o}px`, this.searchInput.focus();
1456
+ let i = t.bottom + window.scrollY + 5, s = t.left + window.scrollX;
1457
+ s + n > window.innerWidth && (s = window.innerWidth - n - 10), this.container.style.top = `${i}px`, this.container.style.left = `${s}px`, this.searchInput.focus();
1448
1458
  }
1449
1459
  close() {
1450
1460
  this.container.parentElement && (this.container.remove(), this.onClose());
@@ -1462,6 +1472,7 @@ class Y {
1462
1472
  activeModal = null;
1463
1473
  statusEl = null;
1464
1474
  boundUpdateActiveStates;
1475
+ itemElements = /* @__PURE__ */ new Map();
1465
1476
  constructor(e) {
1466
1477
  this.editor = e, this.container = this.createToolbarElement(), this.boundUpdateActiveStates = this.updateActiveStates.bind(this), this.render();
1467
1478
  }
@@ -1471,39 +1482,39 @@ class Y {
1471
1482
  }
1472
1483
  render() {
1473
1484
  const e = this.editor.getOptions().toolbarItems, t = [];
1474
- this.items.forEach((o) => {
1475
- (o.type === "divider" || o.id && (!e || e.includes(o.id))) && t.push(o);
1485
+ this.items.forEach((s) => {
1486
+ (s.type === "divider" || s.id && (!e || e.includes(s.id))) && t.push(s);
1476
1487
  });
1477
1488
  const n = [];
1478
- t.forEach((o, s) => {
1479
- if (o.type === "divider") {
1480
- if (n.length === 0 || n[n.length - 1].type === "divider" || !t.slice(s + 1).some((r) => r.type !== "divider")) return;
1481
- n.push(o);
1489
+ t.forEach((s, o) => {
1490
+ if (s.type === "divider") {
1491
+ if (n.length === 0 || n[n.length - 1].type === "divider" || !t.slice(o + 1).some((r) => r.type !== "divider")) return;
1492
+ n.push(s);
1482
1493
  } else
1483
- n.push(o);
1484
- }), n.forEach((o) => {
1485
- if (o.type === "button")
1486
- this.renderButton(o);
1487
- else if (o.type === "select")
1488
- this.renderSelect(o);
1489
- else if (o.type === "input")
1490
- this.renderInput(o);
1491
- else if (o.type === "color-picker")
1492
- this.renderColorPicker(o);
1493
- else if (o.type === "divider") {
1494
- const s = document.createElement("div");
1495
- s.classList.add("te-divider"), this.container.appendChild(s);
1494
+ n.push(s);
1495
+ }), n.forEach((s) => {
1496
+ if (s.type === "button")
1497
+ this.renderButton(s);
1498
+ else if (s.type === "select")
1499
+ this.renderSelect(s);
1500
+ else if (s.type === "input")
1501
+ this.renderInput(s);
1502
+ else if (s.type === "color-picker")
1503
+ this.renderColorPicker(s);
1504
+ else if (s.type === "divider") {
1505
+ const o = document.createElement("div");
1506
+ o.classList.add("te-divider"), this.container.appendChild(o);
1496
1507
  }
1497
1508
  }), this.editor.getOptions().showStatus !== !1 && this.container.appendChild(this.statusEl), this.editor.el.addEventListener("keyup", this.boundUpdateActiveStates), this.editor.el.addEventListener("mouseup", this.boundUpdateActiveStates);
1498
1509
  }
1499
1510
  renderButton(e) {
1500
1511
  const t = document.createElement("button");
1501
- t.classList.add("te-button"), t.innerHTML = e.icon || "", t.title = e.title, t.addEventListener("mousedown", (n) => {
1512
+ t.classList.add("te-button"), t.innerHTML = e.icon || "", t.title = e.title, this.itemElements.set(e, t), t.addEventListener("mousedown", (n) => {
1502
1513
  if (n.preventDefault(), e.command === "createLink" || e.command === "insertTable") {
1503
1514
  const i = window.getSelection();
1504
1515
  if (i && i.rangeCount > 0) {
1505
- const o = i.getRangeAt(0);
1506
- this.editor.el.contains(o.commonAncestorContainer) && (this.savedRange = o.cloneRange());
1516
+ const s = i.getRangeAt(0);
1517
+ this.editor.el.contains(s.commonAncestorContainer) && (this.savedRange = s.cloneRange());
1507
1518
  }
1508
1519
  }
1509
1520
  if (e.command === "insertEmoji") {
@@ -1521,8 +1532,8 @@ class Y {
1521
1532
  }
1522
1533
  if (e.command === "insertImage") {
1523
1534
  const i = document.createElement("input");
1524
- i.type = "file", i.accept = "image/*", i.style.display = "none", i.addEventListener("change", (o) => {
1525
- const a = o.target.files;
1535
+ i.type = "file", i.accept = "image/*", i.style.display = "none", i.addEventListener("change", (s) => {
1536
+ const a = s.target.files;
1526
1537
  a && a.length > 0 && this.editor.handleFiles(Array.from(a)), document.body.removeChild(i);
1527
1538
  }), document.body.appendChild(i), i.click();
1528
1539
  return;
@@ -1546,8 +1557,8 @@ class Y {
1546
1557
  [{ id: "url", label: "URL", type: "text", placeholder: "https://example.com" }],
1547
1558
  (i) => {
1548
1559
  if (this.savedRange) {
1549
- const o = window.getSelection();
1550
- o && (o.removeAllRanges(), o.addRange(this.savedRange));
1560
+ const s = window.getSelection();
1561
+ s && (s.removeAllRanges(), s.addRange(this.savedRange));
1551
1562
  }
1552
1563
  this.editor.createLink(i.url), this.savedRange = null;
1553
1564
  },
@@ -1571,8 +1582,8 @@ class Y {
1571
1582
  const a = window.getSelection();
1572
1583
  a && (a.removeAllRanges(), a.addRange(this.savedRange));
1573
1584
  }
1574
- let o = parseInt(i.rows, 10), s = parseInt(i.cols, 10);
1575
- (isNaN(o) || o < 1) && (o = 1), (isNaN(s) || s < 1) && (s = 1), this.editor.insertTable(o, s), this.savedRange = null;
1585
+ let s = parseInt(i.rows, 10), o = parseInt(i.cols, 10);
1586
+ (isNaN(s) || s < 1) && (s = 1), (isNaN(o) || o < 1) && (o = 1), this.editor.insertTable(s, o), this.savedRange = null;
1576
1587
  },
1577
1588
  () => {
1578
1589
  this.activeModal = null, this.savedRange = null;
@@ -1589,26 +1600,26 @@ class Y {
1589
1600
  const t = document.createElement("input");
1590
1601
  t.type = "number", t.classList.add("te-input"), t.title = e.title, t.value = e.value || "", t.min = "1", t.max = "100";
1591
1602
  const n = () => {
1592
- const o = window.getSelection();
1593
- if (o && o.rangeCount > 0) {
1594
- const s = o.getRangeAt(0);
1595
- this.editor.el.contains(s.commonAncestorContainer) && (this.savedRange = s.cloneRange());
1603
+ const s = window.getSelection();
1604
+ if (s && s.rangeCount > 0) {
1605
+ const o = s.getRangeAt(0);
1606
+ this.editor.el.contains(o.commonAncestorContainer) && (this.savedRange = o.cloneRange());
1596
1607
  }
1597
1608
  };
1598
1609
  t.addEventListener("mousedown", n), t.addEventListener("focus", n);
1599
1610
  const i = () => {
1600
- let o = parseInt(t.value, 10);
1601
- if (!isNaN(o) && (o = Math.max(1, Math.min(100, o)), t.value = o.toString(), e.command === "fontSize")) {
1611
+ let s = parseInt(t.value, 10);
1612
+ if (!isNaN(s) && (s = Math.max(1, Math.min(100, s)), t.value = s.toString(), e.command === "fontSize")) {
1602
1613
  if (this.savedRange) {
1603
- const s = this.editor.setStyle("font-size", `${o}px`, this.savedRange);
1604
- s && (this.savedRange = s);
1614
+ const o = this.editor.setStyle("font-size", `${s}px`, this.savedRange);
1615
+ o && (this.savedRange = o);
1605
1616
  } else
1606
- this.editor.setStyle("font-size", `${o}px`);
1617
+ this.editor.setStyle("font-size", `${s}px`);
1607
1618
  t.focus();
1608
1619
  }
1609
1620
  };
1610
- t.addEventListener("input", i), t.addEventListener("keydown", (o) => {
1611
- o.key === "Enter" && (i(), this.editor.focus());
1621
+ t.addEventListener("input", i), t.addEventListener("keydown", (s) => {
1622
+ s.key === "Enter" && (i(), this.editor.focus());
1612
1623
  }), this.container.appendChild(t);
1613
1624
  }
1614
1625
  renderSelect(e) {
@@ -1628,8 +1639,8 @@ class Y {
1628
1639
  if (t.classList.add("te-color-picker-wrapper"), t.title = e.title, e.icon) {
1629
1640
  const i = document.createElement("div");
1630
1641
  i.classList.add("te-button", "te-color-icon"), i.innerHTML = e.icon;
1631
- const o = document.createElement("div");
1632
- o.classList.add("te-color-indicator"), o.style.backgroundColor = e.value || "#000000", i.appendChild(o), t.appendChild(i);
1642
+ const s = document.createElement("div");
1643
+ s.classList.add("te-color-indicator"), s.style.backgroundColor = e.value || "#000000", i.appendChild(s), this.itemElements.set(e, i), t.appendChild(i);
1633
1644
  }
1634
1645
  const n = document.createElement("input");
1635
1646
  n.type = "color", n.classList.add("te-color-picker-input"), e.icon || (n.classList.add("te-color-picker"), n.title = e.title), n.value = e.value || "#000000", n.addEventListener("mousedown", () => {
@@ -1654,14 +1665,9 @@ class Y {
1654
1665
  return this.container;
1655
1666
  }
1656
1667
  updateActiveStates() {
1657
- const e = this.container.querySelectorAll(".te-button");
1658
- let t = 0;
1659
- this.items.forEach((n) => {
1660
- if (n.type === "button") {
1661
- const i = e[t++];
1662
- if (!i) return;
1663
- n.command && document.queryCommandState(n.command) ? i.classList.add("active") : i.classList.remove("active");
1664
- }
1668
+ this.items.forEach((e) => {
1669
+ const t = this.itemElements.get(e);
1670
+ t && e.type === "button" && (e.command && document.queryCommandState(e.command) ? t.classList.add("active") : t.classList.remove("active"));
1665
1671
  });
1666
1672
  }
1667
1673
  updateStatus(e, t = !1) {
@@ -1686,7 +1692,7 @@ class Z extends K {
1686
1692
  this.toolbar?.updateStatus("Auto saving...", !0), t.onSaving && t.onSaving();
1687
1693
  },
1688
1694
  onSave: (i) => {
1689
- const o = (/* @__PURE__ */ new Date()).toLocaleString([], {
1695
+ const s = (/* @__PURE__ */ new Date()).toLocaleString([], {
1690
1696
  year: "numeric",
1691
1697
  month: "short",
1692
1698
  day: "numeric",
@@ -1694,7 +1700,7 @@ class Z extends K {
1694
1700
  minute: "2-digit",
1695
1701
  hour12: !0
1696
1702
  });
1697
- this.toolbar?.updateStatus(`Saved at ${o}`, !1), t.onSave && t.onSave(i);
1703
+ this.toolbar?.updateStatus(`Saved at ${s}`, !1), t.onSave && t.onSave(i);
1698
1704
  }
1699
1705
  };
1700
1706
  if (super(e, n), typeof document > "u" || !e) {
@@ -1 +1 @@
1
- .te-container,.te-emoji-picker,.te-modal,.te-floating-toolbar{--te-primary-color: #6366f1;--te-primary-hover: #4f46e5;--te-bg-app: #f8fafc;--te-bg-editor: #ffffff;--te-toolbar-bg: #ffffff;--te-border-color: #e2e8f0;--te-border-focus: #cbd5e1;--te-text-main: #1e293b;--te-text-muted: #64748b;--te-placeholder: #94a3b8;--te-btn-hover: #f1f5f9;--te-btn-active: #e2e8f0;--te-radius-lg: 12px;--te-radius-md: 8px;--te-radius-sm: 6px;--te-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .05);--te-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--te-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--te-transition: all .2s cubic-bezier(.4, 0, .2, 1)}.te-container.te-dark,.te-emoji-picker.te-dark,.te-modal.te-dark,.te-floating-toolbar.te-dark{--te-primary-color: #818cf8 !important;--te-primary-hover: #6366f1 !important;--te-bg-app: #0f172a !important;--te-bg-editor: #1e293b !important;--te-toolbar-bg: #1e293b !important;--te-border-color: #334155 !important;--te-border-focus: #475569 !important;--te-text-main: #f8fafc !important;--te-text-muted: #94a3b8 !important;--te-placeholder: #64748b !important;--te-btn-hover: #334155 !important;--te-btn-active: #475569 !important;--te-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .3) !important;--te-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .5), 0 2px 4px -2px rgb(0 0 0 / .5) !important;--te-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .5), 0 4px 6px -4px rgb(0 0 0 / .5) !important}.te-container,.te-container *,.te-emoji-picker,.te-emoji-picker *,.te-modal,.te-modal *,.te-floating-toolbar,.te-floating-toolbar *{box-sizing:border-box}.te-container{display:flex;flex-direction:column;height:500px;border:1px solid var(--te-border-color);border-radius:var(--te-radius-lg);background:var(--te-bg-editor);box-shadow:var(--te-shadow-sm);overflow:hidden;font-family:Inter,-apple-system,system-ui,sans-serif;color:var(--te-text-main)!important;transition:var(--te-transition);max-width:100%;position:relative}.te-container:focus-within{border-color:var(--te-primary-color);box-shadow:0 0 0 4px #6366f11a,var(--te-shadow-md)}.te-toolbar{display:flex;flex-wrap:wrap;gap:6px;padding:10px 12px;border-bottom:1px solid var(--te-border-color);background:var(--te-toolbar-bg);align-items:center;-webkit-user-select:none;user-select:none;position:sticky;top:0;z-index:10}.te-divider{width:1px;height:20px;background-color:var(--te-border-color);margin:0 6px}.te-button,.te-select,.te-input{display:flex;align-items:center;justify-content:center;height:32px;border:1px solid transparent;background:transparent;border-radius:var(--te-radius-sm);cursor:pointer;color:var(--te-text-muted);font-size:13px;font-weight:500;transition:var(--te-transition);box-sizing:border-box}.te-button{width:32px;padding:0}.te-button svg{width:16px;height:16px;stroke:currentColor;stroke-width:2.2;fill:none}.te-select{padding:0 24px 0 8px;min-width:120px;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2364748b'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2.5' d='M19 9l-7 7-7-7'%3E%3C/path%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 6px center;background-size:12px;border:1px solid var(--te-border-color);background-color:var(--te-bg-editor)!important;color:var(--te-text-main)!important}.te-input{width:56px;padding:0 4px;text-align:center;cursor:text;border:1px solid var(--te-border-color);background-color:var(--te-bg-editor)!important;color:var(--te-text-main)!important}.te-color-picker{width:32px;height:32px;padding:4px;border:1px solid var(--te-border-color);border-radius:var(--te-radius-sm);background:var(--te-bg-editor);cursor:pointer;box-sizing:border-box}.te-color-picker:hover{border-color:var(--te-border-focus)}.te-color-picker-wrapper{position:relative;display:inline-flex;width:32px;height:32px;border-radius:var(--te-radius-sm);transition:var(--te-transition)}.te-color-picker-wrapper:hover{background:var(--te-btn-hover)}.te-color-picker-input{position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer;z-index:2}.te-color-icon{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;z-index:1}.te-color-indicator{position:absolute;bottom:4px;left:6px;right:6px;height:3px;border-radius:2px;box-shadow:0 1px 1px var(--te-shadow-sm)}.te-emoji-picker{position:absolute;width:280px;height:320px;background:var(--te-bg-editor);border:1px solid var(--te-border-color);border-radius:var(--te-radius-md);box-shadow:var(--te-shadow-lg);display:flex;flex-direction:column;z-index:1000;animation:te-fade-in .2s ease-out}@keyframes te-fade-in{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.te-emoji-header{padding:12px;border-bottom:1px solid var(--te-border-color)}.te-emoji-search{width:100%;padding:8px 12px;border:1px solid var(--te-border-color);border-radius:var(--te-radius-sm);background-color:var(--te-bg-editor)!important;color:var(--te-text-main)!important;font-size:13px;outline:none;transition:var(--te-transition)}.te-emoji-search:focus{border-color:var(--te-primary-color);box-shadow:0 0 0 2px #6366f11a}.te-emoji-body{flex:1;overflow-y:auto;overflow-x:hidden;padding:8px}.te-emoji-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}.te-emoji-category-title{grid-column:span 7;padding:8px 4px 4px;font-size:11px;font-weight:600;color:var(--te-text-muted);text-transform:uppercase;letter-spacing:.05em}.te-emoji-item{width:32px;height:32px;display:flex;align-items:center;justify-content:center;font-size:20px;border:none;background:transparent;cursor:pointer;border-radius:var(--te-radius-sm);transition:var(--te-transition)}.te-emoji-item:hover{background:var(--te-btn-hover);transform:scale(1.1)}.te-emoji-empty{grid-column:span 7;text-align:center;padding:20px;color:var(--te-text-muted);font-size:13px}.te-button:hover{background:var(--te-btn-hover);color:var(--te-text-main)!important}.te-select:hover,.te-input:hover{border-color:var(--te-border-focus)}.te-button.active{background:var(--te-btn-active);color:var(--te-primary-color);border-color:#6366f133}.te-select:focus,.te-input:focus{border-color:var(--te-primary-color);box-shadow:0 0 0 2px #6366f11a;outline:none;background:var(--te-bg-editor);color:var(--te-text-main)!important}.te-content{flex:1;overflow-y:auto;min-height:240px;padding:24px;line-height:1.25;outline:none;font-size:16px;position:relative}.te-content p{margin:0 0 1.25em}.te-content h1,.te-content h2,.te-content h3,.te-content h4,.te-content h5,.te-content h6{color:var(--te-text-main)!important;font-weight:700;margin:1rem 0 .5rem;line-height:1.1}.te-content h1:first-child,.te-content p:first-child{margin-top:0}.te-content h1{font-size:2.25em}.te-content h2{font-size:1.875em}.te-content h3{font-size:1.5em}.te-content h4{font-size:1.25em}.te-content[data-placeholder].is-empty:before{content:attr(data-placeholder);color:var(--te-placeholder);pointer-events:none;position:absolute}.te-image-container{position:relative;display:inline-block;margin:1.5rem 0;max-width:100%;border-radius:var(--te-radius-lg);overflow:visible;transition:box-shadow var(--te-transition-fast);line-height:0}.te-image-container:hover{box-shadow:0 0 0 2px var(--te-primary-color)}.te-image-container.active{box-shadow:0 0 0 2px var(--te-primary-color),var(--te-shadow-lg)}.te-image{display:block;max-width:100%;height:auto;-webkit-user-select:none;user-select:none}.te-image-caption{font-size:.875rem;color:var(--te-text-muted);text-align:center;padding:.75rem;background:var(--te-bg-app);line-height:normal;border-bottom-left-radius:var(--te-radius-lg);border-bottom-right-radius:var(--te-radius-lg)}.te-image-caption:empty:before{content:attr(data-placeholder);color:var(--te-placeholder)}.te-image-resizer{position:absolute;width:10px;height:10px;background:var(--te-primary-color);border:1px solid var(--te-bg-editor);z-index:10;display:none}.te-image-container:hover .te-image-resizer,.te-image-container.active .te-image-resizer{display:block}.te-resizer-top-left{top:-5px;left:-5px;cursor:nwse-resize}.te-resizer-top-right{top:-5px;right:-5px;cursor:nesw-resize}.te-resizer-bottom-left{bottom:-5px;left:-5px;cursor:nesw-resize}.te-resizer-bottom-right{bottom:-5px;right:-5px;cursor:nwse-resize}.te-content.dragover{background:var(--te-btn-hover);outline:2px dashed var(--te-primary-color);outline-offset:-4px}.te-image-container.is-loading{position:relative;overflow:hidden;background:#f1f5f9;min-width:200px;min-height:150px}.te-image-container.is-loading .te-image{opacity:.3;filter:blur(4px);transition:opacity .5s ease,filter .5s ease}.te-image-container.is-loading:after{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(90deg,#fff0 0,#fff6,#fff0);animation:te-skeleton-pulse 1.5s infinite}@keyframes te-skeleton-pulse{0%{transform:translate(-100%)}to{transform:translate(100%)}}.te-dark .te-image-container.is-loading{background:#334155}.te-table{width:100%;border-collapse:collapse;margin:1.5rem 0;border:1px solid var(--te-border-color);border-radius:var(--te-radius-md);table-layout:fixed}.te-table td,.te-table th{border:1px solid var(--te-border-color);padding:12px;min-height:44px;vertical-align:top;position:relative;transition:background-color .2s ease;color:var(--te-text-main)}.te-table tr{border-bottom:1px solid var(--te-border-color)}.te-table tr:last-child{border-bottom:none}.te-table td:hover{background-color:var(--te-btn-hover)}.te-table td:focus-within{background-color:var(--te-btn-active);outline:none}.te-dark .te-table,.te-dark .te-table td,.te-dark .te-table th{border-color:#334155}.te-dark .te-table td:hover{background-color:#1e293b}.te-toolbar-loader{width:12px;height:12px;border:1.5px solid var(--te-primary-color);border-bottom-color:transparent;border-radius:50%;display:inline-block;animation:te-spin 1s linear infinite}@keyframes te-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.te-toolbar-status{display:flex;align-items:center;gap:8px;transition:opacity .3s ease}.te-modal{position:absolute;width:280px;background:#fffc;backdrop-filter:blur(12px) saturate(180%);-webkit-backdrop-filter:blur(12px) saturate(180%);border:1px solid rgba(226,232,240,.7);border-radius:var(--te-radius-lg);box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a,0 0 0 1px #0000000d;display:flex;flex-direction:column;z-index:1000;animation:te-fade-in .25s cubic-bezier(.4,0,.2,1);padding:20px}.te-dark .te-modal{background:#1e293bcc;border-color:#334155b3;box-shadow:0 20px 25px -5px #0000004d,0 8px 10px -6px #0000004d,0 0 0 1px #ffffff0d}.te-modal-header{font-size:16px;font-weight:700;color:var(--te-text-main);margin-bottom:20px;letter-spacing:-.01em}.te-modal-field{margin-bottom:16px}.te-modal-field label{display:block;font-size:11px;font-weight:700;color:var(--te-text-muted);text-transform:uppercase;margin-bottom:6px;letter-spacing:.05em}.te-modal-input{width:100%;padding:10px 12px;border:1px solid var(--te-border-color);border-radius:var(--te-radius-md);background:var(--te-bg-editor);color:var(--te-text-main);font-size:14px;outline:none;transition:var(--te-transition)}.te-modal-input:focus{border-color:var(--te-primary-color);box-shadow:0 0 0 3px #6366f126;background:var(--te-bg-editor)}.te-modal-footer{display:flex;justify-content:flex-end;gap:12px;margin-top:8px}.te-modal-btn{padding:8px 16px;font-size:13px;font-weight:600;border-radius:var(--te-radius-md);cursor:pointer;transition:var(--te-transition);border:1px solid transparent;display:inline-flex;align-items:center;justify-content:center}.te-modal-btn-cancel{background:transparent;color:var(--te-text-muted);border:1px solid var(--te-border-color)}.te-modal-btn-cancel:hover{background:var(--te-btn-hover);color:var(--te-text-main);border-color:var(--te-border-focus)}.te-modal-btn-confirm{background:var(--te-primary-color);color:#fff;box-shadow:0 4px 6px -1px #6366f133}.te-modal-btn-confirm:hover{background:var(--te-primary-hover);transform:translateY(-1px);box-shadow:0 6px 8px -1px #6366f14d}.te-modal-btn-confirm:active{transform:translateY(0)}.te-floating-toolbar{background:var(--te-bg-editor);border:1px solid var(--te-border-color);border-radius:var(--te-radius-md);padding:4px;box-shadow:var(--te-shadow-lg);display:flex;gap:2px;pointer-events:auto;opacity:0;transform:translateY(10px);transition:opacity .2s ease,transform .2s ease,background .3s ease}.te-floating-toolbar.te-floating-visible{opacity:1;transform:translateY(0)}.te-floating-btn{background:transparent;border:none;cursor:pointer;padding:6px;border-radius:var(--te-radius-sm);color:var(--te-text-muted);display:flex;align-items:center;justify-content:center;transition:all .2s ease}.te-floating-btn:hover{background:var(--te-btn-hover);color:var(--te-text-main)}.te-floating-btn svg{width:18px;height:18px;stroke:currentColor}.te-loader-overlay{position:absolute;inset:0;background:#f1f5f9e6;backdrop-filter:blur(12px) saturate(200%);-webkit-backdrop-filter:blur(12px) saturate(200%);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:1000;transition:opacity .4s cubic-bezier(.4,0,.2,1),visibility .4s;border-radius:var(--te-radius-lg)}.te-dark .te-loader-overlay{background:#0f172ae6}.te-loader-overlay.hidden{opacity:0;visibility:hidden;pointer-events:none}.te-loader-spinner{width:48px;height:48px;border:4px solid var(--te-border-color);border-top-color:var(--te-primary-color);border-radius:50%;animation:te-spin 1s cubic-bezier(.4,0,.2,1) infinite;margin-bottom:24px;filter:drop-shadow(0 0 10px rgba(99,102,241,.2))}.te-loader-shimmer{width:140px;height:4px;background:var(--te-border-color);border-radius:2px;overflow:hidden;position:relative}.te-loader-shimmer:after{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(90deg,#6366f100 0,#6366f166,#6366f100);animation:te-skeleton-pulse 1.5s infinite}.te-loader-text{font-size:13px;font-weight:600;color:var(--te-text-muted);letter-spacing:.02em;margin-top:12px}
1
+ .te-container,.te-emoji-picker,.te-modal,.te-floating-toolbar{--te-primary-color: #6366f1;--te-primary-hover: #4f46e5;--te-bg-app: #f8fafc;--te-bg-editor: #ffffff;--te-toolbar-bg: #ffffff;--te-border-color: #e2e8f0;--te-border-focus: #cbd5e1;--te-text-main: #1e293b;--te-text-muted: #64748b;--te-placeholder: #94a3b8;--te-btn-hover: #f1f5f9;--te-btn-active: #e2e8f0;--te-radius-lg: 12px;--te-radius-md: 8px;--te-radius-sm: 6px;--te-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .05);--te-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--te-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--te-transition: all .2s cubic-bezier(.4, 0, .2, 1)}.te-container.te-dark,.te-emoji-picker.te-dark,.te-modal.te-dark,.te-floating-toolbar.te-dark{--te-primary-color: #818cf8 !important;--te-primary-hover: #6366f1 !important;--te-bg-app: #0f172a !important;--te-bg-editor: #1e293b !important;--te-toolbar-bg: #1e293b !important;--te-border-color: #334155 !important;--te-border-focus: #475569 !important;--te-text-main: #f8fafc !important;--te-text-muted: #94a3b8 !important;--te-placeholder: #64748b !important;--te-btn-hover: #334155 !important;--te-btn-active: #475569 !important;--te-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .3) !important;--te-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .5), 0 2px 4px -2px rgb(0 0 0 / .5) !important;--te-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .5), 0 4px 6px -4px rgb(0 0 0 / .5) !important}.te-container,.te-container *,.te-emoji-picker,.te-emoji-picker *,.te-modal,.te-modal *,.te-floating-toolbar,.te-floating-toolbar *{box-sizing:border-box}.te-container{display:flex;flex-direction:column;height:500px;border:1px solid var(--te-border-color);border-radius:var(--te-radius-lg);background:var(--te-bg-editor);box-shadow:var(--te-shadow-sm);overflow:hidden;font-family:Inter,-apple-system,system-ui,sans-serif;color:var(--te-text-main)!important;transition:var(--te-transition);max-width:100%;position:relative}.te-container:focus-within{border-color:var(--te-primary-color);box-shadow:0 0 0 4px #6366f11a,var(--te-shadow-md)}.te-toolbar{display:flex;flex-wrap:wrap;gap:6px;padding:10px 12px;border-bottom:1px solid var(--te-border-color);background:var(--te-toolbar-bg);align-items:center;-webkit-user-select:none;user-select:none;position:sticky;top:0;z-index:10}.te-divider{width:1px;height:20px;background-color:var(--te-border-color);margin:0 6px}.te-button,.te-select,.te-input{display:flex;align-items:center;justify-content:center;height:32px;border:1px solid transparent;background:transparent;border-radius:var(--te-radius-sm);cursor:pointer;color:var(--te-text-muted);font-size:13px;font-weight:500;transition:var(--te-transition);box-sizing:border-box}.te-button{width:32px;padding:0}.te-button svg{width:16px;height:16px;stroke:currentColor;stroke-width:2.2;fill:none}.te-select{padding:0 24px 0 8px;min-width:120px;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2364748b'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2.5' d='M19 9l-7 7-7-7'%3E%3C/path%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 6px center;background-size:12px;border:1px solid var(--te-border-color);background-color:var(--te-bg-editor)!important;color:var(--te-text-main)!important}.te-input{width:56px;padding:0 4px;text-align:center;cursor:text;border:1px solid var(--te-border-color);background-color:var(--te-bg-editor)!important;color:var(--te-text-main)!important}.te-color-picker{width:32px;height:32px;padding:4px;border:1px solid var(--te-border-color);border-radius:var(--te-radius-sm);background:var(--te-bg-editor);cursor:pointer;box-sizing:border-box}.te-color-picker:hover{border-color:var(--te-border-focus)}.te-color-picker-wrapper{position:relative;display:inline-flex;width:32px;height:32px;border-radius:var(--te-radius-sm);transition:var(--te-transition)}.te-color-picker-wrapper:hover{background:var(--te-btn-hover)}.te-color-picker-input{position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer;z-index:2}.te-color-icon{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;z-index:1}.te-color-indicator{position:absolute;bottom:4px;left:6px;right:6px;height:3px;border-radius:2px;box-shadow:0 1px 1px var(--te-shadow-sm)}.te-emoji-picker{position:absolute;width:280px;height:320px;background:var(--te-bg-editor);border:1px solid var(--te-border-color);border-radius:var(--te-radius-md);box-shadow:var(--te-shadow-lg);display:flex;flex-direction:column;z-index:1000;animation:te-fade-in .2s ease-out}@keyframes te-fade-in{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.te-emoji-header{padding:12px;border-bottom:1px solid var(--te-border-color)}.te-emoji-search{width:100%;padding:8px 12px;border:1px solid var(--te-border-color);border-radius:var(--te-radius-sm);background-color:var(--te-bg-editor)!important;color:var(--te-text-main)!important;font-size:13px;outline:none;transition:var(--te-transition)}.te-emoji-search:focus{border-color:var(--te-primary-color);box-shadow:0 0 0 2px #6366f11a}.te-emoji-body{flex:1;overflow-y:auto;overflow-x:hidden;padding:8px}.te-emoji-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}.te-emoji-category-title{grid-column:span 7;padding:8px 4px 4px;font-size:11px;font-weight:600;color:var(--te-text-muted);text-transform:uppercase;letter-spacing:.05em}.te-emoji-item{width:32px;height:32px;display:flex;align-items:center;justify-content:center;font-size:20px;border:none;background:transparent;cursor:pointer;border-radius:var(--te-radius-sm);transition:var(--te-transition)}.te-emoji-item:hover{background:var(--te-btn-hover);transform:scale(1.1)}.te-emoji-empty{grid-column:span 7;text-align:center;padding:20px;color:var(--te-text-muted);font-size:13px}.te-button:hover{background:var(--te-btn-hover);color:var(--te-text-main)!important}.te-select:hover,.te-input:hover{border-color:var(--te-border-focus)}.te-button.active{background:var(--te-btn-active);color:var(--te-primary-color);border-color:#6366f133}.te-select:focus,.te-input:focus{border-color:var(--te-primary-color);box-shadow:0 0 0 2px #6366f11a;outline:none;background:var(--te-bg-editor);color:var(--te-text-main)!important}.te-content{flex:1;overflow-y:auto;min-height:240px;padding:24px;line-height:1.25;outline:none;font-size:16px;position:relative}.te-content p{margin:0 0 1.25em}.te-content h1,.te-content h2,.te-content h3,.te-content h4,.te-content h5,.te-content h6{color:var(--te-text-main)!important;font-weight:700;margin:1rem 0 .5rem;line-height:1.1}.te-content h1:first-child,.te-content p:first-child{margin-top:0}.te-content h1{font-size:2.25em}.te-content h2{font-size:1.875em}.te-content h3{font-size:1.5em}.te-content h4{font-size:1.25em}.te-content[data-placeholder].is-empty:before{content:attr(data-placeholder);color:var(--te-placeholder);pointer-events:none;position:absolute;left:24px;right:24px;text-align:inherit;white-space:pre-wrap;overflow:hidden}.te-image-container{position:relative;display:inline-block;margin:1.5rem 0;max-width:100%;border-radius:var(--te-radius-lg);overflow:visible;transition:box-shadow var(--te-transition-fast);line-height:0}.te-image-container:hover{box-shadow:0 0 0 2px var(--te-primary-color)}.te-image-container.active{box-shadow:0 0 0 2px var(--te-primary-color),var(--te-shadow-lg)}.te-image{display:block;max-width:100%;height:auto;-webkit-user-select:none;user-select:none}.te-image-caption{font-size:.875rem;color:var(--te-text-muted);text-align:center;padding:.75rem;background:var(--te-bg-app);line-height:normal;border-bottom-left-radius:var(--te-radius-lg);border-bottom-right-radius:var(--te-radius-lg)}.te-image-caption:empty:before{content:attr(data-placeholder);color:var(--te-placeholder)}.te-image-resizer{position:absolute;width:10px;height:10px;background:var(--te-primary-color);border:1px solid var(--te-bg-editor);z-index:10;display:none}.te-image-container:hover .te-image-resizer,.te-image-container.active .te-image-resizer{display:block}.te-resizer-top-left{top:-5px;left:-5px;cursor:nwse-resize}.te-resizer-top-right{top:-5px;right:-5px;cursor:nesw-resize}.te-resizer-bottom-left{bottom:-5px;left:-5px;cursor:nesw-resize}.te-resizer-bottom-right{bottom:-5px;right:-5px;cursor:nwse-resize}.te-content.dragover{background:var(--te-btn-hover);outline:2px dashed var(--te-primary-color);outline-offset:-4px}.te-image-container.is-loading{position:relative;overflow:hidden;background:#f1f5f9;min-width:200px;min-height:150px}.te-image-container.is-loading .te-image{opacity:.3;filter:blur(4px);transition:opacity .5s ease,filter .5s ease}.te-image-container.is-loading:after{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(90deg,#fff0 0,#fff6,#fff0);animation:te-skeleton-pulse 1.5s infinite}@keyframes te-skeleton-pulse{0%{transform:translate(-100%)}to{transform:translate(100%)}}.te-dark .te-image-container.is-loading{background:#334155}.te-table{width:100%;border-collapse:collapse;margin:1.5rem 0;border:1px solid var(--te-border-color);border-radius:var(--te-radius-md);table-layout:fixed}.te-table td,.te-table th{border:1px solid var(--te-border-color);padding:12px;min-height:44px;vertical-align:top;position:relative;transition:background-color .2s ease;color:var(--te-text-main)}.te-table tr{border-bottom:1px solid var(--te-border-color)}.te-table tr:last-child{border-bottom:none}.te-table td:hover{background-color:var(--te-btn-hover)}.te-table td:focus-within{background-color:var(--te-btn-active);outline:none}.te-dark .te-table,.te-dark .te-table td,.te-dark .te-table th{border-color:#334155}.te-dark .te-table td:hover{background-color:#1e293b}.te-toolbar-loader{width:12px;height:12px;border:1.5px solid var(--te-primary-color);border-bottom-color:transparent;border-radius:50%;display:inline-block;animation:te-spin 1s linear infinite}@keyframes te-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.te-toolbar-status{display:flex;align-items:center;gap:8px;transition:opacity .3s ease}.te-modal{position:absolute;width:280px;background:#fffc;backdrop-filter:blur(12px) saturate(180%);-webkit-backdrop-filter:blur(12px) saturate(180%);border:1px solid rgba(226,232,240,.7);border-radius:var(--te-radius-lg);box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a,0 0 0 1px #0000000d;display:flex;flex-direction:column;z-index:1000;animation:te-fade-in .25s cubic-bezier(.4,0,.2,1);padding:20px}.te-dark .te-modal{background:#1e293bcc;border-color:#334155b3;box-shadow:0 20px 25px -5px #0000004d,0 8px 10px -6px #0000004d,0 0 0 1px #ffffff0d}.te-modal-header{font-size:16px;font-weight:700;color:var(--te-text-main);margin-bottom:20px;letter-spacing:-.01em}.te-modal-field{margin-bottom:16px}.te-modal-field label{display:block;font-size:11px;font-weight:700;color:var(--te-text-muted);text-transform:uppercase;margin-bottom:6px;letter-spacing:.05em}.te-modal-input{width:100%;padding:10px 12px;border:1px solid var(--te-border-color);border-radius:var(--te-radius-md);background:var(--te-bg-editor);color:var(--te-text-main);font-size:14px;outline:none;transition:var(--te-transition)}.te-modal-input:focus{border-color:var(--te-primary-color);box-shadow:0 0 0 3px #6366f126;background:var(--te-bg-editor)}.te-modal-footer{display:flex;justify-content:flex-end;gap:12px;margin-top:8px}.te-modal-btn{padding:8px 16px;font-size:13px;font-weight:600;border-radius:var(--te-radius-md);cursor:pointer;transition:var(--te-transition);border:1px solid transparent;display:inline-flex;align-items:center;justify-content:center}.te-modal-btn-cancel{background:transparent;color:var(--te-text-muted);border:1px solid var(--te-border-color)}.te-modal-btn-cancel:hover{background:var(--te-btn-hover);color:var(--te-text-main);border-color:var(--te-border-focus)}.te-modal-btn-confirm{background:var(--te-primary-color);color:#fff;box-shadow:0 4px 6px -1px #6366f133}.te-modal-btn-confirm:hover{background:var(--te-primary-hover);transform:translateY(-1px);box-shadow:0 6px 8px -1px #6366f14d}.te-modal-btn-confirm:active{transform:translateY(0)}.te-floating-toolbar{background:var(--te-bg-editor);border:1px solid var(--te-border-color);border-radius:var(--te-radius-md);padding:4px;box-shadow:var(--te-shadow-lg);display:flex;gap:2px;pointer-events:auto;opacity:0;transform:translateY(10px);transition:opacity .2s ease,transform .2s ease,background .3s ease}.te-floating-toolbar.te-floating-visible{opacity:1;transform:translateY(0)}.te-floating-btn{background:transparent;border:none;cursor:pointer;padding:6px;border-radius:var(--te-radius-sm);color:var(--te-text-muted);display:flex;align-items:center;justify-content:center;transition:all .2s ease}.te-floating-btn:hover{background:var(--te-btn-hover);color:var(--te-text-main)}.te-floating-btn svg{width:18px;height:18px;stroke:currentColor}.te-loader-overlay{position:absolute;inset:0;background:#f1f5f9e6;backdrop-filter:blur(12px) saturate(200%);-webkit-backdrop-filter:blur(12px) saturate(200%);display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:1000;transition:opacity .4s cubic-bezier(.4,0,.2,1),visibility .4s;border-radius:var(--te-radius-lg)}.te-dark .te-loader-overlay{background:#0f172ae6}.te-loader-overlay.hidden{opacity:0;visibility:hidden;pointer-events:none}.te-loader-spinner{width:48px;height:48px;border:4px solid var(--te-border-color);border-top-color:var(--te-primary-color);border-radius:50%;animation:te-spin 1s cubic-bezier(.4,0,.2,1) infinite;margin-bottom:24px;filter:drop-shadow(0 0 10px rgba(99,102,241,.2))}.te-loader-shimmer{width:140px;height:4px;background:var(--te-border-color);border-radius:2px;overflow:hidden;position:relative}.te-loader-shimmer:after{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(90deg,#6366f100 0,#6366f166,#6366f100);animation:te-skeleton-pulse 1.5s infinite}.te-loader-text{font-size:13px;font-weight:600;color:var(--te-text-muted);letter-spacing:.02em;margin-top:12px}
@@ -8,6 +8,7 @@ export declare class Toolbar {
8
8
  private activeModal;
9
9
  private statusEl;
10
10
  private boundUpdateActiveStates;
11
+ private itemElements;
11
12
  constructor(editor: CoreEditor);
12
13
  private createToolbarElement;
13
14
  private render;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meenainwal/rich-text-editor",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "A premium, lightweight, and framework-agnostic WYSIWYG rich text editor with a sophisticated Slate & Indigo design. Highly customizable and optimized for React, Next.js, and Vanilla TypeScript.",
5
5
  "type": "module",
6
6
  "files": [