@mdxeditor/editor 0.7.2 → 0.9.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.
Files changed (28) hide show
  1. package/README.md +2 -2
  2. package/dist/{CodeBlockEditor-6e6cadb7.js → CodeBlockEditor-ce4c85ed.js} +3 -2
  3. package/dist/{CodeBlockEditor-d6235774.cjs → CodeBlockEditor-ed222322.cjs} +1 -1
  4. package/dist/FrontmatterEditor-914aa241.cjs +1 -0
  5. package/dist/{FrontmatterEditor-bcb1a0fd.js → FrontmatterEditor-e2f25a6a.js} +2 -1
  6. package/dist/{ImageEditor-c0184e9a.js → ImageEditor-ad505654.js} +2 -1
  7. package/dist/ImageEditor-c4e65554.cjs +1 -0
  8. package/dist/{JsxEditor-4ff2f120.cjs → JsxEditor-6cff258d.cjs} +1 -1
  9. package/dist/{JsxEditor-6fd46aaa.js → JsxEditor-88d55ef8.js} +1 -1
  10. package/dist/LeafDirectiveEditor-0e1328e6.cjs +1 -0
  11. package/dist/LeafDirectiveEditor-34ead530.js +59 -0
  12. package/dist/{SandpackEditor-1f2bbe22.cjs → SandpackEditor-a999ca47.cjs} +1 -1
  13. package/dist/{SandpackEditor-cdcd7e95.js → SandpackEditor-b1e22784.js} +3 -2
  14. package/dist/{SourceEditor-80e3e5dd.cjs → SourceEditor-0c46ec47.cjs} +1 -1
  15. package/dist/{SourceEditor-0399298a.js → SourceEditor-e509d0a5.js} +2 -1
  16. package/dist/{TableEditor-533f6497.js → TableEditor-44bef804.js} +1 -1
  17. package/dist/{TableEditor-982bfce3.cjs → TableEditor-ced03ce4.cjs} +1 -1
  18. package/dist/index-21fcefae.cjs +1 -0
  19. package/dist/{index-911b7e3d.js → index-ce0832cc.js} +326 -60
  20. package/dist/index.cjs +1 -1
  21. package/dist/index.d.ts +134 -13
  22. package/dist/index.js +23 -17
  23. package/dist/{useCodeMirrorRef-dc6425df.js → useCodeMirrorRef-177e9901.js} +1 -1
  24. package/dist/{useCodeMirrorRef-17daf915.cjs → useCodeMirrorRef-6cb866bd.cjs} +1 -1
  25. package/package.json +5 -2
  26. package/dist/FrontmatterEditor-535e834d.cjs +0 -1
  27. package/dist/ImageEditor-b47dff60.cjs +0 -1
  28. package/dist/index-93ab76f9.cjs +0 -1
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  /// <reference types="react" />
9
9
 
10
10
  import { AdmonitionKind } from 'lexical';
11
- import type { ComponentType } from 'react';
11
+ import { ContentEditable } from '@lexical/react/LexicalContentEditable';
12
12
  import { DecoratorNode } from 'lexical';
13
13
  import type { DOMConversionMap } from 'lexical';
14
14
  import type { DOMExportOutput } from 'lexical';
@@ -17,6 +17,7 @@ import { EditorThemeClasses } from 'lexical';
17
17
  import { ElementNode } from 'lexical';
18
18
  import { FromMarkdownOptions } from 'mdast-util-from-markdown/lib';
19
19
  import { Klass } from 'lexical';
20
+ import { LeafDirective } from 'mdast-util-directive';
20
21
  import { LexicalEditor } from 'lexical';
21
22
  import { LexicalNode } from 'lexical';
22
23
  import * as Mdast from 'mdast';
@@ -68,6 +69,11 @@ export declare function $createImageNode(options: CreateImageNodeOptions): Image
68
69
  */
69
70
  export declare function $createJsxNode(options: CreateJsxNodeOptions): JsxNode;
70
71
 
72
+ /**
73
+ * Creates an {@link LeafDirectiveNode}.
74
+ */
75
+ export declare function $createLeafDirectiveNode(mdastNode: LeafDirective): LeafDirectiveNode;
76
+
71
77
  /**
72
78
  * Creates a {@link SandpackNode}.
73
79
  */
@@ -104,6 +110,11 @@ export declare function $isImageNode(node: LexicalNode | null | undefined): node
104
110
  */
105
111
  export declare function $isJsxNode(node: LexicalNode | null | undefined): node is JsxNode;
106
112
 
113
+ /**
114
+ * Retruns true if the node is an {@link LeafDirectiveNode}.
115
+ */
116
+ export declare function $isLeafDirectiveNode(node: LexicalNode | null | undefined): node is LeafDirectiveNode;
117
+
107
118
  /**
108
119
  * Returns true if the given node is a {@link SandpackNode}.
109
120
  */
