@mdxeditor/editor 3.23.2 → 3.24.0

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.
@@ -48,6 +48,7 @@ function importMarkdownToLexical({
48
48
  }
49
49
  function importMdastTreeToLexical({ root, mdastRoot, visitors, ...descriptors }) {
50
50
  const formattingMap = /* @__PURE__ */ new WeakMap();
51
+ const styleMap = /* @__PURE__ */ new WeakMap();
51
52
  visitors = visitors.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
52
53
  function visitChildren(mdastNode, lexicalParent) {
53
54
  if (!isParent(mdastNode)) {
@@ -112,6 +113,19 @@ function importMdastTreeToLexical({ root, mdastRoot, visitors, ...descriptors })
112
113
  },
113
114
  getParentFormatting() {
114
115
  return formattingMap.get(mdastParent) ?? 0;
116
+ },
117
+ addStyle(style, node) {
118
+ if (!node) {
119
+ if (isParent(mdastNode)) {
120
+ node = mdastNode;
121
+ }
122
+ }
123
+ if (node) {
124
+ styleMap.set(node, style);
125
+ }
126
+ },
127
+ getParentStyle() {
128
+ return styleMap.get(mdastParent) ?? "";
115
129
  }
116
130
  }
117
131
  });
package/dist/index.d.ts CHANGED
@@ -17,6 +17,7 @@ import { KlassConstructor } from 'lexical';
17
17
  import { LexicalCommand } from 'lexical';
18
18
  import { LexicalEditor } from 'lexical';
19
19
  import { LexicalNode } from 'lexical';
20
+ import { LinkNode } from '@lexical/link';
20
21
  import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin.js';
21
22
  import { ListType } from '@lexical/list';
22
23
  import * as Mdast from 'mdast';
@@ -1844,6 +1845,10 @@ export declare const linkDialogPlugin: (params?: {
1844
1845
  * If set, clicking on the link in the preview popup will call this callback instead of opening the link.
1845
1846
  */
1846
1847
  onClickLinkCallback?: ClickLinkCallback | undefined;
1848
+ /**
1849
+ * Invoked when a link is clicked in read-only mode
1850
+ */
1851
+ onReadOnlyClickLinkCallback?: ReadOnlyClickLinkCallback | undefined;
1847
1852
  } | undefined) => RealmPlugin;
1848
1853
 
1849
1854
  /**
@@ -2009,6 +2014,15 @@ export declare interface MdastImportVisitor<UN extends Mdast.Nodes> {
2009
2014
  * Access the current formatting context.
2010
2015
  */
2011
2016
  getParentFormatting(): number;
2017
+ /**
2018
+ * Adds styling as a context for the current node and its children.
2019
+ * This is necessary due to mdast treating styling as a node, while lexical considering it an attribute of a node.
2020
+ */
2021
+ addStyle(style: string, node?: Mdast.Parent | null): void;
2022
+ /**
2023
+ * Access the current style context.
2024
+ */
2025
+ getParentStyle(): string;
2012
2026
  };
2013
2027
  }): void;
2014
2028
  /**
@@ -2286,6 +2300,8 @@ export declare const onBlur$: NodeRef<FocusEvent>;
2286
2300
 
2287
2301
  /* Excluded from this release type: onClickLinkCallback$ */
2288
2302
 
2303
+ /* Excluded from this release type: onReadOnlyClickLinkCallback$ */
2304
+
2289
2305
  /**
2290
2306
  * Emits when the window is resized.
2291
2307
  * @group Utils
@@ -2367,6 +2383,8 @@ export declare const quotePlugin: (params?: unknown) => RealmPlugin;
2367
2383
  */
2368
2384
  export declare const readOnly$: NodeRef<boolean>;
2369
2385
 
2386
+ export declare type ReadOnlyClickLinkCallback = (event: MouseEvent, node: LinkNode, url: string) => void;
2387
+
2370
2388
  /* Excluded from this release type: readOnlyDiff$ */
