ct-rich-text-editor 1.3.0 → 1.3.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.
@@ -21,17 +21,17 @@ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
21
21
  import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
22
22
  import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
23
23
  import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
24
- import { $findMatchingParent, $getNearestNodeOfType, mergeRegister, $getNearestBlockElementAncestorOrThrow, $insertNodeToNearestRoot, $wrapNodeInElement, $isEditorIsNestedEditor, calculateZoomLevel, CAN_USE_DOM } from "@lexical/utils";
24
+ import { $findMatchingParent, $getNearestNodeOfType, mergeRegister, $getNearestBlockElementAncestorOrThrow, $insertNodeToNearestRoot, $wrapNodeInElement, $isEditorIsNestedEditor, mediaFileReader, isMimeType, calculateZoomLevel, CAN_USE_DOM } from "@lexical/utils";
25
25
  import Stack from "@mui/material/Stack";
26
- import { createCommand, COMMAND_PRIORITY_LOW, $getSelection, $isRangeSelection, $insertNodes, $getNearestNodeFromDOMNode, $setSelection, isHTMLElement as isHTMLElement$1, TextNode, $applyNodeReplacement, $getRoot, $createTextNode, $getNodeByKey, DecoratorNode, createEditor, COMMAND_PRIORITY_EDITOR, $createParagraphNode, $isRootOrShadowRoot, $isParagraphNode, $isTextNode, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, UNDO_COMMAND, REDO_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $createNodeSelection, $isNodeSelection, CLICK_COMMAND, getDOMSelection, COMMAND_PRIORITY_HIGH, $isLineBreakNode, isDOMNode } from "lexical";
26
+ import { createCommand, COMMAND_PRIORITY_LOW, $getSelection, $isRangeSelection, $insertNodes, $getNearestNodeFromDOMNode, $setSelection, isHTMLElement as isHTMLElement$1, TextNode, $applyNodeReplacement, $getRoot, $createTextNode, $getNodeByKey, DecoratorNode, createEditor, COMMAND_PRIORITY_EDITOR, $createParagraphNode, $isRootOrShadowRoot, $isParagraphNode, $isTextNode, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, UNDO_COMMAND, REDO_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $createNodeSelection, $isNodeSelection, CLICK_COMMAND, getDOMSelection, COMMAND_PRIORITY_HIGH, $isLineBreakNode, PASTE_COMMAND, isDOMNode } from "lexical";
27
27
  import * as ReactDOM from "react-dom";
28
28
  import ReactDOM__default, { createPortal } from "react-dom";
29
29
  import { $isCodeNode, CodeNode, normalizeCodeLang, getLanguageFriendlyName, CodeHighlightNode, CODE_LANGUAGE_MAP, $createCodeNode, registerCodeHighlighting, $isCodeHighlightNode } from "@lexical/code";
30
30
  import { LinkNode, $isLinkNode, TOGGLE_LINK_COMMAND, $createLinkNode, $isAutoLinkNode } from "@lexical/link";
31
- import { ListNode, ListItemNode, $isListNode, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND } from "@lexical/list";
32
- import { HeadingNode, QuoteNode, $isHeadingNode, $createHeadingNode, $createQuoteNode } from "@lexical/rich-text";
31
+ import { ListNode, ListItemNode, $isListNode, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, $createListNode, $createListItemNode } from "@lexical/list";
32
+ import { HeadingNode, QuoteNode, $isHeadingNode, $createHeadingNode, $createQuoteNode, DRAG_DROP_PASTE } from "@lexical/rich-text";
33
33
  import { $isAtNodeEnd, $selectAll, $patchStyleText, $setBlocksType, $isParentElementRTL, $getSelectionStyleValueForProperty } from "@lexical/selection";
34
- import { TableNode, TableCellNode, TableRowNode, $createTableNodeWithDimensions, TableCellHeaderStates, $isTableNode, $isTableSelection, $getTableCellNodeFromLexicalNode, $getTableNodeFromLexicalNodeOrThrow, getTableElement, getTableObserverFromTableElement, $isTableCellNode, $insertTableRow__EXPERIMENTAL, $insertTableColumn__EXPERIMENTAL, $deleteTableRow__EXPERIMENTAL, $deleteTableColumn__EXPERIMENTAL, $getTableRowIndexFromTableCellNode, $isTableRowNode, $getTableColumnIndexFromTableCellNode, $getNodeTriplet, $unmergeCell, $computeTableMapSkipCellCheck, getDOMCellFromTarget, $getTableAndElementByKey } from "@lexical/table";
34
+ import { TableNode, TableCellNode, TableRowNode, $createTableNodeWithDimensions, TableCellHeaderStates, $isTableNode, $isTableSelection, $getTableCellNodeFromLexicalNode, $getTableNodeFromLexicalNodeOrThrow, getTableElement, getTableObserverFromTableElement, $isTableCellNode, $insertTableRow__EXPERIMENTAL, $insertTableColumn__EXPERIMENTAL, $getNodeTriplet, $isTableRowNode, $deleteTableRow__EXPERIMENTAL, $deleteTableColumn__EXPERIMENTAL, $getTableRowIndexFromTableCellNode, $getTableColumnIndexFromTableCellNode, $unmergeCell, $computeTableMapSkipCellCheck, getDOMCellFromTarget, $getTableAndElementByKey } from "@lexical/table";
35
35
  import { HorizontalRuleNode } from "@lexical/react/LexicalHorizontalRuleNode";
36
36
  import DescriptionIcon from "@mui/icons-material/Description";
37
37
  import FolderZipIcon from "@mui/icons-material/FolderZip";
@@ -343,18 +343,18 @@ function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForD
343
343
  }
344
344
  };
345
345
  }
