@mdxeditor/editor 0.10.0-alpha.1 → 0.10.0-alpha.3
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.
- package/dist/MDXEditor.d.ts +29 -0
- package/dist/MDXEditor.js +1 -1
- package/dist/directive-editors/AdmonitionDirectiveDescriptor.d.ts +13 -0
- package/dist/directive-editors/GenericDirectiveEditor.d.ts +5 -0
- package/dist/importMarkdownToLexical.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -1
- package/dist/jsx-editors/GenericJsxEditor.d.ts +5 -0
- package/dist/plugins/core/NestedLexicalEditor.d.ts +9 -2
- package/dist/plugins/core/PropertyPopover.d.ts +17 -2
- package/dist/plugins/diff-source/SourceEditor.js +2 -0
- package/dist/plugins/diff-source/index.d.ts +1 -0
- package/dist/plugins/image/ImageEditor.d.ts +3 -1
- package/dist/plugins/image/ImageEditor.js +29 -6
- package/dist/plugins/image/ImageNode.d.ts +11 -1
- package/dist/plugins/image/ImageNode.js +37 -9
- package/dist/plugins/image/ImageResizer.d.ts +18 -0
- package/dist/plugins/image/ImageResizer.js +214 -0
- package/dist/plugins/image/LexicalImageVisitor.js +27 -6
- package/dist/plugins/image/MdastImageVisitor.d.ts +3 -0
- package/dist/plugins/image/MdastImageVisitor.js +72 -1
- package/dist/plugins/image/index.d.ts +4 -0
- package/dist/plugins/image/index.js +3 -1
- package/dist/plugins/jsx/MdastMdxJsxElementVisitor.js +1 -1
- package/dist/plugins/jsx/index.d.ts +9 -0
- package/dist/plugins/lists/LexicalListVisitor.js +0 -1
- package/dist/plugins/table/TableEditor.js +25 -15
- package/dist/plugins/toolbar/components/BlockTypeSelect.d.ts +4 -0
- package/dist/plugins/toolbar/components/BoldItalicUnderlineToggles.d.ts +3 -0
- package/dist/plugins/toolbar/components/ChangeAdmonitionType.d.ts +4 -0
- package/dist/plugins/toolbar/components/ChangeCodeMirrorLanguage.d.ts +5 -0
- package/dist/plugins/toolbar/components/ChangeCodeMirrorLanguage.js +2 -2
- package/dist/plugins/toolbar/components/CodeToggle.d.ts +4 -0
- package/dist/plugins/toolbar/components/CreateLink.d.ts +4 -0
- package/dist/plugins/toolbar/components/DiffSourceToggleWrapper.d.ts +5 -0
- package/dist/plugins/toolbar/components/InsertAdmonition.d.ts +4 -0
- package/dist/plugins/toolbar/components/InsertCodeBlock.d.ts +5 -0
- package/dist/plugins/toolbar/components/InsertFrontmatter.d.ts +4 -0
- package/dist/plugins/toolbar/components/InsertImage.d.ts +4 -0
- package/dist/plugins/toolbar/components/InsertSandpack.d.ts +4 -0
- package/dist/plugins/toolbar/components/InsertTable.d.ts +4 -0
- package/dist/plugins/toolbar/components/InsertThematicBreak.d.ts +4 -0
- package/dist/plugins/toolbar/components/KitchenSinkToolbar.d.ts +5 -0
- package/dist/plugins/toolbar/components/ListsToggle.d.ts +5 -0
- package/dist/plugins/toolbar/components/ShowSandpackInfo.d.ts +5 -0
- package/dist/plugins/toolbar/components/UndoRedo.d.ts +3 -0
- package/dist/plugins/toolbar/primitives/TooltipWrap.d.ts +3 -0
- package/dist/plugins/toolbar/primitives/select.d.ts +19 -0
- package/dist/plugins/toolbar/primitives/toolbar.d.ts +80 -5
- package/dist/style.css +232 -158
- package/dist/styles/ui.module.css.js +105 -75
- package/dist/utils/lexicalHelpers.js +2 -2
- package/package.json +12 -1
package/dist/MDXEditor.d.ts
CHANGED
|
@@ -1,12 +1,38 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { RealmPluginInitializer } from './gurx';
|
|
3
3
|
import { ToMarkdownOptions } from './exportMarkdownFromLexical';
|
|
4
|
+
/**
|
|
5
|
+
* The properties of the {@link MDXEditor} React component.
|
|
6
|
+
*/
|
|
4
7
|
export interface MDXEditorProps {
|
|
8
|
+
/**
|
|
9
|
+
* the CSS class to apply to the content editable element of the editor.
|
|
10
|
+
* Use this to style the various content elements like lists and blockquotes.
|
|
11
|
+
*/
|
|
5
12
|
contentEditableClassName?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The markdown to edit. Notice that this is read only when the component is mounted.
|
|
15
|
+
* To change the component content dynamically, use the `MDXEditorMethods.setMarkdown` method.
|
|
16
|
+
*/
|
|
6
17
|
markdown: string;
|
|
18
|
+
/**
|
|
19
|
+
* Triggered when the editor value changes. The callback is not throttled, you can use any throttling mechanism
|
|
20
|
+
* if you intend to do auto-saving.
|
|
21
|
+
*/
|
|
7
22
|
onChange?: (markdown: string) => void;
|
|
23
|
+
/**
|
|
24
|
+
* The markdown options used to generate the resulting markdown.
|
|
25
|
+
* See {@link https://github.com/syntax-tree/mdast-util-to-markdown#options | the mdast-util-to-markdown docs} for the full list of options.
|
|
26
|
+
*/
|
|
8
27
|
toMarkdownOptions?: ToMarkdownOptions;
|
|
28
|
+
/**
|
|
29
|
+
* The plugins to use in the editor.
|
|
30
|
+
*/
|
|
9
31
|
plugins?: React.ComponentProps<typeof RealmPluginInitializer>['plugins'];
|
|
32
|
+
/**
|
|
33
|
+
* The class name to apply to the root component element. Use this if you want to change the editor dimensions, maximum height, etc.
|
|
34
|
+
* For a content-specific styling, Use `contentEditableClassName` property.
|
|
35
|
+
*/
|
|
10
36
|
className?: string;
|
|
11
37
|
}
|
|
12
38
|
/**
|
|
@@ -28,4 +54,7 @@ export interface MDXEditorMethods {
|
|
|
28
54
|
*/
|
|
29
55
|
setMarkdown: (value: string) => void;
|
|
30
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* The MDXEditor React component. See {@link MDXEditorProps} for the list of properties supported and the {@link MDXEditorMethods} for the methods accessible through the ref.
|
|
59
|
+
*/
|
|
31
60
|
export declare const MDXEditor: React.ForwardRefExoticComponent<MDXEditorProps & React.RefAttributes<MDXEditorMethods>>;
|
package/dist/MDXEditor.js
CHANGED
|
@@ -62,7 +62,7 @@ const EditorRootElement = ({ children, className }) => {
|
|
|
62
62
|
React__default.useEffect(() => {
|
|
63
63
|
setEditorRootElementRef(editorRootElementRef);
|
|
64
64
|
}, [editorRootElementRef, setEditorRootElementRef]);
|
|
65
|
-
return /* @__PURE__ */ React__default.createElement("div", { className: classNames(styles.editorRoot, styles.editorWrapper, className), ref: editorRootElementRef }, children);
|
|
65
|
+
return /* @__PURE__ */ React__default.createElement("div", { className: classNames(styles.editorRoot, styles.editorWrapper, className, "mdxeditor"), ref: editorRootElementRef }, children);
|
|
66
66
|
};
|
|
67
67
|
const Methods = ({ mdxRef }) => {
|
|
68
68
|
const realm = corePluginHooks.useRealmContext();
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { DirectiveDescriptor } from '../plugins/directives';
|
|
2
|
+
/** @internal */
|
|
2
3
|
export declare const ADMONITION_TYPES: readonly ["note", "tip", "danger", "info", "caution"];
|
|
4
|
+
/** @internal */
|
|
3
5
|
export type AdmonitionKind = (typeof ADMONITION_TYPES)[number];
|
|
6
|
+
/**
|
|
7
|
+
* Pass this descriptor to the `directivesPlugin` `directiveDescriptors` parameter to enable {@link https://docusaurus.io/docs/markdown-features/admonitions | markdown admonitions}.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <MDXEditor
|
|
12
|
+
* plugins={[
|
|
13
|
+
* directivesPlugin({ directiveDescriptors: [ AdmonitionDirectiveDescriptor] }),
|
|
14
|
+
* ]} />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
4
17
|
export declare const AdmonitionDirectiveDescriptor: DirectiveDescriptor;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { DirectiveEditorProps } from '../plugins/directives';
|
|
3
|
+
/**
|
|
4
|
+
* A generic editor that can be used as an universal UI for any directive.
|
|
5
|
+
* Allows editing of the directive content and properties.
|
|
6
|
+
* Use this editor for the {@link DirectiveDescriptor} Editor option.
|
|
7
|
+
*/
|
|
3
8
|
export declare const GenericDirectiveEditor: React.FC<DirectiveEditorProps>;
|
|
@@ -28,7 +28,7 @@ function importMdastTreeToLexical({ root, mdastRoot, visitors }) {
|
|
|
28
28
|
return visitor2.testNode(mdastNode);
|
|
29
29
|
});
|
|
30
30
|
if (!visitor) {
|
|
31
|
-
throw new Error(`no MdastImportVisitor found for ${mdastNode.type}`, {
|
|
31
|
+
throw new Error(`no MdastImportVisitor found for ${mdastNode.type} ${JSON.stringify(mdastNode)}`, {
|
|
32
32
|
cause: mdastNode
|
|
33
33
|
});
|
|
34
34
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -47,3 +47,5 @@ export * from './plugins/toolbar/primitives/toolbar';
|
|
|
47
47
|
export * from './plugins/toolbar/primitives/DialogButton';
|
|
48
48
|
export * from './plugins/toolbar/primitives/TooltipWrap';
|
|
49
49
|
export * from './plugins/toolbar/primitives/select';
|
|
50
|
+
export * from './plugins/core/NestedLexicalEditor';
|
|
51
|
+
export * from './plugins/core/PropertyPopover';
|
package/dist/index.js
CHANGED
|
@@ -42,6 +42,8 @@ import { Button, ButtonOrDropdownButton, ButtonWithTooltip, ConditionalContents,
|
|
|
42
42
|
import { DialogButton } from "./plugins/toolbar/primitives/DialogButton.js";
|
|
43
43
|
import { TooltipWrap } from "./plugins/toolbar/primitives/TooltipWrap.js";
|
|
44
44
|
import { Select, SelectButtonTrigger, SelectContent, SelectItem, SelectTrigger } from "./plugins/toolbar/primitives/select.js";
|
|
45
|
+
import { NestedEditorsContext, NestedLexicalEditor, useLexicalNodeRemove, useMdastNodeUpdater, useNestedEditorContext } from "./plugins/core/NestedLexicalEditor.js";
|
|
46
|
+
import { PropertyPopover } from "./plugins/core/PropertyPopover.js";
|
|
45
47
|
import { useCodeBlockEditorContext } from "./plugins/codeblock/CodeBlockNode.js";
|
|
46
48
|
export {
|
|
47
49
|
ADMONITION_TYPES,
|
|
@@ -72,6 +74,9 @@ export {
|
|
|
72
74
|
ListsToggle,
|
|
73
75
|
MDXEditor,
|
|
74
76
|
MultipleChoiceToggleGroup,
|
|
77
|
+
NestedEditorsContext,
|
|
78
|
+
NestedLexicalEditor,
|
|
79
|
+
PropertyPopover,
|
|
75
80
|
Root,
|
|
76
81
|
Select,
|
|
77
82
|
SelectButtonTrigger,
|
|
@@ -131,5 +136,8 @@ export {
|
|
|
131
136
|
toolbarPlugin,
|
|
132
137
|
toolbarPluginHooks,
|
|
133
138
|
toolbarSystem,
|
|
134
|
-
useCodeBlockEditorContext
|
|
139
|
+
useCodeBlockEditorContext,
|
|
140
|
+
useLexicalNodeRemove,
|
|
141
|
+
useMdastNodeUpdater,
|
|
142
|
+
useNestedEditorContext
|
|
135
143
|
};
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { JsxEditorProps } from '../plugins/jsx';
|
|
3
|
+
/**
|
|
4
|
+
* A generic editor that can be used as an universal UI for any JSX element.
|
|
5
|
+
* Allows editing of the element content and properties.
|
|
6
|
+
* Use this editor for the {@link JsxComponentDescriptor} Editor option.
|
|
7
|
+
*/
|
|
3
8
|
export declare const GenericJsxEditor: React.FC<JsxEditorProps>;
|
|
@@ -13,7 +13,14 @@ interface NestedEditorsContextValue<T extends Node> {
|
|
|
13
13
|
};
|
|
14
14
|
focusEmitter: VoidEmitter;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Use this context to provide the necessary values to the {@link NestedLexicalEditor} React component.
|
|
18
|
+
* Place it as a wrapper in your custom lexical node decorators.
|
|
19
|
+
*/
|
|
16
20
|
export declare const NestedEditorsContext: React.Context<NestedEditorsContextValue<Node<import("unist").Data>> | undefined>;
|
|
21
|
+
/**
|
|
22
|
+
* A hook to get the current {@link NestedEditorsContext} value. Use this in your custom editor components.
|
|
23
|
+
*/
|
|
17
24
|
export declare const useNestedEditorContext: <T extends Mdast.Content>() => NestedEditorsContextValue<T>;
|
|
18
25
|
/**
|
|
19
26
|
* A hook that returns a function that can be used to update the mdast node. Use this in your custom editor components.
|
|
@@ -24,7 +31,7 @@ export declare function useMdastNodeUpdater<T extends Mdast.Content>(): (node: P
|
|
|
24
31
|
*/
|
|
25
32
|
export declare function useLexicalNodeRemove(): () => void;
|
|
26
33
|
/**
|
|
27
|
-
* The properties of the {@link
|
|
34
|
+
* The properties of the {@link NestedLexicalEditor} React component.
|
|
28
35
|
* @typeParam T - The type of the mdast node of the editor.
|
|
29
36
|
*/
|
|
30
37
|
export interface NestedEditorProps<T extends Mdast.Content> {
|
|
@@ -62,7 +69,7 @@ export interface NestedEditorProps<T extends Mdast.Content> {
|
|
|
62
69
|
* children: Mdast.PhrasingContent[]
|
|
63
70
|
* }
|
|
64
71
|
*
|
|
65
|
-
* return <
|
|
72
|
+
* return <NestedLexicalEditor<CalloutDirectiveNode> getContent={node => node.children} getUpdatedMdastNode={(node, children) => ({ ...node, children })} />
|
|
66
73
|
* ```
|
|
67
74
|
*/
|
|
68
75
|
export declare const NestedLexicalEditor: <T extends Mdast.Content>(props: NestedEditorProps<T>) => React.JSX.Element;
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* The properties of the {@link PropertyPopover} React component.
|
|
4
|
+
*/
|
|
5
|
+
export interface PropertyPopoverProps {
|
|
6
|
+
/**
|
|
7
|
+
* The properties to edit. The key is the name of the property, and the value is the initial value.
|
|
8
|
+
*/
|
|
3
9
|
properties: Record<string, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Triggered when the user edits the property values.
|
|
12
|
+
*/
|
|
4
13
|
onChange: (values: Record<string, string>) => void;
|
|
14
|
+
/**
|
|
15
|
+
* The title to display in the popover.
|
|
16
|
+
*/
|
|
5
17
|
title: string;
|
|
6
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* A React component that can be used in custom editors to edit the properties of the node.
|
|
21
|
+
* Displays a simple, static key/value editing UI in a popover.
|
|
22
|
+
*/
|
|
7
23
|
export declare const PropertyPopover: React.FC<PropertyPopoverProps>;
|
|
8
|
-
export {};
|
|
@@ -3,6 +3,7 @@ import { SandpackProvider, CodeEditor } from "@codesandbox/sandpack-react";
|
|
|
3
3
|
import React__default from "react";
|
|
4
4
|
import { diffSourcePluginHooks } from "./index.js";
|
|
5
5
|
import { corePluginHooks } from "../core/index.js";
|
|
6
|
+
import { EditorView } from "@codemirror/view";
|
|
6
7
|
const SourceEditor = () => {
|
|
7
8
|
const [markdown$1] = corePluginHooks.useEmitterValues("markdown");
|
|
8
9
|
const updateMarkdown = diffSourcePluginHooks.usePublisher("markdownSourceEditorValue");
|
|
@@ -10,6 +11,7 @@ const SourceEditor = () => {
|
|
|
10
11
|
return /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: null }, /* @__PURE__ */ React__default.createElement(SandpackProvider, null, /* @__PURE__ */ React__default.createElement(
|
|
11
12
|
CodeEditor,
|
|
12
13
|
{
|
|
14
|
+
extensions: [EditorView.lineWrapping],
|
|
13
15
|
showLineNumbers: true,
|
|
14
16
|
additionalLanguages: [{ name: "markdown", extensions: ["md"], language: markdown() }],
|
|
15
17
|
initMode: "lazy",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
/** @internal */
|
|
2
3
|
export type ViewMode = 'rich-text' | 'source' | 'diff';
|
|
3
4
|
/** @internal */
|
|
4
5
|
export declare const diffSourceSystem: import("../../gurx").SystemSpec<[import("../../gurx").SystemSpec<[], (r: import("../../gurx").Realm) => {
|
|
@@ -3,5 +3,7 @@ export interface ImageEditorProps {
|
|
|
3
3
|
nodeKey: string;
|
|
4
4
|
src: string;
|
|
5
5
|
title?: string;
|
|
6
|
+
width: number | 'inherit';
|
|
7
|
+
height: number | 'inherit';
|
|
6
8
|
}
|
|
7
|
-
export declare function ImageEditor({ src, title, nodeKey }: ImageEditorProps): JSX.Element;
|
|
9
|
+
export declare function ImageEditor({ src, title, nodeKey, width, height }: ImageEditorProps): JSX.Element;
|
|
@@ -6,6 +6,7 @@ import { $isNodeSelection, $getSelection, $getNodeByKey, $setSelection, SELECTIO
|
|
|
6
6
|
import styles from "../../styles/ui.module.css.js";
|
|
7
7
|
import classNames from "classnames";
|
|
8
8
|
import { $isImageNode } from "./ImageNode.js";
|
|
9
|
+
import ImageResizer from "./ImageResizer.js";
|
|
9
10
|
const imageCache = /* @__PURE__ */ new Set();
|
|
10
11
|
function useSuspenseImage(src) {
|
|
11
12
|
if (!imageCache.has(src)) {
|
|
@@ -23,18 +24,21 @@ function LazyImage({
|
|
|
23
24
|
title,
|
|
24
25
|
className,
|
|
25
26
|
imageRef,
|
|
26
|
-
src
|
|
27
|
+
src,
|
|
28
|
+
width,
|
|
29
|
+
height
|
|
27
30
|
}) {
|
|
28
31
|
useSuspenseImage(src);
|
|
29
|
-
return /* @__PURE__ */ React__default.createElement("img", { className: className || void 0, src, title, ref: imageRef, draggable: "false" });
|
|
32
|
+
return /* @__PURE__ */ React__default.createElement("img", { className: className || void 0, src, title, ref: imageRef, draggable: "false", width, height });
|
|
30
33
|
}
|
|
31
|
-
function ImageEditor({ src, title, nodeKey }) {
|
|
34
|
+
function ImageEditor({ src, title, nodeKey, width, height }) {
|
|
32
35
|
const imageRef = React__default.useRef(null);
|
|
33
36
|
const buttonRef = React__default.useRef(null);
|
|
34
37
|
const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
|
|
35
38
|
const [editor] = useLexicalComposerContext();
|
|
36
39
|
const [selection, setSelection] = React__default.useState(null);
|
|
37
40
|
const activeEditorRef = React__default.useRef(null);
|
|
41
|
+
const [isResizing, setIsResizing] = React__default.useState(false);
|
|
38
42
|
const onDelete = React__default.useCallback(
|
|
39
43
|
(payload) => {
|
|
40
44
|
if (isSelected && $isNodeSelection($getSelection())) {
|
|
@@ -101,6 +105,9 @@ function ImageEditor({ src, title, nodeKey }) {
|
|
|
101
105
|
CLICK_COMMAND,
|
|
102
106
|
(payload) => {
|
|
103
107
|
const event = payload;
|
|
108
|
+
if (isResizing) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
104
111
|
if (event.target === imageRef.current) {
|
|
105
112
|
if (event.shiftKey) {
|
|
106
113
|
setSelected(!isSelected);
|
|
@@ -134,12 +141,28 @@ function ImageEditor({ src, title, nodeKey }) {
|
|
|
134
141
|
isMounted = false;
|
|
135
142
|
unregister();
|
|
136
143
|
};
|
|
137
|
-
}, [clearSelection, editor, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
|
|
144
|
+
}, [clearSelection, editor, isResizing, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
|
|
145
|
+
const onResizeEnd = (nextWidth, nextHeight) => {
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
setIsResizing(false);
|
|
148
|
+
}, 200);
|
|
149
|
+
editor.update(() => {
|
|
150
|
+
const node = $getNodeByKey(nodeKey);
|
|
151
|
+
if ($isImageNode(node)) {
|
|
152
|
+
node.setWidthAndHeight(nextWidth, nextHeight);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
const onResizeStart = () => {
|
|
157
|
+
setIsResizing(true);
|
|
158
|
+
};
|
|
138
159
|
const draggable = $isNodeSelection(selection);
|
|
139
160
|
const isFocused = isSelected;
|
|
140
|
-
return /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: null }, /* @__PURE__ */ React__default.createElement(
|
|
161
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: null }, /* @__PURE__ */ React__default.createElement("div", { className: styles.imageWrapper, "data-editor-block-type": "image" }, /* @__PURE__ */ React__default.createElement("div", { draggable }, /* @__PURE__ */ React__default.createElement(
|
|
141
162
|
LazyImage,
|
|
142
163
|
{
|
|
164
|
+
width,
|
|
165
|
+
height,
|
|
143
166
|
className: classNames({
|
|
144
167
|
[styles.focusedImage]: isFocused
|
|
145
168
|
}),
|
|
@@ -147,7 +170,7 @@ function ImageEditor({ src, title, nodeKey }) {
|
|
|
147
170
|
title: title || "",
|
|
148
171
|
imageRef
|
|
149
172
|
}
|
|
150
|
-
))));
|
|
173
|
+
)), draggable && isFocused && /* @__PURE__ */ React__default.createElement(ImageResizer, { editor, imageRef, onResizeStart, onResizeEnd })));
|
|
151
174
|
}
|
|
152
175
|
export {
|
|
153
176
|
ImageEditor
|
|
@@ -7,6 +7,8 @@ import { DecoratorNode } from 'lexical';
|
|
|
7
7
|
export type SerializedImageNode = Spread<{
|
|
8
8
|
altText: string;
|
|
9
9
|
title?: string;
|
|
10
|
+
width?: number;
|
|
11
|
+
height?: number;
|
|
10
12
|
src: string;
|
|
11
13
|
type: 'image';
|
|
12
14
|
version: 1;
|
|
@@ -18,18 +20,24 @@ export declare class ImageNode extends DecoratorNode<JSX.Element> {
|
|
|
18
20
|
__src: string;
|
|
19
21
|
__altText: string;
|
|
20
22
|
__title: string | undefined;
|
|
23
|
+
__width: 'inherit' | number;
|
|
24
|
+
__height: 'inherit' | number;
|
|
21
25
|
static getType(): string;
|
|
22
26
|
static clone(node: ImageNode): ImageNode;
|
|
23
27
|
static importJSON(serializedNode: SerializedImageNode): ImageNode;
|
|
24
28
|
exportDOM(): DOMExportOutput;
|
|
25
29
|
static importDOM(): DOMConversionMap | null;
|
|
26
|
-
constructor(src: string, altText: string, title: string | undefined, key?: NodeKey);
|
|
30
|
+
constructor(src: string, altText: string, title: string | undefined, width?: 'inherit' | number, height?: 'inherit' | number, key?: NodeKey);
|
|
27
31
|
exportJSON(): SerializedImageNode;
|
|
32
|
+
setWidthAndHeight(width: 'inherit' | number, height: 'inherit' | number): void;
|
|
28
33
|
createDOM(config: EditorConfig): HTMLElement;
|
|
29
34
|
updateDOM(): false;
|
|
30
35
|
getSrc(): string;
|
|
31
36
|
getAltText(): string;
|
|
32
37
|
getTitle(): string | undefined;
|
|
38
|
+
getHeight(): 'inherit' | number;
|
|
39
|
+
getWidth(): 'inherit' | number;
|
|
40
|
+
hasExplicitDimensions(): boolean;
|
|
33
41
|
setTitle(title: string | undefined): void;
|
|
34
42
|
decorate(_parentEditor: LexicalEditor): JSX.Element;
|
|
35
43
|
}
|
|
@@ -38,6 +46,8 @@ export declare class ImageNode extends DecoratorNode<JSX.Element> {
|
|
|
38
46
|
*/
|
|
39
47
|
export interface CreateImageNodeOptions {
|
|
40
48
|
altText: string;
|
|
49
|
+
width?: number;
|
|
50
|
+
height?: number;
|
|
41
51
|
title?: string;
|
|
42
52
|
key?: NodeKey;
|
|
43
53
|
src: string;
|
|
@@ -9,34 +9,40 @@ import { DecoratorNode } from "lexical";
|
|
|
9
9
|
import { ImageEditor } from "./ImageEditor.js";
|
|
10
10
|
function convertImageElement(domNode) {
|
|
11
11
|
if (domNode instanceof HTMLImageElement) {
|
|
12
|
-
const { alt: altText, src, title } = domNode;
|
|
13
|
-
const node = $createImageNode({ altText, src, title });
|
|
12
|
+
const { alt: altText, src, title, width, height } = domNode;
|
|
13
|
+
const node = $createImageNode({ altText, src, title, width, height });
|
|
14
14
|
return { node };
|
|
15
15
|
}
|
|
16
16
|
return null;
|
|
17
17
|
}
|
|
18
18
|
class ImageNode extends DecoratorNode {
|
|
19
|
-
constructor(src, altText, title, key) {
|
|
19
|
+
constructor(src, altText, title, width, height, key) {
|
|
20
20
|
super(key);
|
|
21
21
|
__publicField(this, "__src");
|
|
22
22
|
__publicField(this, "__altText");
|
|
23
23
|
__publicField(this, "__title");
|
|
24
|
+
__publicField(this, "__width");
|
|
25
|
+
__publicField(this, "__height");
|
|
24
26
|
this.__src = src;
|
|
25
27
|
this.__title = title;
|
|
26
28
|
this.__altText = altText;
|
|
29
|
+
this.__width = width || "inherit";
|
|
30
|
+
this.__height = height || "inherit";
|
|
27
31
|
}
|
|
28
32
|
static getType() {
|
|
29
33
|
return "image";
|
|
30
34
|
}
|
|
31
35
|
static clone(node) {
|
|
32
|
-
return new ImageNode(node.__src, node.__altText, node.__title, node.__key);
|
|
36
|
+
return new ImageNode(node.__src, node.__altText, node.__title, node.__width, node.__height, node.__key);
|
|
33
37
|
}
|
|
34
38
|
static importJSON(serializedNode) {
|
|
35
|
-
const { altText, title, src } = serializedNode;
|
|
39
|
+
const { altText, title, src, width, height } = serializedNode;
|
|
36
40
|
const node = $createImageNode({
|
|
37
41
|
altText,
|
|
38
42
|
title,
|
|
39
|
-
src
|
|
43
|
+
src,
|
|
44
|
+
height,
|
|
45
|
+
width
|
|
40
46
|
});
|
|
41
47
|
return node;
|
|
42
48
|
}
|
|
@@ -47,6 +53,12 @@ class ImageNode extends DecoratorNode {
|
|
|
47
53
|
if (this.__title) {
|
|
48
54
|
element.setAttribute("title", this.__title);
|
|
49
55
|
}
|
|
56
|
+
if (this.__width) {
|
|
57
|
+
element.setAttribute("width", this.__width.toString());
|
|
58
|
+
}
|
|
59
|
+
if (this.__height) {
|
|
60
|
+
element.setAttribute("height", this.__height.toString());
|
|
61
|
+
}
|
|
50
62
|
return { element };
|
|
51
63
|
}
|
|
52
64
|
static importDOM() {
|
|
@@ -61,11 +73,18 @@ class ImageNode extends DecoratorNode {
|
|
|
61
73
|
return {
|
|
62
74
|
altText: this.getAltText(),
|
|
63
75
|
title: this.getTitle(),
|
|
76
|
+
height: this.__height === "inherit" ? 0 : this.__height,
|
|
77
|
+
width: this.__width === "inherit" ? 0 : this.__width,
|
|
64
78
|
src: this.getSrc(),
|
|
65
79
|
type: "image",
|
|
66
80
|
version: 1
|
|
67
81
|
};
|
|
68
82
|
}
|
|
83
|
+
setWidthAndHeight(width, height) {
|
|
84
|
+
const writable = this.getWritable();
|
|
85
|
+
writable.__width = width;
|
|
86
|
+
writable.__height = height;
|
|
87
|
+
}
|
|
69
88
|
createDOM(config) {
|
|
70
89
|
const span = document.createElement("span");
|
|
71
90
|
const theme = config.theme;
|
|
@@ -87,16 +106,25 @@ class ImageNode extends DecoratorNode {
|
|
|
87
106
|
getTitle() {
|
|
88
107
|
return this.__title;
|
|
89
108
|
}
|
|
109
|
+
getHeight() {
|
|
110
|
+
return this.__height;
|
|
111
|
+
}
|
|
112
|
+
getWidth() {
|
|
113
|
+
return this.__width;
|
|
114
|
+
}
|
|
115
|
+
hasExplicitDimensions() {
|
|
116
|
+
return this.__width !== "inherit" || this.__height !== "inherit";
|
|
117
|
+
}
|
|
90
118
|
setTitle(title) {
|
|
91
119
|
this.getWritable().__title = title;
|
|
92
120
|
}
|
|
93
121
|
decorate(_parentEditor) {
|
|
94
|
-
return /* @__PURE__ */ React__default.createElement(ImageEditor, { src: this.getSrc(), title: this.getTitle(), nodeKey: this.getKey() });
|
|
122
|
+
return /* @__PURE__ */ React__default.createElement(ImageEditor, { src: this.getSrc(), title: this.getTitle(), nodeKey: this.getKey(), width: this.__width, height: this.__height });
|
|
95
123
|
}
|
|
96
124
|
}
|
|
97
125
|
function $createImageNode(options) {
|
|
98
|
-
const { altText, title, src, key } = options;
|
|
99
|
-
return new ImageNode(src, altText, title, key);
|
|
126
|
+
const { altText, title, src, key, width, height } = options;
|
|
127
|
+
return new ImageNode(src, altText, title, width, height, key);
|
|
100
128
|
}
|
|
101
129
|
function $isImageNode(node) {
|
|
102
130
|
return node instanceof ImageNode;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
/// <reference types="react" />
|
|
9
|
+
import type { LexicalEditor } from 'lexical';
|
|
10
|
+
export default function ImageResizer({ onResizeStart, onResizeEnd, imageRef, maxWidth, editor }: {
|
|
11
|
+
editor: LexicalEditor;
|
|
12
|
+
imageRef: {
|
|
13
|
+
current: null | HTMLElement;
|
|
14
|
+
};
|
|
15
|
+
maxWidth?: number;
|
|
16
|
+
onResizeEnd: (width: 'inherit' | number, height: 'inherit' | number) => void;
|
|
17
|
+
onResizeStart: () => void;
|
|
18
|
+
}): JSX.Element;
|