@@ -241,6 +252,11 @@ export declare interface CreateSandpackNodeOptions {
241
252
  language: string;
242
253
  }
243
254
 
255
+ export declare interface CustomLeafDirectiveEditor<T extends LeafDirective> {
256
+ testNode: (mdastNode: LeafDirective) => boolean;
257
+ Editor: React_2.ComponentType<LeafDirectiveEditorProps<T>>;
258
+ }
259
+
244
260
  /**
245
261
  * The default set of lexical nodes used in the editor.
246
262
  */
@@ -274,6 +290,15 @@ export declare type DefaultMdxOptionValues = {
274
290
  */
275
291
  export declare const defaultMdxOptionValues: DefaultMdxOptionValues;
276
292
 
293
+ declare interface DialogButtonProps {
294
+ autocompleteSuggestions?: string[];
295
+ onSubmit: (value: string) => void;
296
+ tooltipTitle: string;
297
+ buttonContent?: React_2.ReactNode;
298
+ dialogInputPlaceholder: string;
299
+ submitButtonTitle: string;
300
+ }
301
+
277
302
  declare type ExtendedEditorConfig = EditorConfig & {
278
303
  theme: EditorConfig['theme'] & {
279
304
  nodeDecoratorComponents: NodeDecoratorComponents;
@@ -424,6 +449,34 @@ export declare interface JsxPropertyDescriptor {
424
449
  required?: boolean;
425
450
  }
426
451
 
452
+ export declare interface LeafDirectiveEditorProps<T extends LeafDirective> {
453
+ /** The Lexical editor that contains the node */
454
+ parentEditor: LexicalEditor;
455
+ /** The Lexical node that is being edited */
456
+ leafDirective: LeafDirectiveNode;
457
+ /** The MDAST node that is being edited */
458
+ mdastNode: T;
459
+ }
460
+
461
+ /**
462
+ * A lexical node that represents an image. Use {@link "$createLeafDirectiveNode"} to construct one.
463
+ */
464
+ export declare class LeafDirectiveNode extends DecoratorNode<JSX.Element> {
465
+ __mdastNode: LeafDirective;
466
+ static getType(): string;
467
+ static clone(node: LeafDirectiveNode): LeafDirectiveNode;
468
+ static importJSON(serializedNode: SerializedLeafDirectiveNode): LeafDirectiveNode;
469
+ constructor(mdastNode: LeafDirective, key?: NodeKey);
470
+ getMdastNode(): LeafDirective;
471
+ exportJSON(): SerializedLeafDirectiveNode;
472
+ createDOM(): HTMLElement;
473
+ updateDOM(): false;
474
+ setMdastNode(mdastNode: LeafDirective): void;
475
+ decorate(parentEditor: LexicalEditor, { theme: { nodeDecoratorComponents: { LeafDirectiveEditor } } }: ExtendedEditorConfig): JSX.Element;
476
+ isInline(): boolean;
477
+ isKeyboardSelectable(): boolean;
478
+ }
479
+
427
480
  /**
428
481
  * Configures how the lexical tree is converted to a mdast tree and then to markdown.
429
482
  */
@@ -522,7 +575,22 @@ declare type LexicalVisitor = LexicalExportVisitor<LexicalNode, Mdast.Content>;
522
575
  * Options that control how the the markdown input string is parsed into a tree.
523
576
  * @see {@link https://github.com/syntax-tree/mdast-util-from-markdown | fromMarkdown}
524
577
  */
525
- export declare interface MarkdownParseOptions extends Omit<MdastTreeImportOptions, 'mdastRoot'> {
578
+ export declare interface MarkdownParseOptions {
579
+ /**
580
+ * The visitors to process the markdown AST with.
581
+ */
582
+ visitors?: MdastImportVisitor<Mdast.Content>[];
583
+ /**
584
+ * The extensions to use for the markdown parser. Passed as the `extensions` option to the `fromMarkdown` function.
585
+ */
586
+ syntaxExtensions?: NonNullable<ParseOptions['extensions']>;
587
+ /**
588
+ * The mdast extensions to use for the markdown parser. Passed as the `mdastExtensions` option to the `fromMarkdown` function.
589
+ */
590
+ mdastExtensions?: NonNullable<FromMarkdownOptions['mdastExtensions']>;
591
+ }
592
+
593
+ declare interface MarkdownParseOptions_2 extends Omit<MdastTreeImportOptions, 'mdastRoot'> {
526
594
  markdown: string;
527
595
  syntaxExtensions: NonNullable<ParseOptions['extensions']>;
528
596
  mdastExtensions: NonNullable<FromMarkdownOptions['mdastExtensions']>;
@@ -531,7 +599,7 @@ export declare interface MarkdownParseOptions extends Omit<MdastTreeImportOption
531
599
  /**
532
600
  * An extension for the `fromMarkdown` utility tree construction.
533
601
  */
534
- declare type MdastExtension = MarkdownParseOptions['mdastExtensions'][number];
602
+ declare type MdastExtension = MarkdownParseOptions_2['mdastExtensions'][number];
535
603
 
536
604
  /**
537
605
  * Implement this interface to convert certian mdast nodes into lexical nodes.
@@ -595,7 +663,7 @@ export declare interface MdastVisitParams<T extends Mdast.Content> {
595
663
  }
596
664
 
597
665
  /**
598
- * The MDXEditor React component
666
+ * The MDXEditor React component. See {@link MDXEditorProps} for the list of available props and the {@link MDXEditorMethods} for the methods exposed through the ref.
599
667
  */
600
668
  export declare const MDXEditor: React_2.ForwardRefExoticComponent<MDXEditorProps & React_2.RefAttributes<MDXEditorMethods>>;
601
669
 
@@ -610,11 +678,11 @@ export declare const MDXEditor: React_2.ForwardRefExoticComponent<MDXEditorProps
610
678
  */
611
679
  export declare interface MDXEditorMethods {
612
680
  /**
613
- * gets the current markdown value
681
+ * Gets the current markdown value.
614
682
  */
615
683
  getMarkdown: () => string;
616
684
  /**
617
- * Updates the markdown value
685
+ * Updates the markdown value of the editor.
618
686
  */
619
687
  setMarkdown: (value: string) => void;
620
688
  }
@@ -654,7 +722,7 @@ export declare interface MDXEditorProps {
654
722
  /**
655
723
  * The set of components to be rendered in the toolbar.
656
724
  */
657
- toolbarComponents?: ComponentType[];
725
+ toolbarComponents?: React_2.ComponentType[];
658
726
  /**
659
727
  * The initial view mode for the editor. Defaults to `ViewMode.editor`.
660
728
  */
@@ -675,7 +743,7 @@ export declare interface MDXEditorProps {
675
743
  * The options to be used when parsing the markdown content.
676
744
  * @see the {@link MarkdownParseOptions} interface for more details.
677
745
  */
678
- markdownParseOptions?: Partial<MarkdownParseOptions>;
746
+ markdownParseOptions?: MarkdownParseOptions;
679
747
  /**
680
748
  * The {@link https://lexical.dev/ | Lexical nodes} used by the editor.
681
749
  */
@@ -704,6 +772,44 @@ export declare interface MDXEditorProps {
704
772
  * ```
705
773
  */
706
774
  imageUploadHandler?: (image: File) => Promise<string>;
775
+ customLeafDirectiveEditors?: CustomLeafDirectiveEditor<any>[];
776
+ }
777
+
778
+ /**
779
+ * A nested editor React component that allows editing of the contents of complex markdown nodes that have nested markdown content (for example, custom directives or JSX elements). See the {@link NestedEditorProps} for more details on the compoment props.
780
+ *
781
+ * @example
782
+ * You can use a type param to specify the type of the mdast node
783
+ *
784
+ * ```tsx
785
+ *
786
+ * interface CalloutDirectiveNode extends LeafDirective {
787
+ * name: 'callout'
788
+ * children: Mdast.PhrasingContent[]
789
+ * }
790
+ *
791
+ * return <NestedEditor<CalloutDirectiveNode> getContent={node => node.children} getUpdatedMdastNode={(node, children) => ({ ...node, children })} />
792
+ * ```
793
+ */
794
+ export declare const NestedEditor: <T extends Mdast.Content>(props: NestedEditorProps<T>) => React_2.JSX.Element;
795
+
796
+ /**
797
+ * The properties of the {@link NestedEditor} React Component.
798
+ * @typeParam T - The type of the mdast node of the editor.
799
+ */
800
+ export declare interface NestedEditorProps<T extends Mdast.Content> {
801
+ /**
802
+ * A function that returns the phrasing content of the mdast node. In most cases, this will be the `children` property of the mdast node, but you can also have multiple nested nodes with their own children.
803
+ */
804
+ getContent: (mdastNode: T) => Mdast.PhrasingContent[];
805
+ /**
806
+ * A function that should return the updated mdast node based on the original mdast node and the new content (serialized as mdast tree) produced by the editor.
807
+ */
808
+ getUpdatedMdastNode: (mdastNode: T, children: Mdast.PhrasingContent[]) => T;
809
+ /**
810
+ * Props passed to the {@link https://github.com/facebook/lexical/blob/main/packages/lexical-react/src/LexicalContentEditable.tsx | ContentEditable} component.
811
+ */
812
+ contentEditableProps?: React_2.ComponentProps<typeof ContentEditable>;
707
813
  }
708
814
 
709
815
  declare interface NodeDecoratorComponents {
@@ -713,6 +819,7 @@ declare interface NodeDecoratorComponents {
713
819
  CodeBlockEditor: React.FC<CodeBlockEditorProps>;
714
820
  TableEditor: React.FC<TableEditorProps>;
715
821
  ImageEditor: React.FC<ImageEditorProps>;
822
+ LeafDirectiveEditor: React.FC<LeafDirectiveEditorProps<LeafDirective>>;
716
823
  }
717
824
 
718
825
  /**
@@ -858,6 +965,15 @@ export declare type SerializedJsxNode = Spread<Omit<CreateJsxNodeOptions, 'updat
858
965
  type: 'jsx';
859
966
  }, SerializedLexicalNode>;
860
967
 
968
+ /**
969
+ * A serialized representation of an {@link LeafDirectiveNode}.
970
+ */
971
+ export declare type SerializedLeafDirectiveNode = Spread<{
972
+ mdastNode: LeafDirective;
973
+ type: 'leafDirective';
974
+ version: 1;
975
+ }, SerializedLexicalNode>;
976
+
861
977
  /**
862
978
  * A serialized representation of an {@link SandpackNode}.
863
979
  */
@@ -876,7 +992,7 @@ export declare type SerializedTableNode = Spread<{
876
992
  /**
877
993
  * An extension for the `fromMarkdown` utility markdown parse.
878
994
  */
879
- declare type SyntaxExtension = MarkdownParseOptions['syntaxExtensions'][number];
995
+ declare type SyntaxExtension = MarkdownParseOptions_2['syntaxExtensions'][number];
880
996
 
881
997
  declare interface TableEditorProps {
882
998
  parentEditor: LexicalEditor;
@@ -929,13 +1045,12 @@ export declare const ToolbarComponents: {
929
1045
  BlockTypeSelect: () => React_2.JSX.Element;
930
1046
  BoldItalicUnderlineButtons: React_2.FC<{}>;
931
1047
  CodeBlockButton: React_2.FC<{}>;
1048
+ CodeFormattingButton: React_2.FC<{}>;
932
1049
  FrontmatterButton: React_2.FC<{}>;
933
1050
  GroupGroup: React_2.FC<{
934
1051
  children: React_2.ReactNode;
935
1052
  }>;
936
- HorizontalRuleIcon: React_2.FC<React_2.SVGProps<SVGSVGElement> & {
937
- title?: string | undefined;
938
- }>;
1053
+ HorizontalRuleButton: React_2.FC<{}>;
939
1054
  LinkButton: React_2.FC<{}>;
940
1055
  ListButtons: React_2.FC<{}>;
941
1056
  SandpackButton: React_2.FC<{}>;
@@ -952,11 +1067,17 @@ export declare const ToolbarComponents: {
952
1067
  title: string;
953
1068
  } & React_2.RefAttributes<HTMLButtonElement>>;
954
1069
  ToolbarSeparator: React_2.ForwardRefExoticComponent<RadixToolbar.ToolbarSeparatorProps & React_2.RefAttributes<HTMLDivElement>>;
955
- ImageButton: React_2.ForwardRefExoticComponent<RadixToolbar.ToolbarButtonProps & React_2.RefAttributes<HTMLButtonElement>>;
1070
+ ImageButton: React_2.ForwardRefExoticComponent<Omit<Record<string, never>, "ref"> & React_2.RefAttributes<HTMLButtonElement>>;
1071
+ DialogButton: React_2.ForwardRefExoticComponent<DialogButtonProps & React_2.RefAttributes<HTMLButtonElement>>;
956
1072
  };
957
1073
 
958
1074
  export declare type updateFn = (node: LexicalNode) => void;
959
1075
 
1076
+ /**
1077
+ * A hook that returns a function that can be used to update the mdast node. Use this in your custom editor components.
1078
+ */
1079
+ export declare function useMdastNodeUpdater<T extends Mdast.Content>(): (node: T) => void;
1080
+
960
1081
  /**
961
1082
  * The editor view mode.
962
1083
  * editor - The default rich text view mode.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { b, d, g, j, k, n, r, c, f, h, $, l, o, q, A, C, F, I, J, M, m, p, T, v } from "./index-911b7e3d.js";
1
+ import { d, g, j, l, m, x, p, w, f, h, k, $, n, y, q, v, A, C, F, I, J, L, M, b, o, r, T, z, c } from "./index-ce0832cc.js";
2
2
  import { AdmonitionKind } from "lexical";
3
3
  import "@lexical/react/LexicalComposer";
4
4
  import "@lexical/react/LexicalContentEditable";
@@ -39,30 +39,36 @@ import "unidiff";
39
39
  import "@radix-ui/react-toolbar";
40
40
  import "@radix-ui/react-select";
41
41
  import "@radix-ui/react-dialog";
42
+ import "@lexical/react/LexicalNestedComposer";
42
43
  export {
43
- b as $createAdmonitionNode,
44
- d as $createCodeBlockNode,
45
- g as $createFrontmatterNode,
46
- j as $createImageNode,
47
- k as $createJsxNode,
48
- n as $createSandpackNode,
49
- r as $createTableNode,
50
- c as $isAdmonitionNode,
51
- f as $isCodeBlockNode,
52
- h as $isFrontmatterNode,
44
+ d as $createAdmonitionNode,
45
+ g as $createCodeBlockNode,
46
+ j as $createFrontmatterNode,
47
+ l as $createImageNode,
48
+ m as $createJsxNode,
49
+ x as $createLeafDirectiveNode,
50
+ p as $createSandpackNode,
51
+ w as $createTableNode,
52
+ f as $isAdmonitionNode,
53
+ h as $isCodeBlockNode,
54
+ k as $isFrontmatterNode,
53
55
  $ as $isImageNode,
54
- l as $isJsxNode,
55
- o as $isSandpackNode,
56
- q as $isTableNode,
56
+ n as $isJsxNode,
57
+ y as $isLeafDirectiveNode,
58
+ q as $isSandpackNode,
59
+ v as $isTableNode,
57
60
  AdmonitionKind,
58
61
  A as AdmonitionNode,
59
62
  C as CodeBlockNode,
60
63
  F as FrontmatterNode,
61
64
  I as ImageNode,
62
65
  J as JsxNode,
66
+ L as LeafDirectiveNode,
63
67
  M as MDXEditor,
64
- m as SandpackNode,
65
- p as TableNode,
68
+ b as NestedEditor,
69
+ o as SandpackNode,
70
+ r as TableNode,
66
71
  T as ToolbarComponents,
67
- v as defaultMdxOptionValues
72
+ z as defaultMdxOptionValues,
73
+ c as useMdastNodeUpdater
68
74
  };
@@ -1,6 +1,6 @@
1
1
  import { $getNodeByKey, $createParagraphNode } from "lexical";
2
2
  import React__default from "react";
3
- import { u as useEmitterValues, a as usePublisher } from "./index-911b7e3d.js";
3
+ import { u as useEmitterValues, a as usePublisher } from "./index-ce0832cc.js";
4
4
  function useCodeMirrorRef(nodeKey, editorType, language) {
5
5
  const [activeEditor] = useEmitterValues("activeEditor");
6
6
  const setActiveEditorType = usePublisher("activeEditorType");
@@ -1 +1 @@
1
- "use strict";const e=require("lexical"),r=require("react"),t=require("./index-93ab76f9.cjs");exports.useCodeMirrorRef=function(n,o,l){const[u]=t.useEmitterValues("activeEditor"),i=t.usePublisher("activeEditorType"),s=r.useRef(null),c=r.useRef(!1),d=r.useRef(!1),v=r.useCallback((()=>{i({type:o,nodeKey:n})}),[n,i,o]),a=r.useCallback((r=>{var t,o,l,i;if("ArrowDown"===r.key){const r=null==(o=null==(t=null==s?void 0:s.current)?void 0:t.getCodemirror())?void 0:o.state;if(r){r.doc.length===r.selection.ranges[0].to&&(c.current?(null==u||u.update((()=>{var r,t;const o=e.$getNodeByKey(n);o.getNextSibling()?(null==(t=null==(r=null==s?void 0:s.current)?void 0:r.getCodemirror())||t.contentDOM.blur(),o.selectNext()):o.insertAfter(e.$createParagraphNode())})),c.current=!1):c.current=!0)}}else if("ArrowUp"===r.key){const r=null==(i=null==(l=null==s?void 0:s.current)?void 0:l.getCodemirror())?void 0:i.state;if(r){0===r.selection.ranges[0].from&&(d.current?(null==u||u.update((()=>{var r,t;const o=e.$getNodeByKey(n);o.getPreviousSibling()&&(null==(t=null==(r=null==s?void 0:s.current)?void 0:r.getCodemirror())||t.contentDOM.blur(),o.selectPrevious())})),d.current=!1):d.current=!0)}}else"Enter"===r.key&&r.stopPropagation()}),[u,n]);return r.useEffect((()=>{const e=s.current;return setTimeout((()=>{var r,t,n,o;null==(t=null==(r=null==e?void 0:e.getCodemirror())?void 0:r.contentDOM)||t.addEventListener("focus",v),null==(o=null==(n=null==e?void 0:e.getCodemirror())?void 0:n.contentDOM)||o.addEventListener("keydown",a)}),100),()=>{var r,t;null==(r=null==e?void 0:e.getCodemirror())||r.contentDOM.removeEventListener("focus",v),null==(t=null==e?void 0:e.getCodemirror())||t.contentDOM.removeEventListener("keydown",a)}}),[s,v,a,l]),s};
1
+ "use strict";const e=require("lexical"),r=require("react"),t=require("./index-21fcefae.cjs");exports.useCodeMirrorRef=function(n,o,l){const[u]=t.useEmitterValues("activeEditor"),i=t.usePublisher("activeEditorType"),s=r.useRef(null),c=r.useRef(!1),d=r.useRef(!1),v=r.useCallback((()=>{i({type:o,nodeKey:n})}),[n,i,o]),a=r.useCallback((r=>{var t,o,l,i;if("ArrowDown"===r.key){const r=null==(o=null==(t=null==s?void 0:s.current)?void 0:t.getCodemirror())?void 0:o.state;if(r){r.doc.length===r.selection.ranges[0].to&&(c.current?(null==u||u.update((()=>{var r,t;const o=e.$getNodeByKey(n);o.getNextSibling()?(null==(t=null==(r=null==s?void 0:s.current)?void 0:r.getCodemirror())||t.contentDOM.blur(),o.selectNext()):o.insertAfter(e.$createParagraphNode())})),c.current=!1):c.current=!0)}}else if("ArrowUp"===r.key){const r=null==(i=null==(l=null==s?void 0:s.current)?void 0:l.getCodemirror())?void 0:i.state;if(r){0===r.selection.ranges[0].from&&(d.current?(null==u||u.update((()=>{var r,t;const o=e.$getNodeByKey(n);o.getPreviousSibling()&&(null==(t=null==(r=null==s?void 0:s.current)?void 0:r.getCodemirror())||t.contentDOM.blur(),o.selectPrevious())})),d.current=!1):d.current=!0)}}else"Enter"===r.key&&r.stopPropagation()}),[u,n]);return r.useEffect((()=>{const e=s.current;return setTimeout((()=>{var r,t,n,o;null==(t=null==(r=null==e?void 0:e.getCodemirror())?void 0:r.contentDOM)||t.addEventListener("focus",v),null==(o=null==(n=null==e?void 0:e.getCodemirror())?void 0:n.contentDOM)||o.addEventListener("keydown",a)}),100),()=>{var r,t;null==(r=null==e?void 0:e.getCodemirror())||r.contentDOM.removeEventListener("focus",v),null==(t=null==e?void 0:e.getCodemirror())||t.contentDOM.removeEventListener("keydown",a)}}),[s,v,a,l]),s};
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "main": "dist/index.cjs",
22
22
  "module": "dist/index.js",
23
23
  "types": "dist/index.d.ts",
24
- "version": "0.7.2",
24
+ "version": "0.9.0",
25
25
  "description": "React component for rich text markdown editing",
26
26
  "scripts": {
27
27
  "build": "vite build",
@@ -31,7 +31,8 @@
31
31
  "typecheck": "tsc --noEmit",
32
32
  "lint": "eslint src --ext .ts,.tsx",
33
33
  "test": "vitest",
34
- "semantic-release": "semantic-release"
34
+ "semantic-release": "semantic-release",
35
+ "image-upload-backend": "node ./src/stories/file-backend.js"
35
36
  },
36
37
  "files": [
37
38
  "dist"
@@ -105,8 +106,10 @@
105
106
  "@ngneat/falso": "^6.4.0",
106
107
  "@testing-library/jest-dom": "^5.16.5",
107
108
  "@testing-library/react": "^14.0.0",
109
+ "@types/express": "^4.17.17",
108
110
  "@types/js-yaml": "4.0.5",
109
111
  "@types/mdast": "3.0.11",
112
+ "@types/multer": "^1.4.7",
110
113
  "@types/node": "^20.2.5",
111
114
  "@types/react": "^18.2.7",
112
115
  "@types/react-dom": "^18.2.4",
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("js-yaml"),t=require("react"),r=require("react-hook-form"),l=require("classnames"),a=require("./index-93ab76f9.cjs");function i(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const l=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,l.get?l:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}require("@lexical/react/LexicalComposer"),require("@lexical/react/LexicalContentEditable"),require("@lexical/react/LexicalErrorBoundary"),require("@lexical/react/LexicalHorizontalRulePlugin"),require("@lexical/react/LexicalLinkPlugin"),require("@lexical/react/LexicalListPlugin"),require("@lexical/react/LexicalRichTextPlugin"),require("@lexical/react/LexicalTabIndentationPlugin"),require("lexical"),require("@lexical/code"),require("@lexical/link"),require("@lexical/list"),require("@lexical/react/LexicalHorizontalRuleNode"),require("@lexical/rich-text"),require("mdast-util-directive"),require("mdast-util-from-markdown"),require("mdast-util-frontmatter"),require("mdast-util-gfm-table"),require("mdast-util-mdx"),require("micromark-extension-directive"),require("micromark-extension-frontmatter"),require("micromark-extension-gfm-table"),require("micromark-extension-mdxjs"),require("@lexical/utils"),require("@lexical/react/LexicalComposerContext"),require("@lexical/selection"),require("@lexical/react/LexicalHistoryPlugin"),require("mdast-util-to-markdown"),require("@radix-ui/react-popover"),require("@radix-ui/react-tooltip"),require("downshift"),require("@lexical/markdown"),require("@lexical/react/LexicalMarkdownShortcutPlugin"),require("react-diff-view"),require("unidiff"),require("@radix-ui/react-toolbar"),require("@radix-ui/react-select"),require("@radix-ui/react-dialog");const n=i(t),c=e=>n.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:24,height:24,fill:"currentColor",viewBox:"0 0 24 24",...e},n.createElement("mask",{id:"a",width:24,height:24,x:0,y:0,maskUnits:"userSpaceOnUse",style:{maskType:"alpha"}},n.createElement("path",{d:"M0 0h24v24H0z"})),n.createElement("g",{mask:"url(#a)"},n.createElement("path",{d:"M10 17V7l5 5-5 5Z"}))),u=e=>n.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:24,height:24,fill:"currentColor",viewBox:"0 0 24 24",...e},n.createElement("mask",{id:"a",width:24,height:24,x:0,y:0,maskUnits:"userSpaceOnUse",style:{maskType:"alpha"}},n.createElement("path",{d:"M0 0h24v24H0z"})),n.createElement("g",{mask:"url(#a)"},n.createElement("path",{d:"m12 15-5-5h10l-5 5Z"}))),o=e=>n.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:20,height:20,fill:"currentColor",viewBox:"0 0 20 20",...e},n.createElement("mask",{id:"a",width:20,height:20,x:0,y:0,maskUnits:"userSpaceOnUse",style:{maskType:"alpha"}},n.createElement("path",{d:"M0 0h20v20H0z"})),n.createElement("g",{mask:"url(#a)"},n.createElement("path",{d:"M5 17V6.5H4V5h4V4h4v1h4v1.5h-1V17H5Zm1.5-1.5h7v-9h-7v9ZM8 14h1.5V8H8v6Zm2.5 0H12V8h-1.5v6Z"}))),m=t.forwardRef((({className:e,autofocusIfEmpty:r,...i},n)=>(i.autoFocus=Boolean(!i.value&&r),t.createElement("input",{className:l(a.styles.frontmatterInput,e),...i,ref:n}))));exports.FrontmatterEditor=({yaml:l,onChange:i})=>{const[n,s]=t.useState(!0),d=t.useMemo((()=>l?Object.entries(e.load(l)).map((([e,t])=>({key:e,value:t}))):[]),[l]),{register:x,control:h,watch:E}=r.useForm({defaultValues:{yamlConfig:d}}),{fields:f,append:p,remove:g}=r.useFieldArray({control:h,name:"yamlConfig"});return t.useEffect((()=>{const t=E((({yamlConfig:t})=>{const r=t.reduce(((e,{key:t,value:r})=>(t&&r&&(e[t]=r),e)),{});i(e.dump(r).trim())}));return()=>t.unsubscribe()}),[E,i]),t.createElement("div",{className:a.styles.frontmatterWrapper,"data-expanded":n,"data-editor-type":"frontmatter"},t.createElement("button",{className:a.styles.frontmatterToggleButton,onClick:e=>{e.preventDefault(),s((e=>!e))}},n?t.createElement(u,null):t.createElement(c,null),"Document frontmatter"),n&&t.createElement("form",null,t.createElement("table",{className:a.styles.frontmatterEditorTable},t.createElement("colgroup",null,t.createElement("col",null),t.createElement("col",null),t.createElement("col",null)),t.createElement("thead",null,t.createElement("tr",null,t.createElement("th",null,"Key"),t.createElement("th",null,"Value"),t.createElement("th",null))),t.createElement("tbody",null,f.map(((e,r)=>t.createElement("tr",{key:e.id},t.createElement("td",null,t.createElement(m,{...x(`yamlConfig.${r}.key`,{required:!0}),autofocusIfEmpty:!0})),t.createElement("td",null,t.createElement(m,{...x(`yamlConfig.${r}.value`,{required:!0})})),t.createElement("td",null,t.createElement("button",{type:"button",onClick:()=>g(r),className:a.styles.iconButton},t.createElement(o,null))))))),t.createElement("tfoot",null,t.createElement("tr",null,t.createElement("td",null,t.createElement("button",{className:a.styles.primaryButton,type:"button",onClick:()=>{p({key:"",value:""})}},"Add new key")))))))};
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),r=require("@lexical/react/LexicalComposerContext"),t=require("@lexical/react/useLexicalNodeSelection"),i=require("@lexical/utils"),l=require("lexical"),a=require("./index-93ab76f9.cjs"),c=require("classnames");require("@lexical/react/LexicalComposer"),require("@lexical/react/LexicalContentEditable"),require("@lexical/react/LexicalErrorBoundary"),require("@lexical/react/LexicalHorizontalRulePlugin"),require("@lexical/react/LexicalLinkPlugin"),require("@lexical/react/LexicalListPlugin"),require("@lexical/react/LexicalRichTextPlugin"),require("@lexical/react/LexicalTabIndentationPlugin"),require("@lexical/code"),require("@lexical/link"),require("@lexical/list"),require("@lexical/react/LexicalHorizontalRuleNode"),require("@lexical/rich-text"),require("mdast-util-directive"),require("mdast-util-from-markdown"),require("mdast-util-frontmatter"),require("mdast-util-gfm-table"),require("mdast-util-mdx"),require("micromark-extension-directive"),require("micromark-extension-frontmatter"),require("micromark-extension-gfm-table"),require("micromark-extension-mdxjs"),require("@lexical/selection"),require("@lexical/react/LexicalHistoryPlugin"),require("mdast-util-to-markdown"),require("@radix-ui/react-popover"),require("@radix-ui/react-tooltip"),require("downshift"),require("@lexical/markdown"),require("@lexical/react/LexicalMarkdownShortcutPlugin"),require("react-diff-view"),require("unidiff"),require("@radix-ui/react-toolbar"),require("@radix-ui/react-select"),require("@radix-ui/react-dialog");const n=new Set;function u({title:r,className:t,imageRef:i,src:l}){return function(e){if(!n.has(e))throw new Promise((r=>{const t=new Image;t.src=e,t.onload=()=>{n.add(e),r(null)}}))}(l),e.createElement("img",{className:t||void 0,src:l,title:r,ref:i,draggable:"false"})}exports.ImageEditor=function({src:n,title:o,nodeKey:s}){const m=e.useRef(null),d=e.useRef(null),[x,g,q]=t.useLexicalNodeSelection(s),[C]=r.useLexicalComposerContext(),[f,M]=e.useState(null),N=e.useRef(null),O=e.useCallback((e=>{if(x&&l.$isNodeSelection(l.$getSelection())){e.preventDefault();const r=l.$getNodeByKey(s);a.$isImageNode(r)&&r.remove()}return!1}),[x,s]),L=e.useCallback((e=>{const r=l.$getSelection(),t=d.current;return!(!x||!l.$isNodeSelection(r)||1!==r.getNodes().length||null===t||t===document.activeElement)&&(e.preventDefault(),t.focus(),!0)}),[x]),R=e.useCallback((e=>d.current===e.target&&(l.$setSelection(null),C.update((()=>{g(!0);const e=C.getRootElement();null!==e&&e.focus()})),!0)),[C,g]);e.useEffect((()=>{let e=!0;const r=i.mergeRegister(C.registerUpdateListener((({editorState:r})=>{e&&M(r.read((()=>l.$getSelection())))})),C.registerCommand(l.SELECTION_CHANGE_COMMAND,((e,r)=>(N.current=r,!1)),l.COMMAND_PRIORITY_LOW),C.registerCommand(l.CLICK_COMMAND,(e=>{const r=e;return r.target===m.current&&(r.shiftKey?g(!x):(q(),g(!0)),!0)}),l.COMMAND_PRIORITY_LOW),C.registerCommand(l.DRAGSTART_COMMAND,(e=>e.target===m.current&&(e.preventDefault(),!0)),l.COMMAND_PRIORITY_LOW),C.registerCommand(l.KEY_DELETE_COMMAND,O,l.COMMAND_PRIORITY_LOW),C.registerCommand(l.KEY_BACKSPACE_COMMAND,O,l.COMMAND_PRIORITY_LOW),C.registerCommand(l.KEY_ENTER_COMMAND,L,l.COMMAND_PRIORITY_LOW),C.registerCommand(l.KEY_ESCAPE_COMMAND,R,l.COMMAND_PRIORITY_LOW));return()=>{e=!1,r()}}),[q,C,x,s,O,L,R,g]);const E=l.$isNodeSelection(f),_=x;return e.createElement(e.Suspense,{fallback:null},e.createElement(e.Fragment,null,e.createElement("div",{draggable:E,className:a.styles.imageWrapper,"data-editor-block-type":"image"},e.createElement(u,{className:c({[a.styles.focusedImage]:_}),src:n,title:o||"",imageRef:m}))))};