346
- function setRef(ref, value) {
346
+ function setRef$1(ref, value) {
347
347
  if (typeof ref === "function") {
348
348
  return ref(value);
349
349
  } else if (ref !== null && ref !== void 0) {
350
350
  ref.current = value;
351
351
  }
352
352
  }
353
- function composeRefs(...refs) {
353
+ function composeRefs$1(...refs) {
354
354
  return (node) => {
355
355
  let hasCleanup = false;
356
356
  const cleanups = refs.map((ref) => {
357
- const cleanup = setRef(ref, node);
357
+ const cleanup = setRef$1(ref, node);
358
358
  if (!hasCleanup && typeof cleanup == "function") {
359
359
  hasCleanup = true;
360
360
  }
@@ -367,7 +367,7 @@ function composeRefs(...refs) {
367
367
  if (typeof cleanup == "function") {
368
368
  cleanup();
369
369
  } else {
370
- setRef(refs[i2], null);
370
+ setRef$1(refs[i2], null);
371
371
  }
372
372
  }
373
373
  };
@@ -375,7 +375,7 @@ function composeRefs(...refs) {
375
375
  };
376
376
  }
377
377
  function useComposedRefs(...refs) {
378
- return React$1.useCallback(composeRefs(...refs), refs);
378
+ return React$1.useCallback(composeRefs$1(...refs), refs);
379
379
  }
380
380
  function createContext2(rootComponentName, defaultContext) {
381
381
  const Context2 = React$1.createContext(defaultContext);
@@ -536,12 +536,12 @@ function isFunction(value) {
536
536
  return typeof value === "function";
537
537
  }
538
538
  // @__NO_SIDE_EFFECTS__
539
- function createSlot(ownerName) {
540
- const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
539
+ function createSlot$1(ownerName) {
540
+ const SlotClone = /* @__PURE__ */ createSlotClone$1(ownerName);
541
541
  const Slot2 = React$1.forwardRef((props, forwardedRef) => {
542
542
  const { children, ...slotProps } = props;
543
543
  const childrenArray = React$1.Children.toArray(children);
544
- const slottable = childrenArray.find(isSlottable);
544
+ const slottable = childrenArray.find(isSlottable$1);
545
545
  if (slottable) {
546
546
  const newElement = slottable.props.children;
547
547
  const newChildren = childrenArray.map((child) => {
@@ -560,16 +560,15 @@ function createSlot(ownerName) {
560
560
  Slot2.displayName = `${ownerName}.Slot`;
561
561
  return Slot2;
562
562
  }
563
- var Slot$4 = /* @__PURE__ */ createSlot("Slot");
564
563
  // @__NO_SIDE_EFFECTS__
565
- function createSlotClone(ownerName) {
564
+ function createSlotClone$1(ownerName) {
566
565
  const SlotClone = React$1.forwardRef((props, forwardedRef) => {
567
566
  const { children, ...slotProps } = props;
568
567
  if (React$1.isValidElement(children)) {
569
- const childrenRef = getElementRef$1(children);
570
- const props2 = mergeProps(slotProps, children.props);
568
+ const childrenRef = getElementRef$2(children);
569
+ const props2 = mergeProps$1(slotProps, children.props);
571
570
  if (children.type !== React$1.Fragment) {
572
- props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
571
+ props2.ref = forwardedRef ? composeRefs$1(forwardedRef, childrenRef) : childrenRef;
573
572
  }
574
573
  return React$1.cloneElement(children, props2);
575
574
  }
@@ -578,20 +577,20 @@ function createSlotClone(ownerName) {
578
577
  SlotClone.displayName = `${ownerName}.SlotClone`;
579
578
  return SlotClone;
580
579
  }
581
- var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
580
+ var SLOTTABLE_IDENTIFIER$1 = Symbol("radix.slottable");
582
581
  // @__NO_SIDE_EFFECTS__
583
582
  function createSlottable(ownerName) {
584
583
  const Slottable2 = ({ children }) => {
585
584
  return /* @__PURE__ */ jsx(Fragment, { children });
586
585
  };
587
586
  Slottable2.displayName = `${ownerName}.Slottable`;
588
- Slottable2.__radixId = SLOTTABLE_IDENTIFIER;
587
+ Slottable2.__radixId = SLOTTABLE_IDENTIFIER$1;
589
588
  return Slottable2;
590
589
  }
591
- function isSlottable(child) {
592
- return React$1.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
590
+ function isSlottable$1(child) {
591
+ return React$1.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER$1;
593
592
  }
594
- function mergeProps(slotProps, childProps) {
593
+ function mergeProps$1(slotProps, childProps) {
595
594
  const overrideProps = { ...childProps };
596
595
  for (const propName in childProps) {
597
596
  const slotPropValue = slotProps[propName];
@@ -615,7 +614,7 @@ function mergeProps(slotProps, childProps) {
615
614
  }
616
615
  return { ...slotProps, ...overrideProps };
617
616
  }
618
- function getElementRef$1(element) {
617
+ function getElementRef$2(element) {
619
618
  var _a, _b;
620
619
  let getter = (_a = Object.getOwnPropertyDescriptor(element.props, "ref")) == null ? void 0 : _a.get;
621
620
  let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
@@ -649,7 +648,7 @@ var NODES = [
649
648
  "ul"
650
649
  ];
651
650
  var Primitive = NODES.reduce((primitive, node) => {
652
- const Slot2 = /* @__PURE__ */ createSlot(`Primitive.${node}`);
651
+ const Slot2 = /* @__PURE__ */ createSlot$1(`Primitive.${node}`);
653
652
  const Node2 = React$1.forwardRef((props, forwardedRef) => {
654
653
  const { asChild, ...primitiveProps } = props;
655
654
  const Comp = asChild ? Slot2 : node;
@@ -1134,7 +1133,7 @@ var Presence = (props) => {
1134
1133
  const { present, children } = props;
1135
1134
  const presence = usePresence(present);
1136
1135
  const child = typeof children === "function" ? children({ present: presence.isPresent }) : React$1.Children.only(children);
1137
- const ref = useComposedRefs(presence.ref, getElementRef(child));
1136
+ const ref = useComposedRefs(presence.ref, getElementRef$1(child));
1138
1137
  const forceMount = typeof children === "function";
1139
1138
  return forceMount || presence.isPresent ? React$1.cloneElement(child, { ref }) : null;
1140
1139
  };
@@ -1233,7 +1232,7 @@ function usePresence(present) {
1233
1232
  function getAnimationName(styles) {
1234
1233
  return (styles == null ? void 0 : styles.animationName) || "none";
1235
1234
  }
1236
- function getElementRef(element) {
1235
+ function getElementRef$1(element) {
1237
1236
  var _a, _b;
1238
1237
  let getter = (_a = Object.getOwnPropertyDescriptor(element.props, "ref")) == null ? void 0 : _a.get;
1239
1238
  let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
@@ -2135,7 +2134,7 @@ var DialogOverlay$1 = React$1.forwardRef(
2135
2134
  }
2136
2135
  );
2137
2136
  DialogOverlay$1.displayName = OVERLAY_NAME;
2138
- var Slot$3 = /* @__PURE__ */ createSlot("DialogOverlay.RemoveScroll");
2137
+ var Slot$4 = /* @__PURE__ */ createSlot$1("DialogOverlay.RemoveScroll");
2139
2138
  var DialogOverlayImpl = React$1.forwardRef(
2140
2139
  (props, forwardedRef) => {
2141
2140
  const { __scopeDialog, ...overlayProps } = props;
@@ -2143,7 +2142,7 @@ var DialogOverlayImpl = React$1.forwardRef(
2143
2142
  return (
2144
2143
  // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`
2145
2144
  // ie. when `Overlay` and `Content` are siblings
2146
- /* @__PURE__ */ jsx(RemoveScroll, { as: Slot$3, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(
2145
+ /* @__PURE__ */ jsx(RemoveScroll, { as: Slot$4, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(
2147
2146
  Primitive.div,
2148
2147
  {
2149
2148
  "data-state": getState$1(context.open),
@@ -2848,28 +2847,6 @@ const Plus = createLucideIcon("Plus", [
2848
2847
  ["path", { d: "M5 12h14", key: "1ays0h" }],
2849
2848
  ["path", { d: "M12 5v14", key: "s699le" }]
2850
2849
  ]);
2851
- /**
2852
- * @license lucide-react v0.344.0 - ISC
2853
- *
2854
- * This source code is licensed under the ISC license.
2855
- * See the LICENSE file in the root directory of this source tree.
2856
- */
2857
- const Quote = createLucideIcon("Quote", [
2858
- [
2859
- "path",
2860
- {
2861
- d: "M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z",
2862
- key: "4rm80e"
2863
- }
2864
- ],
2865
- [
2866
- "path",
2867
- {
2868
- d: "M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z",
2869
- key: "10za9r"
2870
- }
2871
- ]
2872
- ]);
2873
2850
  /**
2874
2851
  * @license lucide-react v0.344.0 - ISC
2875
2852
  *
@@ -6074,6 +6051,136 @@ const DialogDescription = React$1.forwardRef(({ className, ...props }, ref) => /
6074
6051
  }
6075
6052
  ));
6076
6053
  DialogDescription.displayName = Description.displayName;
6054
+ function setRef(ref, value) {
6055
+ if (typeof ref === "function") {
6056
+ return ref(value);
6057
+ } else if (ref !== null && ref !== void 0) {
6058
+ ref.current = value;
6059
+ }
6060
+ }
6061
+ function composeRefs(...refs) {
6062
+ return (node) => {
6063
+ let hasCleanup = false;
6064
+ const cleanups = refs.map((ref) => {
6065
+ const cleanup = setRef(ref, node);
6066
+ if (!hasCleanup && typeof cleanup == "function") {
6067
+ hasCleanup = true;
6068
+ }
6069
+ return cleanup;
6070
+ });
6071
+ if (hasCleanup) {
6072
+ return () => {
6073
+ for (let i2 = 0; i2 < cleanups.length; i2++) {
6074
+ const cleanup = cleanups[i2];
6075
+ if (typeof cleanup == "function") {
6076
+ cleanup();
6077
+ } else {
6078
+ setRef(refs[i2], null);
6079
+ }
6080
+ }
6081
+ };
6082
+ }
6083
+ };
6084
+ }
6085
+ var REACT_LAZY_TYPE = Symbol.for("react.lazy");
6086
+ var use = React$1[" use ".trim().toString()];
6087
+ function isPromiseLike(value) {
6088
+ return typeof value === "object" && value !== null && "then" in value;
6089
+ }
6090
+ function isLazyComponent(element) {
6091
+ return element != null && typeof element === "object" && "$$typeof" in element && element.$$typeof === REACT_LAZY_TYPE && "_payload" in element && isPromiseLike(element._payload);
6092
+ }
6093
+ // @__NO_SIDE_EFFECTS__
6094
+ function createSlot(ownerName) {
6095
+ const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
6096
+ const Slot2 = React$1.forwardRef((props, forwardedRef) => {
6097
+ let { children, ...slotProps } = props;
6098
+ if (isLazyComponent(children) && typeof use === "function") {
6099
+ children = use(children._payload);
6100
+ }
6101
+ const childrenArray = React$1.Children.toArray(children);
6102
+ const slottable = childrenArray.find(isSlottable);
6103
+ if (slottable) {
6104
+ const newElement = slottable.props.children;
6105
+ const newChildren = childrenArray.map((child) => {
6106
+ if (child === slottable) {
6107
+ if (React$1.Children.count(newElement) > 1)
6108
+ return React$1.Children.only(null);
6109
+ return React$1.isValidElement(newElement) ? newElement.props.children : null;
6110
+ } else {
6111
+ return child;
6112
+ }
6113
+ });
6114
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React$1.isValidElement(newElement) ? React$1.cloneElement(newElement, void 0, newChildren) : null });
6115
+ }
6116
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });
6117
+ });
6118
+ Slot2.displayName = `${ownerName}.Slot`;
6119
+ return Slot2;
6120
+ }
6121
+ var Slot$3 = /* @__PURE__ */ createSlot("Slot");
6122
+ // @__NO_SIDE_EFFECTS__
6123
+ function createSlotClone(ownerName) {
6124
+ const SlotClone = React$1.forwardRef((props, forwardedRef) => {
6125
+ let { children, ...slotProps } = props;
6126
+ if (isLazyComponent(children) && typeof use === "function") {
6127
+ children = use(children._payload);
6128
+ }
6129
+ if (React$1.isValidElement(children)) {
6130
+ const childrenRef = getElementRef(children);
6131
+ const props2 = mergeProps(slotProps, children.props);
6132
+ if (children.type !== React$1.Fragment) {
6133
+ props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
6134
+ }
6135
+ return React$1.cloneElement(children, props2);
6136
+ }
6137
+ return React$1.Children.count(children) > 1 ? React$1.Children.only(null) : null;
6138
+ });
6139
+ SlotClone.displayName = `${ownerName}.SlotClone`;
6140
+ return SlotClone;
6141
+ }
6142
+ var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
6143
+ function isSlottable(child) {
6144
+ return React$1.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
6145
+ }
6146
+ function mergeProps(slotProps, childProps) {
6147
+ const overrideProps = { ...childProps };
6148
+ for (const propName in childProps) {
6149
+ const slotPropValue = slotProps[propName];
6150
+ const childPropValue = childProps[propName];
6151
+ const isHandler = /^on[A-Z]/.test(propName);
6152
+ if (isHandler) {
6153
+ if (slotPropValue && childPropValue) {
6154
+ overrideProps[propName] = (...args) => {
6155
+ const result = childPropValue(...args);
6156
+ slotPropValue(...args);
6157
+ return result;
6158
+ };
6159
+ } else if (slotPropValue) {
6160
+ overrideProps[propName] = slotPropValue;
6161
+ }
6162
+ } else if (propName === "style") {
6163
+ overrideProps[propName] = { ...slotPropValue, ...childPropValue };
6164
+ } else if (propName === "className") {
6165
+ overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
6166
+ }
6167
+ }
6168
+ return { ...slotProps, ...overrideProps };
6169
+ }
6170
+ function getElementRef(element) {
6171
+ var _a, _b;
6172
+ let getter = (_a = Object.getOwnPropertyDescriptor(element.props, "ref")) == null ? void 0 : _a.get;
6173
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
6174
+ if (mayWarn) {
6175
+ return element.ref;
6176
+ }
6177
+ getter = (_b = Object.getOwnPropertyDescriptor(element, "ref")) == null ? void 0 : _b.get;
6178
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
6179
+ if (mayWarn) {
6180
+ return element.props.ref;
6181
+ }
6182
+ return element.props.ref || element.ref;
6183
+ }
6077
6184
  const falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
6078
6185
  const cx = clsx;
6079
6186
  const cva = (base, config) => (props) => {
@@ -6146,7 +6253,7 @@ const buttonVariants = cva(
6146
6253
  );
6147
6254
  const Button = React$1.forwardRef(
6148
6255
  ({ className, variant, size: size2, asChild = false, ...props }, ref) => {
6149
- const Comp = asChild ? Slot$4 : "button";
6256
+ const Comp = asChild ? Slot$3 : "button";
6150
6257
  return /* @__PURE__ */ jsx(
6151
6258
  Comp,
6152
6259
  {
@@ -8726,7 +8833,7 @@ function createCollection(name) {
8726
8833
  };
8727
8834
  CollectionProvider.displayName = PROVIDER_NAME2;
8728
8835
  const COLLECTION_SLOT_NAME = name + "CollectionSlot";
8729
- const CollectionSlotImpl = /* @__PURE__ */ createSlot(COLLECTION_SLOT_NAME);
8836
+ const CollectionSlotImpl = /* @__PURE__ */ createSlot$1(COLLECTION_SLOT_NAME);
8730
8837
  const CollectionSlot = React__default.forwardRef(
8731
8838
  (props, forwardedRef) => {
8732
8839
  const { scope, children } = props;
@@ -8738,7 +8845,7 @@ function createCollection(name) {
8738
8845
  CollectionSlot.displayName = COLLECTION_SLOT_NAME;
8739
8846
  const ITEM_SLOT_NAME = name + "CollectionItemSlot";
8740
8847
  const ITEM_DATA_ATTR = "data-radix-collection-item";
8741
- const CollectionItemSlotImpl = /* @__PURE__ */ createSlot(ITEM_SLOT_NAME);
8848
+ const CollectionItemSlotImpl = /* @__PURE__ */ createSlot$1(ITEM_SLOT_NAME);
8742
8849
  const CollectionItemSlot = React__default.forwardRef(
8743
8850
  (props, forwardedRef) => {
8744
8851
  const { scope, children, ...itemData } = props;
@@ -12717,10 +12824,10 @@ const PDF_CONFIG = {
12717
12824
  };
12718
12825
  const loadHtml2Pdf = async () => {
12719
12826
  try {
12720
- const mod = await import("./html2pdf.bundle.min-d9d93bc1.js").then((n) => n.h);
12827
+ const mod = await import("./html2pdf.bundle.min-96e9ee6a.js").then((n) => n.h);
12721
12828
  return (mod == null ? void 0 : mod.default) || mod;
12722
12829
  } catch {
12723
- const mod2 = await import("./html2pdf.bundle-0fecc54c.js").then((n) => n.h);
12830
+ const mod2 = await import("./html2pdf.bundle-7d125fec.js").then((n) => n.h);
12724
12831
  return (mod2 == null ? void 0 : mod2.default) || mod2;
12725
12832
  }
12726
12833
  };
@@ -13927,7 +14034,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
13927
14034
  }
13928
14035
  );
13929
14036
  };
13930
- const ImageView = React__default.lazy(() => import("./index-113e3eb2.js"));
14037
+ const ImageView = React__default.lazy(() => import("./index-91e0322d.js"));
13931
14038
  function isGoogleDocCheckboxImg(img) {
13932
14039
  return img.parentElement != null && img.parentElement.tagName === "LI" && img.previousSibling === null && img.getAttribute("aria-roledescription") === "checkbox";
13933
14040
  }
@@ -15386,38 +15493,10 @@ const BulletListIcon = () => /* @__PURE__ */ jsx(
15386
15493
  )
15387
15494
  }
15388
15495
  );
15389
- const CheckBoxIcon = () => /* @__PURE__ */ jsxs(
15390
- "svg",
15391
- {
15392
- xmlns: "http://www.w3.org/2000/svg",
15393
- width: "24",
15394
- height: "24",
15395
- viewBox: "0 0 24 24",
15396
- fill: "none",
15397
- children: [
15398
- /* @__PURE__ */ jsx(
15399
- "path",
15400
- {
15401
- d: "M19 3H5C3.89543 3 3 3.89543 3 5V19C3 20.1046 3.89543 21 5 21H19C20.1046 21 21 20.1046 21 19V5C21 3.89543 20.1046 3 19 3Z",
15402
- stroke: "currentColor",
15403
- strokeWidth: "2",
15404
- strokeLinecap: "round",
15405
- strokeLinejoin: "round"
15406
- }
15407
- ),
15408
- /* @__PURE__ */ jsx(
15409
- "path",
15410
- {
15411
- d: "M7 13L10 16L17 9",
15412
- stroke: "currentColor",
15413
- strokeWidth: "2",
15414
- strokeLinecap: "round",
15415
- strokeLinejoin: "round"
15416
- }
15417
- )
15418
- ]
15419
- }
15420
- );
15496
+ const CheckBoxIcon = () => /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: [
15497
+ /* @__PURE__ */ jsx("path", { d: "M18.2222 4H5.77778C4.79594 4 4 4.79594 4 5.77778V18.2222C4 19.2041 4.79594 20 5.77778 20H18.2222C19.2041 20 20 19.2041 20 18.2222V5.77778C20 4.79594 19.2041 4 18.2222 4Z", stroke: "currentColor" }),
15498
+ /* @__PURE__ */ jsx("path", { d: "M7.55566 12.8886L10.2223 15.5552L16.4446 9.33301", stroke: "currentColor" })
15499
+ ] });
15421
15500
  const SearchTextIcon = () => /* @__PURE__ */ jsx(
15422
15501
  "svg",
15423
15502
  {
@@ -15601,6 +15680,10 @@ const RecordingIcon = () => /* @__PURE__ */ jsx(
15601
15680
  );
15602
15681
  const AddCommentIcon = () => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M19 14.3333C19 14.7459 18.8361 15.1416 18.5444 15.4333C18.2527 15.725 17.857 15.8889 17.4444 15.8889H8.11111L5 19V6.55556C5 6.143 5.16389 5.74733 5.45561 5.45561C5.74733 5.16389 6.143 5 6.55556 5H17.4444C17.857 5 18.2527 5.16389 18.5444 5.45561C18.8361 5.74733 19 6.143 19 6.55556V14.3333Z", stroke: "currentColor", "stroke-width": "1.33333", "stroke-linecap": "round", "stroke-linejoin": "round" }) });
15603
15682
  const CheckIcon = () => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
15683
+ const QuoteIcon = () => /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: [
15684
+ /* @__PURE__ */ jsx("path", { d: "M4.75 19C7 19 10 18.2222 10 12.7779V6.55575C10 5.58354 9.433 4.98699 8.5 5.00022H5.5C4.5625 5.00022 4 5.58354 4 6.53397V11.2223C4 12.1945 4.5625 12.7779 5.5 12.7779C6.25 12.7779 6.25 12.7779 6.25 13.5556V14.3334C6.25 15.1112 5.5 15.8889 4.75 15.8889C4 15.8889 4 15.8952 4 16.6908V18.2222C4 19 4 19 4.75 19Z", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }),
15685
+ /* @__PURE__ */ jsx("path", { d: "M14.75 19C17 19 20 18.2222 20 12.7779V6.55575C20 5.58354 19.4323 4.98699 18.5 5.00022H15.5C14.5625 5.00022 14 5.58354 14 6.53397V11.2223C14 12.1945 14.5625 12.7779 15.5 12.7779H16.0625C16.0625 14.5278 16.25 15.8889 14 15.8889V18.2222C14 19 14 19 14.75 19Z", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" })
15686
+ ] });
15604
15687
  const EDITOR_NODES = [
15605
15688
  CodeNode,
15606
15689
  CodeHighlightNode,
@@ -15736,7 +15819,7 @@ const formatMenuItems = [
15736
15819
  },
15737
15820
  {
15738
15821
  name: "Quote",
15739
- icon: /* @__PURE__ */ jsx(Quote, { className: "size-4 mx-1" }),
15822
+ icon: /* @__PURE__ */ jsx(QuoteIcon, {}),
15740
15823
  payload: "quote"
15741
15824
  }
15742
15825
  ];
@@ -16457,6 +16540,7 @@ function TableOptionPlugin() {
16457
16540
  htmlCell.style.setProperty("padding", "8px", "important");
16458
16541
  htmlCell.style.setProperty("border", "1px solid #ddd", "important");
16459
16542
  htmlCell.style.setProperty("font-weight", "bold", "important");
16543
+ htmlCell.style.setProperty("white-space", "nowrap", "important");
16460
16544
  }
16461
16545
  });
16462
16546
  }
@@ -16504,6 +16588,7 @@ function TableOptionPlugin() {
16504
16588
  for (let i2 = 0; i2 < cells.length; i2++) {
16505
16589
  const headingText = (columnHeadings[i2] || "").trim();
16506
16590
  const cellNode = cells[i2];
16591
+ cellNode.clear();
16507
16592
  if (headingText) {
16508
16593
  cellNode.append($createTextNode(headingText));
16509
16594
  }
@@ -16536,6 +16621,7 @@ function TableOptionPlugin() {
16536
16621
  htmlCell.style.setProperty("padding", "8px", "important");
16537
16622
  htmlCell.style.setProperty("border", "1px solid #ddd", "important");
16538
16623
  htmlCell.style.setProperty("font-weight", "bold", "important");
16624
+ htmlCell.style.setProperty("white-space", "nowrap", "important");
16539
16625
  });
16540
16626
  return true;
16541
16627
  }
@@ -17292,7 +17378,7 @@ var MenuRootContentNonModal = React$1.forwardRef((props, forwardedRef) => {
17292
17378
  }
17293
17379
  );
17294
17380
  });
17295
- var Slot$2 = /* @__PURE__ */ createSlot("MenuContent.ScrollLock");
17381
+ var Slot$2 = /* @__PURE__ */ createSlot$1("MenuContent.ScrollLock");
17296
17382
  var MenuContentImpl = React$1.forwardRef(
17297
17383
  (props, forwardedRef) => {
17298
17384
  const {
@@ -17764,7 +17850,7 @@ var MenuSubTrigger = React$1.forwardRef(
17764
17850
  "aria-controls": subContext.contentId,
17765
17851
  "data-state": getOpenState(context.open),
17766
17852
  ...props,
17767
- ref: composeRefs(forwardedRef, subContext.onTriggerChange),
17853
+ ref: composeRefs$1(forwardedRef, subContext.onTriggerChange),
17768
17854
  onClick: (event) => {
17769
17855
  var _a;
17770
17856
  (_a = props.onClick) == null ? void 0 : _a.call(props, event);
@@ -18028,7 +18114,7 @@ var DropdownMenuTrigger$1 = React$1.forwardRef(
18028
18114
  "data-disabled": disabled ? "" : void 0,
18029
18115
  disabled,
18030
18116
  ...triggerProps,
18031
- ref: composeRefs(forwardedRef, context.triggerRef),
18117
+ ref: composeRefs$1(forwardedRef, context.triggerRef),
18032
18118
  onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
18033
18119
  if (!disabled && event.button === 0 && event.ctrlKey === false) {
18034
18120
  context.onOpenToggle();
@@ -18859,7 +18945,7 @@ var PopoverContent$1 = React$1.forwardRef(
18859
18945
  }
18860
18946
  );
18861
18947
  PopoverContent$1.displayName = CONTENT_NAME$1;
18862
- var Slot$1 = /* @__PURE__ */ createSlot("PopoverContent.RemoveScroll");
18948
+ var Slot$1 = /* @__PURE__ */ createSlot$1("PopoverContent.RemoveScroll");
18863
18949
  var PopoverContentModal = React$1.forwardRef(
18864
18950
  (props, forwardedRef) => {
18865
18951
  const context = usePopoverContext(CONTENT_NAME$1, props.__scopePopover);
@@ -19625,7 +19711,7 @@ SelectContent$1.displayName = CONTENT_NAME;
19625
19711
  var CONTENT_MARGIN = 10;
19626
19712
  var [SelectContentProvider, useSelectContentContext] = createSelectContext(CONTENT_NAME);
19627
19713
  var CONTENT_IMPL_NAME = "SelectContentImpl";
19628
- var Slot = /* @__PURE__ */ createSlot("SelectContent.RemoveScroll");
19714
+ var Slot = /* @__PURE__ */ createSlot$1("SelectContent.RemoveScroll");
19629
19715
  var SelectContentImpl = React$1.forwardRef(
19630
19716
  (props, forwardedRef) => {
19631
19717
  const {
@@ -20694,7 +20780,7 @@ const FontFamilyMenu = ({
20694
20780
  applyFontFamily(value);
20695
20781
  };
20696
20782
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Select, { value: selectedFont, onValueChange: handleFontChange, children: [
20697
- /* @__PURE__ */ jsx(SelectTrigger, { className: "!cteditor-h-7 !cteditor-bg-secondary cteditor-text-foreground !cteditor-w-[120px] cteditor-text-xs", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select font" }) }),
20783
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "!cteditor-h-7 md:!cteditor-bg-secondary !cteditor-bg-foreground/5 cteditor-text-foreground md:!cteditor-w-[120px] cteditor-text-xs max-md:cteditor-w-full", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select font" }) }),
20698
20784
  /* @__PURE__ */ jsx(SelectContent, { children: fonts.map((font) => /* @__PURE__ */ jsx(SelectItem, { value: font, style: { fontFamily: font }, children: font }, font)) })
20699
20785
  ] }) });
20700
20786
  };
@@ -20887,7 +20973,7 @@ const FormatTextMenu = ({ hasFormat, blockType }) => {
20887
20973
  },
20888
20974
  index2
20889
20975
  )),
20890
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
20976
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "!cteditor-bg-foreground/10" }),
20891
20977
  listQuoteFormattingItems.map((option, index2) => /* @__PURE__ */ jsxs(
20892
20978
  DropdownMenuItem$1,
20893
20979
  {
@@ -21205,7 +21291,7 @@ const InsertFileUploadedDialogBody = ({ onClick }) => {
21205
21291
  Input$1,
21206
21292
  {
21207
21293
  type: "file",
21208
- className: "cteditor-w-full",
21294
+ className: "cteditor-w-full cteditor-border-[1px] cteditor-border-dashed cteditor-border-foreground cteditor-h-auto cteditor-py-4 cteditor-rounded-xl cteditor-cursor-pointer",
21209
21295
  accept: ALLOWED_MIME_TYPES.join(","),
21210
21296
  onChange: onChangeFile
21211
21297
  }
@@ -21222,7 +21308,7 @@ const InsertFileUploadedDialogBody = ({ onClick }) => {
21222
21308
  {
21223
21309
  disabled: !fileToUpload || uploading,
21224
21310
  onClick: handleConfirmUpload,
21225
- className: "cteditor-mt-2",
21311
+ className: "cteditor-mt-2 cteditor-w-full",
21226
21312
  children: uploading ? `Uploading... ${progress}%` : "Confirm Upload"
21227
21313
  }
21228
21314
  )
@@ -21238,8 +21324,7 @@ const InsertFileDialog = ({
21238
21324
  };
21239
21325
  return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:cteditor-max-w-md", children: [
21240
21326
  /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: "Insert File" }) }),
21241
- /* @__PURE__ */ jsx("div", { className: "cteditor-py-2", children: /* @__PURE__ */ jsx(InsertFileUploadedDialogBody, { onClick }) }),
21242
- /* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { onClick: onClose, children: "Cancel" }) })
21327
+ /* @__PURE__ */ jsx("div", { className: "cteditor-py-2", children: /* @__PURE__ */ jsx(InsertFileUploadedDialogBody, { onClick }) })
21243
21328
  ] }) });
21244
21329
  };
21245
21330
  const INSERT_IMAGE_COMMAND = createCommand("INSERT_IMAGE_COMMAND");
@@ -21276,6 +21361,7 @@ const InsertImageUploadedDialogBody = ({
21276
21361
  const { uploadFileToS3, uploadedUrl, progress, uploading } = useS3Uploader(apiKey || void 0);
21277
21362
  const [tempSrc, setTempSrc] = useState$1("");
21278
21363
  const [fileToUpload, setFileToUpload] = useState$1(null);
21364
+ const [imageDimensions, setImageDimensions] = useState$1(null);
21279
21365
  const onChangeImage = async (event) => {
21280
21366
  const files = event.target.files;
21281
21367
  if (!files || files.length === 0)
@@ -21286,6 +21372,11 @@ const InsertImageUploadedDialogBody = ({
21286
21372
  reader.onload = () => {
21287
21373
  if (typeof reader.result === "string") {
21288
21374
  setTempSrc(reader.result);
21375
+ const img = new Image();
21376
+ img.onload = () => {
21377
+ setImageDimensions({ width: img.naturalWidth, height: img.naturalHeight });
21378
+ };
21379
+ img.src = reader.result;
21289
21380
  }
21290
21381
  };
21291
21382
  reader.readAsDataURL(file);
@@ -21295,57 +21386,46 @@ const InsertImageUploadedDialogBody = ({
21295
21386
  return;
21296
21387
  try {
21297
21388
  const uploadedUrl2 = await uploadFileToS3(fileToUpload);
21298
- onClick({ altText, src: uploadedUrl2 });
21389
+ console.log("Upload successful! URL:", uploadedUrl2);
21390
+ console.log("Image dimensions:", imageDimensions);
21391
+ const payload = {
21392
+ altText,
21393
+ src: uploadedUrl2,
21394
+ width: imageDimensions == null ? void 0 : imageDimensions.width,
21395
+ height: imageDimensions == null ? void 0 : imageDimensions.height
21396
+ };
21397
+ console.log("Inserting image with payload:", payload);
21398
+ onClick(payload);
21299
21399
  setTempSrc("");
21300
21400
  setFileToUpload(null);
21401
+ setImageDimensions(null);
21301
21402
  } catch (error) {
21302
21403
  console.error("Upload failed:", error);
21303
21404
  }
21304
21405
  };
21305
21406
  return /* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-4", children: [
21306
- tempSrc && /* @__PURE__ */ jsx("div", { className: "cteditor-mb-4", children: /* @__PURE__ */ jsx(
21407
+ tempSrc && /* @__PURE__ */ jsx("div", { className: "cteditor-mb-4 cteditor-flex cteditor-justify-center", children: /* @__PURE__ */ jsx(
21307
21408
  "img",
21308
21409
  {
21309
21410
  src: tempSrc,
21310
21411
  alt: "Preview",
21311
- className: "cteditor-max-w-full cteditor-max-h-[200px] cteditor-object-contain"
21412
+ className: "cteditor-max-w-full cteditor-max-h-44 cteditor-object-contain"
21312
21413
  }
21313
21414
  ) }),
21314
- /* @__PURE__ */ jsxs("div", { className: "fileUploadBox cteditor-flex cteditor-items-center cteditor-justify-center cteditor-border-2 cteditor-border-dashed cteditor-border-gray-300 cteditor-p-4 cteditor-rounded-lg", children: [
21315
- /* @__PURE__ */ jsx("div", { className: "fubIcon cteditor-mr-4", children: /* @__PURE__ */ jsxs(
21316
- "svg",
21415
+ /* @__PURE__ */ jsx("div", { className: "fileUploadBox cteditor-flex cteditor-items-center cteditor-justify-center cteditor-border-[1px] cteditor-border-dashed cteditor-h-auto cteditor-border-foreground cteditor-rounded-xl cteditor-p-0 ", children: /* @__PURE__ */ jsxs("div", { className: "flex-grow cteditor-w-full", children: [
21416
+ /* @__PURE__ */ jsx(Label$2, { htmlFor: "image-upload", className: "!cteditor-sr-only", children: "Upload Image" }),
21417
+ /* @__PURE__ */ jsx(
21418
+ Input$1,
21317
21419
  {
21318
- xmlns: "http://www.w3.org/2000/svg",
21319
- width: "24",
21320
- height: "24",
21321
- viewBox: "0 0 24 24",
21322
- fill: "none",
21323
- stroke: "currentColor",
21324
- strokeWidth: "2",
21325
- strokeLinecap: "round",
21326
- strokeLinejoin: "round",
21327
- children: [
21328
- /* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
21329
- /* @__PURE__ */ jsx("polyline", { points: "17 8 12 3 7 8" }),
21330
- /* @__PURE__ */ jsx("line", { x1: "12", x2: "12", y1: "3", y2: "15" })
21331
- ]
21420
+ id: "image-upload",
21421
+ type: "file",
21422
+ accept: "image/*",
21423
+ onChange: onChangeImage,
21424
+ "data-test-id": "image-modal-file-upload",
21425
+ className: "cteditor-w-full !cteditor-py-3 !cteditor-h-auto !cteditor-border-none"
21332
21426
  }
21333
- ) }),
21334
- /* @__PURE__ */ jsxs("div", { className: "flex-grow", children: [
21335
- /* @__PURE__ */ jsx(Label$2, { htmlFor: "image-upload", className: "!cteditor-sr-only", children: "Upload Image" }),
21336
- /* @__PURE__ */ jsx(
21337
- Input$1,
21338
- {
21339
- id: "image-upload",
21340
- type: "file",
21341
- accept: "image/*",
21342
- onChange: onChangeImage,
21343
- "data-test-id": "image-modal-file-upload",
21344
- className: "cteditor-w-full"
21345
- }
21346
- )
21347
- ] })
21348
- ] }),
21427
+ )
21428
+ ] }) }),
21349
21429
  /* @__PURE__ */ jsxs("div", { children: [
21350
21430
  /* @__PURE__ */ jsx(Label$2, { htmlFor: "alt-text", className: "cteditor-mb-2 cteditor-block", children: "Alt Text" }),
21351
21431
  /* @__PURE__ */ jsx(
@@ -21356,7 +21436,7 @@ const InsertImageUploadedDialogBody = ({
21356
21436
  value: altText,
21357
21437
  onChange: (e) => setAltText(e.target.value),
21358
21438
  "data-test-id": "image-modal-alt-text-input",
21359
- className: "cteditor-w-full"
21439
+ className: "cteditor-w-full cteditor-cursor-pointer"
21360
21440
  }
21361
21441
  )
21362
21442
  ] }),
@@ -21379,6 +21459,7 @@ const InsertImageUrlDialogBody = ({
21379
21459
  const [altText, setAltText] = useState$1("");
21380
21460
  const [isValidUrl, setIsValidUrl] = useState$1(false);
21381
21461
  const [previewError, setPreviewError] = useState$1(null);
21462
+ const [imageDimensions, setImageDimensions] = useState$1(null);
21382
21463
  const validateUrl2 = (url) => {
21383
21464
  if (!url.trim())
21384
21465
  return false;
@@ -21414,6 +21495,7 @@ const InsertImageUrlDialogBody = ({
21414
21495
  img.onload = () => {
21415
21496
  setPreviewError(null);
21416
21497
  setIsValidUrl(true);
21498
+ setImageDimensions({ width: img.naturalWidth, height: img.naturalHeight });
21417
21499
  };
21418
21500
  img.onerror = () => {
21419
21501
  setPreviewError(
@@ -21426,7 +21508,12 @@ const InsertImageUrlDialogBody = ({
21426
21508
  const handleConfirmUrl = () => {
21427
21509
  if (!imageUrl || !isValidUrl)
21428
21510
  return;
21429
- onClick({ altText, src: imageUrl });
21511
+ onClick({
21512
+ altText,
21513
+ src: imageUrl,
21514
+ width: imageDimensions == null ? void 0 : imageDimensions.width,
21515
+ height: imageDimensions == null ? void 0 : imageDimensions.height
21516
+ });
21430
21517
  };
21431
21518
  return /* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-4", children: [
21432
21519
  imageUrl && isValidUrl && !previewError && /* @__PURE__ */ jsx("div", { className: "cteditor-mb-4", children: /* @__PURE__ */ jsx(
@@ -21540,8 +21627,7 @@ const InsertImageDialog = ({ activeEditor, onClose }) => {
21540
21627
  ]
21541
21628
  }
21542
21629
  )
21543
- ] }) : mode === "file" ? /* @__PURE__ */ jsx(InsertImageUploadedDialogBody, { onClick }) : /* @__PURE__ */ jsx(InsertImageUrlDialogBody, { onClick }),
21544
- /* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, children: "Cancel" }) })
21630
+ ] }) : mode === "file" ? /* @__PURE__ */ jsx(InsertImageUploadedDialogBody, { onClick }) : /* @__PURE__ */ jsx(InsertImageUrlDialogBody, { onClick })
21545
21631
  ] }) });
21546
21632
  };
21547
21633
  function _extends() {
@@ -22471,30 +22557,33 @@ const SignatureCanvasDialog = ({
22471
22557
  return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: () => onClose(), children: /* @__PURE__ */ jsxs(DialogContent, { className: "!cteditor-max-w-3xl", children: [
22472
22558
  /* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-4", children: [
22473
22559
  /* @__PURE__ */ jsx("div", { className: "cteditor-text-lg cteditor-font-medium", children: "Draw your signature" }),
22474
- /* @__PURE__ */ jsxs("div", { className: "cteditor-mb-2", children: [
22475
- /* @__PURE__ */ jsx("label", { htmlFor: "penColor", className: "cteditor-mr-2", children: "Choose Color:" }),
22476
- /* @__PURE__ */ jsx(
22477
- "input",
22478
- {
22479
- type: "color",
22480
- id: "penColor",
22481
- value: penColor,
22482
- onChange: handleColorChange
22483
- }
22484
- )
22485
- ] }),
22486
- /* @__PURE__ */ jsxs("div", { className: "cteditor-mb-4", children: [
22487
- /* @__PURE__ */ jsx("label", { htmlFor: "uploadSignature", className: "cteditor-mr-2 cteditor-cursor-pointer cteditor-text-blue-600 underline", children: "Upload Signature Image" }),
22488
- /* @__PURE__ */ jsx(
22489
- "input",
22490
- {
22491
- type: "file",
22492
- id: "uploadSignature",
22493
- accept: "image/*",
22494
- onChange: handleUpload,
22495
- className: "cteditor-hidden"
22496
- }
22497
- )
22560
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-justify-between cteditor-gap-3 cteditor-items-center", children: [
22561
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-gap-2 cteditor-items-center", children: [
22562
+ /* @__PURE__ */ jsx("label", { htmlFor: "penColor", children: "Choose Color:" }),
22563
+ /* @__PURE__ */ jsx("div", { className: "cteditor-size-8 cteditor-overflow-hidden cteditor-relative cteditor-rounded-md cteditor-border cteditor-border-foreground/5", children: /* @__PURE__ */ jsx(
22564
+ "input",
22565
+ {
22566
+ type: "color",
22567
+ id: "penColor",
22568
+ value: penColor,
22569
+ onChange: handleColorChange,
22570
+ className: "cteditor-scale-[5] cteditor-absolute cteditor-inset-0 cteditor-cursor-pointer"
22571
+ }
22572
+ ) })
22573
+ ] }),
22574
+ /* @__PURE__ */ jsxs("div", { children: [
22575
+ /* @__PURE__ */ jsx("label", { htmlFor: "uploadSignature", className: "cteditor-cursor-pointer cteditor-text-foreground underline cteditor-text-sm cteditor-rounded-md cteditor-h-9 cteditor-px-4 cteditor-font-medium cteditor-shadow-sm cteditor-bg-background cteditor-border-input cteditor-border cteditor-flex cteditor-items-center hover:cteditor-bg-accent", children: "Upload Signature Image" }),
22576
+ /* @__PURE__ */ jsx(
22577
+ "input",
22578
+ {
22579
+ type: "file",
22580
+ id: "uploadSignature",
22581
+ accept: "image/*",
22582
+ onChange: handleUpload,
22583
+ className: "cteditor-hidden"
22584
+ }
22585
+ )
22586
+ ] })
22498
22587
  ] }),
22499
22588
  /* @__PURE__ */ jsx("div", { className: "cteditor-border cteditor-border-gray-300 cteditor-rounded-sm cteditor-bg-white", children: /* @__PURE__ */ jsx(
22500
22589
  SignatureCanvas,
@@ -22706,8 +22795,8 @@ const NotePanelMenu = ({ className }) => {
22706
22795
  ] });
22707
22796
  };
22708
22797
  const useStyles$1 = () => ({
22709
- root: "cteditor-p-2 cteditor-border-b cteditor-border-[#e0e0e0] cteditor-overflow-auto",
22710
- toolbar: "cteditor-p-2 cteditor-overflow-auto",
22798
+ root: "cteditor-p-2 cteditor-border-b cteditor-border-[#e0e0e0] cteditor-max-w-full cteditor-overflow-x-auto",
22799
+ toolbar: "cteditor-p-2 cteditor-max-w-full cteditor-overflow-x-auto cteditor-flex cteditor-flex-nowrap cteditor-gap-1",
22711
22800
  toolbarButton: "cteditor-p-1.5"
22712
22801
  });
22713
22802
  const useModal$1 = () => {
@@ -22756,14 +22845,14 @@ const InsertMenuDrop = () => {
22756
22845
  }
22757
22846
  ];
22758
22847
  return /* @__PURE__ */ jsxs(Fragment, { children: [
22759
- /* @__PURE__ */ jsx("div", { className: "cteditor-flex cteditor-flex-col cteditor-gap-1", children: insertMenuItems.map((option, index2) => /* @__PURE__ */ jsxs(
22848
+ /* @__PURE__ */ jsx("div", { className: "cteditor-flex cteditor-flex-col", children: insertMenuItems.map((option, index2) => /* @__PURE__ */ jsxs(
22760
22849
  "button",
22761
22850
  {
22762
- className: "cteditor-relative cteditor-flex cteditor-cursor-pointer cteditor-select-none cteditor-items-center cteditor-gap-2 cteditor-rounded-sm cteditor-px-2 cteditor-py-1.5 cteditor-text-[13px] cteditor-outline-none cteditor-transition-colors focus:cteditor-bg-foreground/5 focus:cteditor-text-accent-foreground data-[disabled]:cteditor-pointer-events-none data-[disabled]:cteditor-opacity-50 [&>svg]:cteditor-size-4 [&>svg]:cteditor-shrink-0",
22851
+ className: "cteditor-relative cteditor-flex cteditor-cursor-pointer cteditor-select-none cteditor-items-center cteditor-gap-2 cteditor-rounded-sm cteditor-px-2 cteditor-py-1.5 cteditor-text-[13px] cteditor-outline-none cteditor-transition-colors focus:cteditor-bg-foreground/5 focus:cteditor-text-accent-foreground hover:cteditor-bg-foreground/5 data-[disabled]:cteditor-pointer-events-none data-[disabled]:cteditor-opacity-50 [&>svg]:cteditor-shrink-0",
22763
22852
  onClick: option.onClick,
22764
22853
  title: option.name,
22765
22854
  children: [
22766
- /* @__PURE__ */ jsx("span", { className: "[&>svg]:cteditor-size-4", children: option.icon }),
22855
+ /* @__PURE__ */ jsx("span", { className: "cteditor-size-6 [&>svg]:cteditor-size-4 cteditor-flex cteditor-justify-center cteditor-items-center", children: option.icon }),
22767
22856
  /* @__PURE__ */ jsx("span", { children: option.name })
22768
22857
  ]
22769
22858
  },
@@ -22780,7 +22869,7 @@ const AlignMenuDrop = () => {
22780
22869
  onClick: () => {
22781
22870
  editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, option.payload);
22782
22871
  },
22783
- className: "cteditor-relative cteditor-flex cteditor-cursor-pointer cteditor-select-none cteditor-items-center cteditor-gap-2 cteditor-rounded-sm cteditor-px-2 cteditor-py-1.5 cteditor-text-[13px] cteditor-outline-none cteditor-transition-colors focus:cteditor-bg-foreground/5 focus:cteditor-text-accent-foreground data-[disabled]:cteditor-pointer-events-none data-[disabled]:cteditor-opacity-50 [&>svg]:cteditor-size-4 [&>svg]:cteditor-shrink-0",
22872
+ className: "cteditor-relative cteditor-flex cteditor-cursor-pointer cteditor-select-none cteditor-items-center cteditor-gap-2 cteditor-rounded-sm cteditor-px-2 cteditor-py-1.5 cteditor-text-[13px] cteditor-outline-none cteditor-transition-colors focus:cteditor-bg-foreground/5 focus:cteditor-text-accent-foreground hover:cteditor-bg-foreground/5 data-[disabled]:cteditor-pointer-events-none data-[disabled]:cteditor-opacity-50 [&>svg]:cteditor-size-4 [&>svg]:cteditor-shrink-0",
22784
22873
  title: option.name,
22785
22874
  children: [
22786
22875
  /* @__PURE__ */ jsx("span", { className: "[&>svg]:cteditor-size-4", children: option.icon }),
@@ -22790,38 +22879,131 @@ const AlignMenuDrop = () => {
22790
22879
  index2
22791
22880
  )) });
22792
22881
  };
22793
- const Toolbar = ({
22794
- editable,
22795
- enableUndoRedo = true,
22796
- enableTextFormatting = true,
22797
- enableAlignment = true,
22798
- enableFontControls = true,
22799
- enableTableOptions = true,
22800
- enableInsertMenu = true,
22801
- enableColorPicker = true,
22802
- enableClearOptions = true,
22803
- enableEmojiPicker = true,
22804
- enableDatePicker = true,
22805
- enableLinks = true,
22806
- enableFormatTextMenu = true,
22807
- enableCodeFormat = true,
22808
- enableAIChat = true,
22809
- enableTodoList = true,
22810
- enableHtmlViewToggle = true,
22811
- enableHtmlView = true,
22812
- enableNotePanels = true,
22813
- enableAutocompleteToggle = true,
22814
- fonts,
22815
- editor,
22816
- activeEditor,
22817
- setActiveEditor
22818
- }) => {
22819
- const [disableMap, setDisableMap] = useState$1({
22820
- ["undo"]: true,
22821
- ["redo"]: true
22822
- });
22823
- const [isLinkEditMode, setIsLinkEditMode] = useState$1(false);
22824
- const [selectedElementKey, setSelectedElementKey] = useState$1(
22882
+ const FormatTextMenuDrop = ({ hasFormat, blockType }) => {
22883
+ const [editor] = useLexicalComposerContext();
22884
+ const textFormats = [
22885
+ "bold",
22886
+ "italic",
22887
+ "strikethrough",
22888
+ "underline",
22889
+ "code",
22890
+ "subscript",
22891
+ "superscript"
22892
+ ];
22893
+ const handleFormatClick = (payload) => {
22894
+ if (textFormats.includes(payload)) {
22895
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, payload);
22896
+ return;
22897
+ }
22898
+ editor.update(() => {
22899
+ const selection = $getSelection();
22900
+ if (!$isRangeSelection(selection))
22901
+ return;
22902
+ switch (payload) {
22903
+ case "bullet":
22904
+ if (blockType !== "bullet") {
22905
+ editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
22906
+ } else {
22907
+ editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0);
22908
+ }
22909
+ break;
22910
+ case "number":
22911
+ if (blockType !== "number") {
22912
+ editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
22913
+ } else {
22914
+ editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0);
22915
+ }
22916
+ break;
22917
+ case "check":
22918
+ if (blockType !== "check") {
22919
+ editor.dispatchCommand(INSERT_CHECK_LIST_COMMAND, void 0);
22920
+ } else {
22921
+ editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0);
22922
+ }
22923
+ break;
22924
+ case "quote":
22925
+ $setBlocksType(selection, () => $createQuoteNode());
22926
+ break;
22927
+ }
22928
+ });
22929
+ };
22930
+ const textFormattingItems = formatMenuItems.filter(
22931
+ (item) => textFormats.includes(item.payload)
22932
+ );
22933
+ const listQuoteFormattingItems = formatMenuItems.filter(
22934
+ (item) => !textFormats.includes(item.payload)
22935
+ );
22936
+ return /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-flex-col cteditor-w-full", children: [
22937
+ textFormattingItems.map((option, index2) => /* @__PURE__ */ jsxs(
22938
+ Button,
22939
+ {
22940
+ variant: "ghost",
22941
+ size: "sm",
22942
+ className: cn$1(
22943
+ "cteditor-relative cteditor-flex cteditor-cursor-pointer cteditor-select-none cteditor-items-center cteditor-gap-2 cteditor-rounded-sm cteditor-px-2 cteditor-py-1.5 cteditor-text-[13px] cteditor-outline-none cteditor-transition-colors focus:cteditor-bg-foreground/5 focus:cteditor-text-accent-foreground hover:cteditor-bg-foreground/5 data-[disabled]:cteditor-pointer-events-none data-[disabled]:cteditor-opacity-50 [&>svg]:cteditor-size-4 [&>svg]:cteditor-shrink-0 !cteditor-justify-start cteditor-h-auto ",
22944
+ hasFormat[option.payload] && "cteditor-bg-accent"
22945
+ ),
22946
+ onClick: () => handleFormatClick(option.payload),
22947
+ title: option.name,
22948
+ children: [
22949
+ /* @__PURE__ */ jsx("span", { className: "[&>svg]:cteditor-size-4", children: option.icon }),
22950
+ /* @__PURE__ */ jsx("span", { children: option.name })
22951
+ ]
22952
+ },
22953
+ index2
22954
+ )),
22955
+ listQuoteFormattingItems.map((option, index2) => /* @__PURE__ */ jsxs(
22956
+ Button,
22957
+ {
22958
+ variant: "ghost",
22959
+ size: "sm",
22960
+ className: cn$1(
22961
+ "cteditor-relative cteditor-flex cteditor-cursor-pointer cteditor-select-none cteditor-items-center cteditor-gap-2 cteditor-rounded-sm cteditor-px-2 cteditor-py-1.5 cteditor-text-[13px] cteditor-outline-none cteditor-transition-colors focus:cteditor-bg-foreground/5 focus:cteditor-text-accent-foreground hover:cteditor-bg-foreground/5 data-[disabled]:cteditor-pointer-events-none data-[disabled]:cteditor-opacity-50 [&>svg]:cteditor-size-4 [&>svg]:cteditor-shrink-0 !cteditor-justify-start cteditor-h-auto",
22962
+ blockType === option.payload && "cteditor-bg-accent"
22963
+ ),
22964
+ onClick: () => handleFormatClick(option.payload),
22965
+ title: option.name,
22966
+ children: [
22967
+ /* @__PURE__ */ jsx("span", { className: "[&>svg]:cteditor-size-4", children: option.icon }),
22968
+ /* @__PURE__ */ jsx("span", { children: option.name })
22969
+ ]
22970
+ },
22971
+ `list-quote-${index2}`
22972
+ ))
22973
+ ] });
22974
+ };
22975
+ const Toolbar = ({
22976
+ editable,
22977
+ enableUndoRedo = true,
22978
+ enableTextFormatting = true,
22979
+ enableAlignment = true,
22980
+ enableFontControls = true,
22981
+ enableTableOptions = true,
22982
+ enableInsertMenu = true,
22983
+ enableColorPicker = true,
22984
+ enableClearOptions = true,
22985
+ enableEmojiPicker = true,
22986
+ enableDatePicker = true,
22987
+ enableLinks = true,
22988
+ enableFormatTextMenu = true,
22989
+ enableCodeFormat = true,
22990
+ enableAIChat = true,
22991
+ enableTodoList = true,
22992
+ enableHtmlViewToggle = true,
22993
+ enableHtmlView = true,
22994
+ enableNotePanels = true,
22995
+ enableAutocompleteToggle = true,
22996
+ fonts,
22997
+ editor,
22998
+ activeEditor,
22999
+ setActiveEditor
23000
+ }) => {
23001
+ const [disableMap, setDisableMap] = useState$1({
23002
+ ["undo"]: true,
23003
+ ["redo"]: true
23004
+ });
23005
+ const [isLinkEditMode, setIsLinkEditMode] = useState$1(false);
23006
+ const [selectedElementKey, setSelectedElementKey] = useState$1(
22825
23007
  null
22826
23008
  );
22827
23009
  const [showMoreMenu, setShowMoreMenu] = useState$1(false);
@@ -23220,14 +23402,17 @@ const Toolbar = ({
23220
23402
  "div",
23221
23403
  {
23222
23404
  ref: contentRef,
23223
- className: "cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-flex-1 cteditor-overflow-x-auto cteditor-scrollbar-hide",
23224
- style: { scrollbarWidth: "none", msOverflowStyle: "none" },
23405
+ className: "cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-overflow-x-auto cteditor-overflow-y-hidden cteditor-flex-nowrap no-scrollbar",
23406
+ style: {
23407
+ scrollBehavior: "smooth",
23408
+ WebkitOverflowScrolling: "touch"
23409
+ },
23225
23410
  children: [
23226
23411
  enableUndoRedo && /* @__PURE__ */ jsxs(
23227
23412
  "div",
23228
23413
  {
23229
23414
  "data-toolbar-item": "undoRedo",
23230
- className: "cteditor-flex cteditor-items-center cteditor-gap-1.5",
23415
+ className: "cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-flex-shrink-0",
23231
23416
  children: [
23232
23417
  /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
23233
23418
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
@@ -23391,8 +23576,10 @@ const Toolbar = ({
23391
23576
  ) }),
23392
23577
  /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: "Insert code block" }) })
23393
23578
  ] }) }),
23394
- enableFormatTextMenu && activeEditor === editor && /* @__PURE__ */ jsx("div", { "data-toolbar-item": "formatTextMenu", className: "cteditor-size-6", children: /* @__PURE__ */ jsx(FormatTextMenu, { hasFormat, blockType }) }),
23395
- /* @__PURE__ */ jsx(Separator$2, { orientation: "vertical", className: "!cteditor-h-7" }),
23579
+ enableFormatTextMenu && activeEditor === editor && /* @__PURE__ */ jsxs("div", { "data-toolbar-item": "formatTextMenu", className: "cteditor-size-6", children: [
23580
+ /* @__PURE__ */ jsx(FormatTextMenu, { hasFormat, blockType }),
23581
+ /* @__PURE__ */ jsx(Separator$2, { orientation: "vertical", className: "!cteditor-h-7" })
23582
+ ] }),
23396
23583
  enableColorPicker && activeEditor === editor && /* @__PURE__ */ jsxs(
23397
23584
  "div",
23398
23585
  {
@@ -23429,8 +23616,7 @@ const Toolbar = ({
23429
23616
  }
23430
23617
  },
23431
23618
  "bg-color-picker"
23432
- ) }),
23433
- /* @__PURE__ */ jsx(Separator$2, { orientation: "vertical", className: "!cteditor-h-7" })
23619
+ ) })
23434
23620
  ]
23435
23621
  }
23436
23622
  ),
@@ -23443,7 +23629,7 @@ const Toolbar = ({
23443
23629
  size: "icon-sm",
23444
23630
  onClick: insertLink,
23445
23631
  className: cn$1(
23446
- isLinkActive ? "dark:cteditor-text-blue-500 cteditor-text-blue-700" : "cteditor-text-foreground"
23632
+ isLinkActive ? "cteditor-bg-accent" : "cteditor-text-foreground"
23447
23633
  ),
23448
23634
  children: /* @__PURE__ */ jsx(LinkIcon, {})
23449
23635
  }
@@ -23519,8 +23705,8 @@ const Toolbar = ({
23519
23705
  disabled: !editable,
23520
23706
  className: cn$1(
23521
23707
  classes.toolbarButton,
23522
- toolbarState.isAutocompleteEnabled && "cteditor-bg-foreground/20",
23523
- "[&>svg]:!cteditor-size-4"
23708
+ toolbarState.isAutocompleteEnabled && "",
23709
+ "[&>svg]:!cteditor-size-4 p-1"
23524
23710
  ),
23525
23711
  children: /* @__PURE__ */ jsx(SearchTextIcon2, {})
23526
23712
  }
@@ -23559,7 +23745,7 @@ const Toolbar = ({
23559
23745
  className: "cteditor-relative",
23560
23746
  children: [
23561
23747
  isExportingPDF ? /* @__PURE__ */ jsx(Loader2, { className: "!cteditor-size-4 cteditor-animate-spin" }) : /* @__PURE__ */ jsx(Download, { className: "!cteditor-size-4" }),
23562
- /* @__PURE__ */ jsx("span", { className: "cteditor-ml-1", children: isExportingPDF ? `Exporting... ${exportProgress}%` : "Export" })
23748
+ /* @__PURE__ */ jsx("span", { children: isExportingPDF ? `Exporting... ${exportProgress}%` : "Export" })
23563
23749
  ]
23564
23750
  }
23565
23751
  ) }),
@@ -23571,7 +23757,7 @@ const Toolbar = ({
23571
23757
  {
23572
23758
  variant: "outline",
23573
23759
  size: "sm",
23574
- className: "cteditor-px-4 cteditor-gap-3 [&>svg]:!cteditor-size-4 cteditor-bg-gradient-to-r cteditor-from-background cteditor-via-primary/10 cteditor-to-background hover:cteditor-from-background/80 hover:cteditor-via-primary/10 hover:cteditor-to-background/80",
23760
+ className: "cteditor-px-4 cteditor-gap-2 [&>svg]:!cteditor-size-4 cteditor-bg-gradient-to-r cteditor-from-background cteditor-via-primary/10 cteditor-to-background hover:cteditor-from-background/80 hover:cteditor-via-primary/10 hover:cteditor-to-background/80",
23575
23761
  children: [
23576
23762
  /* @__PURE__ */ jsx(MagicoonIcon, {}),
23577
23763
  " Go with AI"
@@ -23676,7 +23862,7 @@ const Toolbar = ({
23676
23862
  open: isMoreMenuOpen,
23677
23863
  onOpenChange: setIsMoreMenuOpen,
23678
23864
  children: [
23679
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", className: "!cteditor-px-1 !cteditor-py-0.5 !cteditor-h-7 !cteditor-gap-1", children: [
23865
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", className: "!cteditor-px-1 !cteditor-py-0.5 !cteditor-h-7 !cteditor-gap-1 !cteditor-bg-accent", children: [
23680
23866
  /* @__PURE__ */ jsx(Plus, { className: "!cteditor-size-5" }),
23681
23867
  /* @__PURE__ */ jsx(ChevronDown, { className: "!cteditor-size-3.5" })
23682
23868
  ] }) }),
@@ -23747,33 +23933,32 @@ const Toolbar = ({
23747
23933
  children: /* @__PURE__ */ jsx(
23748
23934
  "div",
23749
23935
  {
23750
- className: "cteditor-w-full",
23936
+ className: "cteditor-w-full ",
23751
23937
  onClick: (e) => e.stopPropagation(),
23752
23938
  children: /* @__PURE__ */ jsx(FontSizeControl, {})
23753
23939
  }
23754
23940
  )
23755
23941
  }
23756
- ),
23757
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {})
23758
- ] }),
23759
- enableTableOptions && activeEditor === editor && hiddenItemIds.has("tableOptions") && /* @__PURE__ */ jsxs(Fragment, { children: [
23760
- /* @__PURE__ */ jsx(
23761
- DropdownMenuItem$1,
23762
- {
23763
- asChild: true,
23764
- onSelect: (e) => e.preventDefault(),
23765
- children: /* @__PURE__ */ jsx(
23766
- "div",
23767
- {
23768
- className: "cteditor-w-full",
23769
- onClick: (e) => e.stopPropagation(),
23770
- children: /* @__PURE__ */ jsx(TableOptionPlugin, {})
23771
- }
23772
- )
23773
- }
23774
- ),
23775
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {})
23942
+ )
23776
23943
  ] }),
23944
+ enableTableOptions && activeEditor === editor && hiddenItemIds.has("tableOptions") && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
23945
+ DropdownMenuItem$1,
23946
+ {
23947
+ asChild: true,
23948
+ onSelect: (e) => e.preventDefault(),
23949
+ children: /* @__PURE__ */ jsxs(
23950
+ "div",
23951
+ {
23952
+ className: "cteditor-w-full",
23953
+ onClick: (e) => e.stopPropagation(),
23954
+ children: [
23955
+ /* @__PURE__ */ jsx(TableOptionPlugin, {}),
23956
+ "Table"
23957
+ ]
23958
+ }
23959
+ )
23960
+ }
23961
+ ) }),
23777
23962
  enableTextFormatting && hiddenItemIds.has("inlineFormats") && /* @__PURE__ */ jsxs(
23778
23963
  DropdownMenuItem$1,
23779
23964
  {
@@ -23782,33 +23967,22 @@ const Toolbar = ({
23782
23967
  "strikethrough"
23783
23968
  ),
23784
23969
  children: [
23785
- /* @__PURE__ */ jsx("div", { className: "cteditor-mr-2 [&>svg]:!cteditor-size-4", children: /* @__PURE__ */ jsx(StrikethroughIcon, {}) }),
23970
+ /* @__PURE__ */ jsx("div", { className: "[&>svg]:!cteditor-size-6", children: /* @__PURE__ */ jsx(StrikethroughIcon, {}) }),
23786
23971
  "Strikethrough"
23787
23972
  ]
23788
23973
  }
23789
23974
  ),
23790
23975
  enableCodeFormat && activeEditor === editor && hiddenItemIds.has("codeBlock") && /* @__PURE__ */ jsxs(DropdownMenuItem$1, { onClick: formatCodeBlock, children: [
23791
- /* @__PURE__ */ jsx("div", { className: "cteditor-mr-2 [&>svg]:!cteditor-size-4", children: /* @__PURE__ */ jsx(CodeIcon, {}) }),
23976
+ /* @__PURE__ */ jsx("div", { className: " [&>svg]:!cteditor-size-6", children: /* @__PURE__ */ jsx(CodeIcon, {}) }),
23792
23977
  "Code Block"
23793
23978
  ] }),
23794
- enableFormatTextMenu && activeEditor === editor && hiddenItemIds.has("formatTextMenu") && /* @__PURE__ */ jsx(
23795
- DropdownMenuItem$1,
23796
- {
23797
- asChild: true,
23798
- onSelect: (e) => e.preventDefault(),
23799
- children: /* @__PURE__ */ jsx(
23800
- "div",
23801
- {
23802
- className: "cteditor-w-full",
23803
- onClick: (e) => e.stopPropagation(),
23804
- children: /* @__PURE__ */ jsx(FormatTextMenu, { hasFormat, blockType })
23805
- }
23806
- )
23807
- }
23808
- ),
23979
+ enableFormatTextMenu && activeEditor === editor && hiddenItemIds.has("formatTextMenu") && /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full cteditor-pt-1", children: [
23980
+ /* @__PURE__ */ jsx("div", { className: "cteditor-text-xs cteditor-font-medium cteditor-mb-1 cteditor-opacity-60 cteditor-px-2", children: "Format" }),
23981
+ /* @__PURE__ */ jsx(FormatTextMenuDrop, { hasFormat, blockType }),
23982
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "!cteditor-bg-foreground/10" })
23983
+ ] }),
23809
23984
  enableColorPicker && activeEditor === editor && hiddenItemIds.has("colorPickers") && /* @__PURE__ */ jsxs(Fragment, { children: [
23810
- /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "!cteditor-bg-foreground/10" }),
23811
- /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-px-2 cteditor-py-1.5", children: [
23985
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-px-2 cteditor-py-1.5 hover:cteditor-bg-foreground/5", children: [
23812
23986
  /* @__PURE__ */ jsx(
23813
23987
  ColorPicker$2,
23814
23988
  {
@@ -23835,7 +24009,7 @@ const Toolbar = ({
23835
24009
  ),
23836
24010
  /* @__PURE__ */ jsx("span", { className: "cteditor-flex-1 cteditor-text-xs", children: "Font Color" })
23837
24011
  ] }),
23838
- /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-px-2 cteditor-py-1.5", children: [
24012
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-px-2 cteditor-py-1.5 hover:cteditor-bg-foreground/5", children: [
23839
24013
  /* @__PURE__ */ jsx(
23840
24014
  ColorPicker$2,
23841
24015
  {
@@ -23897,7 +24071,7 @@ const Toolbar = ({
23897
24071
  )
23898
24072
  }
23899
24073
  ),
23900
- hiddenItemIds.has("highlight") && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-px-2 cteditor-py-1.5", children: [
24074
+ hiddenItemIds.has("highlight") && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-px-2 cteditor-py-1.5 hover:cteditor-bg-foreground/5", children: [
23901
24075
  /* @__PURE__ */ jsx(
23902
24076
  HighlightColorPicker,
23903
24077
  {
@@ -23910,108 +24084,119 @@ const Toolbar = ({
23910
24084
  ),
23911
24085
  /* @__PURE__ */ jsx("span", { className: "cteditor-flex-1 cteditor-text-sm", children: "Highlight" })
23912
24086
  ] }) }),
23913
- enableAlignment && activeEditor === editor && hiddenItemIds.has("alignMenu") && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full cteditor-p-2", children: [
23914
- /* @__PURE__ */ jsx("div", { className: "cteditor-text-xs cteditor-font-medium cteditor-mb-1 cteditor-opacity-60", children: "Align Menu" }),
24087
+ enableAlignment && activeEditor === editor && hiddenItemIds.has("alignMenu") && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full cteditor-pt-2", children: [
24088
+ /* @__PURE__ */ jsx("div", { className: "cteditor-text-xs cteditor-font-medium cteditor-mb-1 cteditor-opacity-60 cteditor-px-2", children: "Align Menu" }),
23915
24089
  /* @__PURE__ */ jsx(AlignMenuDrop, {})
23916
24090
  ] }) }),
23917
- hiddenItemIds.has("aiOptions") && /* @__PURE__ */ jsxs(Fragment, { children: [
23918
- /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full", children: [
23919
- /* @__PURE__ */ jsx("div", { className: "cteditor-text-xs cteditor-font-medium cteditor-mb-1 cteditor-opacity-60 cteditor-px-2 cteditor-pt-2", children: "Go with AI" }),
23920
- /* @__PURE__ */ jsxs("div", { className: "cteditor-aiOption cteditor-w-full cteditor-space-y-1 [&>button]:cteditor-relative [&>button]:cteditor-flex [&>button]:cteditor-cursor-pointer [&>button]:cteditor-select-none [&>button]:cteditor-items-center [&>button]:cteditor-gap-2 [&>button]:cteditor-rounded-sm [&>button]:cteditor-px-2 [&>button]:cteditor-py-1.5 [&>button]:cteditor-text-[13px] [&>button]:cteditor-outline-none [&>button]:cteditor-transition-colors [&>button]:focus:cteditor-bg-foreground/5 [&>button]:focus:cteditor-text-accent-foreground [&>button]:data-[disabled]:cteditor-pointer-events-none [&>button]:data-[disabled]:cteditor-opacity-50 [&>button>svg]:cteditor-size-4 [&>button>svg]:cteditor-shrink-0", children: [
23921
- /* @__PURE__ */ jsxs(
23922
- "button",
23923
- {
23924
- onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
23925
- type: "SPELLING_GRAMMAR"
23926
- }),
23927
- className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
23928
- children: [
23929
- /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(SearchTextIcon, {}) }),
23930
- "Fix Grammar"
23931
- ]
23932
- }
23933
- ),
23934
- /* @__PURE__ */ jsxs(
23935
- "button",
23936
- {
23937
- onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
23938
- type: "SIMPLIFY"
23939
- }),
23940
- className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
23941
- children: [
23942
- /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(PenLineIcon, {}) }),
23943
- "Simplify"
23944
- ]
23945
- }
23946
- ),
23947
- /* @__PURE__ */ jsxs(
23948
- "button",
23949
- {
23950
- onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
23951
- type: "COMPLETE_SENTENCE"
23952
- }),
23953
- className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
23954
- children: [
23955
- /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(MenuAltIcon, {}) }),
23956
- "Complete Sentence"
23957
- ]
23958
- }
23959
- ),
23960
- /* @__PURE__ */ jsxs(
23961
- "button",
23962
- {
23963
- onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
23964
- type: "EMOJIFY"
23965
- }),
23966
- className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
23967
- children: [
23968
- /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(FaceSmileIcon2, {}) }),
23969
- "Emojify"
23970
- ]
23971
- }
23972
- ),
23973
- /* @__PURE__ */ jsxs(
23974
- "button",
23975
- {
23976
- onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
23977
- type: "TRANSLATE"
23978
- }),
23979
- className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
23980
- children: [
23981
- /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(TranslateIcon, {}) }),
23982
- "Translate"
23983
- ]
23984
- }
23985
- ),
23986
- /* @__PURE__ */ jsxs(
23987
- "button",
23988
- {
23989
- onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
23990
- type: "AI_RESPONSE"
23991
- }),
23992
- className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
23993
- children: [
23994
- /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(SparkleIcon, {}) }),
23995
- "AI"
23996
- ]
23997
- }
23998
- ),
23999
- /* @__PURE__ */ jsxs(
24000
- "button",
24001
- {
24002
- onClick: () => editor.dispatchCommand(AI_IMAGE_COMMAND, {
24003
- type: "CREATE_IMAGE"
24004
- }),
24005
- className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
24006
- children: [
24007
- /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(ImageIcon, {}) }),
24008
- "Generate Image"
24009
- ]
24010
- }
24011
- )
24012
- ] })
24013
- ] }),
24014
- /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "!cteditor-bg-foreground/10" })
24091
+ hiddenItemIds.has("aiOptions") && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "cteditor-w-full", children: [
24092
+ /* @__PURE__ */ jsx("div", { className: "cteditor-text-xs cteditor-font-medium cteditor-mb-1 cteditor-opacity-60 cteditor-px-2 cteditor-pt-2", children: "Go with AI" }),
24093
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-aiOption cteditor-w-full [&>button]:cteditor-relative [&>button]:cteditor-flex [&>button]:cteditor-cursor-pointer [&>button]:cteditor-select-none [&>button]:cteditor-items-center [&>button]:cteditor-gap-2 [&>button]:cteditor-rounded-sm [&>button]:cteditor-px-2 [&>button]:cteditor-py-1.5 [&>button]:cteditor-text-[13px] [&>button]:cteditor-outline-none [&>button]:cteditor-transition-colors focus:[&>button]:cteditor-bg-foreground/5 focus:[&>button]:cteditor-text-accent-foreground hover:[&>button]:cteditor-bg-foreground/5 [&>button]:data-[disabled]:cteditor-pointer-events-none [&>button]:data-[disabled]:cteditor-opacity-50 [&>button>svg]:cteditor-size-4 [&>button>svg]:cteditor-shrink-0", children: [
24094
+ /* @__PURE__ */ jsxs(
24095
+ "button",
24096
+ {
24097
+ onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
24098
+ type: "SPELLING_GRAMMAR"
24099
+ }),
24100
+ className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
24101
+ children: [
24102
+ /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(SearchTextIcon, {}) }),
24103
+ "Fix Grammar"
24104
+ ]
24105
+ }
24106
+ ),
24107
+ /* @__PURE__ */ jsxs(
24108
+ "button",
24109
+ {
24110
+ onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
24111
+ type: "SIMPLIFY"
24112
+ }),
24113
+ className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
24114
+ children: [
24115
+ /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(PenLineIcon, {}) }),
24116
+ "Simplify"
24117
+ ]
24118
+ }
24119
+ ),
24120
+ /* @__PURE__ */ jsxs(
24121
+ "button",
24122
+ {
24123
+ onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
24124
+ type: "COMPLETE_SENTENCE"
24125
+ }),
24126
+ className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
24127
+ children: [
24128
+ /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(MenuAltIcon, {}) }),
24129
+ "Complete Sentence"
24130
+ ]
24131
+ }
24132
+ ),
24133
+ /* @__PURE__ */ jsxs(
24134
+ "button",
24135
+ {
24136
+ onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
24137
+ type: "EMOJIFY"
24138
+ }),
24139
+ className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
24140
+ children: [
24141
+ /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(FaceSmileIcon2, {}) }),
24142
+ "Emojify"
24143
+ ]
24144
+ }
24145
+ ),
24146
+ /* @__PURE__ */ jsxs(
24147
+ "button",
24148
+ {
24149
+ onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
24150
+ type: "TRANSLATE"
24151
+ }),
24152
+ className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
24153
+ children: [
24154
+ /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(TranslateIcon, {}) }),
24155
+ "Translate"
24156
+ ]
24157
+ }
24158
+ ),
24159
+ /* @__PURE__ */ jsxs(
24160
+ "button",
24161
+ {
24162
+ onClick: () => editor.dispatchCommand(AI_ACTION_COMMAND, {
24163
+ type: "AI_RESPONSE"
24164
+ }),
24165
+ className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
24166
+ children: [
24167
+ /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(SparkleIcon, {}) }),
24168
+ "AI"
24169
+ ]
24170
+ }
24171
+ ),
24172
+ /* @__PURE__ */ jsxs(
24173
+ "button",
24174
+ {
24175
+ onClick: () => editor.dispatchCommand(AI_IMAGE_COMMAND, {
24176
+ type: "CREATE_IMAGE"
24177
+ }),
24178
+ className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
24179
+ children: [
24180
+ /* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(ImageIcon, {}) }),
24181
+ "Generate Image"
24182
+ ]
24183
+ }
24184
+ )
24185
+ ] })
24186
+ ] }) }),
24187
+ (enableHtmlViewToggle || enableHtmlView) && hiddenItemIds.has("htmlView") && /* @__PURE__ */ jsxs(Fragment, { children: [
24188
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "!cteditor-bg-foreground/10" }),
24189
+ /* @__PURE__ */ jsxs(
24190
+ DropdownMenuItem$1,
24191
+ {
24192
+ onClick: toggleHtmlView,
24193
+ disabled: !editable,
24194
+ children: [
24195
+ /* @__PURE__ */ jsx("div", { className: "[&>svg]:!cteditor-size-4 cteditor-size-6 cteditor-flex cteditor-items-center cteditor-justify-center", children: /* @__PURE__ */ jsx(FileCode2, {}) }),
24196
+ isHtmlView ? "Switch to Editor View" : "Switch to HTML View"
24197
+ ]
24198
+ }
24199
+ )
24015
24200
  ] }),
24016
24201
  enableAutocompleteToggle && hiddenItemIds.has("autocomplete") && /* @__PURE__ */ jsxs(
24017
24202
  DropdownMenuItem$1,
@@ -24023,17 +24208,6 @@ const Toolbar = ({
24023
24208
  toolbarState.isAutocompleteEnabled ? "Disable Autocorrection" : "Enable Autocorrection"
24024
24209
  ]
24025
24210
  }
24026
- ),
24027
- (enableHtmlViewToggle || enableHtmlView) && hiddenItemIds.has("htmlView") && /* @__PURE__ */ jsxs(
24028
- DropdownMenuItem$1,
24029
- {
24030
- onClick: toggleHtmlView,
24031
- disabled: !editable,
24032
- children: [
24033
- /* @__PURE__ */ jsx("div", { className: "[&>svg]:!cteditor-size-4 cteditor-size-6 cteditor-flex cteditor-items-center cteditor-justify-center", children: /* @__PURE__ */ jsx(FileCode2, {}) }),
24034
- isHtmlView ? "Switch to Editor View" : "Switch to HTML View"
24035
- ]
24036
- }
24037
24211
  )
24038
24212
  ]