2371
2389
 
2372
2390
  /**
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import { appendCodeBlockEditorDescriptor$, codeBlockPlugin, defaultCodeBlockLang
23
23
  import { directivesPlugin, insertDirective$ } from "./plugins/directives/index.js";
24
24
  import { ADMONITION_TYPES, AdmonitionDirectiveDescriptor } from "./directive-editors/AdmonitionDirectiveDescriptor.js";
25
25
  import { GenericDirectiveEditor } from "./directive-editors/GenericDirectiveEditor.js";
26
- import { applyLinkChanges$, cancelLinkEdit$, linkAutocompleteSuggestions$, linkDialogPlugin, linkDialogState$, onClickLinkCallback$, onWindowChange$, openLinkEditDialog$, removeLink$, switchFromPreviewToLinkEdit$, updateLink$ } from "./plugins/link-dialog/index.js";
26
+ import { applyLinkChanges$, cancelLinkEdit$, linkAutocompleteSuggestions$, linkDialogPlugin, linkDialogState$, onClickLinkCallback$, onReadOnlyClickLinkCallback$, onWindowChange$, openLinkEditDialog$, removeLink$, switchFromPreviewToLinkEdit$, updateLink$ } from "./plugins/link-dialog/index.js";
27
27
  import { toolbarClassName$, toolbarContents$, toolbarPlugin } from "./plugins/toolbar/index.js";
28
28
  import { cmExtensions$, diffMarkdown$, diffSourcePlugin, readOnlyDiff$ } from "./plugins/diff-source/index.js";
29
29
  import { markdownShortcutPlugin } from "./plugins/markdown-shortcut/index.js";
@@ -276,6 +276,7 @@ export {
276
276
  noop,
277
277
  onBlur$,
278
278
  onClickLinkCallback$,
279
+ onReadOnlyClickLinkCallback$,
279
280
  onWindowChange$,
280
281
  openEditImageDialog$,
281
282
  openLinkEditDialog$,
@@ -2,8 +2,13 @@ import { $createGenericHTMLNode } from "./GenericHTMLNode.js";
2
2
  import { isMdastHTMLNode } from "./MdastHTMLNode.js";
3
3
  const MdastHTMLVisitor = {
4
4
  testNode: isMdastHTMLNode,
5
- visitNode: function({ mdastNode, actions }) {
6
- actions.addAndStepInto($createGenericHTMLNode(mdastNode.name, mdastNode.type, mdastNode.attributes));
5
+ visitNode: function({ mdastNode, actions, lexicalParent }) {
6
+ if (mdastNode.name === "span" && mdastNode.attributes.length === 1 && mdastNode.attributes[0].type === "mdxJsxAttribute" && mdastNode.attributes[0].name === "style") {
7
+ actions.addStyle(mdastNode.attributes[0].value, mdastNode);
8
+ actions.visitChildren(mdastNode, lexicalParent);
9
+ } else {
10
+ actions.addAndStepInto($createGenericHTMLNode(mdastNode.name, mdastNode.type, mdastNode.attributes));
11
+ }
7
12
  },
8
13
  priority: -100
9
14
  };
@@ -2,7 +2,13 @@ import { $createTextNode } from "lexical";
2
2
  const MdastTextVisitor = {
3
3
  testNode: "text",
4
4
  visitNode({ mdastNode, actions }) {
5
- actions.addAndStepInto($createTextNode(mdastNode.value).setFormat(actions.getParentFormatting()));
5
+ const node = $createTextNode(mdastNode.value);
6
+ node.setFormat(actions.getParentFormatting());
7
+ const style = actions.getParentStyle();
8
+ if (style !== "") {
9
+ node.setStyle(style);
10
+ }
11
+ actions.addAndStepInto(node);
6
12
  }
7
13
  };
8
14
  export {
@@ -1,11 +1,12 @@
1
- import { $createLinkNode, TOGGLE_LINK_COMMAND, $isLinkNode } from "@lexical/link";
1
+ import { $createLinkNode, TOGGLE_LINK_COMMAND, $isLinkNode, LinkNode } from "@lexical/link";
2
2
  import { Signal, Cell, withLatestFrom, map, Action, filter } from "@mdxeditor/gurx";
3
- import { KEY_ESCAPE_COMMAND, COMMAND_PRIORITY_LOW, KEY_MODIFIER_COMMAND, $getSelection, $isRangeSelection, COMMAND_PRIORITY_HIGH, $createTextNode, $insertNodes } from "lexical";
3
+ import { KEY_ESCAPE_COMMAND, COMMAND_PRIORITY_LOW, KEY_MODIFIER_COMMAND, $getSelection, $isRangeSelection, COMMAND_PRIORITY_HIGH, $createTextNode, $insertNodes, $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";
7
7
  import { createActiveEditorSubscription$, viewMode$, readOnly$, activeEditor$, currentSelection$, addComposerChild$ } from "../core/index.js";
8
8
  import { LinkDialog } from "./LinkDialog.js";
9
+ import { $findMatchingParent } from "@lexical/utils";
9
10
  function getLinkNodeInSelection(selection) {
10
11
  if (!selection) {
11
12
  return null;
@@ -228,10 +229,38 @@ const openLinkEditDialog$ = Action((r) => {
228
229
  });
229
230
  const linkAutocompleteSuggestions$ = Cell([]);
230
231
  const onClickLinkCallback$ = Cell(null);
232
+ const onReadOnlyClickLinkCallback$ = Cell(null, (r) => {
233
+ r.pub(createActiveEditorSubscription$, (editor) => {
234
+ function onClick(event) {
235
+ const [readOnly, callback] = r.getValues([readOnly$, onReadOnlyClickLinkCallback$]);
236
+ if (!readOnly || callback === null) {
237
+ return;
238
+ }
239
+ editor.update(() => {
240
+ const nearestNode = $getNearestNodeFromDOMNode(event.target);
241
+ if (nearestNode !== null) {
242
+ const targetNode = $findMatchingParent(nearestNode, (node) => node instanceof LinkNode);
243
+ if (targetNode !== null) {
244
+ callback(event, targetNode, targetNode.getURL());
245
+ }
246
+ }
247
+ });
248
+ }
249
+ return editor.registerRootListener((rootElement, prevRoot) => {
250
+ if (rootElement) {
251
+ rootElement.addEventListener("click", onClick);
252
+ }
253
+ if (prevRoot) {
254
+ prevRoot.removeEventListener("click", onClick);
255
+ }
256
+ });
257
+ });
258
+ });
231
259
  const linkDialogPlugin = realmPlugin({
232
260
  init(r, params) {
233
261
  r.pub(addComposerChild$, (params == null ? void 0 : params.LinkDialog) ?? LinkDialog);
234
262
  r.pub(onClickLinkCallback$, (params == null ? void 0 : params.onClickLinkCallback) ?? null);
263
+ r.pub(onReadOnlyClickLinkCallback$, (params == null ? void 0 : params.onReadOnlyClickLinkCallback) ?? null);
235
264
  },
236
265
  update(r, params = {}) {
237
266
  r.pub(linkAutocompleteSuggestions$, params.linkAutocompleteSuggestions ?? []);
@@ -244,6 +273,7 @@ export {
244
273
  linkDialogPlugin,
245
274
  linkDialogState$,
246
275
  onClickLinkCallback$,
276
+ onReadOnlyClickLinkCallback$,
247
277
  onWindowChange$,
248
278
  openLinkEditDialog$,
249
279
  removeLink$,
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "*.css"
12
12
  ],
13
13
  "type": "module",
14
- "version": "3.23.2",
14
+ "version": "3.24.0",
15
15
  "description": "React component for rich text markdown editing",
16
16
  "scripts": {
17
17
  "build": "vite build",