@mdxeditor/editor 3.52.2 → 3.52.4

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.
@@ -9,10 +9,11 @@ const AdmonitionDirectiveDescriptor = {
9
9
  return ADMONITION_TYPES.includes(node.name);
10
10
  },
11
11
  Editor({ mdastNode }) {
12
+ var _a;
12
13
  const {
13
14
  config: { theme }
14
15
  } = useNestedEditorContext();
15
- return /* @__PURE__ */ React__default.createElement("div", { className: theme.admonition[mdastNode.name] }, /* @__PURE__ */ React__default.createElement(
16
+ return /* @__PURE__ */ React__default.createElement("div", { className: (_a = theme.admonition) == null ? void 0 : _a[mdastNode.name] }, /* @__PURE__ */ React__default.createElement(
16
17
  NestedLexicalEditor,
17
18
  {
18
19
  block: true,
@@ -212,7 +212,7 @@ function fixWrappingWhitespace(node, parentChain) {
212
212
  if (node.type === "strong" || node.type === "emphasis") {
213
213
  const lastChild = node.children.at(-1);
214
214
  if ((lastChild == null ? void 0 : lastChild.type) === "text") {
215
- const trailingWhitespace = lastChild.value.match(TRAILING_WHITESPACE_REGEXP);
215
+ const trailingWhitespace = TRAILING_WHITESPACE_REGEXP.exec(lastChild.value);
216
216
  if (trailingWhitespace) {
217
217
  lastChild.value = lastChild.value.replace(TRAILING_WHITESPACE_REGEXP, "");
218
218
  const parent = parentChain.at(-1);
@@ -227,7 +227,7 @@ function fixWrappingWhitespace(node, parentChain) {
227
227
  }
228
228
  const firstChild = node.children.at(0);
229
229
  if ((firstChild == null ? void 0 : firstChild.type) === "text") {
230
- const leadingWhitespace = firstChild.value.match(LEADING_WHITESPACE_REGEXP);
230
+ const leadingWhitespace = LEADING_WHITESPACE_REGEXP.exec(firstChild.value);
231
231
  if (leadingWhitespace) {
232
232
  firstChild.value = firstChild.value.replace(LEADING_WHITESPACE_REGEXP, "");
233
233
  const parent = parentChain.at(-1);
@@ -98,7 +98,7 @@ function importMdastTreeToLexical({ root, mdastRoot, visitors, ...descriptors })
98
98
  if (!visitor) {
99
99
  try {
100
100
  throw new UnrecognizedMarkdownConstructError(`Unsupported markdown syntax: ${toMarkdown(mdastNode)}`);
101
- } catch (e) {
101
+ } catch (_e) {
102
102
  throw new UnrecognizedMarkdownConstructError(
103
103
  `Parsing of the following markdown structure failed: ${JSON.stringify({
104
104
  type: mdastNode.type,
package/dist/index.d.ts CHANGED
@@ -229,6 +229,12 @@ export declare const addNestedEditorChild$: NodeRef<default_2.ComponentType<{}>
229
229
  */
230
230
  export declare const addSyntaxExtension$: NodeRef< Extension | Extension[]>;
231
231
 
232
+ /**
233
+ * Lets you add React components as children of table cell editors.
234
+ * @group Core
235
+ */
236
+ export declare const addTableCellEditorChild$: NodeRef<default_2.ComponentType<{}> | default_2.ComponentType<{}>[]>;
237
+
232
238
  /**
233
239
  * Adds a markdown to string extension to be used when exporting markdown from the Lexical tree.
234
240
  * @group Markdown Processing
@@ -424,7 +430,7 @@ export declare const ChangeAdmonitionType: () => JSX_2.Element;
424
430
  * See {@link ConditionalContents} for an example on how to display the dropdown only when a code block is in focus.
425
431
  * @group Toolbar Components
426
432
  */
427
- export declare const ChangeCodeMirrorLanguage: () => JSX_2.Element;
433
+ export declare const ChangeCodeMirrorLanguage: () => JSX_2.Element | null;
428
434
 
429
435
  export declare type ClickLinkCallback = (url: string) => void;
430
436
 
@@ -548,11 +554,12 @@ export declare class CodeBlockNode extends DecoratorNode<JSX.Element> {
548
554
  };
549
555
  static getType(): string;
550
556
  static clone(node: CodeBlockNode): CodeBlockNode;
557
+ afterCloneFrom(prevNode: this): void;
551
558
  static importJSON(serializedNode: SerializedCodeBlockNode): CodeBlockNode;
552
559
  static importDOM(): DOMConversionMap;
553
560
  constructor(code: string, language: string, meta: string, key?: NodeKey);
554
561
  exportJSON(): SerializedCodeBlockNode;
555
- createDOM(_config: EditorConfig): HTMLDivElement;
562
+ createDOM(_config: EditorConfig, _editor: LexicalEditor): HTMLDivElement;
556
563
  updateDOM(): false;
557
564
  getCode(): string;
558
565
  getMeta(): string;
@@ -573,11 +580,11 @@ export declare const codeBlockPlugin: (params?: {
573
580
  /**
574
581
  * Pass an array of {@link CodeBlockEditorDescriptor} to register custom code block editors.
575
582
  */
576
- codeBlockEditorDescriptors?: CodeBlockEditorDescriptor[] | undefined;
583
+ codeBlockEditorDescriptors?: CodeBlockEditorDescriptor[];
577
584
  /**
578
585
  * The default language to use when creating a new code block if no language is passed.
579
586
  */
580
- defaultCodeBlockLanguage?: string | undefined;
587
+ defaultCodeBlockLanguage?: string;
581
588
  } | undefined) => RealmPlugin;
582
589
 
583
590
  /**
@@ -604,13 +611,13 @@ export declare const codeMirrorPlugin: (params?: {
604
611
  /**
605
612
  * Optional, additional CodeMirror extensions to load in the diff/source mode.
606
613
  */
607
- codeMirrorExtensions?: Extension_2[] | undefined;
614
+ codeMirrorExtensions?: Extension_2[];
608
615
  /**
609
616
  * Whether or not to try to dynamically load the code block language support.
610
617
  * Disable if you want to manually pass the supported languages.
611
618
  * @group CodeMirror
612
619
  */
613
- autoLoadLanguageSupport?: boolean | undefined;
620
+ autoLoadLanguageSupport?: boolean;
614
621
  } | undefined) => RealmPlugin;
615
622
 
616
623
  /**
@@ -887,7 +894,7 @@ export declare const DialogButton: default_2.ForwardRefExoticComponent<{
887
894
  /**
888
895
  * The autocomplete suggestions to show in the dialog input.
889
896
  */
890
- autocompleteSuggestions?: string[] | undefined;
897
+ autocompleteSuggestions?: string[];
891
898
  /**
892
899
  * The callback to call when the dialog is submitted. The callback receives the value of the text input as a parameter.
893
900
  */
@@ -924,21 +931,21 @@ export declare const diffSourcePlugin: (params?: {
924
931
  * The initial view mode of the editor.
925
932
  * @default 'rich-text'
926
933
  */
927
- viewMode?: ViewMode | undefined;
934
+ viewMode?: ViewMode;
928
935
  /**
929
936
  * The markdown to show in the diff editor.
930
937
  * @default ''
931
938
  */
932
- diffMarkdown?: string | undefined;
939
+ diffMarkdown?: string;
933
940
  /**
934
941
  * Optional, additional CodeMirror extensions to load in the diff/source mode.
935
942
  */
936
- codeMirrorExtensions?: Extension_2[] | undefined;
943
+ codeMirrorExtensions?: Extension_2[];
937
944
  /**
938
945
  * Set the diff editor to read-only.
939
946
  * @default false
940
947
  */
941
- readOnlyDiff?: boolean | undefined;
948
+ readOnlyDiff?: boolean;
942
949
  } | undefined) => RealmPlugin;
943
950
 
944
951
  /**
@@ -1072,7 +1079,7 @@ export declare const directivesPlugin: (params?: {
1072
1079
  * Set this option to display unknown text-directives as normal text nodes.
1073
1080
  * This is handy when colons are used to separate words, e.g. in german "Schüler:in"
1074
1081
  */
1075
- escapeUnknownTextDirectives?: boolean | undefined;
1082
+ escapeUnknownTextDirectives?: boolean;
1076
1083
  } | undefined) => RealmPlugin;
1077
1084
 
1078
1085
  /**
@@ -1146,6 +1153,12 @@ export declare interface EditorInFocus {
1146
1153
  editorRef: unknown;
1147
1154
  }
1148
1155
 
1156
+ /**
1157
+ * Whether the currently active editor is inside a table cell.
1158
+ * @group Core
1159
+ */
1160
+ export declare const editorInTable$: NodeRef<boolean>;
1161
+
1149
1162
  /**
1150
1163
  * A reference to a DOM element. used for the various popups, dialogs, and tooltips
1151
1164
  * @group Core
@@ -1362,7 +1375,7 @@ export declare const headingsPlugin: (params?: {
1362
1375
  * Allows you to limit the headings used in the editor. Affects the block type dropdown and the keyboard shortcuts.
1363
1376
  * @default [1, 2, 3, 4, 5, 6]
1364
1377
  */
1365
- allowedHeadingLevels?: readonly HEADING_LEVEL[] | undefined;
1378
+ allowedHeadingLevels?: readonly HEADING_LEVEL[];
1366
1379
  } | undefined) => RealmPlugin;
1367
1380
 
1368
1381
  /**
@@ -1412,6 +1425,7 @@ export declare class ImageNode extends DecoratorNode<JSX.Element> {
1412
1425
  /* Excluded from this release type: __rest */
1413
1426
  /* Excluded from this release type: getType */
1414
1427
  /* Excluded from this release type: clone */
1428
+ /* Excluded from this release type: afterCloneFrom */
1415
1429
  /* Excluded from this release type: importJSON */
1416
1430
  /* Excluded from this release type: exportDOM */
1417
1431
  /* Excluded from this release type: importDOM */
@@ -1451,15 +1465,15 @@ export declare const imagePlaceholder$: NodeRef< FC<{}> | null>;
1451
1465
  * @group Image
1452
1466
  */
1453
1467
  export declare const imagePlugin: (params?: {
1454
- imageUploadHandler?: ImageUploadHandler | undefined;
1455
- imageAutocompleteSuggestions?: string[] | undefined;
1456
- disableImageResize?: boolean | undefined;
1457
- disableImageSettingsButton?: boolean | undefined;
1458
- allowSetImageDimensions?: boolean | undefined;
1459
- imagePreviewHandler?: ImagePreviewHandler | undefined;
1460
- ImageDialog?: FC<{}> | (() => JSX.Element) | undefined;
1461
- EditImageToolbar?: FC<{}> | (() => JSX.Element) | undefined;
1462
- imagePlaceholder?: (() => JSX.Element) | null | undefined;
1468
+ imageUploadHandler?: ImageUploadHandler;
1469
+ imageAutocompleteSuggestions?: string[];
1470
+ disableImageResize?: boolean;
1471
+ disableImageSettingsButton?: boolean;
1472
+ allowSetImageDimensions?: boolean;
1473
+ imagePreviewHandler?: ImagePreviewHandler;
1474
+ ImageDialog?: (() => JSX.Element) | React.FC;
1475
+ EditImageToolbar?: (() => JSX.Element) | React.FC;
1476
+ imagePlaceholder?: (() => JSX.Element) | null;
1463
1477
  } | undefined) => RealmPlugin;
1464
1478
 
1465
1479
  /**
@@ -1577,9 +1591,9 @@ export declare const insertDecoratorNode$: NodeRef<() => DecoratorNode<unknown>>
1577
1591
  * @group Directive
1578
1592
  */
1579
1593
  export declare const insertDirective$: NodeRef<{
1580
- type: Directives['type'];
1594
+ type: Directives["type"];
1581
1595
  name: string;
1582
- attributes?: Directives['attributes'];
1596
+ attributes?: Directives["attributes"];
1583
1597
  }>;
1584
1598
 
1585
1599
  /**
@@ -1620,15 +1634,15 @@ export declare type InsertImageParameters = FileImageParameters | SrcImageParame
1620
1634
  * @group JSX
1621
1635
  */
1622
1636
  export declare const insertJsx$: NodeRef<{
1623
- kind: 'text';
1637
+ kind: "text";
1624
1638
  name: string;
1625
1639
  props: JsxProperties;
1626
- children?: Mdast.PhrasingContent[] | undefined;
1640
+ children?: MdxJsxTextElement["children"];
1627
1641
  } | {
1628
- kind: 'flow';
1642
+ kind: "flow";
1629
1643
  name: string;
1630
1644
  props: JsxProperties;
1631
- children?: (Mdast.BlockContent | Mdast.DefinitionContent)[] | undefined;
1645
+ children?: MdxJsxFlowElement["children"];
1632
1646
  }>;
1633
1647
 
1634
1648
  /**
@@ -1666,11 +1680,11 @@ export declare const insertTable$: NodeRef<{
1666
1680
  /**
1667
1681
  * The number of rows of the table.
1668
1682
  */
1669
- rows?: number | undefined;
1683
+ rows?: number;
1670
1684
  /**
1671
1685
  * The number of columns of the table.
1672
1686
  */
1673
- columns?: number | undefined;
1687
+ columns?: number;
1674
1688
  }>;
1675
1689
 
1676
1690
  /**
@@ -1968,23 +1982,23 @@ export declare const linkDialogPlugin: (params?: {
1968
1982
  /**
1969
1983
  * If passed, the link dialog will be rendered using this component instead of the default one.
1970
1984
  */
1971
- LinkDialog?: (() => JSX.Element) | undefined;
1985
+ LinkDialog?: () => JSX.Element;
1972
1986
  /**
1973
1987
  * If passed, the link input field will autocomplete using the published suggestions.
1974
1988
  */
1975
- linkAutocompleteSuggestions?: string[] | undefined;
1989
+ linkAutocompleteSuggestions?: string[];
1976
1990
  /**
1977
1991
  * If set, clicking on the link in the preview popup will call this callback instead of opening the link.
1978
1992
  */
1979
- onClickLinkCallback?: ClickLinkCallback | undefined;
1993
+ onClickLinkCallback?: ClickLinkCallback;
1980
1994
  /**
1981
1995
  * Invoked when a link is clicked in read-only mode
1982
1996
  */
1983
- onReadOnlyClickLinkCallback?: ReadOnlyClickLinkCallback | undefined;
1997
+ onReadOnlyClickLinkCallback?: ReadOnlyClickLinkCallback;
1984
1998
  /**
1985
1999
  * If true, show the "Link title" field in link dialogs (this sets mouseover text, NOT anchor text)
1986
2000
  */
1987
- showLinkTitleField?: boolean | undefined;
2001
+ showLinkTitleField?: boolean;
1988
2002
  } | undefined) => RealmPlugin;
1989
2003
 
1990
2004
  /**
@@ -2002,12 +2016,12 @@ export declare const linkPlugin: (params?: {
2002
2016
  * An optional function to validate the URL of a link.
2003
2017
  * By default, no validation is performed.
2004
2018
  */
2005
- validateUrl?: default_2.ComponentProps<typeof LinkPlugin>['validateUrl'];
2019
+ validateUrl?: default_2.ComponentProps<typeof LinkPlugin>["validateUrl"];
2006
2020
  /**
2007
2021
  * Whether to disable the auto-linking of URLs and email addresses.
2008
2022
  * @default false
2009
2023
  */
2010
- disableAutoLink?: boolean | undefined;
2024
+ disableAutoLink?: boolean;
2011
2025
  } | undefined) => RealmPlugin;
2012
2026
 
2013
2027
  /**
@@ -2237,7 +2251,7 @@ export declare interface MDXEditorMethods {
2237
2251
  /**
2238
2252
  * Sets focus on input
2239
2253
  */
2240
- focus: (callbackFn?: (() => void) | undefined, opts?: {
2254
+ focus: (callbackFn?: () => void, opts?: {
2241
2255
  defaultSelection?: 'rootStart' | 'rootEnd';
2242
2256
  preventScroll?: boolean;
2243
2257
  }) => void;
@@ -2781,7 +2795,7 @@ export declare const Select: <T extends string>(props: {
2781
2795
  items: ({
2782
2796
  label: string | JSX.Element;
2783
2797
  value: T;
2784
- } | 'separator')[];
2798
+ } | "separator")[];
2785
2799
  }) => JSX_2.Element;
2786
2800
 
2787
2801
  /* Excluded from this release type: SelectButtonTrigger */
@@ -2875,22 +2889,23 @@ export declare const showLinkTitleField$: NodeRef<boolean>;
2875
2889
  * See {@link ConditionalContents} for an example on how to display the dropdown only when a sandpack editor is in focus.
2876
2890
  * @group Toolbar Components
2877
2891
  */
2878
- export declare const ShowSandpackInfo: () => JSX_2.Element;
2892
+ export declare const ShowSandpackInfo: () => JSX_2.Element | null;
2879
2893
 
2880
2894
  /**
2881
2895
  * A toolbar primitive that allows you to build an UI with multiple exclusive toggle groups, like the list type toggle.
2882
2896
  * @group Toolbar Primitives
2883
2897
  */
2884
- export declare const SingleChoiceToggleGroup: <T extends string>({ value, onChange, className, ggClassName, items }: {
2898
+ export declare const SingleChoiceToggleGroup: <T extends string>({ value, onChange, className, ggClassName, items, disabled }: {
2885
2899
  items: {
2886
2900
  title: string;
2887
2901
  value: T;
2888
2902
  contents: default_2.ReactNode;
2889
2903
  }[];
2890
- onChange: (value: T | '') => void;
2891
- value: T | '';
2904
+ onChange: (value: T | "") => void;
2905
+ value: T | "";
2892
2906
  ggClassName?: string;
2893
2907
  className?: string;
2908
+ disabled?: boolean;
2894
2909
  }) => JSX_2.Element;
2895
2910
 
2896
2911
  /* Excluded from this release type: SingleToggleGroup */
@@ -2928,6 +2943,13 @@ export declare const switchFromPreviewToLinkEdit$: NodeRef<void>;
2928
2943
 
2929
2944
  export declare const syntaxExtensions$: NodeRef< Extension[]>;
2930
2945
 
2946
+ /**
2947
+ * React Components registered to be rendered inside table cell editors. Use this instead of {@link addNestedEditorChild$} for components that should only appear in table cells.
2948
+ * Plugins that should not be active in table cells (e.g. lists) should not register here.
2949
+ * @group Core
2950
+ */
2951
+ export declare const tableCellEditorChildren$: NodeRef<default_2.ComponentType<{}>[]>;
2952
+
2931
2953
  /**
2932
2954
  * A Lexical node that represents a markdown table.
2933
2955
  * Use {@link "$createTableNode"} to construct one.
@@ -3036,11 +3058,11 @@ export declare const toolbarPlugin: (params?: {
3036
3058
  /**
3037
3059
  * The class name to apply to the toolbar element
3038
3060
  */
3039
- toolbarClassName?: string | undefined;
3061
+ toolbarClassName?: string;
3040
3062
  /**
3041
3063
  * Controls the position of the toolbar (top by default)
3042
3064
  */
3043
- toolbarPosition?: "top" | "bottom" | undefined;
3065
+ toolbarPosition?: "top" | "bottom";
3044
3066
  } | undefined) => RealmPlugin;
3045
3067
 
3046
3068
  /* Excluded from this release type: ToolbarToggleItem */
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { MDXEditor } from "./MDXEditor.js";
4
4
  import { defaultSvgIcons } from "./defaultSvgIcons.js";
5
5
  import { MarkdownParseError, UnrecognizedMarkdownConstructError, importMarkdownToLexical, importMdastTreeToLexical } from "./importMarkdownToLexical.js";
6
6
  import { exportLexicalTreeToMdast, exportMarkdownFromLexical } from "./exportMarkdownFromLexical.js";
7
- import { Appender, NESTED_EDITOR_UPDATED_COMMAND, activeEditor$, activeEditorSubscriptions$, activePlugins$, addActivePlugin$, addBottomAreaChild$, addComposerChild$, addEditorWrapper$, addExportVisitor$, addImportVisitor$, addLexicalNode$, addMdastExtension$, addNestedEditorChild$, addSyntaxExtension$, addToMarkdownExtension$, addTopAreaChild$, applyBlockType$, applyFormat$, autoFocus$, bottomAreaChildren$, codeBlockEditorDescriptors$, composerChildren$, contentEditableClassName$, contentEditableRef$, contentEditableWrapperElement$, convertSelectionToNode$, corePlugin, createActiveEditorSubscription$, createRootEditorSubscription$, currentBlockType$, currentFormat$, currentSelection$, directiveDescriptors$, editorInFocus$, editorRootElementRef$, editorWrapperElementRef$, editorWrappers$, exportVisitors$, historyState$, iconComponentFor$, importVisitors$, inFocus$, initialMarkdown$, initialMarkdownNormalize$, insertDecoratorNode$, insertMarkdown$, jsxComponentDescriptors$, jsxIsAvailable$, lexicalTheme$, markdown$, markdownErrorSignal$, markdownProcessingError$, markdownSourceEditorValue$, mdastExtensions$, muteChange$, nestedEditorChildren$, onBlur$, placeholder$, readOnly$, rootEditor$, rootEditorSubscriptions$, setMarkdown$, spellCheck$, syntaxExtensions$, toMarkdownExtensions$, toMarkdownOptions$, topAreaChildren$, translation$, useTranslation, usedLexicalNodes$, viewMode$ } from "./plugins/core/index.js";
7
+ import { Appender, NESTED_EDITOR_UPDATED_COMMAND, activeEditor$, activeEditorSubscriptions$, activePlugins$, addActivePlugin$, addBottomAreaChild$, addComposerChild$, addEditorWrapper$, addExportVisitor$, addImportVisitor$, addLexicalNode$, addMdastExtension$, addNestedEditorChild$, addSyntaxExtension$, addTableCellEditorChild$, addToMarkdownExtension$, addTopAreaChild$, applyBlockType$, applyFormat$, autoFocus$, bottomAreaChildren$, codeBlockEditorDescriptors$, composerChildren$, contentEditableClassName$, contentEditableRef$, contentEditableWrapperElement$, convertSelectionToNode$, corePlugin, createActiveEditorSubscription$, createRootEditorSubscription$, currentBlockType$, currentFormat$, currentSelection$, directiveDescriptors$, editorInFocus$, editorInTable$, editorRootElementRef$, editorWrapperElementRef$, editorWrappers$, exportVisitors$, historyState$, iconComponentFor$, importVisitors$, inFocus$, initialMarkdown$, initialMarkdownNormalize$, insertDecoratorNode$, insertMarkdown$, jsxComponentDescriptors$, jsxIsAvailable$, lexicalTheme$, markdown$, markdownErrorSignal$, markdownProcessingError$, markdownSourceEditorValue$, mdastExtensions$, muteChange$, nestedEditorChildren$, onBlur$, placeholder$, readOnly$, rootEditor$, rootEditorSubscriptions$, setMarkdown$, spellCheck$, syntaxExtensions$, tableCellEditorChildren$, toMarkdownExtensions$, toMarkdownOptions$, topAreaChildren$, translation$, useTranslation, usedLexicalNodes$, viewMode$ } from "./plugins/core/index.js";
8
8
  import { ALL_HEADING_LEVELS, allowedHeadingLevels$, headingsPlugin } from "./plugins/headings/index.js";
9
9
  import { insertThematicBreak$, thematicBreakPlugin } from "./plugins/thematic-break/index.js";
10
10
  import { applyListType$, currentListType$, listsPlugin } from "./plugins/lists/index.js";
@@ -179,6 +179,7 @@ export {
179
179
  addMdastExtension$,
180
180
  addNestedEditorChild$,
181
181
  addSyntaxExtension$,
182
+ addTableCellEditorChild$,
182
183
  addToMarkdownExtension$,
183
184
  addTopAreaChild$,
184
185
  admonitionLabelsMap,
@@ -230,6 +231,7 @@ export {
230
231
  disableImageSettingsButton$,
231
232
  editImageToolbarComponent$,
232
233
  editorInFocus$,
234
+ editorInTable$,
233
235
  editorRootElementRef$,
234
236
  editorSearchCursor$,
235
237
  editorSearchRanges$,
@@ -333,6 +335,7 @@ export {
333
335
  spellCheck$,
334
336
  switchFromPreviewToLinkEdit$,
335
337
  syntaxExtensions$,
338
+ tableCellEditorChildren$,
336
339
  tablePlugin,
337
340
  tap,
338
341
  thematicBreakPlugin,
@@ -45,6 +45,13 @@ class CodeBlockNode extends DecoratorNode {
45
45
  static clone(node) {
46
46
  return new CodeBlockNode(node.__code, node.__language, node.__meta, node.__key);
47
47
  }
48
+ afterCloneFrom(prevNode) {
49
+ super.afterCloneFrom(prevNode);
50
+ this.__code = prevNode.__code;
51
+ this.__meta = prevNode.__meta;
52
+ this.__language = prevNode.__language;
53
+ this.__focusEmitter = voidEmitter();
54
+ }
48
55
  static importJSON(serializedNode) {
49
56
  const { code, meta, language } = serializedNode;
50
57
  return $createCodeBlockNode({
@@ -73,7 +80,7 @@ class CodeBlockNode extends DecoratorNode {
73
80
  };
74
81
  }
75
82
  // View
76
- createDOM(_config) {
83
+ createDOM(_config, _editor) {
77
84
  return document.createElement("div");
78
85
  }
79
86
  updateDOM() {
@@ -145,9 +152,7 @@ const CodeBlockEditorContainer = (props) => {
145
152
  const codeBlockEditorDescriptors = useCellValue(codeBlockEditorDescriptors$);
146
153
  const defaultCodeBlockLanguage = useCellValue(defaultCodeBlockLanguage$);
147
154
  let descriptor = codeBlockEditorDescriptors.sort((a, b) => b.priority - a.priority).find((descriptor2) => descriptor2.match(props.language || "", props.meta || ""));
148
- if (!descriptor) {
149
- descriptor = codeBlockEditorDescriptors.find((descriptor2) => descriptor2.match(defaultCodeBlockLanguage || "", props.meta || ""));
150
- }
155
+ descriptor ?? (descriptor = codeBlockEditorDescriptors.find((descriptor2) => descriptor2.match(defaultCodeBlockLanguage || "", props.meta || "")));
151
156
  if (!descriptor) {
152
157
  throw new Error(`No CodeBlockEditor registered for language=${props.language} meta=${props.meta}`);
153
158
  }
@@ -164,10 +169,10 @@ function $isCodeBlockNode(node) {
164
169
  }
165
170
  function $convertPreElement(element) {
166
171
  const preElement = element;
167
- const code = preElement.textContent ?? "";
172
+ const code = preElement.textContent;
168
173
  const classAttribute = element.getAttribute("class") ?? "";
169
174
  const dataLanguageAttribute = element.getAttribute("data-language") ?? "";
170
- const languageMatch = classAttribute.match(/language-(\w+)/);
175
+ const languageMatch = /language-(\w+)/.exec(classAttribute);
171
176
  const language = languageMatch ? languageMatch[1] : dataLanguageAttribute;
172
177
  const meta = preElement.getAttribute("data-meta") ?? "";
173
178
  return {
@@ -66,7 +66,7 @@ const CodeMirrorEditor = ({ language, nodeKey, code, focusEmitter }) => {
66
66
  try {
67
67
  const languageSupport = await languageData.load();
68
68
  extensions.push(languageSupport.extension);
69
- } catch (e) {
69
+ } catch (_e) {
70
70
  console.warn("failed to load language support for", language);
71
71
  }
72
72
  }
@@ -46,7 +46,7 @@ const codeMirrorPlugin = realmPlugin({
46
46
  function buildCodeBlockDescriptor(codeBlockLanguages) {
47
47
  return {
48
48
  match(language, meta) {
49
- return Boolean(Object.hasOwn(codeBlockLanguages, language ?? "")) && !meta;
49
+ return Object.hasOwn(codeBlockLanguages, language ?? "") && !meta;
50
50
  },
51
51
  priority: 1,
52
52
  Editor: CodeMirrorEditor
@@ -3,7 +3,7 @@ import { createEmptyHistoryState } from "@lexical/react/LexicalHistoryPlugin.js"
3
3
  import { $isHeadingNode } from "@lexical/rich-text";
4
4
  import { $setBlocksType } from "@lexical/selection";
5
5
  import { $findMatchingParent, $wrapNodeInElement, $insertNodeToNearestRoot } from "@lexical/utils";
6
- import { Cell, Signal, withLatestFrom, filter, useCellValue, scan, map } from "@mdxeditor/gurx";
6
+ import { Cell, Signal, withLatestFrom, filter, map, useCellValue, scan } from "@mdxeditor/gurx";
7
7
  import { createCommand, FORMAT_TEXT_COMMAND, $isRootOrShadowRoot, $getRoot, $setSelection, $getSelection, $insertNodes, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, DecoratorNode, $createParagraphNode, FOCUS_COMMAND, BLUR_COMMAND, $isRangeSelection, createEditor, ParagraphNode, TextNode } from "lexical";
8
8
  import { gfmStrikethrough } from "micromark-extension-gfm-strikethrough";
9
9
  import { gfmStrikethroughToMarkdown, gfmStrikethroughFromMarkdown } from "mdast-util-gfm-strikethrough";
@@ -70,9 +70,7 @@ const currentSelection$ = Cell(null, (r) => {
70
70
  const parent = e.getParent();
71
71
  return parent !== null && $isRootOrShadowRoot(parent);
72
72
  });
73
- if (element === null) {
74
- element = anchorNode.getTopLevelElementOrThrow();
75
- }
73
+ element ?? (element = anchorNode.getTopLevelElementOrThrow());
76
74
  const elementKey = element.getKey();
77
75
  const elementDOM = theEditor.getElementByKey(elementKey);
78
76
  if (elementDOM !== null) {
@@ -404,6 +402,20 @@ const editorWrappers$ = Cell([]);
404
402
  const addEditorWrapper$ = Appender(editorWrappers$);
405
403
  const nestedEditorChildren$ = Cell([]);
406
404
  const addNestedEditorChild$ = Appender(nestedEditorChildren$);
405
+ const tableCellEditorChildren$ = Cell([]);
406
+ const addTableCellEditorChild$ = Appender(tableCellEditorChildren$);
407
+ const editorInTable$ = Cell(false, (r) => {
408
+ r.link(
409
+ r.pipe(
410
+ activeEditor$,
411
+ map((editor) => {
412
+ var _a, _b;
413
+ return ["td", "th"].includes(((_b = (_a = editor == null ? void 0 : editor.getRootElement()) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.nodeName.toLowerCase()) ?? "");
414
+ })
415
+ ),
416
+ editorInTable$
417
+ );
418
+ });
407
419
  const historyState$ = Cell(createEmptyHistoryState());
408
420
  const currentBlockType$ = Cell("");
409
421
  const applyBlockType$ = Signal();
@@ -616,6 +628,7 @@ export {
616
628
  addMdastExtension$,
617
629
  addNestedEditorChild$,
618
630
  addSyntaxExtension$,
631
+ addTableCellEditorChild$,
619
632
  addToMarkdownExtension$,
620
633
  addTopAreaChild$,
621
634
  applyBlockType$,
@@ -636,6 +649,7 @@ export {
636
649
  currentSelection$,
637
650
  directiveDescriptors$,
638
651
  editorInFocus$,
652
+ editorInTable$,
639
653
  editorRootElementRef$,
640
654
  editorWrapperElementRef$,
641
655
  editorWrappers$,
@@ -666,6 +680,7 @@ export {
666
680
  setMarkdown$,
667
681
  spellCheck$,
668
682
  syntaxExtensions$,
683
+ tableCellEditorChildren$,
669
684
  toMarkdownExtensions$,
670
685
  toMarkdownOptions$,
671
686
  topAreaChildren$,
@@ -6,31 +6,31 @@ import { controlOrMeta } from "../../utils/detectMac.js";
6
6
  import { createRootEditorSubscription$, convertSelectionToNode$, addExportVisitor$, addLexicalNode$, addImportVisitor$, addActivePlugin$ } from "../core/index.js";
7
7
  import { LexicalHeadingVisitor } from "./LexicalHeadingVisitor.js";
8
8
  import { MdastHeadingVisitor } from "./MdastHeadingVisitor.js";
9
- const FORMATTING_KEYS = [48, 49, 50, 51, 52, 53, 54];
9
+ const FORMATTING_KEYS = ["Digit0", "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6"];
10
10
  const ALL_HEADING_LEVELS = [1, 2, 3, 4, 5, 6];
11
11
  const CODE_TO_HEADING_LEVEL_MAP = {
12
- 49: 1,
13
- 50: 2,
14
- 51: 3,
15
- 52: 4,
16
- 53: 5,
17
- 54: 6
12
+ Digit1: 1,
13
+ Digit2: 2,
14
+ Digit3: 3,
15
+ Digit4: 4,
16
+ Digit5: 5,
17
+ Digit6: 6
18
18
  };
19
19
  const allowedHeadingLevels$ = Cell(ALL_HEADING_LEVELS, (r) => {
20
20
  r.pub(createRootEditorSubscription$, (theRootEditor) => {
21
21
  return theRootEditor.registerCommand(
22
22
  KEY_DOWN_COMMAND,
23
23
  (event) => {
24
- const { keyCode, ctrlKey, metaKey, altKey } = event;
25
- if (FORMATTING_KEYS.includes(keyCode) && controlOrMeta(metaKey, ctrlKey) && altKey) {
24
+ const { code, ctrlKey, metaKey, altKey } = event;
25
+ if (FORMATTING_KEYS.includes(code) && controlOrMeta(metaKey, ctrlKey) && altKey) {
26
26
  event.preventDefault();
27
27
  theRootEditor.update(() => {
28
- if (keyCode === 48) {
28
+ if (code === "Digit0") {
29
29
  r.pub(convertSelectionToNode$, () => $createParagraphNode());
30
30
  } else {
31
31
  const allowedHeadingLevels = r.getValue(allowedHeadingLevels$);
32
- const requestedHeadingLevel = CODE_TO_HEADING_LEVEL_MAP[keyCode];
33
- if (!allowedHeadingLevels.includes(requestedHeadingLevel)) {
32
+ const requestedHeadingLevel = CODE_TO_HEADING_LEVEL_MAP[code];
33
+ if (allowedHeadingLevels.includes(requestedHeadingLevel)) {
34
34
  r.pub(convertSelectionToNode$, () => $createHeadingNode(`h${requestedHeadingLevel}`));
35
35
  }
36
36
  }
@@ -39,7 +39,7 @@ function EditImageToolbar(props) {
39
39
  openEditImageDialog({
40
40
  nodeKey,
41
41
  initialValues: {
42
- src: !initialImagePath ? imageSource : initialImagePath,
42
+ src: initialImagePath ?? imageSource,
43
43
  title,
44
44
  altText: alt,
45
45
  width: parseImageDimension(width),
@@ -37,8 +37,8 @@ class ImageNode extends DecoratorNode {
37
37
  this.__src = src;
38
38
  this.__title = title;
39
39
  this.__altText = altText;
40
- this.__width = width ? width : "inherit";
41
- this.__height = height ? height : "inherit";
40
+ this.__width = width ?? "inherit";
41
+ this.__height = height ?? "inherit";
42
42
  this.__rest = rest ?? [];
43
43
  }
44
44
  /** @internal */
@@ -50,6 +50,16 @@ class ImageNode extends DecoratorNode {
50
50
  return new ImageNode(node.__src, node.__altText, node.__title, node.__width, node.__height, node.__rest, node.__key);
51
51
  }
52
52
  /** @internal */
53
+ afterCloneFrom(prevNode) {
54
+ super.afterCloneFrom(prevNode);
55
+ this.__src = prevNode.__src;
56
+ this.__altText = prevNode.__altText;
57
+ this.__title = prevNode.__title;
58
+ this.__width = prevNode.__width;
59
+ this.__height = prevNode.__height;
60
+ this.__rest = prevNode.__rest;
61
+ }
62
+ /** @internal */
53
63
  static importJSON(serializedNode) {
54
64
  const { altText, title, src, width, rest, height } = serializedNode;
55
65
  const node = $createImageNode({
@@ -109,7 +119,7 @@ class ImageNode extends DecoratorNode {
109
119
  writable.__height = height;
110
120
  }
111
121
  /** @internal */
112
- createDOM(config) {
122
+ createDOM(config, _editor) {
113
123
  const span = document.createElement("span");
114
124
  const theme = config.theme;
115
125
  const className = theme.image;
@@ -35,7 +35,7 @@ function ImageResizer({
35
35
  startY: 0
36
36
  });
37
37
  const editorRootElement = editor.getRootElement();
38
- const maxWidthContainer = maxWidth ? maxWidth : editorRootElement !== null ? editorRootElement.getBoundingClientRect().width - 20 : 100;
38
+ const maxWidthContainer = maxWidth ?? (editorRootElement !== null ? editorRootElement.getBoundingClientRect().width - 20 : 100);
39
39
  const maxHeightContainer = editorRootElement !== null ? editorRootElement.getBoundingClientRect().height - 20 : 100;
40
40
  const minWidth = 100;
41
41
  const minHeight = 100;
@@ -6,7 +6,7 @@ import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
6
6
  import { LexicalAutoLinkPlugin } from "./AutoLinkPlugin.js";
7
7
  import { Cell } from "@mdxeditor/gurx";
8
8
  import { realmPlugin } from "../../RealmWithPlugins.js";
9
- import { addComposerChild$, addNestedEditorChild$, addExportVisitor$, addLexicalNode$, addImportVisitor$, addActivePlugin$ } from "../core/index.js";
9
+ import { addComposerChild$, addTableCellEditorChild$, addNestedEditorChild$, addExportVisitor$, addLexicalNode$, addImportVisitor$, addActivePlugin$ } from "../core/index.js";
10
10
  const disableAutoLink$ = Cell(false);
11
11
  const linkPlugin = realmPlugin({
12
12
  init(realm, params) {
@@ -20,6 +20,7 @@ const linkPlugin = realmPlugin({
20
20
  [addExportVisitor$]: LexicalLinkVisitor,
21
21
  [disableAutoLink$]: disableAutoLink,
22
22
  [addNestedEditorChild$]: EditorChild,
23
+ [addTableCellEditorChild$]: EditorChild,
23
24
  [addComposerChild$]: EditorChild
24
25
  });
25
26
  }
@@ -1,6 +1,6 @@
1
1
  import { $isLinkNode, $createLinkNode, $isAutoLinkNode, TOGGLE_LINK_COMMAND, LinkNode } from "@lexical/link";
2
2
  import { Signal, Cell, Action, withLatestFrom, map, filter } from "@mdxeditor/gurx";
3
- import { KEY_ESCAPE_COMMAND, COMMAND_PRIORITY_LOW, KEY_MODIFIER_COMMAND, $getSelection, $isRangeSelection, COMMAND_PRIORITY_HIGH, $getNodeByKey, $createTextNode, $insertNodes, $isTextNode, $getNearestNodeFromDOMNode } from "lexical";
3
+ import { KEY_ESCAPE_COMMAND, COMMAND_PRIORITY_LOW, KEY_DOWN_COMMAND, $getSelection, $isRangeSelection, COMMAND_PRIORITY_HIGH, $getNodeByKey, $createTextNode, $insertNodes, $isTextNode, $getNearestNodeFromDOMNode } from "lexical";
4
4
  import { realmPlugin } from "../../RealmWithPlugins.js";
5
5
  import { IS_APPLE } from "../../utils/detectMac.js";
6
6
  import { getSelectionRectangle, getSelectedNode } from "../../utils/lexicalHelpers.js";
@@ -46,7 +46,7 @@ const linkDialogState$ = Cell({ type: "inactive" }, (r) => {
46
46
  });
47
47
  r.pub(createActiveEditorSubscription$, (editor) => {
48
48
  return editor.registerCommand(
49
- KEY_MODIFIER_COMMAND,
49
+ KEY_DOWN_COMMAND,
50
50
  (event) => {
51
51
  if (event.key === "k" && (IS_APPLE ? event.metaKey : event.ctrlKey) && !r.getValue(readOnly$)) {
52
52
  const selection = $getSelection();
@@ -23,12 +23,10 @@ const LexicalListItemVisitor = {
23
23
  let surroundingParagraph = null;
24
24
  for (const child of lexicalNode.getChildren()) {
25
25
  if ($isTextNode(child) || $isLineBreakNode(child) || child.isInline() && ($isElementNode(child) || $isDecoratorNode(child))) {
26
- if (!surroundingParagraph) {
27
- surroundingParagraph = actions.appendToParent(listItem, {
28
- type: "paragraph",
29
- children: []
30
- });
31
- }
26
+ surroundingParagraph ?? (surroundingParagraph = actions.appendToParent(listItem, {
27
+ type: "paragraph",
28
+ children: []
29
+ }));
32
30
  actions.visit(child, surroundingParagraph);
33
31
  } else {
34
32
  surroundingParagraph = null;
@@ -29,9 +29,7 @@ const currentListType$ = Cell("", (r) => {
29
29
  const parent = e.getParent();
30
30
  return parent !== null && $isRootOrShadowRoot(parent);
31
31
  });
32
- if (element === null) {
33
- element = anchorNode.getTopLevelElementOrThrow();
34
- }
32
+ element ?? (element = anchorNode.getTopLevelElementOrThrow());
35
33
  const elementKey = element.getKey();
36
34
  const elementDOM = theEditor.getElementByKey(elementKey);
37
35
  if (elementDOM !== null) {
@@ -64,6 +62,7 @@ const listsPlugin = realmPlugin({
64
62
  [addToMarkdownExtension$]: gfmTaskListItemToMarkdown(),
65
63
  [addComposerChild$]: [TabIndentationPlugin, ListPlugin, CheckListPlugin],
66
64
  [addNestedEditorChild$]: [TabIndentationPlugin, ListPlugin, CheckListPlugin]
65
+ // Note: intentionally not registered to addTableCellEditorChild$ — lists are not supported in table cells
67
66
  });
68
67
  }
69
68
  });
@@ -1,10 +1,10 @@
1
+ import React__default from "react";
1
2
  import { BOLD_ITALIC_STAR, BOLD_ITALIC_UNDERSCORE, BOLD_STAR, BOLD_UNDERSCORE, INLINE_CODE, ITALIC_STAR, ITALIC_UNDERSCORE, QUOTE, LINK, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST, CODE } from "@lexical/markdown";
2
3
  import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
3
4
  import { HeadingNode, $isHeadingNode, $createHeadingNode } from "@lexical/rich-text";
4
- import React__default from "react";
5
5
  import { realmPlugin } from "../../RealmWithPlugins.js";
6
6
  import { CodeBlockNode, $createCodeBlockNode } from "../codeblock/CodeBlockNode.js";
7
- import { activePlugins$, addNestedEditorChild$, addComposerChild$ } from "../core/index.js";
7
+ import { activePlugins$, addTableCellEditorChild$, addNestedEditorChild$, addComposerChild$ } from "../core/index.js";
8
8
  import { allowedHeadingLevels$ } from "../headings/index.js";
9
9
  import { HorizontalRuleNode, $createHorizontalRuleNode, $isHorizontalRuleNode } from "@lexical/react/LexicalHorizontalRuleNode";
10
10
  const markdownShortcutPlugin = realmPlugin({
@@ -12,9 +12,11 @@ const markdownShortcutPlugin = realmPlugin({
12
12
  const pluginIds = realm.getValue(activePlugins$);
13
13
  const allowedHeadingLevels = pluginIds.includes("headings") ? realm.getValue(allowedHeadingLevels$) : [];
14
14
  const transformers = pickTransformersForActivePlugins(pluginIds, allowedHeadingLevels);
15
+ const tableCellTransformers = transformers.filter((t) => !LIST_TRANSFORMERS.has(t));
15
16
  realm.pubIn({
16
17
  [addComposerChild$]: () => /* @__PURE__ */ React__default.createElement(MarkdownShortcutPlugin, { transformers }),
17
- [addNestedEditorChild$]: () => /* @__PURE__ */ React__default.createElement(MarkdownShortcutPlugin, { transformers })
18
+ [addNestedEditorChild$]: () => /* @__PURE__ */ React__default.createElement(MarkdownShortcutPlugin, { transformers }),
19
+ [addTableCellEditorChild$]: () => /* @__PURE__ */ React__default.createElement(MarkdownShortcutPlugin, { transformers: tableCellTransformers })
18
20
  });
19
21
  }
20
22
  });
@@ -43,6 +45,7 @@ const THEMATIC_BREAK = {
43
45
  },
44
46
  type: "element"
45
47
  };
48
+ const LIST_TRANSFORMERS = /* @__PURE__ */ new Set([ORDERED_LIST, UNORDERED_LIST, CHECK_LIST]);
46
49
  function pickTransformersForActivePlugins(pluginIds, allowedHeadingLevels) {
47
50
  const transformers = [
48
51
  BOLD_ITALIC_STAR,
@@ -1,4 +1,4 @@
1
- import { trimTextContentFromAnchor } from "@lexical/selection";
1
+ import { $trimTextContentFromAnchor } from "@lexical/selection";
2
2
  import { $restoreEditorState } from "@lexical/utils";
3
3
  import { RootNode, $getSelection, $isRangeSelection } from "lexical";
4
4
  import { realmPlugin } from "../../RealmWithPlugins.js";
@@ -23,7 +23,7 @@ const maxLengthPlugin = realmPlugin({
23
23
  lastRestoredEditorState = prevEditorState;
24
24
  $restoreEditorState(editor, prevEditorState);
25
25
  } else {
26
- trimTextContentFromAnchor(editor, anchor, delCount);
26
+ $trimTextContentFromAnchor(editor, anchor, delCount);
27
27
  }
28
28
  }
29
29
  }
@@ -15,7 +15,7 @@ import classNames from "classnames";
15
15
  import styles from "../../styles/ui.module.css.js";
16
16
  import { isPartOftheEditorUI } from "../../utils/isPartOftheEditorUI.js";
17
17
  import { uuidv4 } from "../../utils/uuid4.js";
18
- import { iconComponentFor$, readOnly$, useTranslation, editorRootElementRef$, importVisitors$, exportVisitors$, usedLexicalNodes$, jsxComponentDescriptors$, directiveDescriptors$, codeBlockEditorDescriptors$, jsxIsAvailable$, rootEditor$, nestedEditorChildren$, NESTED_EDITOR_UPDATED_COMMAND } from "../core/index.js";
18
+ import { iconComponentFor$, readOnly$, useTranslation, editorRootElementRef$, importVisitors$, exportVisitors$, usedLexicalNodes$, jsxComponentDescriptors$, directiveDescriptors$, codeBlockEditorDescriptors$, jsxIsAvailable$, rootEditor$, tableCellEditorChildren$, NESTED_EDITOR_UPDATED_COMMAND } from "../core/index.js";
19
19
  import { useCellValues } from "@mdxeditor/gurx";
20
20
  const getCellType = (rowIndex) => {
21
21
  if (rowIndex === 0) {
@@ -33,9 +33,7 @@ const TableEditor = ({ mdastNode, parentEditor, lexicalTable }) => {
33
33
  const [iconComponentFor, readOnly] = useCellValues(iconComponentFor$, readOnly$);
34
34
  const getCellKey = React__default.useMemo(() => {
35
35
  return (cell) => {
36
- if (!cell.__cacheKey) {
37
- cell.__cacheKey = uuidv4();
38
- }
36
+ cell.__cacheKey ?? (cell.__cacheKey = uuidv4());
39
37
  return cell.__cacheKey;
40
38
  };
41
39
  }, []);
@@ -219,7 +217,7 @@ const CellEditor = ({ focus, setActiveCell, parentEditor, lexicalTable, contents
219
217
  codeBlockEditorDescriptors,
220
218
  jsxIsAvailable,
221
219
  rootEditor,
222
- nestedEditorChildren
220
+ tableCellEditorChildren
223
221
  ] = useCellValues(
224
222
  importVisitors$,
225
223
  exportVisitors$,
@@ -229,7 +227,7 @@ const CellEditor = ({ focus, setActiveCell, parentEditor, lexicalTable, contents
229
227
  codeBlockEditorDescriptors$,
230
228
  jsxIsAvailable$,
231
229
  rootEditor$,
232
- nestedEditorChildren$
230
+ tableCellEditorChildren$
233
231
  );
234
232
  const [editor] = React__default.useState(() => {
235
233
  const editor2 = createEditor({
@@ -323,9 +321,11 @@ const CellEditor = ({ focus, setActiveCell, parentEditor, lexicalTable, contents
323
321
  );
324
322
  }, [colIndex, editor, rootEditor, rowIndex, saveAndFocus, setActiveCell]);
325
323
  React__default.useEffect(() => {
326
- focus && editor.focus();
324
+ if (focus) {
325
+ editor.focus();
326
+ }
327
327
  }, [focus, editor]);
328
- return /* @__PURE__ */ React__default.createElement(LexicalNestedComposer, { initialEditor: editor }, /* @__PURE__ */ React__default.createElement(RichTextPlugin, { contentEditable: /* @__PURE__ */ React__default.createElement(ContentEditable, null), placeholder: /* @__PURE__ */ React__default.createElement("div", null), ErrorBoundary: LexicalErrorBoundary }), nestedEditorChildren.map((Child, index) => /* @__PURE__ */ React__default.createElement(Child, { key: index })), /* @__PURE__ */ React__default.createElement(HistoryPlugin, null));
328
+ return /* @__PURE__ */ React__default.createElement(LexicalNestedComposer, { initialEditor: editor }, /* @__PURE__ */ React__default.createElement(RichTextPlugin, { contentEditable: /* @__PURE__ */ React__default.createElement(ContentEditable, null), placeholder: /* @__PURE__ */ React__default.createElement("div", null), ErrorBoundary: LexicalErrorBoundary }), tableCellEditorChildren.map((Child, index) => /* @__PURE__ */ React__default.createElement(Child, { key: index })), /* @__PURE__ */ React__default.createElement(HistoryPlugin, null));
329
329
  };
330
330
  const ColumnEditor = ({
331
331
  parentEditor,
@@ -157,9 +157,7 @@ class TableNode extends DecoratorNode {
157
157
  setColumnAlign(colIndex, align) {
158
158
  const self = this.getWritable();
159
159
  const table = self.__mdastNode;
160
- if (table.align == null) {
161
- table.align = [];
162
- }
160
+ table.align ?? (table.align = []);
163
161
  table.align[colIndex] = align;
164
162
  }
165
163
  /** @internal */
@@ -195,7 +193,7 @@ function $convertTableElement(element) {
195
193
  children: [
196
194
  {
197
195
  type: "text",
198
- value: cell.textContent ?? ""
196
+ value: cell.textContent
199
197
  }
200
198
  ]
201
199
  };
@@ -1,14 +1,18 @@
1
1
  import { useCellValues } from "@mdxeditor/gurx";
2
2
  import React__default from "react";
3
3
  import styles from "../../../styles/ui.module.css.js";
4
+ import { $isCodeBlockNode } from "../../codeblock/CodeBlockNode.js";
4
5
  import { codeBlockLanguages$ } from "../../codemirror/index.js";
5
6
  import { editorInFocus$, activeEditor$, useTranslation } from "../../core/index.js";
6
7
  import { Select } from "../primitives/select.js";
7
8
  const EMPTY_VALUE = "__EMPTY_VALUE__";
8
9
  const ChangeCodeMirrorLanguage = () => {
9
10
  const [editorInFocus, theEditor, codeBlockLanguages] = useCellValues(editorInFocus$, activeEditor$, codeBlockLanguages$);
10
- const codeBlockNode = editorInFocus.rootNode;
11
+ const codeBlockNode = $isCodeBlockNode(editorInFocus.rootNode) ? editorInFocus.rootNode : null;
11
12
  const t = useTranslation();
13
+ if (!codeBlockNode) {
14
+ return null;
15
+ }
12
16
  let currentLanguage = codeBlockNode.getLanguage();
13
17
  if (currentLanguage === "") {
14
18
  currentLanguage = EMPTY_VALUE;
@@ -1,25 +1,13 @@
1
1
  import { ButtonWithTooltip } from "../primitives/toolbar.js";
2
2
  import React__default from "react";
3
3
  import { insertTable$ } from "../../table/index.js";
4
- import { useCellValue, usePublisher, Cell, map } from "@mdxeditor/gurx";
5
- import { iconComponentFor$, useTranslation, activeEditor$ } from "../../core/index.js";
6
- const disableInsertTableButton$ = Cell(false, (r) => {
7
- r.link(
8
- r.pipe(
9
- activeEditor$,
10
- map((editor) => {
11
- var _a, _b;
12
- return ["td", "th"].includes(((_b = (_a = editor == null ? void 0 : editor.getRootElement()) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.nodeName.toLowerCase()) ?? "");
13
- })
14
- ),
15
- disableInsertTableButton$
16
- );
17
- });
4
+ import { useCellValue, usePublisher } from "@mdxeditor/gurx";
5
+ import { iconComponentFor$, useTranslation, editorInTable$ } from "../../core/index.js";
18
6
  const InsertTable = () => {
19
7
  const iconComponentFor = useCellValue(iconComponentFor$);
20
8
  const insertTable = usePublisher(insertTable$);
21
9
  const t = useTranslation();
22
- const isDisabled = useCellValue(disableInsertTableButton$);
10
+ const isDisabled = useCellValue(editorInTable$);
23
11
  return /* @__PURE__ */ React__default.createElement(
24
12
  ButtonWithTooltip,
25
13
  {
@@ -2,14 +2,14 @@ import React__default from "react";
2
2
  import { currentListType$, applyListType$ } from "../../lists/index.js";
3
3
  import { SingleChoiceToggleGroup } from "../primitives/toolbar.js";
4
4
  import { useCellValues, usePublisher } from "@mdxeditor/gurx";
5
- import { iconComponentFor$, useTranslation } from "../../core/index.js";
5
+ import { iconComponentFor$, editorInTable$, useTranslation } from "../../core/index.js";
6
6
  const ICON_NAME_MAP = {
7
7
  bullet: "format_list_bulleted",
8
8
  number: "format_list_numbered",
9
9
  check: "format_list_checked"
10
10
  };
11
11
  const ListsToggle = ({ options = ["bullet", "number", "check"] }) => {
12
- const [currentListType, iconComponentFor] = useCellValues(currentListType$, iconComponentFor$);
12
+ const [currentListType, iconComponentFor, inTable] = useCellValues(currentListType$, iconComponentFor$, editorInTable$);
13
13
  const applyListType = usePublisher(applyListType$);
14
14
  const t = useTranslation();
15
15
  const LIST_TITLE_MAP = {
@@ -22,7 +22,7 @@ const ListsToggle = ({ options = ["bullet", "number", "check"] }) => {
22
22
  title: LIST_TITLE_MAP[type],
23
23
  contents: iconComponentFor(ICON_NAME_MAP[type])
24
24
  }));
25
- return /* @__PURE__ */ React__default.createElement(SingleChoiceToggleGroup, { value: currentListType || "", items, onChange: applyListType });
25
+ return /* @__PURE__ */ React__default.createElement(SingleChoiceToggleGroup, { value: currentListType || "", items, onChange: applyListType, disabled: inTable });
26
26
  };
27
27
  export {
28
28
  ListsToggle
@@ -1,5 +1,6 @@
1
1
  import React__default from "react";
2
2
  import styles from "../../../styles/ui.module.css.js";
3
+ import { $isCodeBlockNode } from "../../codeblock/CodeBlockNode.js";
3
4
  import { editorInFocus$, activeEditor$, iconComponentFor$, useTranslation } from "../../core/index.js";
4
5
  import { sandpackConfig$ } from "../../sandpack/index.js";
5
6
  import { ButtonWithTooltip } from "../primitives/toolbar.js";
@@ -11,8 +12,11 @@ const ShowSandpackInfo = () => {
11
12
  iconComponentFor$,
12
13
  sandpackConfig$
13
14
  );
14
- const sandpackNode = editorInFocus.rootNode;
15
15
  const t = useTranslation();
16
+ const sandpackNode = $isCodeBlockNode(editorInFocus.rootNode) ? editorInFocus.rootNode : null;
17
+ if (!sandpackNode) {
18
+ return null;
19
+ }
16
20
  const preset = sandpackConfig.presets.find((preset2) => preset2.meta === sandpackNode.getMeta());
17
21
  return /* @__PURE__ */ React__default.createElement("div", { className: styles.selectWithLabel }, /* @__PURE__ */ React__default.createElement(
18
22
  ButtonWithTooltip,
@@ -71,7 +71,8 @@ const SingleChoiceToggleGroup = ({
71
71
  onChange,
72
72
  className,
73
73
  ggClassName,
74
- items
74
+ items,
75
+ disabled
75
76
  }) => {
76
77
  const t = useTranslation();
77
78
  return /* @__PURE__ */ React__default.createElement("div", { className: classNames(styles.toolbarGroupOfGroups, ggClassName) }, /* @__PURE__ */ React__default.createElement(
@@ -82,6 +83,7 @@ const SingleChoiceToggleGroup = ({
82
83
  className: classNames(styles.toolbarToggleSingleGroup, className),
83
84
  onValueChange: onChange,
84
85
  value: value || "",
86
+ disabled,
85
87
  onFocus: (e) => {
86
88
  e.preventDefault();
87
89
  }
@@ -1,5 +1,9 @@
1
1
  const CAN_USE_DOM = typeof window !== "undefined" && typeof window.document.createElement !== "undefined";
2
- const IS_APPLE = CAN_USE_DOM && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
2
+ const IS_APPLE = CAN_USE_DOM && (() => {
3
+ var _a;
4
+ const platform = (_a = navigator.userAgentData) == null ? void 0 : _a.platform;
5
+ return platform ? /mac/i.test(platform) : /Mac|iPod|iPhone|iPad/.test(navigator.userAgent);
6
+ })();
3
7
  function controlOrMeta(metaKey, ctrlKey) {
4
8
  if (IS_APPLE) {
5
9
  return metaKey;
@@ -27,10 +27,26 @@ function getSelectedNode(selection) {
27
27
  } else {
28
28
  return $isAtNodeEnd(anchor) ? anchorNode : focusNode;
29
29
  }
30
- } catch (e) {
30
+ } catch {
31
31
  return null;
32
32
  }
33
33
  }
34
+ const WILL_CHANGE_CONTAINING_BLOCK_PROPS = ["transform", "perspective", "filter", "backdrop-filter", "contain", "container-type"];
35
+ const CONTAIN_VALUES_CREATING_CONTAINING_BLOCK = ["layout", "paint", "strict", "content"];
36
+ function getFixedContainingBlock(element) {
37
+ let current = element == null ? void 0 : element.parentElement;
38
+ while (current) {
39
+ const style = window.getComputedStyle(current);
40
+ const willChangeProps = style.willChange.split(",").map((v) => v.trim());
41
+ const hasRelevantWillChange = willChangeProps.some((prop) => WILL_CHANGE_CONTAINING_BLOCK_PROPS.includes(prop));
42
+ const createsContainingBlock = style.transform !== "none" || style.perspective !== "none" || style.filter !== "none" || style.backdropFilter !== "none" || CONTAIN_VALUES_CREATING_CONTAINING_BLOCK.includes(style.contain) || style.containerType !== "normal" || style.contentVisibility === "auto" || hasRelevantWillChange;
43
+ if (createsContainingBlock) {
44
+ return current;
45
+ }
46
+ current = current.parentElement;
47
+ }
48
+ return null;
49
+ }
34
50
  function getSelectionRectangle(editor) {
35
51
  const selection = $getSelection();
36
52
  const nativeSelection = window.getSelection();
@@ -57,13 +73,23 @@ function getSelectionRectangle(editor) {
57
73
  rect = domRange.getBoundingClientRect();
58
74
  }
59
75
  }
76
+ const fixedContainer = getFixedContainingBlock(rootElement);
77
+ if (fixedContainer) {
78
+ const containerRect = fixedContainer.getBoundingClientRect();
79
+ return {
80
+ top: Math.round(rect.top - containerRect.top),
81
+ left: Math.round(rect.left - containerRect.left),
82
+ width: Math.round(rect.width),
83
+ height: Math.round(rect.height)
84
+ };
85
+ }
60
86
  return {
61
87
  top: Math.round(rect.top),
62
88
  left: Math.round(rect.left),
63
89
  width: Math.round(rect.width),
64
90
  height: Math.round(rect.height)
65
91
  };
66
- } else if (!activeElement || activeElement.className !== "link-input") {
92
+ } else if ((activeElement == null ? void 0 : activeElement.className) !== "link-input") {
67
93
  return null;
68
94
  }
69
95
  return null;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "*.css"
12
12
  ],
13
13
  "type": "module",
14
- "version": "3.52.2",
14
+ "version": "3.52.4",
15
15
  "description": "React component for rich text markdown editing",
16
16
  "scripts": {
17
17
  "build": "vite build",
@@ -107,6 +107,7 @@
107
107
  "@babel/preset-typescript": "^7.23.3",
108
108
  "@ladle/react": "^5.0.2",
109
109
  "@ngneat/falso": "^6.4.0",
110
+ "@testing-library/dom": "^10.4.1",
110
111
  "@testing-library/jest-dom": "^6.1.6",
111
112
  "@testing-library/react": "^16.3.0",
112
113
  "@types/express": "^4.17.17",
@@ -117,14 +118,14 @@
117
118
  "@types/react": "^19.2.7",
118
119
  "@types/react-dom": "^19.2.3",
119
120
  "@types/unist": "^3.0.2",
120
- "@typescript-eslint/eslint-plugin": "^7.9.0",
121
- "@typescript-eslint/parser": "^7.9.0",
121
+ "@typescript-eslint/eslint-plugin": "^8.50.1",
122
+ "@typescript-eslint/parser": "^8.50.1",
122
123
  "@vitejs/plugin-react": "^4.0.0",
123
124
  "@vitejs/plugin-react-swc": "^3.5.0",
124
125
  "autoprefixer": "^10.4.14",
125
126
  "cm6-theme-basic-dark": "^0.2.0",
126
127
  "dotenv": "^16.4.5",
127
- "eslint": "^8.56.0",
128
+ "eslint": "^8.57.0",
128
129
  "eslint-config-prettier": "^9.1.0",
129
130
  "eslint-plugin-html": "^7.1.0",
130
131
  "eslint-plugin-import": "^2.29.1",
@@ -152,9 +153,9 @@
152
153
  "typedoc": "^0.25.13",
153
154
  "typedoc-plugin-markdown": "^4.0.2",
154
155
  "typedoc-plugin-no-inherit": "^1.4.0",
155
- "typescript": "^5.4.5",
156
- "typescript-eslint": "^7.9.0",
156
+ "typescript": "^5.9.3",
157
157
  "typescript-plugin-css-modules": "^5.0.2",
158
+ "user-agent-data-types": "^0.4.2",
158
159
  "vite": "^5.0.10",
159
160
  "vite-plugin-dts": "^3.9.1",
160
161
  "vite-plugin-svgr": "^4.2.0",