24039
24213
  }
@@ -24122,9 +24296,8 @@ function Skeleton({
24122
24296
  }
24123
24297
  );
24124
24298
  }
24125
- createCommand(
24126
- "AUTOCOMPLETE_COMMAND"
24127
- );
24299
+ const GrammarCheckPlugin = "";
24300
+ createCommand("AUTOCOMPLETE_COMMAND");
24128
24301
  const STATIC_SUGGESTIONS = [
24129
24302
  "javascript",
24130
24303
  "typescript",
@@ -24152,7 +24325,6 @@ class AIService {
24152
24325
  __publicField(this, "apiEndpoint");
24153
24326
  __publicField(this, "cache", /* @__PURE__ */ new Map());
24154
24327
  __publicField(this, "requestTimeout", 1e4);
24155
- // 10 seconds timeout for more reliable responses
24156
24328
  __publicField(this, "pendingRequests", /* @__PURE__ */ new Map());
24157
24329
  this.apiEndpoint = "https://api.cteditor.com/" + apiEndpoint;
24158
24330
  }
@@ -24174,19 +24346,9 @@ class AIService {
24174
24346
  }
24175
24347
  }
24176
24348
  async executeRequest(payload, cacheKey) {
24177
- var _a;
24178
24349
  try {
24179
24350
  const controller = new AbortController();
24180
- const timeoutId = setTimeout(
24181
- () => controller.abort(),
24182
- this.requestTimeout
24183
- );
24184
- console.log("🌐 AIService: Making request to:", this.apiEndpoint);
24185
- console.log("📦 AIService: Payload:", {
24186
- ...payload,
24187
- text: ((_a = payload.text) == null ? void 0 : _a.substring(0, 100)) + "..."
24188
- // Log only first 100 chars
24189
- });
24351
+ const timeoutId = setTimeout(() => controller.abort(), this.requestTimeout);
24190
24352
  const response = await fetch(this.apiEndpoint, {
24191
24353
  method: "POST",
24192
24354
  headers: {
@@ -24196,14 +24358,11 @@ class AIService {
24196
24358
  signal: controller.signal
24197
24359
  });
24198
24360
  clearTimeout(timeoutId);
24199
- console.log("📡 AIService: Response status:", response.status);
24200
24361
  if (!response.ok) {
24201
24362
  const errorText = await response.text();
24202
- console.error("❌ AIService: Error response:", errorText);
24203
24363
  throw new Error(`AI service error: ${response.status} - ${errorText}`);
24204
24364
  }
24205
24365
  const result = await response.json();
24206
- console.log("✅ AIService: Successful response received");
24207
24366
  this.cache.set(cacheKey, result.data);
24208
24367
  if (this.cache.size > 50) {
24209
24368
  const firstKey = this.cache.keys().next().value;
@@ -24213,15 +24372,7 @@ class AIService {
24213
24372
  }
24214
24373
  return result.data;
24215
24374
  } catch (error) {
24216
- if (error instanceof Error && error.name === "AbortError") {
24217
- console.warn(
24218
- "⏰ AIService: Request timed out after",
24219
- this.requestTimeout,
24220
- "ms"
24221
- );
24222
- } else {
24223
- console.error("❌ AIService: Request failed:", error);
24224
- }
24375
+ console.error("❌ AIService: Request failed:", error);
24225
24376
  return null;
24226
24377
  }
24227
24378
  }
@@ -24231,46 +24382,121 @@ class AIService {
24231
24382
  }
24232
24383
  const result = await this.makeRequest({
24233
24384
  text: text.trim(),
24234
- // Send the sentence/text for correction
24235
24385
  currentWord: currentWord == null ? void 0 : currentWord.trim(),
24236
- // Send current word being typed (optional)
24237
24386
  maxSuggestions
24238
24387
  });
24239
24388
  return result;
24240
24389
  }
24241
24390
  }
24242
- function AutocompletePlugin({
24243
- onQueryChange,
24244
- onSelectOption,
24245
- minMatchLength = 2,
24246
- maxSuggestions = 10,
24247
- // anchorClassName = "",
24248
- // menuClassName = "",
24249
- // itemClassName = "",
24250
- // selectedItemClassName = "",
24251
- apiEndpoint = "api/ai/process",
24252
- enableAI = true,
24253
- debounceDelay = 200
24254
- }) {
24255
- const [editor] = useLexicalComposerContext();
24256
- const { updateToolbarState } = useToolbarState();
24257
- const [queryString, setQueryString] = useState$1(null);
24258
- const [suggestions, setSuggestions] = useState$1([]);
24259
- const [selectedIndex, setSelectedIndex] = useState$1(0);
24260
- const [isLoading, setIsLoading] = useState$1(false);
24261
- const menuRef = useRef(null);
24262
- const anchorElementRef = useRef(null);
24263
- const [anchorElement, setAnchorElement] = useState$1(
24264
- null
24265
- );
24266
- const aiService = useRef(new AIService(apiEndpoint));
24267
- const debounceTimer = useRef(null);
24268
- const justSelectedOption = useRef(false);
24269
- const lastRequestTime = useRef(0);
24270
- const requestThrottle = 100;
24271
- const extractWordsFromEditor = useCallback(() => {
24272
- const words = /* @__PURE__ */ new Set();
24273
- STATIC_SUGGESTIONS.forEach((word) => words.add(word));
24391
+ class GrammarCheckService {
24392
+ constructor() {
24393
+ __publicField(this, "cache", /* @__PURE__ */ new Map());
24394
+ __publicField(this, "apiEndpoint");
24395
+ __publicField(this, "pendingRequest", null);
24396
+ this.apiEndpoint = "https://api.cteditor.com/api/ai/process";
24397
+ }
24398
+ async check(text) {
24399
+ if (!text || text.trim().length < 3) {
24400
+ return [];
24401
+ }
24402
+ const cacheKey = text.trim();
24403
+ if (this.cache.has(cacheKey)) {
24404
+ return this.cache.get(cacheKey);
24405
+ }
24406
+ if (this.pendingRequest) {
24407
+ return this.pendingRequest;
24408
+ }
24409
+ this.pendingRequest = this.executeCheck(text);
24410
+ try {
24411
+ const result = await this.pendingRequest;
24412
+ return result;
24413
+ } finally {
24414
+ this.pendingRequest = null;
24415
+ }
24416
+ }
24417
+ async executeCheck(text) {
24418
+ var _a, _b, _c, _d, _e, _f;
24419
+ try {
24420
+ const response = await fetch(this.apiEndpoint, {
24421
+ method: "POST",
24422
+ headers: { "Content-Type": "application/json" },
24423
+ body: JSON.stringify({ text: text.trim(), maxSuggestions: 3 }),
24424
+ signal: AbortSignal.timeout(1e4)
24425
+ });
24426
+ if (!response.ok) {
24427
+ console.error("❌ GrammarCheck: API error:", response.status);
24428
+ return [];
24429
+ }
24430
+ const result = await response.json();
24431
+ const foundErrors = [];
24432
+ if ((_c = (_b = (_a = result.data) == null ? void 0 : _a.corrections) == null ? void 0 : _b.spelling) == null ? void 0 : _c.errors) {
24433
+ result.data.corrections.spelling.errors.forEach((err, idx) => {
24434
+ foundErrors.push({
24435
+ type: "spelling",
24436
+ original: err.original,
24437
+ suggestions: err.suggestions || [],
24438
+ index: idx
24439
+ });
24440
+ });
24441
+ }
24442
+ if ((_f = (_e = (_d = result.data) == null ? void 0 : _d.corrections) == null ? void 0 : _e.grammar) == null ? void 0 : _f.errors) {
24443
+ result.data.corrections.grammar.errors.forEach((err, idx) => {
24444
+ foundErrors.push({
24445
+ type: "grammar",
24446
+ original: err.original || text,
24447
+ suggestions: [err.suggestion],
24448
+ index: foundErrors.length + idx,
24449
+ issue: err.issue
24450
+ });
24451
+ });
24452
+ }
24453
+ this.cache.set(text.trim(), foundErrors);
24454
+ if (this.cache.size > 30) {
24455
+ const firstKey = this.cache.keys().next().value;
24456
+ if (firstKey) {
24457
+ this.cache.delete(firstKey);
24458
+ }
24459
+ }
24460
+ return foundErrors;
24461
+ } catch (error) {
24462
+ console.error("❌ GrammarCheck: Check failed:", error);
24463
+ return [];
24464
+ }
24465
+ }
24466
+ }
24467
+ function CombinedAutocompleteGrammarPlugin({
24468
+ onQueryChange,
24469
+ onSelectOption,
24470
+ minMatchLength = 2,
24471
+ maxSuggestions = 10,
24472
+ apiEndpoint = "api/ai/process",
24473
+ enableAI = true,
24474
+ debounceDelay = 200
24475
+ }) {
24476
+ const [editor] = useLexicalComposerContext();
24477
+ const { updateToolbarState } = useToolbarState();
24478
+ const [activeTab, setActiveTab] = useState$1("autocomplete");
24479
+ const [queryString, setQueryString] = useState$1(null);
24480
+ const [suggestions, setSuggestions] = useState$1([]);
24481
+ const [selectedIndex, setSelectedIndex] = useState$1(0);
24482
+ const [isLoading, setIsLoading] = useState$1(false);
24483
+ const menuRef = useRef(null);
24484
+ const anchorElementRef = useRef(null);
24485
+ const [anchorElement, setAnchorElement] = useState$1(null);
24486
+ const aiService = useRef(new AIService(apiEndpoint));
24487
+ const debounceTimer = useRef(null);
24488
+ const justSelectedOption = useRef(false);
24489
+ const lastRequestTime = useRef(0);
24490
+ const requestThrottle = 100;
24491
+ const [errors, setErrors] = useState$1([]);
24492
+ const [userDismissed, setUserDismissed] = useState$1(false);
24493
+ const grammarService = useRef(new GrammarCheckService());
24494
+ const checkTimeout = useRef();
24495
+ const lastCheckedText = useRef("");
24496
+ const highlightElementsRef = useRef([]);
24497
+ const extractWordsFromEditor = useCallback(() => {
24498
+ const words = /* @__PURE__ */ new Set();
24499
+ STATIC_SUGGESTIONS.forEach((word) => words.add(word));
24274
24500
  editor.getEditorState().read(() => {
24275
24501
  const root2 = $getRoot();
24276
24502
  const textContent = root2.getTextContent();
@@ -24292,17 +24518,12 @@ function AutocompletePlugin({
24292
24518
  return [];
24293
24519
  }
24294
24520
  if (justSelectedOption.current) {
24295
- console.log(
24296
- "🚫 AutocompletePlugin: Skipping AI request - just selected option"
24297
- );
24298
24521
  return [];
24299
24522
  }
24300
24523
  const now2 = Date.now();
24301
24524
  if (now2 - lastRequestTime.current < requestThrottle) {
24302
- console.log("🚫 AutocompletePlugin: Throttling AI request");
24303
24525
  return [];
24304
24526
  }
24305
- console.log("🤖 AutocompletePlugin: Getting AI suggestions for:", query);
24306
24527
  setIsLoading(true);
24307
24528
  lastRequestTime.current = now2;
24308
24529
  let lastSentence = "";
@@ -24341,11 +24562,8 @@ function AutocompletePlugin({
24341
24562
  try {
24342
24563
  const result = await aiService.current.getIntelligentSuggestions(
24343
24564
  query,
24344
- // currentWord
24345
24565
  lastSentence,
24346
- // text (the sentence to correct)
24347
24566
  maxSuggestions
24348
- // maxSuggestions
24349
24567
  );
24350
24568
  const aiOptions = [];
24351
24569
  if (result) {
@@ -24418,10 +24636,6 @@ function AutocompletePlugin({
24418
24636
  });
24419
24637
  }
24420
24638
  }
24421
- console.log(
24422
- "✅ AutocompletePlugin: AI sentence corrections received:",
24423
- aiOptions
24424
- );
24425
24639
  return aiOptions.slice(0, Math.floor(maxSuggestions * 0.8));
24426
24640
  } catch (error) {
24427
24641
  console.error("❌ AutocompletePlugin: AI suggestions failed:", error);
@@ -24430,7 +24644,7 @@ function AutocompletePlugin({
24430
24644
  setIsLoading(false);
24431
24645
  }
24432
24646
  },
24433
- [enableAI, minMatchLength, maxSuggestions]
24647
+ [enableAI, minMatchLength, maxSuggestions, editor]
24434
24648
  );
24435
24649
  const getTraditionalSuggestions = useCallback(
24436
24650
  (query) => {
@@ -24487,7 +24701,6 @@ function AutocompletePlugin({
24487
24701
  }, 100);
24488
24702
  return;
24489
24703
  }
24490
- console.log("🎯 AutocompletePlugin: Checking for autocomplete trigger");
24491
24704
  editor.update(() => {
24492
24705
  const selection = $getSelection();
24493
24706
  if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
@@ -24520,18 +24733,10 @@ function AutocompletePlugin({
24520
24733
  }
24521
24734
  if (queryString && !justSelectedOption.current) {
24522
24735
  debounceTimer.current = setTimeout(async () => {
24523
- console.log(
24524
- "🔄 AutocompletePlugin: Getting suggestions for:",
24525
- queryString
24526
- );
24527
24736
  const newSuggestions = await getCombinedSuggestions(queryString);
24528
24737
  setSuggestions(newSuggestions);
24529
24738
  setSelectedIndex(0);
24530
24739
  onQueryChange == null ? void 0 : onQueryChange(queryString);
24531
- console.log(
24532
- "🎯 AutocompletePlugin: Updated suggestions:",
24533
- newSuggestions
24534
- );
24535
24740
  }, debounceDelay);
24536
24741
  } else {
24537
24742
  setSuggestions([]);
@@ -24546,7 +24751,6 @@ function AutocompletePlugin({
24546
24751
  }, [queryString, getCombinedSuggestions, onQueryChange, debounceDelay]);
24547
24752
  const selectOption = useCallback(
24548
24753
  (option) => {
24549
- console.log("✅ AutocompletePlugin: Selecting option:", option);
24550
24754
  justSelectedOption.current = true;
24551
24755
  editor.update(() => {
24552
24756
  const selection = $getSelection();
@@ -24584,9 +24788,6 @@ function AutocompletePlugin({
24584
24788
  const newOffset = sentenceStart + option.displayText.length;
24585
24789
  selection.anchor.set(textNode.getKey(), newOffset, "text");
24586
24790
  selection.focus.set(textNode.getKey(), newOffset, "text");
24587
- console.log(
24588
- "✅ AutocompletePlugin: Sentence replaced successfully"
24589
- );
24590
24791
  }
24591
24792
  } else {
24592
24793
  let wordStart = anchorOffset;
@@ -24600,7 +24801,6 @@ function AutocompletePlugin({
24600
24801
  const newOffset = wordStart + option.displayText.length;
24601
24802
  selection.anchor.set(textNode.getKey(), newOffset, "text");
24602
24803
  selection.focus.set(textNode.getKey(), newOffset, "text");
24603
- console.log("✅ AutocompletePlugin: Word replaced successfully");
24604
24804
  }
24605
24805
  }
24606
24806
  });
@@ -24704,6 +24904,136 @@ function AutocompletePlugin({
24704
24904
  inputListener();
24705
24905
  };
24706
24906
  }, [editor, checkForAutocompleteTrigger]);
24907
+ const checkGrammar = useCallback(async () => {
24908
+ const isSlashActive = editor.getEditorState().read(() => {
24909
+ const selection = $getSelection();
24910
+ if (!$isRangeSelection(selection))
24911
+ return false;
24912
+ const anchor = selection.anchor;
24913
+ const anchorNode = anchor.getNode();
24914
+ const anchorOffset = anchor.offset;
24915
+ const textContent = anchorNode.getTextContent();
24916
+ let wordStart = anchorOffset;
24917
+ while (wordStart > 0 && /[a-zA-Z0-9_']/.test(textContent[wordStart - 1])) {
24918
+ wordStart--;
24919
+ }
24920
+ return wordStart > 0 && textContent[wordStart - 1] === "/";
24921
+ });
24922
+ if (isSlashActive) {
24923
+ setErrors([]);
24924
+ return;
24925
+ }
24926
+ const text = editor.getEditorState().read(() => $getRoot().getTextContent());
24927
+ if (text === lastCheckedText.current) {
24928
+ return;
24929
+ }
24930
+ if (Math.abs(text.length - lastCheckedText.current.length) > 20) {
24931
+ setUserDismissed(false);
24932
+ }
24933
+ lastCheckedText.current = text;
24934
+ if (!text || text.trim().length < 3) {
24935
+ setErrors([]);
24936
+ return;
24937
+ }
24938
+ const foundErrors = await grammarService.current.check(text);
24939
+ setErrors(foundErrors);
24940
+ }, [editor]);
24941
+ useEffect$1(() => {
24942
+ const unregister = editor.registerUpdateListener(() => {
24943
+ clearTimeout(checkTimeout.current);
24944
+ checkTimeout.current = window.setTimeout(checkGrammar, 2e3);
24945
+ });
24946
+ return () => {
24947
+ unregister();
24948
+ clearTimeout(checkTimeout.current);
24949
+ };
24950
+ }, [editor, checkGrammar]);
24951
+ useEffect$1(() => {
24952
+ highlightElementsRef.current.forEach((el) => {
24953
+ el.classList.remove("spelling-error", "grammar-error");
24954
+ });
24955
+ highlightElementsRef.current = [];
24956
+ if (errors.length === 0 || userDismissed)
24957
+ return;
24958
+ const timeoutId = setTimeout(() => {
24959
+ const editorElement = document.querySelector(".ContentEditable__root");
24960
+ if (!editorElement)
24961
+ return;
24962
+ const walker = document.createTreeWalker(
24963
+ editorElement,
24964
+ NodeFilter.SHOW_TEXT,
24965
+ null
24966
+ );
24967
+ const textNodes = [];
24968
+ let node;
24969
+ while (node = walker.nextNode()) {
24970
+ textNodes.push(node);
24971
+ }
24972
+ errors.forEach((error) => {
24973
+ textNodes.forEach((textNode) => {
24974
+ const nodeText = textNode.textContent || "";
24975
+ const errorIndex = nodeText.toLowerCase().indexOf(error.original.toLowerCase());
24976
+ if (errorIndex !== -1 && textNode.parentElement) {
24977
+ const className = error.type === "spelling" ? "spelling-error" : "grammar-error";
24978
+ if (textNode.parentElement.tagName === "SPAN") {
24979
+ textNode.parentElement.classList.add(className);
24980
+ highlightElementsRef.current.push(textNode.parentElement);
24981
+ } else if (textNode.parentElement) {
24982
+ const range = document.createRange();
24983
+ range.setStart(textNode, errorIndex);
24984
+ range.setEnd(textNode, Math.min(errorIndex + error.original.length, nodeText.length));
24985
+ const span = document.createElement("span");
24986
+ span.className = className;
24987
+ span.setAttribute("data-error-type", error.type);
24988
+ try {
24989
+ range.surroundContents(span);
24990
+ highlightElementsRef.current.push(span);
24991
+ } catch (e) {
24992
+ if (textNode.parentElement) {
24993
+ textNode.parentElement.classList.add(className);
24994
+ highlightElementsRef.current.push(textNode.parentElement);
24995
+ }
24996
+ }
24997
+ }
24998
+ }
24999
+ });
25000
+ });
25001
+ }, 100);
25002
+ return () => clearTimeout(timeoutId);
25003
+ }, [errors, userDismissed]);
25004
+ const applyCorrection = useCallback(
25005
+ (suggestion, original, errorType) => {
25006
+ editor.update(() => {
25007
+ const root2 = $getRoot();
25008
+ const currentText = root2.getTextContent();
25009
+ const isSpellingError = errorType === "spelling";
25010
+ let newText = currentText;
25011
+ if (isSpellingError) {
25012
+ const escapedOriginal = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
25013
+ const regex = new RegExp(`\\b${escapedOriginal}\\b`, "gi");
25014
+ newText = currentText.replace(regex, suggestion);
25015
+ } else {
25016
+ const escapedOriginal = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
25017
+ const regex = new RegExp(escapedOriginal, "gi");
25018
+ if (currentText.toLowerCase().includes(original.toLowerCase())) {
25019
+ newText = currentText.replace(regex, suggestion);
25020
+ } else {
25021
+ newText = suggestion;
25022
+ }
25023
+ }
25024
+ root2.clear();
25025
+ const paragraph = $createParagraphNode();
25026
+ const textNode = $createTextNode(newText);
25027
+ paragraph.append(textNode);
25028
+ root2.append(paragraph);
25029
+ });
25030
+ setTimeout(() => {
25031
+ lastCheckedText.current = "";
25032
+ checkGrammar();
25033
+ }, 100);
25034
+ },
25035
+ [editor, checkGrammar]
25036
+ );
24707
25037
  const calculateMenuPosition = useCallback(() => {
24708
25038
  if (!anchorElement)
24709
25039
  return { top: 0, left: 0 };
@@ -24736,10 +25066,7 @@ function AutocompletePlugin({
24736
25066
  try {
24737
25067
  document.body.removeChild(anchorElementRef.current);
24738
25068
  } catch (error) {
24739
- console.warn(
24740
- "🚨 AutocompletePlugin: Error removing existing anchor:",
24741
- error
24742
- );
25069
+ console.warn("Error removing existing anchor:", error);
24743
25070
  }
24744
25071
  }
24745
25072
  document.body.appendChild(anchor);
@@ -24750,7 +25077,7 @@ function AutocompletePlugin({
24750
25077
  try {
24751
25078
  document.body.removeChild(anchorElementRef.current);
24752
25079
  } catch (error) {
24753
- console.warn("🚨 AutocompletePlugin: Error during cleanup:", error);
25080
+ console.warn("Error during cleanup:", error);
24754
25081
  }
24755
25082
  }
24756
25083
  };
@@ -24779,76 +25106,171 @@ function AutocompletePlugin({
24779
25106
  return "outline";
24780
25107
  }
24781
25108
  };
24782
- if (!anchorElement || !queryString || suggestions.length === 0 && !isLoading) {
25109
+ useEffect$1(() => {
25110
+ const showAutocomplete2 = queryString && (suggestions.length > 0 || isLoading);
25111
+ const showGrammar2 = errors.length > 0 && !userDismissed;
25112
+ if (showAutocomplete2 && !showGrammar2) {
25113
+ setActiveTab("autocomplete");
25114
+ } else if (showGrammar2 && !showAutocomplete2) {
25115
+ setActiveTab("grammar");
25116
+ }
25117
+ }, [queryString, suggestions.length, isLoading, errors.length, userDismissed]);
25118
+ const showAutocomplete = queryString && (suggestions.length > 0 || isLoading);
25119
+ const showGrammar = errors.length > 0 && !userDismissed;
25120
+ if (!anchorElement || !showAutocomplete && !showGrammar) {
24783
25121
  return null;
24784
25122
  }
24785
25123
  return createPortal(
24786
- /* @__PURE__ */ jsx(
25124
+ /* @__PURE__ */ jsxs(
24787
25125
  Card,
24788
25126
  {
24789
25127
  ref: menuRef,
24790
- className: "cteditor-w-80 cteditor-max-h-64 cteditor-overflow-y-auto cteditor-shadow-lg cteditor-border cteditor-bg-background cteditor-rounded-md",
24791
- children: /* @__PURE__ */ jsxs(CardContent, { className: "cteditor-p-2", children: [
24792
- isLoading && /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-p-3 cteditor-text-sm cteditor-text-muted-foreground", children: [
24793
- /* @__PURE__ */ jsx(Skeleton, { className: "cteditor-h-4 cteditor-w-4 cteditor-rounded-full" }),
24794
- /* @__PURE__ */ jsx("span", { children: "Getting AI suggestions..." })
24795
- ] }),
24796
- /* @__PURE__ */ jsx("div", { className: "cteditor-space-y-1", children: suggestions.map((option, index2) => /* @__PURE__ */ jsxs(
24797
- "div",
24798
- {
24799
- className: cn$1(
24800
- "cteditor-flex cteditor-items-start cteditor-gap-3 cteditor-p-3 cteditor-rounded-md cteditor-cursor-pointer cteditor-transition-colors cteditor-text-sm",
24801
- index2 === selectedIndex ? "cteditor-bg-foreground/5" : "hover:cteditor-bg-red"
24802
- ),
24803
- onClick: () => selectOption(option),
24804
- onMouseEnter: () => setSelectedIndex(index2),
24805
- children: [
24806
- /* @__PURE__ */ jsx(
24807
- "div",
24808
- {
24809
- className: cn$1(
24810
- "cteditor-mt-0.5",
24811
- index2 === selectedIndex ? "cteditor-text-primary" : "cteditor-text-primary"
24812
- ),
24813
- children: getSuggestionIcon(option.type)
24814
- }
25128
+ className: "sm:cteditor-w-[28rem] sm:cteditor-max-w-md cteditor-w-[20rem] cteditor-max-w-xs cteditor-max-h-64 cteditor-overflow-hidden cteditor-shadow-lg cteditor-border cteditor-bg-background cteditor-rounded-md",
25129
+ children: [
25130
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-border-b cteditor-bg-muted/30", children: [
25131
+ /* @__PURE__ */ jsxs(
25132
+ "button",
25133
+ {
25134
+ onClick: () => setActiveTab("autocomplete"),
25135
+ className: cn$1(
25136
+ "cteditor-flex-1 cteditor-px-4 cteditor-py-2 cteditor-text-sm cteditor-font-medium cteditor-transition-colors",
25137
+ activeTab === "autocomplete" ? "cteditor-bg-background cteditor-text-foreground cteditor-border-b-2 cteditor-border-primary" : "cteditor-text-muted-foreground hover:cteditor-text-foreground"
25138
+ ),
25139
+ children: [
25140
+ /* @__PURE__ */ jsx(Sparkles, { className: "cteditor-inline cteditor-size-4 cteditor-mr-2" }),
25141
+ "Autocomplete"
25142
+ ]
25143
+ }
25144
+ ),
25145
+ /* @__PURE__ */ jsxs(
25146
+ "button",
25147
+ {
25148
+ onClick: () => setActiveTab("grammar"),
25149
+ className: cn$1(
25150
+ "cteditor-flex-1 cteditor-px-4 cteditor-py-2 cteditor-text-sm cteditor-font-medium cteditor-transition-colors",
25151
+ activeTab === "grammar" ? "cteditor-bg-background cteditor-text-foreground cteditor-border-b-2 cteditor-border-primary" : "cteditor-text-muted-foreground hover:cteditor-text-foreground"
24815
25152
  ),
24816
- /* @__PURE__ */ jsxs("div", { className: "cteditor-flex-1 cteditor-min-w-0", children: [
24817
- /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-mb-2", children: [
25153
+ children: [
25154
+ /* @__PURE__ */ jsx(CheckCircle, { className: "cteditor-inline cteditor-size-4 cteditor-mr-2" }),
25155
+ "Grammar & Spelling",
25156
+ errors.length > 0 && /* @__PURE__ */ jsx(Badge, { variant: "destructive", className: "cteditor-ml-2 cteditor-text-xs", children: errors.length })
25157
+ ]
25158
+ }
25159
+ )
25160
+ ] }),
25161
+ /* @__PURE__ */ jsxs(CardContent, { className: "cteditor-p-2 cteditor-max-h-56 cteditor-overflow-y-auto", children: [
25162
+ activeTab === "autocomplete" && /* @__PURE__ */ jsxs(Fragment, { children: [
25163
+ isLoading && /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-p-3 cteditor-text-sm cteditor-text-muted-foreground", children: [
25164
+ /* @__PURE__ */ jsx(Skeleton, { className: "cteditor-h-4 cteditor-w-4 cteditor-rounded-full" }),
25165
+ /* @__PURE__ */ jsx("span", { children: "Getting AI suggestions..." })
25166
+ ] }),
25167
+ /* @__PURE__ */ jsx("div", { className: "cteditor-space-y-1", children: suggestions.map((option, index2) => /* @__PURE__ */ jsxs(
25168
+ "div",
25169
+ {
25170
+ className: cn$1(
25171
+ "cteditor-flex cteditor-items-start cteditor-gap-3 cteditor-p-3 cteditor-rounded-md cteditor-cursor-pointer cteditor-transition-colors cteditor-text-sm",
25172
+ index2 === selectedIndex ? "cteditor-bg-foreground/5" : "hover:cteditor-bg-muted/50"
25173
+ ),
25174
+ onClick: () => selectOption(option),
25175
+ onMouseEnter: () => setSelectedIndex(index2),
25176
+ children: [
24818
25177
  /* @__PURE__ */ jsx(
24819
- Badge,
25178
+ "div",
24820
25179
  {
24821
- variant: index2 === selectedIndex ? "secondary" : getSuggestionVariant(option.type),
24822
- className: "cteditor-text-xs cteditor-border cteditor-border-foreground/20 cteditor-rounded-2xl !cteditor-font-normal ",
24823
- children: option.type
25180
+ className: cn$1(
25181
+ "cteditor-mt-0.5",
25182
+ index2 === selectedIndex ? "cteditor-text-primary" : "cteditor-text-primary"
25183
+ ),
25184
+ children: getSuggestionIcon(option.type)
24824
25185
  }
24825
25186
  ),
24826
- option.confidence && /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-px-2 cteditor-py-0.5 cteditor-rounded-md cteditor-bg-muted/50 cteditor-text-foreground", children: option.confidence })
24827
- ] }),
24828
- /* @__PURE__ */ jsx("p", { className: "cteditor-leading-relaxed cteditor-break-words", children: option.displayText })
24829
- ] })
24830
- ]
24831
- },
24832
- option.key
24833
- )) }),
24834
- /* @__PURE__ */ jsx("div", { className: "cteditor-mt-1 cteditor-pt-1 cteditor-border-t cteditor-sticky cteditor-bottom-0 cteditor-bg-background", children: /* @__PURE__ */ jsxs(
24835
- Button,
24836
- {
24837
- variant: "ghost",
24838
- size: "sm",
24839
- className: "cteditor-w-full cteditor-justify-start cteditor-gap-2 cteditor-text-muted-foreground hover:cteditor-text-foreground",
24840
- onClick: () => {
24841
- setQueryString(null);
24842
- setSuggestions([]);
24843
- updateToolbarState("isAutocompleteEnabled", false);
24844
- },
24845
- children: [
24846
- /* @__PURE__ */ jsx(Ban, { className: "!cteditor-size-3" }),
24847
- "Disable Autocorrection"
24848
- ]
24849
- }
24850
- ) })
24851
- ] })
25187
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-flex-1 cteditor-min-w-0", children: [
25188
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-mb-2", children: [
25189
+ /* @__PURE__ */ jsx(
25190
+ Badge,
25191
+ {
25192
+ variant: index2 === selectedIndex ? "secondary" : getSuggestionVariant(option.type),
25193
+ className: "cteditor-text-xs cteditor-border cteditor-border-foreground/20 cteditor-rounded-2xl !cteditor-font-normal",
25194
+ children: option.type
25195
+ }
25196
+ ),
25197
+ option.confidence && /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-px-2 cteditor-py-0.5 cteditor-rounded-md cteditor-bg-muted/50 cteditor-text-foreground", children: option.confidence })
25198
+ ] }),
25199
+ /* @__PURE__ */ jsx("p", { className: "cteditor-leading-relaxed cteditor-break-words", children: option.displayText })
25200
+ ] })
25201
+ ]
25202
+ },
25203
+ option.key
25204
+ )) }),
25205
+ /* @__PURE__ */ jsx("div", { className: "cteditor-mt-1 cteditor-pt-1 cteditor-border-t cteditor-sticky cteditor-bottom-0 cteditor-bg-background", children: /* @__PURE__ */ jsxs(
25206
+ Button,
25207
+ {
25208
+ variant: "ghost",
25209
+ size: "sm",
25210
+ className: "cteditor-w-full cteditor-justify-start cteditor-gap-2 cteditor-text-muted-foreground hover:cteditor-text-foreground",
25211
+ onClick: () => {
25212
+ setQueryString(null);
25213
+ setSuggestions([]);
25214
+ updateToolbarState("isAutocompleteEnabled", false);
25215
+ },
25216
+ children: [
25217
+ /* @__PURE__ */ jsx(Ban, { className: "!cteditor-size-3" }),
25218
+ "Disable Autocomplete & Grammar Check"
25219
+ ]
25220
+ }
25221
+ ) })
25222
+ ] }),
25223
+ activeTab === "grammar" && /* @__PURE__ */ jsxs(Fragment, { children: [
25224
+ /* @__PURE__ */ jsx("div", { className: "cteditor-space-y-2 cteditor-p-2", children: errors.map((error, idx) => /* @__PURE__ */ jsx(
25225
+ "div",
25226
+ {
25227
+ className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-p-3 cteditor-rounded-md cteditor-bg-muted/50 cteditor-border",
25228
+ children: /* @__PURE__ */ jsxs("div", { className: "cteditor-flex-1", children: [
25229
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-mb-1", children: [
25230
+ /* @__PURE__ */ jsx(
25231
+ Badge,
25232
+ {
25233
+ variant: error.type === "spelling" ? "destructive" : "default",
25234
+ className: "cteditor-text-xs",
25235
+ children: error.type
25236
+ }
25237
+ ),
25238
+ error.confidence && /* @__PURE__ */ jsx("span", { className: "cteditor-text-xs cteditor-text-muted-foreground", children: error.confidence })
25239
+ ] }),
25240
+ /* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-line-through cteditor-text-red-600 cteditor-mb-1", children: error.original }),
25241
+ error.suggestions.length > 0 && /* @__PURE__ */ jsx("div", { className: "cteditor-space-y-1", children: error.suggestions.slice(0, 2).map((suggestion, sIdx) => /* @__PURE__ */ jsx(
25242
+ "button",
25243
+ {
25244
+ onClick: () => applyCorrection(suggestion, error.original, error.type),
25245
+ className: "cteditor-block cteditor-w-full cteditor-text-left cteditor-text-sm cteditor-text-green-600 hover:cteditor-text-green-700 cteditor-px-2 cteditor-py-1 cteditor-rounded cteditor-bg-green-50 hover:cteditor-bg-green-100",
25246
+ children: suggestion
25247
+ },
25248
+ sIdx
25249
+ )) })
25250
+ ] })
25251
+ },
25252
+ idx
25253
+ )) }),
25254
+ /* @__PURE__ */ jsx("div", { className: "cteditor-mt-1 cteditor-pt-1 cteditor-border-t cteditor-sticky cteditor-bottom-0 cteditor-bg-background", children: /* @__PURE__ */ jsxs(
25255
+ Button,
25256
+ {
25257
+ variant: "ghost",
25258
+ size: "sm",
25259
+ className: "cteditor-w-full cteditor-justify-start cteditor-gap-2 cteditor-text-muted-foreground hover:cteditor-text-foreground",
25260
+ onClick: () => {
25261
+ setUserDismissed(true);
25262
+ setErrors([]);
25263
+ updateToolbarState("isGrammarCheckEnabled", false);
25264
+ },
25265
+ children: [
25266
+ /* @__PURE__ */ jsx(Ban, { className: "!cteditor-size-3" }),
25267
+ "Disable Autocomplete & Grammar Check"
25268
+ ]
25269
+ }
25270
+ ) })
25271
+ ] })
25272
+ ] })
25273
+ ]
24852
25274
  }
24853
25275
  ),
24854
25276
  anchorElement
@@ -25048,6 +25470,174 @@ const CommentBubblePlugin = () => {
25048
25470
  }, [editor, getCommentById]);
25049
25471
  return null;
25050
25472
  };
25473
+ const ACCEPTABLE_IMAGE_TYPES = [
25474
+ "image/",
25475
+ "image/heic",
25476
+ "image/heif",
25477
+ "image/gif",
25478
+ "image/webp",
25479
+ "image/png",
25480
+ "image/jpg",
25481
+ "image/jpeg",
25482
+ "image/svg+xml"
25483
+ ];
25484
+ const ACCEPTABLE_APPLICATION_TYPES = [
25485
+ "application/pdf",
25486
+ "application/msword",
25487
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
25488
+ ];
25489
+ const fileToDataURL = (file) => {
25490
+ return new Promise((resolve, reject) => {
25491
+ const reader = new FileReader();
25492
+ reader.onload = () => resolve(reader.result);
25493
+ reader.onerror = reject;
25494
+ reader.readAsDataURL(file);
25495
+ });
25496
+ };
25497
+ function DragDropPaste() {
25498
+ const [editor] = useLexicalComposerContext();
25499
+ const [isDragging, setIsDragging] = useState$1(false);
25500
+ const apiKey = void 0;
25501
+ const { uploadFileToS3 } = useS3Uploader(apiKey);
25502
+ useEffect$1(() => {
25503
+ const handleDragEnter = (e) => {
25504
+ var _a, _b;
25505
+ e.preventDefault();
25506
+ e.stopPropagation();
25507
+ const hasFiles = (_a = e.dataTransfer) == null ? void 0 : _a.types.includes("Files");
25508
+ const hasImages = (_b = e.dataTransfer) == null ? void 0 : _b.types.some(
25509
+ (type) => type === "text/html" || type === "text/uri-list"
25510
+ );
25511
+ if (hasFiles || hasImages) {
25512
+ setIsDragging(true);
25513
+ const editorEl = editor.getRootElement();
25514
+ if (editorEl) {
25515
+ editorEl.style.backgroundColor = "rgba(59, 130, 246, 0.05)";
25516
+ editorEl.style.border = "2px dashed rgb(59, 130, 246)";
25517
+ editorEl.style.borderRadius = "8px";
25518
+ }
25519
+ }
25520
+ };
25521
+ const handleDragOver = (e) => {
25522
+ e.preventDefault();
25523
+ e.stopPropagation();
25524
+ if (e.dataTransfer) {
25525
+ e.dataTransfer.dropEffect = "copy";
25526
+ }
25527
+ };
25528
+ const handleDragLeave = (e) => {
25529
+ e.preventDefault();
25530
+ e.stopPropagation();
25531
+ const editorEl = editor.getRootElement();
25532
+ if (e.relatedTarget === null || editorEl && !editorEl.contains(e.relatedTarget)) {
25533
+ setIsDragging(false);
25534
+ if (editorEl) {
25535
+ editorEl.style.backgroundColor = "";
25536
+ editorEl.style.border = "";
25537
+ editorEl.style.borderRadius = "";
25538
+ }
25539
+ }
25540
+ };
25541
+ const handleDrop = (e) => {
25542
+ var _a, _b, _c;
25543
+ e.preventDefault();
25544
+ e.stopPropagation();
25545
+ setIsDragging(false);
25546
+ const editorEl = editor.getRootElement();
25547
+ if (editorEl) {
25548
+ editorEl.style.backgroundColor = "";
25549
+ editorEl.style.border = "";
25550
+ editorEl.style.borderRadius = "";
25551
+ }
25552
+ const files = (_a = e.dataTransfer) == null ? void 0 : _a.files;
25553
+ if (files && files.length > 0) {
25554
+ console.log("File drop detected, letting DRAG_DROP_PASTE command handle it");
25555
+ return;
25556
+ }
25557
+ const html = (_b = e.dataTransfer) == null ? void 0 : _b.getData("text/html");
25558
+ if (html) {
25559
+ const tempDiv = document.createElement("div");
25560
+ tempDiv.innerHTML = html;
25561
+ const img = tempDiv.querySelector("img");
25562
+ if (img && img.src) {
25563
+ editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
25564
+ altText: img.alt || "Dragged image",
25565
+ src: img.src
25566
+ });
25567
+ console.log("Image from web browser inserted:", img.src);
25568
+ return;
25569
+ }
25570
+ }
25571
+ const uriList = (_c = e.dataTransfer) == null ? void 0 : _c.getData("text/uri-list");
25572
+ if (uriList) {
25573
+ const urls = uriList.split("\n").filter((url) => url.trim().length > 0);
25574
+ urls.forEach((url) => {
25575
+ if (/\.(jpg|jpeg|png|gif|webp|svg)$/i.test(url)) {
25576
+ editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
25577
+ altText: "Dragged image",
25578
+ src: url.trim()
25579
+ });
25580
+ console.log("Image from URL inserted:", url);
25581
+ }
25582
+ });
25583
+ }
25584
+ };
25585
+ const editorElement = editor.getRootElement();
25586
+ if (editorElement) {
25587
+ editorElement.addEventListener("dragenter", handleDragEnter);
25588
+ editorElement.addEventListener("dragover", handleDragOver);
25589
+ editorElement.addEventListener("dragleave", handleDragLeave);
25590
+ editorElement.addEventListener("drop", handleDrop);
25591
+ return () => {
25592
+ editorElement.removeEventListener("dragenter", handleDragEnter);
25593
+ editorElement.removeEventListener("dragover", handleDragOver);
25594
+ editorElement.removeEventListener("dragleave", handleDragLeave);
25595
+ editorElement.removeEventListener("drop", handleDrop);
25596
+ };
25597
+ }
25598
+ }, [editor]);
25599
+ useEffect$1(() => {
25600
+ return editor.registerCommand(
25601
+ DRAG_DROP_PASTE,
25602
+ (files) => {
25603
+ (async () => {
25604
+ const filesResult = await mediaFileReader(files, [
25605
+ ...ACCEPTABLE_IMAGE_TYPES,
25606
+ ...ACCEPTABLE_APPLICATION_TYPES
25607
+ ]);
25608
+ for (const { file, result } of filesResult) {
25609
+ let fileUrl;
25610
+ try {
25611
+ if (apiKey)
25612
+ ;
25613
+ else {
25614
+ fileUrl = await fileToDataURL(file);
25615
+ console.log("Using local data URL (no S3 upload)");
25616
+ }
25617
+ } catch (error) {
25618
+ console.error("Upload failed, using local data URL:", error);
25619
+ fileUrl = await fileToDataURL(file);
25620
+ }
25621
+ if (isMimeType(file, ACCEPTABLE_IMAGE_TYPES)) {
25622
+ editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
25623
+ altText: file.name,
25624
+ src: fileUrl
25625
+ });
25626
+ } else if (isMimeType(file, ACCEPTABLE_APPLICATION_TYPES)) {
25627
+ editor.dispatchCommand(INSERT_FILE_COMMAND, {
25628
+ linkText: file.name || "Download File",
25629
+ src: fileUrl
25630
+ });
25631
+ }
25632
+ }
25633
+ })();
25634
+ return true;
25635
+ },
25636
+ COMMAND_PRIORITY_LOW
25637
+ );
25638
+ }, [editor, apiKey, uploadFileToS3]);
25639
+ return null;
25640
+ }
25051
25641
  const FloatingEmbedMenuPlugin$1 = "";
