@mdxeditor/editor 3.23.2 → 3.25.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';
@@ -905,6 +906,7 @@ export declare const diffSourcePlugin: (params?: {
905
906
  export declare const DiffSourceToggleWrapper: default_2.FC<{
906
907
  children: default_2.ReactNode;
907
908
  options?: ViewMode[];
909
+ SourceToolbar?: default_2.ReactNode;
908
910
  }>;
909
911
 
910
912
  /**
@@ -1844,6 +1846,10 @@ export declare const linkDialogPlugin: (params?: {
1844
1846
  * If set, clicking on the link in the preview popup will call this callback instead of opening the link.
1845
1847
  */
1846
1848
  onClickLinkCallback?: ClickLinkCallback | undefined;
1849
+ /**
1850
+ * Invoked when a link is clicked in read-only mode
1851
+ */
1852
+ onReadOnlyClickLinkCallback?: ReadOnlyClickLinkCallback | undefined;
1847
1853
  } | undefined) => RealmPlugin;
1848
1854
 
1849
1855
  /**
@@ -2009,6 +2015,15 @@ export declare interface MdastImportVisitor<UN extends Mdast.Nodes> {
2009
2015
  * Access the current formatting context.
2010
2016
  */
2011
2017
  getParentFormatting(): number;
2018
+ /**
2019
+ * Adds styling as a context for the current node and its children.
2020
+ * This is necessary due to mdast treating styling as a node, while lexical considering it an attribute of a node.
2021
+ */
2022
+ addStyle(style: string, node?: Mdast.Parent | null): void;
2023
+ /**
2024
+ * Access the current style context.
2025
+ */
2026
+ getParentStyle(): string;
2012
2027
  };
2013
2028
  }): void;
2014
2029
  /**
@@ -2286,6 +2301,8 @@ export declare const onBlur$: NodeRef<FocusEvent>;
2286
2301
 
2287
2302
  /* Excluded from this release type: onClickLinkCallback$ */
2288
2303
 
2304
+ /* Excluded from this release type: onReadOnlyClickLinkCallback$ */
2305
+
2289
2306
  /**
2290
2307
  * Emits when the window is resized.
2291
2308
  * @group Utils
@@ -2367,6 +2384,8 @@ export declare const quotePlugin: (params?: unknown) => RealmPlugin;
2367
2384
  */
2368
2385
  export declare const readOnly$: NodeRef<boolean>;
2369
2386
 
2387
+ export declare type ReadOnlyClickLinkCallback = (event: MouseEvent, node: LinkNode, url: string) => void;
2388
+
2370
2389
  /* Excluded from this release type: readOnlyDiff$ */
2371
2390
 
2372
2391
  /**
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$,
@@ -5,6 +5,7 @@ import styles from "../../../styles/ui.module.css.js";
5
5
  import { SingleChoiceToggleGroup } from "../primitives/toolbar.js";
6
6
  const DiffSourceToggleWrapper = ({
7
7
  children,
8
+ SourceToolbar,
8
9
  options = ["rich-text", "diff", "source"]
9
10
  }) => {
10
11
  const [viewMode, iconComponentFor] = useCellValues(viewMode$, iconComponentFor$);
@@ -20,7 +21,7 @@ const DiffSourceToggleWrapper = ({
20
21
  if (options.includes("source")) {
21
22
  toggleGroupItems.push({ title: t("toolbar.source", "Source mode"), contents: iconComponentFor("markdown"), value: "source" });
22
23
  }
23
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, viewMode === "rich-text" ? children : viewMode === "diff" ? /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, t("toolbar.diffMode", "Diff mode")) : /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, t("toolbar.source", "Source mode")), /* @__PURE__ */ React__default.createElement("div", { style: { marginLeft: "auto", pointerEvents: "auto", opacity: 1 } }, /* @__PURE__ */ React__default.createElement(
24
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, viewMode === "rich-text" ? children : viewMode === "diff" ? /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, t("toolbar.diffMode", "Diff mode")) : SourceToolbar ?? /* @__PURE__ */ React__default.createElement("span", { className: styles.toolbarTitleMode }, t("toolbar.source", "Source mode")), /* @__PURE__ */ React__default.createElement("div", { style: { marginLeft: "auto", pointerEvents: "auto", opacity: 1 } }, /* @__PURE__ */ React__default.createElement(
24
25
  SingleChoiceToggleGroup,
25
26
  {
26
27
  className: styles.diffSourceToggle,
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.25.0",
15
15
  "description": "React component for rich text markdown editing",
16
16
  "scripts": {
17
17
  "build": "vite build",