25052
25642
  function FloatingEmbedMenu({
25053
25643
  editor,
@@ -25815,19 +26405,15 @@ function FloatingLinkEditor({
25815
26405
  "div",
25816
26406
  {
25817
26407
  ref: editorRef,
25818
- className: "link-editor cteditor-bg-background cteditor-border cteditor-border-border cteditor-rounded-xl cteditor-shadow-2xl cteditor-overflow-hidden cteditor-backdrop-blur-sm",
25819
- style: {
25820
- background: "linear-gradient(135deg, hsl(var(--cteditor-background)) 0%, hsl(var(--cteditor-accent) / 0.05) 100%)",
25821
- minWidth: "200px"
25822
- },
26408
+ className: "link-editor cteditor-border cteditor-border-background/20 cteditor-rounded-md cteditor-shadow-2xl cteditor-overflow-hidden cteditor-backdrop-blur-sm",
25823
26409
  children: shouldShowEditMode ? (
25824
26410
  // EDIT MODE - Input to edit URL
25825
- /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-p-3", children: [
26411
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-p-1 cteditor-w-full", children: [
25826
26412
  /* @__PURE__ */ jsx("div", { className: "cteditor-flex-1", children: /* @__PURE__ */ jsx(
25827
26413
  "input",
25828
26414
  {
25829
26415
  ref: inputRef,
25830
- className: "link-input cteditor-w-full cteditor-px-4 cteditor-py-2.5 cteditor-text-sm cteditor-border cteditor-border-border/50 cteditor-rounded-lg cteditor-bg-background focus:cteditor-bg-background focus:cteditor-outline-none focus:cteditor-ring-2 focus:cteditor-ring-primary/50 focus:cteditor-border-primary cteditor-transition-all cteditor-duration-200 placeholder:cteditor-text-muted-foreground cteditor-font-medium",
26416
+ className: "link-input cteditor-w-full cteditor-px-4 cteditor-py-2.5 cteditor-text-sm cteditor-border cteditor-border-background/20 cteditor-rounded-md cteditor-bg-transparent cteditor-transition-all cteditor-duration-200 cteditor-text-background placeholder:cteditor-text-background cteditor-font-medium cteditor-outline-background/30",
25831
26417
  value: editedLinkUrl,
25832
26418
  placeholder: "Enter URL (e.g., https://example.com)",
25833
26419
  onChange: (event) => setEditedLinkUrl(event.target.value),
@@ -25846,7 +26432,7 @@ function FloatingLinkEditor({
25846
26432
  /* @__PURE__ */ jsx(
25847
26433
  "button",
25848
26434
  {
25849
- className: "cteditor-p-2.5 cteditor-rounded-lg cteditor-bg-primary cteditor-text-primary-foreground hover:cteditor-bg-primary/90 cteditor-transition-all cteditor-duration-200 hover:cteditor-scale-105 active:cteditor-scale-95 cteditor-shadow-md hover:cteditor-shadow-lg",
26435
+ className: "cteditor-p-2.5 cteditor-rounded-lg cteditor-bg-background hover:cteditor-bg-background/80 cteditor-text-foreground hover:cteditor-text-foreground cteditor-transition-all cteditor-duration-200 hover:cteditor-scale-105 active:cteditor-scale-95",
25850
26436
  onClick: handleLinkSubmission,
25851
26437
  title: "Save link",
25852
26438
  children: /* @__PURE__ */ jsx(Check, { className: "cteditor-size-4" })
@@ -25855,7 +26441,7 @@ function FloatingLinkEditor({
25855
26441
  /* @__PURE__ */ jsx(
25856
26442
  "button",
25857
26443
  {
25858
- className: "cteditor-p-2.5 cteditor-rounded-lg cteditor-bg-muted hover:cteditor-bg-muted/80 cteditor-text-muted-foreground hover:cteditor-text-foreground cteditor-transition-all cteditor-duration-200 hover:cteditor-scale-105 active:cteditor-scale-95",
26444
+ className: "cteditor-p-2.5 cteditor-rounded-lg cteditor-bg-background hover:cteditor-bg-background/80 cteditor-text-foreground hover:cteditor-text-foreground cteditor-transition-all cteditor-duration-200 hover:cteditor-scale-105 active:cteditor-scale-95",
25859
26445
  onClick: () => {
25860
26446
  setIsLinkEditMode(false);
25861
26447
  setShowUrlView(true);
@@ -27007,6 +27593,203 @@ function NewMentionsPlugin({
27007
27593
  }
27008
27594
  );
27009
27595
  }
27596
+ function RichTextPastePlugin() {
27597
+ const [editor] = useLexicalComposerContext();
27598
+ useEffect$1(() => {
27599
+ return editor.registerCommand(
27600
+ PASTE_COMMAND,
27601
+ (event) => {
27602
+ const clipboardData = event.clipboardData;
27603
+ if (!clipboardData)
27604
+ return false;
27605
+ const htmlContent = clipboardData.getData("text/html");
27606
+ const plainText = clipboardData.getData("text/plain");
27607
+ if (htmlContent) {
27608
+ event.preventDefault();
27609
+ handleHtmlPaste(htmlContent);
27610
+ return true;
27611
+ } else if (plainText) {
27612
+ event.preventDefault();
27613
+ handleMarkdownPaste(plainText);
27614
+ return true;
27615
+ }
27616
+ return false;
27617
+ },
27618
+ COMMAND_PRIORITY_LOW
27619
+ );
27620
+ }, [editor]);
27621
+ const handleHtmlPaste = (htmlContent) => {
27622
+ editor.update(() => {
27623
+ const selection = $getSelection();
27624
+ if ($isRangeSelection(selection)) {
27625
+ const tempDiv = document.createElement("div");
27626
+ tempDiv.innerHTML = htmlContent;
27627
+ const processNode = (node) => {
27628
+ if (node.nodeType === Node.TEXT_NODE) {
27629
+ const text = node.textContent || "";
27630
+ const textNode = $createTextNode(text);
27631
+ if (node.parentElement) {
27632
+ if (node.parentElement.tagName === "STRONG" || node.parentElement.tagName === "B") {
27633
+ textNode.setFormat("bold");
27634
+ }
27635
+ if (node.parentElement.tagName === "EM" || node.parentElement.tagName === "I") {
27636
+ textNode.setFormat("italic");
27637
+ }
27638
+ if (node.parentElement.tagName === "U") {
27639
+ textNode.setFormat("underline");
27640
+ }
27641
+ if (node.parentElement.tagName === "CODE") {
27642
+ textNode.setFormat("code");
27643
+ }
27644
+ if (node.parentElement.tagName === "STRIKE" || node.parentElement.tagName === "S") {
27645
+ textNode.setFormat("strikethrough");
27646
+ }
27647
+ if (node.parentElement.tagName === "SUB") {
27648
+ textNode.setFormat("subscript");
27649
+ }
27650
+ if (node.parentElement.tagName === "SUP") {
27651
+ textNode.setFormat("superscript");
27652
+ }
27653
+ }
27654
+ return textNode;
27655
+ }
27656
+ if (node.nodeType === Node.ELEMENT_NODE) {
27657
+ const element = node;
27658
+ if (element.tagName === "UL" || element.tagName === "OL") {
27659
+ const listNode = $createListNode(
27660
+ element.tagName === "UL" ? "bullet" : "number"
27661
+ );
27662
+ Array.from(element.childNodes).forEach((child) => {
27663
+ if (child.nodeType === Node.ELEMENT_NODE && child.tagName === "LI") {
27664
+ const listItemNode = $createListItemNode();
27665
+ Array.from(child.childNodes).forEach((grandChild) => {
27666
+ const processedNode = processNode(grandChild);
27667
+ if (processedNode) {
27668
+ if (Array.isArray(processedNode)) {
27669
+ processedNode.forEach(
27670
+ (node2) => listItemNode.append(node2)
27671
+ );
27672
+ } else {
27673
+ listItemNode.append(processedNode);
27674
+ }
27675
+ }
27676
+ });
27677
+ listNode.append(listItemNode);
27678
+ }
27679
+ });
27680
+ return listNode;
27681
+ }
27682
+ if (element.tagName.match(/^H[1-6]$/)) {
27683
+ const headingNode = $createHeadingNode(
27684
+ element.tagName.toLowerCase()
27685
+ );
27686
+ Array.from(element.childNodes).forEach((child) => {
27687
+ const processedNode = processNode(child);
27688
+ if (processedNode) {
27689
+ if (Array.isArray(processedNode)) {
27690
+ processedNode.forEach((node2) => headingNode.append(node2));
27691
+ } else {
27692
+ headingNode.append(processedNode);
27693
+ }
27694
+ }
27695
+ });
27696
+ return headingNode;
27697
+ }
27698
+ if (element.tagName === "P") {
27699
+ const paragraphNode = $createParagraphNode();
27700
+ Array.from(element.childNodes).forEach((child) => {
27701
+ const processedNode = processNode(child);
27702
+ if (processedNode) {
27703
+ if (Array.isArray(processedNode)) {
27704
+ processedNode.forEach((node2) => paragraphNode.append(node2));
27705
+ } else {
27706
+ paragraphNode.append(processedNode);
27707
+ }
27708
+ }
27709
+ });
27710
+ return paragraphNode;
27711
+ }
27712
+ const nodes = [];
27713
+ Array.from(element.childNodes).forEach((child) => {
27714
+ const processedNode = processNode(child);
27715
+ if (processedNode) {
27716
+ if (Array.isArray(processedNode)) {
27717
+ nodes.push(...processedNode);
27718
+ } else {
27719
+ nodes.push(processedNode);
27720
+ }
27721
+ }
27722
+ });
27723
+ return nodes;
27724
+ }
27725
+ return null;
27726
+ };
27727
+ const processedNodes = processNode(tempDiv);
27728
+ if (processedNodes) {
27729
+ if (Array.isArray(processedNodes)) {
27730
+ selection.insertNodes(processedNodes);
27731
+ } else {
27732
+ selection.insertNodes([processedNodes]);
27733
+ }
27734
+ }
27735
+ }
27736
+ });
27737
+ };
27738
+ const handleMarkdownPaste = (text) => {
27739
+ editor.update(() => {
27740
+ const selection = $getSelection();
27741
+ if ($isRangeSelection(selection)) {
27742
+ const lines = text.split("\n");
27743
+ const nodes = [];
27744
+ lines.forEach((line) => {
27745
+ const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
27746
+ if (headingMatch) {
27747
+ const level = headingMatch[1].length;
27748
+ const content = headingMatch[2];
27749
+ const headingNode = $createHeadingNode(
27750
+ `h${level}`
27751
+ );
27752
+ headingNode.append($createTextNode(content));
27753
+ nodes.push(headingNode);
27754
+ return;
27755
+ }
27756
+ const bulletMatch = line.match(/^-\s+(.+)$/);
27757
+ if (bulletMatch) {
27758
+ const listNode = $createListNode("bullet");
27759
+ const listItemNode = $createListItemNode();
27760
+ listItemNode.append($createTextNode(bulletMatch[1]));
27761
+ listNode.append(listItemNode);
27762
+ nodes.push(listNode);
27763
+ return;
27764
+ }
27765
+ const numberedMatch = line.match(/^\d+\.\s+(.+)$/);
27766
+ if (numberedMatch) {
27767
+ const listNode = $createListNode("number");
27768
+ const listItemNode = $createListItemNode();
27769
+ listItemNode.append($createTextNode(numberedMatch[1]));
27770
+ listNode.append(listItemNode);
27771
+ nodes.push(listNode);
27772
+ return;
27773
+ }
27774
+ const textNode = $createTextNode(line);
27775
+ if (line.includes("**") || line.includes("__")) {
27776
+ textNode.setFormat("bold");
27777
+ }
27778
+ if (line.includes("*") || line.includes("_")) {
27779
+ textNode.setFormat("italic");
27780
+ }
27781
+ if (line.includes("***") || line.includes("___")) {
27782
+ textNode.setFormat("bold");
27783
+ textNode.setFormat("italic");
27784
+ }
27785
+ nodes.push(textNode);
27786
+ });
27787
+ selection.insertNodes(nodes);
27788
+ }
27789
+ });
27790
+ };
27791
+ return null;
27792
+ }
27010
27793
  function useModal() {
27011
27794
  const [modalContent, setModalContent] = useState$1(null);
27012
27795
  const onClose = useCallback(() => {
@@ -27552,8 +28335,79 @@ function TableActionMenu({
27552
28335
  for (let i2 = 0; i2 < selectionCounts.columns; i2++) {
27553
28336
  $insertTableColumn__EXPERIMENTAL(shouldInsertAfter);
27554
28337
  }
28338
+ const selection = $getSelection();
28339
+ if ($isRangeSelection(selection) || $isTableSelection(selection)) {
28340
+ const [cell] = $getNodeTriplet(selection.anchor);
28341
+ if ($isTableCellNode(cell)) {
28342
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(cell);
28343
+ const rows = tableNode.getChildren();
28344
+ if (rows.length > 0 && $isTableRowNode(rows[0])) {
28345
+ const firstRow = rows[0];
28346
+ const firstRowCells = firstRow.getChildren();
28347
+ if (firstRowCells.length > 0 && $isTableCellNode(firstRowCells[0])) {
28348
+ const firstCell = firstRowCells[0];
28349
+ const hasColumnHeaders = (firstCell.getHeaderStyles() & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN;
28350
+ if (hasColumnHeaders) {
28351
+ const headerBackgroundColor = firstCell.getBackgroundColor();
28352
+ for (let i2 = 0; i2 < selectionCounts.columns; i2++) {
28353
+ const newHeaderCellIndex = firstRowCells.length - 1 - i2;
28354
+ if (newHeaderCellIndex >= 0) {
28355
+ const newHeaderCell = firstRowCells[newHeaderCellIndex];
28356
+ if ($isTableCellNode(newHeaderCell)) {
28357
+ newHeaderCell.setHeaderStyles(TableCellHeaderStates.COLUMN);
28358
+ if (headerBackgroundColor) {
28359
+ newHeaderCell.setBackgroundColor(headerBackgroundColor);
28360
+ }
28361
+ }
28362
+ }
28363
+ }
28364
+ }
28365
+ }
28366
+ }
28367
+ }
28368
+ }
27555
28369
  onClose();
27556
28370
  });
28371
+ requestAnimationFrame(() => {
28372
+ const applyHeaderStyles = () => {
28373
+ const rootElement = editor.getRootElement();
28374
+ if (!rootElement)
28375
+ return false;
28376
+ const tables = rootElement.querySelectorAll("table");
28377
+ tables.forEach((table) => {
28378
+ const rows = table.querySelectorAll("tr");
28379
+ if (rows.length > 0) {
28380
+ const firstRow = rows[0];
28381
+ const cells = firstRow.querySelectorAll("th, td");
28382
+ if (cells.length > 1) {
28383
+ const firstHeaderCell = cells[0];
28384
+ const headerColor = firstHeaderCell.getAttribute("data-header-color");
28385
+ const textColor = firstHeaderCell.getAttribute("data-text-color");
28386
+ if (headerColor && textColor) {
28387
+ for (let i2 = 0; i2 < selectionCounts.columns; i2++) {
28388
+ const cellIndex = cells.length - 1 - i2;
28389
+ if (cellIndex >= 0) {
28390
+ const newCell = cells[cellIndex];
28391
+ newCell.setAttribute("data-header-color", headerColor);
28392
+ newCell.setAttribute("data-text-color", textColor);
28393
+ newCell.style.setProperty("background-color", headerColor, "important");
28394
+ newCell.style.setProperty("color", textColor, "important");
28395
+ newCell.style.setProperty("padding", "8px", "important");
28396
+ newCell.style.setProperty("border", "1px solid #ddd", "important");
28397
+ newCell.style.setProperty("font-weight", "bold", "important");
28398
+ newCell.style.setProperty("white-space", "nowrap", "important");
28399
+ }
28400
+ }
28401
+ }
28402
+ }
28403
+ }
28404
+ });
28405
+ return true;
28406
+ };
28407
+ if (!applyHeaderStyles()) {
28408
+ setTimeout(applyHeaderStyles, 100);
28409
+ }
28410
+ });
27557
28411
  },
27558
28412
  [editor, onClose, selectionCounts.columns]
27559
28413
  );
@@ -28550,12 +29404,75 @@ function TableHoverActionsContainer({
28550
29404
  } else {
28551
29405
  $insertTableColumn__EXPERIMENTAL();
28552
29406
  setShownColumn(false);
29407
+ const tableCellNode = $getNearestNodeFromDOMNode(tableCellDOMNodeRef.current);
29408
+ if ($isTableCellNode(tableCellNode)) {
29409
+ const tableNode = $findMatchingParent(
29410
+ tableCellNode,
29411
+ (node) => $isTableNode(node)
29412
+ );
29413
+ if ($isTableNode(tableNode)) {
29414
+ const rows = tableNode.getChildren();
29415
+ if (rows.length > 0) {
29416
+ const firstRow = rows[0];
29417
+ const firstRowCells = firstRow.getChildren();
29418
+ if (firstRowCells.length > 0) {
29419
+ const firstCell = firstRowCells[0];
29420
+ const hasColumnHeaders = (firstCell.getHeaderStyles() & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN;
29421
+ if (hasColumnHeaders) {
29422
+ const newHeaderCell = firstRowCells[firstRowCells.length - 1];
29423
+ newHeaderCell.setHeaderStyles(TableCellHeaderStates.COLUMN);
29424
+ const headerBackgroundColor = firstCell.getBackgroundColor();
29425
+ if (headerBackgroundColor) {
29426
+ newHeaderCell.setBackgroundColor(headerBackgroundColor);
29427
+ }
29428
+ }
29429
+ }
29430
+ }
29431
+ }
29432
+ }
28553
29433
  }
28554
29434
  }
28555
29435
  });
28556
- };
28557
- if (!isEditable) {
28558
- return null;
29436
+ if (!insertRow) {
29437
+ requestAnimationFrame(() => {
29438
+ const applyHeaderStyles = () => {
29439
+ const rootElement = editor.getRootElement();
29440
+ if (!rootElement)
29441
+ return false;
29442
+ const tables = rootElement.querySelectorAll("table");
29443
+ tables.forEach((table) => {
29444
+ const rows = table.querySelectorAll("tr");
29445
+ if (rows.length > 0) {
29446
+ const firstRow = rows[0];
29447
+ const cells = firstRow.querySelectorAll("th, td");
29448
+ if (cells.length > 1) {
29449
+ const firstHeaderCell = cells[0];
29450
+ const headerColor = firstHeaderCell.getAttribute("data-header-color");
29451
+ const textColor = firstHeaderCell.getAttribute("data-text-color");
29452
+ if (headerColor && textColor) {
29453
+ const lastCell = cells[cells.length - 1];
29454
+ lastCell.setAttribute("data-header-color", headerColor);
29455
+ lastCell.setAttribute("data-text-color", textColor);
29456
+ lastCell.style.setProperty("background-color", headerColor, "important");
29457
+ lastCell.style.setProperty("color", textColor, "important");
29458
+ lastCell.style.setProperty("padding", "8px", "important");
29459
+ lastCell.style.setProperty("border", "1px solid #ddd", "important");
29460
+ lastCell.style.setProperty("font-weight", "bold", "important");
29461
+ lastCell.style.setProperty("white-space", "nowrap", "important");
29462
+ }
29463
+ }
29464
+ }
29465
+ });
29466
+ return true;
29467
+ };
29468
+ if (!applyHeaderStyles()) {
29469
+ setTimeout(applyHeaderStyles, 100);
29470
+ }
29471
+ });
29472
+ }
29473
+ };
29474
+ if (!isEditable) {
29475
+ return null;
28559
29476
  }
28560
29477
  return /* @__PURE__ */ jsxs(Fragment, { children: [
28561
29478
  isShownRow && /* @__PURE__ */ jsx(
@@ -28686,6 +29603,10 @@ function SlashMenuItem({
28686
29603
  function SlashCommandPlugin() {
28687
29604
  const [editor] = useLexicalComposerContext();
28688
29605
  const [queryString, setQueryString] = useState$1(null);
29606
+ const menuRef = useRef(null);
29607
+ const [menuPosition, setMenuPosition] = useState$1({ left: 0 });
29608
+ const anchorRef = useRef(null);
29609
+ const [isMenuOpen, setIsMenuOpen] = useState$1(false);
28689
29610
  const triggerFn = useBasicTypeaheadTriggerMatch("/", { minLength: 0 });
28690
29611
  const makeBlock = useCallback((cb) => {
28691
29612
  editor.update(() => {
@@ -28772,9 +29693,55 @@ function SlashCommandPlugin() {
28772
29693
  }
28773
29694
  });
28774
29695
  closeMenu();
29696
+ setIsMenuOpen(false);
28775
29697
  },
28776
29698
  [editor]
28777
29699
  );
29700
+ useEffect$1(() => {
29701
+ if (!isMenuOpen) {
29702
+ return;
29703
+ }
29704
+ const menu = menuRef.current;
29705
+ const anchor = anchorRef.current;
29706
+ if (!menu || !anchor) {
29707
+ return;
29708
+ }
29709
+ const updatePosition = () => {
29710
+ const menuRect = menu.getBoundingClientRect();
29711
+ const viewportHeight = window.innerHeight;
29712
+ const viewportWidth = window.innerWidth;
29713
+ const anchorRect = anchor.getBoundingClientRect();
29714
+ const spaceBelow = viewportHeight - anchorRect.bottom;
29715
+ const spaceAbove = anchorRect.top;
29716
+ const menuHeight = menuRect.height || 240;
29717
+ const menuWidth = menuRect.width || 288;
29718
+ let newPosition = { left: anchorRect.left };
29719
+ if (spaceBelow >= menuHeight || spaceBelow >= spaceAbove) {
29720
+ newPosition.top = anchorRect.bottom + 4;
29721
+ } else {
29722
+ newPosition.bottom = viewportHeight - anchorRect.top + 4;
29723
+ }
29724
+ if (anchorRect.left + menuWidth > viewportWidth) {
29725
+ newPosition.left = Math.max(8, viewportWidth - menuWidth - 8);
29726
+ } else {
29727
+ newPosition.left = Math.max(8, anchorRect.left);
29728
+ }
29729
+ setMenuPosition((prev) => {
29730
+ if (prev.top === newPosition.top && prev.bottom === newPosition.bottom && prev.left === newPosition.left) {
29731
+ return prev;
29732
+ }
29733
+ return newPosition;
29734
+ });
29735
+ };
29736
+ const timeoutId = setTimeout(updatePosition, 0);
29737
+ window.addEventListener("scroll", updatePosition, true);
29738
+ window.addEventListener("resize", updatePosition);
29739
+ return () => {
29740
+ clearTimeout(timeoutId);
29741
+ window.removeEventListener("scroll", updatePosition, true);
29742
+ window.removeEventListener("resize", updatePosition);
29743
+ };
29744
+ }, [isMenuOpen]);
28778
29745
  return /* @__PURE__ */ jsx(
28779
29746
  LexicalTypeaheadMenuPlugin,
28780
29747
  {
@@ -28782,31 +29749,52 @@ function SlashCommandPlugin() {
28782
29749
  onSelectOption,
28783
29750
  triggerFn,
28784
29751
  options,
28785
- menuRenderFn: (anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) => anchorElementRef.current ? ReactDOM.createPortal(
28786
- /* @__PURE__ */ jsxs("div", { className: "cteditor-w-72 cteditor-max-h-60 cteditor-overflow-y-auto no-scrollbar cteditor-backdrop-blur-md cteditor-shadow-xl cteditor-rounded-lg cteditor-border cteditor-border-border cteditor-p-1.5 cteditor-bg-background", style: { position: "absolute" }, children: [
28787
- /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-justify-between cteditor-px-2 cteditor-py-1 cteditor-text-[11px] cteditor-text-muted-foreground", children: [
28788
- /* @__PURE__ */ jsx("span", { children: queryString ? "Search results" : "Quick actions" }),
28789
- /* @__PURE__ */ jsx("span", { className: "cteditor-hidden sm:cteditor-inline", children: "Type to filter" })
28790
- ] }),
28791
- options.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "cteditor-space-y-1", children: options.map((option, i2) => /* @__PURE__ */ jsx(
28792
- SlashMenuItem,
29752
+ menuRenderFn: (anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) => {
29753
+ anchorRef.current = anchorElementRef.current;
29754
+ if (anchorElementRef.current && !isMenuOpen) {
29755
+ setIsMenuOpen(true);
29756
+ } else if (!anchorElementRef.current && isMenuOpen) {
29757
+ setIsMenuOpen(false);
29758
+ }
29759
+ return anchorElementRef.current ? ReactDOM.createPortal(
29760
+ /* @__PURE__ */ jsxs(
29761
+ "div",
28793
29762
  {
28794
- index: i2,
28795
- isSelected: selectedIndex === i2,
28796
- onClick: () => {
28797
- setHighlightedIndex(i2);
28798
- selectOptionAndCleanUp(option);
28799
- },
28800
- onMouseEnter: () => {
28801
- setHighlightedIndex(i2);
29763
+ ref: menuRef,
29764
+ className: "cteditor-w-72 cteditor-max-h-60 cteditor-overflow-y-auto no-scrollbar cteditor-backdrop-blur-md cteditor-shadow-xl cteditor-rounded-lg cteditor-border cteditor-border-border cteditor-p-1.5 cteditor-bg-background cteditor-z-50",
29765
+ style: {
29766
+ position: "fixed",
29767
+ top: menuPosition.top,
29768
+ bottom: menuPosition.bottom,
29769
+ left: menuPosition.left
28802
29770
  },
28803
- option
28804
- },
28805
- option.key
28806
- )) }) : /* @__PURE__ */ jsx("div", { className: "cteditor-text-[11px] cteditor-text-muted-foreground cteditor-px-3 cteditor-py-2", children: "No results" })
28807
- ] }),
28808
- anchorElementRef.current
28809
- ) : null
29771
+ children: [
29772
+ /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-justify-between cteditor-px-2 cteditor-py-1 cteditor-text-[11px] cteditor-text-muted-foreground", children: [
29773
+ /* @__PURE__ */ jsx("span", { children: queryString ? "Search results" : "Quick actions" }),
29774
+ /* @__PURE__ */ jsx("span", { className: "cteditor-hidden sm:cteditor-inline", children: "Type to filter" })
29775
+ ] }),
29776
+ options.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "cteditor-space-y-1", children: options.map((option, i2) => /* @__PURE__ */ jsx(
29777
+ SlashMenuItem,
29778
+ {
29779
+ index: i2,
29780
+ isSelected: selectedIndex === i2,
29781
+ onClick: () => {
29782
+ setHighlightedIndex(i2);
29783
+ selectOptionAndCleanUp(option);
29784
+ },
29785
+ onMouseEnter: () => {
29786
+ setHighlightedIndex(i2);
29787
+ },
29788
+ option
29789
+ },
29790
+ option.key
29791
+ )) }) : /* @__PURE__ */ jsx("div", { className: "cteditor-text-[11px] cteditor-text-muted-foreground cteditor-px-3 cteditor-py-2", children: "No results" })
29792
+ ]
29793
+ }
29794
+ ),
29795
+ anchorElementRef.current
29796
+ ) : null;
29797
+ }
28810
29798
  }
28811
29799
  );
28812
29800
  }
@@ -28858,421 +29846,12 @@ const WordCountPlugin = () => {
28858
29846
  }
28859
29847
  );
28860
29848
  };
28861
- const GrammarCheckPlugin$1 = "";
28862
- class GrammarCheckService {
28863
- constructor() {
28864
- __publicField(this, "cache", /* @__PURE__ */ new Map());
28865
- __publicField(this, "apiEndpoint");
28866
- __publicField(this, "pendingRequest", null);
28867
- this.apiEndpoint = "https://api.cteditor.com/api/ai/process";
28868
- }
28869
- async check(text) {
28870
- if (!text || text.trim().length < 3) {
28871
- return [];
28872
- }
28873
- const cacheKey = text.trim();
28874
- if (this.cache.has(cacheKey)) {
28875
- return this.cache.get(cacheKey);
28876
- }
28877
- if (this.pendingRequest) {
28878
- return this.pendingRequest;
28879
- }
28880
- this.pendingRequest = this.executeCheck(text);
28881
- try {
28882
- const result = await this.pendingRequest;
28883
- return result;
28884
- } finally {
28885
- this.pendingRequest = null;
28886
- }
28887
- }
28888
- async executeCheck(text) {
28889
- var _a, _b, _c, _d, _e, _f;
28890
- try {
28891
- const response = await fetch(this.apiEndpoint, {
28892
- method: "POST",
28893
- headers: { "Content-Type": "application/json" },
28894
- body: JSON.stringify({ text: text.trim(), maxSuggestions: 3 }),
28895
- signal: AbortSignal.timeout(1e4)
28896
- });
28897
- if (!response.ok) {
28898
- console.error("❌ GrammarCheck: API error:", response.status);
28899
- return [];
28900
- }
28901
- const result = await response.json();
28902
- const foundErrors = [];
28903
- if ((_c = (_b = (_a = result.data) == null ? void 0 : _a.corrections) == null ? void 0 : _b.spelling) == null ? void 0 : _c.errors) {
28904
- result.data.corrections.spelling.errors.forEach((err, idx) => {
28905
- foundErrors.push({
28906
- type: "spelling",
28907
- original: err.original,
28908
- suggestions: err.suggestions || [],
28909
- index: idx
28910
- });
28911
- });
28912
- }
28913
- if ((_f = (_e = (_d = result.data) == null ? void 0 : _d.corrections) == null ? void 0 : _e.grammar) == null ? void 0 : _f.errors) {
28914
- result.data.corrections.grammar.errors.forEach((err, idx) => {
28915
- foundErrors.push({
28916
- type: "grammar",
28917
- original: err.original || text,
28918
- suggestions: [err.suggestion],
28919
- index: foundErrors.length + idx,
28920
- issue: err.issue
28921
- });
28922
- });
28923
- }
28924
- this.cache.set(text.trim(), foundErrors);
28925
- if (this.cache.size > 30) {
28926
- const firstKey = this.cache.keys().next().value;
28927
- if (firstKey) {
28928
- this.cache.delete(firstKey);
28929
- }
28930
- }
28931
- return foundErrors;
28932
- } catch (error) {
28933
- console.error("❌ GrammarCheck: Check failed:", error);
28934
- return [];
28935
- }
28936
- }
28937
- }
28938
- function GrammarCheckPlugin() {
28939
- const [editor] = useLexicalComposerContext();
28940
- const { updateToolbarState } = useToolbarState();
28941
- const [errors, setErrors] = useState$1([]);
28942
- const [tooltip, setTooltip] = useState$1(null);
28943
- const [userDismissed, setUserDismissed] = useState$1(false);
28944
- const grammarService = useRef(new GrammarCheckService());
28945
- const checkTimeout = useRef();
28946
- const lastCheckedText = useRef("");
28947
- const highlightElementsRef = useRef([]);
28948
- const checkGrammar = useCallback(async () => {
28949
- const isSlashActive = editor.getEditorState().read(() => {
28950
- const selection = $getSelection();
28951
- if (!$isRangeSelection(selection))
28952
- return false;
28953
- const anchor = selection.anchor;
28954
- const anchorNode = anchor.getNode();
28955
- const anchorOffset = anchor.offset;
28956
- const textContent = anchorNode.getTextContent();
28957
- let wordStart = anchorOffset;
28958
- while (wordStart > 0 && /[a-zA-Z0-9_']/.test(textContent[wordStart - 1])) {
28959
- wordStart--;
28960
- }
28961
- return wordStart > 0 && textContent[wordStart - 1] === "/";
28962
- });
28963
- if (isSlashActive) {
28964
- setErrors([]);
28965
- return;
28966
- }
28967
- const text = editor.getEditorState().read(() => $getRoot().getTextContent());
28968
- if (text === lastCheckedText.current) {
28969
- return;
28970
- }
28971
- if (Math.abs(text.length - lastCheckedText.current.length) > 20) {
28972
- setUserDismissed(false);
28973
- }
28974
- lastCheckedText.current = text;
28975
- if (!text || text.trim().length < 3) {
28976
- setErrors([]);
28977
- return;
28978
- }
28979
- const foundErrors = await grammarService.current.check(text);
28980
- setErrors(foundErrors);
28981
- }, [editor]);
28982
- useEffect$1(() => {
28983
- const unregister = editor.registerUpdateListener(() => {
28984
- clearTimeout(checkTimeout.current);
28985
- checkTimeout.current = window.setTimeout(checkGrammar, 2e3);
28986
- });
28987
- return () => {
28988
- unregister();
28989
- clearTimeout(checkTimeout.current);
28990
- };
28991
- }, [editor, checkGrammar]);
28992
- useEffect$1(() => {
28993
- highlightElementsRef.current.forEach((el) => {
28994
- el.classList.remove("spelling-error", "grammar-error");
28995
- });
28996
- highlightElementsRef.current = [];
28997
- if (errors.length === 0 || userDismissed)
28998
- return;
28999
- const timeoutId = setTimeout(() => {
29000
- const editorElement = document.querySelector(".ContentEditable__root");
29001
- if (!editorElement)
29002
- return;
29003
- const walker = document.createTreeWalker(
29004
- editorElement,
29005
- NodeFilter.SHOW_TEXT,
29006
- null
29007
- );
29008
- const textNodes = [];
29009
- let node;
29010
- while (node = walker.nextNode()) {
29011
- textNodes.push(node);
29012
- }
29013
- errors.forEach((error) => {
29014
- textNodes.forEach((textNode) => {
29015
- const nodeText = textNode.textContent || "";
29016
- const errorIndex = nodeText.toLowerCase().indexOf(error.original.toLowerCase());
29017
- if (errorIndex !== -1 && textNode.parentElement) {
29018
- const className = error.type === "spelling" ? "spelling-error" : "grammar-error";
29019
- if (textNode.parentElement.tagName === "SPAN") {
29020
- textNode.parentElement.classList.add(className);
29021
- highlightElementsRef.current.push(textNode.parentElement);
29022
- } else if (textNode.parentElement) {
29023
- const range = document.createRange();
29024
- range.setStart(textNode, errorIndex);
29025
- range.setEnd(textNode, Math.min(errorIndex + error.original.length, nodeText.length));
29026
- const span = document.createElement("span");
29027
- span.className = className;
29028
- span.setAttribute("data-error-type", error.type);
29029
- try {
29030
- range.surroundContents(span);
29031
- highlightElementsRef.current.push(span);
29032
- } catch (e) {
29033
- if (textNode.parentElement) {
29034
- textNode.parentElement.classList.add(className);
29035
- highlightElementsRef.current.push(textNode.parentElement);
29036
- }
29037
- }
29038
- }
29039
- }
29040
- });
29041
- });
29042
- }, 100);
29043
- return () => clearTimeout(timeoutId);
29044
- }, [errors, userDismissed]);
29045
- const getWordAtPoint = useCallback((x2, y2) => {
29046
- try {
29047
- let range = null;
29048
- if (document.caretRangeFromPoint) {
29049
- range = document.caretRangeFromPoint(x2, y2);
29050
- } else if (document.caretPositionFromPoint) {
29051
- const position = document.caretPositionFromPoint(x2, y2);
29052
- if (position) {
29053
- range = document.createRange();
29054
- range.setStart(position.offsetNode, position.offset);
29055
- }
29056
- }
29057
- if (!range)
29058
- return null;
29059
- const textNode = range.startContainer;
29060
- if (textNode.nodeType !== Node.TEXT_NODE)
29061
- return null;
29062
- const text = textNode.textContent || "";
29063
- let start = range.startOffset;
29064
- let end = range.startOffset;
29065
- while (start > 0 && /\w/.test(text[start - 1])) {
29066
- start--;
29067
- }
29068
- while (end < text.length && /\w/.test(text[end])) {
29069
- end++;
29070
- }
29071
- const word = text.substring(start, end).trim();
29072
- return word || null;
29073
- } catch (error) {
29074
- console.error("Error getting word at point:", error);
29075
- return null;
29076
- }
29077
- }, []);
29078
- useEffect$1(() => {
29079
- if (errors.length === 0)
29080
- return;
29081
- let hoverTimeout;
29082
- const handleMouseMove = (e) => {
29083
- clearTimeout(hoverTimeout);
29084
- hoverTimeout = window.setTimeout(() => {
29085
- const wordAtCursor = getWordAtPoint(e.clientX, e.clientY);
29086
- if (wordAtCursor) {
29087
- const matchedError = errors.find(
29088
- (err) => wordAtCursor.toLowerCase() === err.original.toLowerCase()
29089
- );
29090
- if (matchedError) {
29091
- setTooltip({
29092
- error: matchedError,
29093
- x: e.clientX,
29094
- y: e.clientY
29095
- });
29096
- }
29097
- }
29098
- }, 50);
29099
- };
29100
- const handleClick = () => {
29101
- setTooltip(null);
29102
- };
29103
- document.addEventListener("mousemove", handleMouseMove);
29104
- document.addEventListener("click", handleClick);
29105
- return () => {
29106
- clearTimeout(hoverTimeout);
29107
- document.removeEventListener("mousemove", handleMouseMove);
29108
- document.removeEventListener("click", handleClick);
29109
- };
29110
- }, [errors, getWordAtPoint]);
29111
- const applyCorrection = useCallback(
29112
- (suggestion, original, errorType) => {
29113
- editor.update(() => {
29114
- const root2 = $getRoot();
29115
- const currentText = root2.getTextContent();
29116
- const isSpellingError = errorType === "spelling";
29117
- let newText = currentText;
29118
- if (isSpellingError) {
29119
- const escapedOriginal = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
29120
- const regex = new RegExp(`\\b${escapedOriginal}\\b`, "gi");
29121
- newText = currentText.replace(regex, suggestion);
29122
- } else {
29123
- const escapedOriginal = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
29124
- const regex = new RegExp(escapedOriginal, "gi");
29125
- if (currentText.toLowerCase().includes(original.toLowerCase())) {
29126
- newText = currentText.replace(regex, suggestion);
29127
- } else {
29128
- newText = suggestion;
29129
- }
29130
- }
29131
- root2.clear();
29132
- const paragraph = $createParagraphNode();
29133
- const textNode = $createTextNode(newText);
29134
- paragraph.append(textNode);
29135
- root2.append(paragraph);
29136
- });
29137
- setTooltip(null);
29138
- setTimeout(() => {
29139
- lastCheckedText.current = "";
29140
- checkGrammar();
29141
- }, 100);
29142
- },
29143
- [editor, checkGrammar]
29144
- );
29145
- const showErrorTooltip = (error, event) => {
29146
- setTooltip({
29147
- error,
29148
- x: event.clientX,
29149
- y: event.clientY
29150
- });
29151
- };
29152
- return /* @__PURE__ */ jsxs(Fragment, { children: [
29153
- errors.length > 0 && !userDismissed && /* @__PURE__ */ jsx("div", { className: "grammar-error-panel", children: /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-bg-amber-50 cteditor-border cteditor-border-amber-200 cteditor-rounded-lg cteditor-px-3 cteditor-py-2 cteditor-shadow-sm", children: [
29154
- /* @__PURE__ */ jsx(AlertCircle, { className: "cteditor-h-4 cteditor-w-4 cteditor-text-amber-600 cteditor-flex-shrink-0" }),
29155
- /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-flex-1 cteditor-overflow-x-auto cteditor-max-w-2xl", children: [
29156
- /* @__PURE__ */ jsxs("span", { className: "cteditor-text-xs cteditor-font-semibold cteditor-text-amber-800 cteditor-whitespace-nowrap", children: [
29157
- errors.length,
29158
- " ",
29159
- errors.length === 1 ? "issue" : "issues",
29160
- ":"
29161
- ] }),
29162
- /* @__PURE__ */ jsx("div", { className: "cteditor-flex cteditor-gap-2 cteditor-items-center", children: errors.map((error, idx) => /* @__PURE__ */ jsxs(
29163
- "div",
29164
- {
29165
- className: "cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-bg-white cteditor-border cteditor-border-gray-200 cteditor-rounded cteditor-px-2 cteditor-py-1 cteditor-whitespace-nowrap cteditor-cursor-pointer hover:cteditor-bg-gray-50 cteditor-transition-colors",
29166
- onClick: (e) => showErrorTooltip(error, e),
29167
- children: [
29168
- /* @__PURE__ */ jsx("span", { className: "cteditor-text-xs cteditor-line-through cteditor-text-red-600 cteditor-max-w-24 cteditor-truncate", title: error.original, children: error.original }),
29169
- /* @__PURE__ */ jsx("span", { className: "cteditor-text-xs cteditor-text-gray-400", children: "→" }),
29170
- /* @__PURE__ */ jsx(
29171
- "button",
29172
- {
29173
- onClick: (e) => {
29174
- e.stopPropagation();
29175
- applyCorrection(error.suggestions[0], error.original, error.type);
29176
- },
29177
- className: "cteditor-text-xs cteditor-text-green-600 hover:cteditor-text-green-700 cteditor-font-medium cteditor-max-w-24 cteditor-truncate",
29178
- title: error.suggestions[0],
29179
- children: error.suggestions[0]
29180
- }
29181
- )
29182
- ]
29183
- },
29184
- idx
29185
- )) })
29186
- ] }),
29187
- /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-1 cteditor-flex-shrink-0", children: [
29188
- /* @__PURE__ */ jsx(
29189
- Button,
29190
- {
29191
- variant: "link",
29192
- size: "sm",
29193
- onClick: () => {
29194
- setUserDismissed(true);
29195
- setErrors([]);
29196
- updateToolbarState("isGrammarCheckEnabled", false);
29197
- },
29198
- className: "cteditor-h-7 cteditor-px-2 cteditor-text-xs !cteditor-text-amber-700 ",
29199
- title: "Disable Grammar Check",
29200
- children: "Disable"
29201
- }
29202
- ),
29203
- /* @__PURE__ */ jsx(
29204
- "button",
29205
- {
29206
- onClick: () => setUserDismissed(true),
29207
- className: "cteditor-p-1 hover:cteditor-bg-amber-100 cteditor-rounded cteditor-transition-colors",
29208
- title: "Dismiss grammar suggestions",
29209
- children: /* @__PURE__ */ jsx(X$1, { className: "cteditor-h-3.5 cteditor-w-3.5 cteditor-text-amber-600" })
29210
- }
29211
- )
29212
- ] })
29213
- ] }) }),
29214
- tooltip && createPortal(
29215
- /* @__PURE__ */ jsx(
29216
- "div",
29217
- {
29218
- className: "grammar-tooltip ",
29219
- style: {
29220
- position: "fixed",
29221
- left: tooltip.x,
29222
- top: tooltip.y + 20,
29223
- zIndex: 1e4
29224
- },
29225
- onMouseEnter: () => {
29226
- },
29227
- onMouseLeave: () => {
29228
- setTooltip(null);
29229
- },
29230
- children: /* @__PURE__ */ jsx(Card, { className: "cteditor-w-72 cteditor-shadow-xl cteditor-border-2 cteditor-bg-background cteditor-rounded-xl", children: /* @__PURE__ */ jsxs(CardContent, { className: "cteditor-p-3", children: [
29231
- /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-mb-3", children: [
29232
- tooltip.error.type === "spelling" ? /* @__PURE__ */ jsx(AlertCircle, { className: "cteditor-h-4 cteditor-w-4 cteditor-text-red-500" }) : /* @__PURE__ */ jsx(CheckCircle, { className: "cteditor-h-4 cteditor-w-4 cteditor-text-blue-500" }),
29233
- /* @__PURE__ */ jsx(
29234
- Badge,
29235
- {
29236
- variant: tooltip.error.type === "spelling" ? "destructive" : "default",
29237
- className: "cteditor-text-xs",
29238
- children: tooltip.error.type === "spelling" ? "Spelling Error" : "Grammar Issue"
29239
- }
29240
- )
29241
- ] }),
29242
- tooltip.error.issue && /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-text-muted-foreground cteditor-mb-2 cteditor-italic", children: tooltip.error.issue }),
29243
- /* @__PURE__ */ jsxs("div", { className: "cteditor-mb-2", children: [
29244
- /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-font-semibold cteditor-text-muted-foreground", children: "Original:" }),
29245
- /* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-line-through cteditor-text-red-600", children: tooltip.error.original })
29246
- ] }),
29247
- tooltip.error.suggestions.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
29248
- /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-font-semibold cteditor-text-muted-foreground cteditor-mb-1", children: "Suggestions:" }),
29249
- /* @__PURE__ */ jsx("div", { className: "cteditor-space-y-1", children: tooltip.error.suggestions.map((suggestion, idx) => /* @__PURE__ */ jsxs(
29250
- "button",
29251
- {
29252
- onClick: () => applyCorrection(suggestion, tooltip.error.original, tooltip.error.type),
29253
- className: "cteditor-w-full cteditor-text-left cteditor-p-2 cteditor-text-sm cteditor-rounded-md cteditor-bg-accent/50 hover:cteditor-bg-accent cteditor-transition-colors cteditor-border cteditor-border-transparent hover:cteditor-border-primary",
29254
- children: [
29255
- "✓ ",
29256
- suggestion
29257
- ]
29258
- },
29259
- idx
29260
- )) })
29261
- ] }),
29262
- tooltip.error.suggestions.length === 0 && /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-text-muted-foreground cteditor-italic", children: "No suggestions available" })
29263
- ] }) })
29264
- }
29265
- ),
29266
- document.body
29267
- )
29268
- ] });
29269
- }
29270
29849
  const useStyles = () => ({
29271
29850
  // container: "cteditor-relative cteditor-w-full cteditor-bg-white cteditor-text-black cteditor-font-normal cteditor-text-left cteditor-border cteditor-border-red-500",
29272
29851
  contentEditable: cn$1(
29273
29852
  "cteditor-relative cteditor-min-h-[150px] !cteditor-h-auto cteditor-resize-none cteditor-outline-0",
29274
29853
  // Ensure strong contrast in both themes
29275
- "cteditor-text-black dark:cteditor-text-white cteditor-bg-white dark:cteditor-bg-[#0b0b0b]",
29854
+ "cteditor-text-black dark:cteditor-text-white ",
29276
29855
  // Caret and spacing
29277
29856
  "cteditor-caret-[#3b82f6] cteditor-p-0 cteditor-transition-all cteditor-duration-200",
29278
29857
  "cteditor-w-full ",
@@ -29360,12 +29939,12 @@ const ToolbarWithEditor = (props) => {
29360
29939
  }
29361
29940
  );
29362
29941
  };
29363
- const AutocompleteWrapper = () => {
29942
+ const CombinedPluginWrapper = () => {
29364
29943
  const { toolbarState } = useToolbarState();
29365
- if (!toolbarState.isAutocompleteEnabled) {
29944
+ if (!toolbarState.isAutocompleteEnabled && !toolbarState.isGrammarCheckEnabled) {
29366
29945
  return null;
29367
29946
  }
29368
- return /* @__PURE__ */ jsx(AutocompletePlugin, { minMatchLength: 2, maxSuggestions: 10 });
29947
+ return /* @__PURE__ */ jsx(CombinedAutocompleteGrammarPlugin, { minMatchLength: 2, maxSuggestions: 10, enableAI: true });
29369
29948
  };
29370
29949
  const OnChangeWrapper = ({ onChange }) => {
29371
29950
  const [editor] = useLexicalComposerContext();
@@ -29443,7 +30022,7 @@ const ConfigurableEditor = ({
29443
30022
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(CommentProvider, { children: /* @__PURE__ */ jsxs(LexicalComposer, { initialConfig: editorInitialConfig, children: [
29444
30023
  /* @__PURE__ */ jsx(HtmlViewProvider, { children: /* @__PURE__ */ jsxs(ToolbarContext, { children: [
29445
30024
  /* @__PURE__ */ jsxs(Stack, { children: [
29446
- config.enableToolbar && /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-justify-between cteditor-items-center cteditor-mb-4", children: [
30025
+ config.enableToolbar && /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-justify-between cteditor-items-center cteditor-mb-4 cteditor-sticky cteditor-top-2 cteditor-z-50", children: [
29447
30026
  /* @__PURE__ */ jsx(
29448
30027
  ToolbarWithEditor,
29449
30028
  {
@@ -29492,14 +30071,15 @@ const ConfigurableEditor = ({
29492
30071
  /* @__PURE__ */ jsx(HtmlSyncPlugin, {}),
29493
30072
  /* @__PURE__ */ jsx(CodeHighlightPlugin, {}),
29494
30073
  /* @__PURE__ */ jsx(SlashCommandPlugin, {}),
29495
- /* @__PURE__ */ jsx(AutocompleteWrapper, {}),
29496
- /* @__PURE__ */ jsx(GrammarCheckPlugin, {}),
30074
+ /* @__PURE__ */ jsx(CombinedPluginWrapper, {}),
29497
30075
  /* @__PURE__ */ jsx(OnChangeWrapper, { onChange }),
29498
30076
  /* @__PURE__ */ jsx(InitialContentPlugin, { initialContent }),
29499
30077
  /* @__PURE__ */ jsx(HistoryPlugin, {}),
29500
30078
  /* @__PURE__ */ jsx(LocalStoragePlugin$1, { namespace: initialConfig.namespace }),
29501
30079
  /* @__PURE__ */ jsx(ListPlugin, {}),
29502
30080
  /* @__PURE__ */ jsx(LinkPlugin, { hasLinkAttributes: false }),
30081
+ /* @__PURE__ */ jsx(DragDropPaste, {}),
30082
+ /* @__PURE__ */ jsx(RichTextPastePlugin, {}),
29503
30083
  /* @__PURE__ */ jsx(FilePlugin, {}),
29504
30084
  /* @__PURE__ */ jsx(HorizontalRulePlugin, {}),
29505
30085
  /* @__PURE__ */ jsx(CustomHorizontalRulePlugin, {}),
@@ -29561,7 +30141,7 @@ const ScopedEditorWrapper = ({
29561
30141
  className = "",
29562
30142
  darkMode = false
29563
30143
  }) => {
29564
- return /* @__PURE__ */ jsx("div", { id: "ct-editor-f47ac10b", children: /* @__PURE__ */ jsx("div", { className: "cteditor-p-2 ", children }) });
30144
+ return /* @__PURE__ */ jsx("div", { id: "ct-editor-f47ac10b", className: "cteditor-max-w-full", children: /* @__PURE__ */ jsx("div", { className: "cteditor-p-2 cteditor-w-full", children }) });
29565
30145
  };
29566
30146
  const MessageContainer = styled.div`
29567
30147
  display: flex;
@@ -29685,4 +30265,4 @@ export {
29685
30265
  useHtmlView as u,
29686
30266
  verifyApiKey as v
29687
30267
  };
29688
- //# sourceMappingURL=index-7aab7b5a.js.map
30268
+ //# sourceMappingURL=index-413952d9.js.map