@mdxeditor/editor 3.40.1 → 3.41.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.
- package/README.md +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.js +3 -1
- package/dist/plugins/image/EditImageToolbar.js +6 -3
- package/dist/plugins/image/ImageDialog.js +10 -5
- package/dist/plugins/image/ImageEditor.js +20 -3
- package/dist/plugins/image/index.js +25 -3
- package/dist/style.css +252 -247
- package/dist/styles/ui.module.css.js +97 -94
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ If you find a bug, check if something similar is not reported already in the [is
|
|
|
26
26
|
|
|
27
27
|
If you're integrating the component in your commercial project and need dedicated assistance with your issues in exchange of sponsorship, [contact me over email](mailto:petyo@mdxeditor.dev).
|
|
28
28
|
|
|
29
|
-
If you want to discuss ideas
|
|
29
|
+
If you want to discuss ideas start a discussion in the [Discussions](https://github.com/mdx-editor/editor/discussions) section.
|
|
30
30
|
|
|
31
31
|
## License
|
|
32
32
|
|
package/dist/index.d.ts
CHANGED
|
@@ -268,6 +268,12 @@ export declare const ALL_HEADING_LEVELS: readonly [1, 2, 3, 4, 5, 6];
|
|
|
268
268
|
*/
|
|
269
269
|
export declare const allowedHeadingLevels$: NodeRef<readonly HEADING_LEVEL[]>;
|
|
270
270
|
|
|
271
|
+
/**
|
|
272
|
+
* Allow to set width and height of image through dialog window
|
|
273
|
+
* @group Image
|
|
274
|
+
*/
|
|
275
|
+
export declare const allowSetImageDimensions$: NodeRef<boolean>;
|
|
276
|
+
|
|
271
277
|
/**
|
|
272
278
|
* returns a function which when called always returns the passed value
|
|
273
279
|
* @group Utils
|
|
@@ -311,6 +317,8 @@ export declare const applyListType$: NodeRef<"" | ListType>;
|
|
|
311
317
|
declare interface BaseImageParameters {
|
|
312
318
|
altText?: string;
|
|
313
319
|
title?: string;
|
|
320
|
+
width?: number;
|
|
321
|
+
height?: number;
|
|
314
322
|
}
|
|
315
323
|
|
|
316
324
|
/**
|
|
@@ -1086,6 +1094,8 @@ declare interface EditImageToolbarProps {
|
|
|
1086
1094
|
initialImagePath: string | null;
|
|
1087
1095
|
title: string;
|
|
1088
1096
|
alt: string;
|
|
1097
|
+
width?: number | 'inherit';
|
|
1098
|
+
height?: number | 'inherit';
|
|
1089
1099
|
}
|
|
1090
1100
|
|
|
1091
1101
|
/**
|
|
@@ -1416,6 +1426,7 @@ export declare const imagePlugin: (params?: {
|
|
|
1416
1426
|
imageAutocompleteSuggestions?: string[] | undefined;
|
|
1417
1427
|
disableImageResize?: boolean | undefined;
|
|
1418
1428
|
disableImageSettingsButton?: boolean | undefined;
|
|
1429
|
+
allowSetImageDimensions?: boolean | undefined;
|
|
1419
1430
|
imagePreviewHandler?: ImagePreviewHandler | undefined;
|
|
1420
1431
|
ImageDialog?: FC<{}> | (() => JSX.Element) | undefined;
|
|
1421
1432
|
EditImageToolbar?: FC<{}> | (() => JSX.Element) | undefined;
|
|
@@ -2441,6 +2452,8 @@ export declare const openLinkEditDialog$: NodeRef<void>;
|
|
|
2441
2452
|
*/
|
|
2442
2453
|
export declare const openNewImageDialog$: NodeRef<void>;
|
|
2443
2454
|
|
|
2455
|
+
export declare const parseImageDimension: (value: string | number | undefined) => number | undefined;
|
|
2456
|
+
|
|
2444
2457
|
/* Excluded from this release type: placeholder$ */
|
|
2445
2458
|
|
|
2446
2459
|
/**
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { insertThematicBreak$, thematicBreakPlugin } from "./plugins/thematic-br
|
|
|
10
10
|
import { applyListType$, currentListType$, listsPlugin } from "./plugins/lists/index.js";
|
|
11
11
|
import { insertTable$, tablePlugin } from "./plugins/table/index.js";
|
|
12
12
|
import { disableAutoLink$, linkPlugin } from "./plugins/link/index.js";
|
|
13
|
-
import { INSERT_IMAGE_COMMAND, closeImageDialog$, disableImageResize$, disableImageSettingsButton$, editImageToolbarComponent$, imageAutocompleteSuggestions$, imageDialogState$, imagePlaceholder$, imagePlugin, imagePreviewHandler$, imageUploadHandler$, insertImage$, openEditImageDialog$, openNewImageDialog$, saveImage$ } from "./plugins/image/index.js";
|
|
13
|
+
import { INSERT_IMAGE_COMMAND, allowSetImageDimensions$, closeImageDialog$, disableImageResize$, disableImageSettingsButton$, editImageToolbarComponent$, imageAutocompleteSuggestions$, imageDialogState$, imagePlaceholder$, imagePlugin, imagePreviewHandler$, imageUploadHandler$, insertImage$, openEditImageDialog$, openNewImageDialog$, parseImageDimension, saveImage$ } from "./plugins/image/index.js";
|
|
14
14
|
import { frontmatterDialogOpen$, frontmatterPlugin, hasFrontmatter$, insertFrontmatter$, removeFrontmatter$ } from "./plugins/frontmatter/index.js";
|
|
15
15
|
import { quotePlugin } from "./plugins/quote/index.js";
|
|
16
16
|
import { maxLengthPlugin } from "./plugins/maxlength/index.js";
|
|
@@ -180,6 +180,7 @@ export {
|
|
|
180
180
|
addToMarkdownExtension$,
|
|
181
181
|
addTopAreaChild$,
|
|
182
182
|
admonitionLabelsMap,
|
|
183
|
+
allowSetImageDimensions$,
|
|
183
184
|
allowedHeadingLevels$,
|
|
184
185
|
always,
|
|
185
186
|
appendCodeBlockEditorDescriptor$,
|
|
@@ -304,6 +305,7 @@ export {
|
|
|
304
305
|
openEditImageDialog$,
|
|
305
306
|
openLinkEditDialog$,
|
|
306
307
|
openNewImageDialog$,
|
|
308
|
+
parseImageDimension,
|
|
307
309
|
placeholder$,
|
|
308
310
|
prop,
|
|
309
311
|
quotePlugin,
|
|
@@ -3,10 +3,11 @@ import { useCellValues, usePublisher } from "@mdxeditor/gurx";
|
|
|
3
3
|
import classNames from "classnames";
|
|
4
4
|
import { $getNodeByKey } from "lexical";
|
|
5
5
|
import React__default from "react";
|
|
6
|
-
import { disableImageSettingsButton$, openEditImageDialog
|
|
6
|
+
import { disableImageSettingsButton$, openEditImageDialog$, parseImageDimension } from "./index.js";
|
|
7
7
|
import styles from "../../styles/ui.module.css.js";
|
|
8
8
|
import { iconComponentFor$, readOnly$, useTranslation } from "../core/index.js";
|
|
9
|
-
function EditImageToolbar(
|
|
9
|
+
function EditImageToolbar(props) {
|
|
10
|
+
const { nodeKey, imageSource, initialImagePath, title, alt, width, height } = props;
|
|
10
11
|
const [disableImageSettingsButton, iconComponentFor, readOnly] = useCellValues(disableImageSettingsButton$, iconComponentFor$, readOnly$);
|
|
11
12
|
const [editor] = useLexicalComposerContext();
|
|
12
13
|
const openEditImageDialog = usePublisher(openEditImageDialog$);
|
|
@@ -40,7 +41,9 @@ function EditImageToolbar({ nodeKey, imageSource, initialImagePath, title, alt }
|
|
|
40
41
|
initialValues: {
|
|
41
42
|
src: !initialImagePath ? imageSource : initialImagePath,
|
|
42
43
|
title,
|
|
43
|
-
altText: alt
|
|
44
|
+
altText: alt,
|
|
45
|
+
width: parseImageDimension(width),
|
|
46
|
+
height: parseImageDimension(height)
|
|
44
47
|
}
|
|
45
48
|
});
|
|
46
49
|
}
|
|
@@ -4,15 +4,16 @@ import React__default from "react";
|
|
|
4
4
|
import { useForm } from "react-hook-form";
|
|
5
5
|
import styles from "../../styles/ui.module.css.js";
|
|
6
6
|
import { editorRootElementRef$, useTranslation } from "../core/index.js";
|
|
7
|
-
import { imageAutocompleteSuggestions$, imageDialogState$, imageUploadHandler$, saveImage$, closeImageDialog$ } from "./index.js";
|
|
7
|
+
import { imageAutocompleteSuggestions$, imageDialogState$, imageUploadHandler$, allowSetImageDimensions$, saveImage$, closeImageDialog$ } from "./index.js";
|
|
8
8
|
import { DownshiftAutoComplete } from "../core/ui/DownshiftAutoComplete.js";
|
|
9
9
|
import { useCellValues, usePublisher } from "@mdxeditor/gurx";
|
|
10
10
|
const ImageDialog = () => {
|
|
11
|
-
const [imageAutocompleteSuggestions, state, editorRootElementRef, imageUploadHandler] = useCellValues(
|
|
11
|
+
const [imageAutocompleteSuggestions, state, editorRootElementRef, imageUploadHandler, allowSetImageDimensions] = useCellValues(
|
|
12
12
|
imageAutocompleteSuggestions$,
|
|
13
13
|
imageDialogState$,
|
|
14
14
|
editorRootElementRef$,
|
|
15
|
-
imageUploadHandler
|
|
15
|
+
imageUploadHandler$,
|
|
16
|
+
allowSetImageDimensions$
|
|
16
17
|
);
|
|
17
18
|
const saveImage = usePublisher(saveImage$);
|
|
18
19
|
const closeImageDialog = usePublisher(closeImageDialog$);
|
|
@@ -21,6 +22,9 @@ const ImageDialog = () => {
|
|
|
21
22
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
22
23
|
values: state.type === "editing" ? state.initialValues : {}
|
|
23
24
|
});
|
|
25
|
+
const resetFormState = () => {
|
|
26
|
+
reset({ src: "", title: "", altText: "", width: void 0, height: void 0 });
|
|
27
|
+
};
|
|
24
28
|
if (state.type === "inactive")
|
|
25
29
|
return null;
|
|
26
30
|
return /* @__PURE__ */ React__default.createElement(
|
|
@@ -30,7 +34,7 @@ const ImageDialog = () => {
|
|
|
30
34
|
onOpenChange: (open) => {
|
|
31
35
|
if (!open) {
|
|
32
36
|
closeImageDialog();
|
|
33
|
-
|
|
37
|
+
resetFormState();
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
},
|
|
@@ -50,7 +54,7 @@ const ImageDialog = () => {
|
|
|
50
54
|
e.preventDefault();
|
|
51
55
|
e.stopPropagation();
|
|
52
56
|
await handleSubmit(saveImage)(e);
|
|
53
|
-
|
|
57
|
+
resetFormState();
|
|
54
58
|
},
|
|
55
59
|
className: styles.multiFieldForm
|
|
56
60
|
},
|
|
@@ -69,6 +73,7 @@ const ImageDialog = () => {
|
|
|
69
73
|
)),
|
|
70
74
|
/* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "alt" }, t("uploadImage.alt", "Alt:")), /* @__PURE__ */ React__default.createElement("input", { type: "text", ...register("altText"), className: styles.textInput })),
|
|
71
75
|
/* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "title" }, t("uploadImage.title", "Title:")), /* @__PURE__ */ React__default.createElement("input", { type: "text", ...register("title"), className: styles.textInput })),
|
|
76
|
+
allowSetImageDimensions && /* @__PURE__ */ React__default.createElement("div", { className: styles.imageDimensionsContainer }, /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "width" }, t("uploadImage.width", "Width:")), /* @__PURE__ */ React__default.createElement("input", { type: "number", min: 0, ...register("width"), className: styles.textInput })), /* @__PURE__ */ React__default.createElement("div", { className: styles.formField }, /* @__PURE__ */ React__default.createElement("label", { htmlFor: "height" }, t("uploadImage.height", "Height:")), /* @__PURE__ */ React__default.createElement("input", { type: "number", min: 0, ...register("height"), className: styles.textInput }))),
|
|
72
77
|
/* @__PURE__ */ React__default.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: "var(--spacing-2)" } }, /* @__PURE__ */ React__default.createElement(
|
|
73
78
|
"button",
|
|
74
79
|
{
|
|
@@ -5,7 +5,7 @@ import { mergeRegister } from "@lexical/utils";
|
|
|
5
5
|
import { useCellValues } from "@mdxeditor/gurx";
|
|
6
6
|
import classNames from "classnames";
|
|
7
7
|
import { $isNodeSelection, $getSelection, $getNodeByKey, $setSelection, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_LOW, CLICK_COMMAND, DRAGSTART_COMMAND, KEY_DELETE_COMMAND, KEY_BACKSPACE_COMMAND, KEY_ENTER_COMMAND, KEY_ESCAPE_COMMAND } from "lexical";
|
|
8
|
-
import { imagePlaceholder$, disableImageResize$, imagePreviewHandler$, editImageToolbarComponent$ } from "./index.js";
|
|
8
|
+
import { imagePlaceholder$, disableImageResize$, allowSetImageDimensions$, imagePreviewHandler$, editImageToolbarComponent$ } from "./index.js";
|
|
9
9
|
import styles from "../../styles/ui.module.css.js";
|
|
10
10
|
import { readOnly$ } from "../core/index.js";
|
|
11
11
|
import { $isImageNode } from "./ImageNode.js";
|
|
@@ -66,9 +66,10 @@ function LazyImage({
|
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
function ImageEditor({ src, title, alt, nodeKey, width, height, rest }) {
|
|
69
|
-
const [ImagePlaceholderComponent, disableImageResize, imagePreviewHandler, readOnly, EditImageToolbar] = useCellValues(
|
|
69
|
+
const [ImagePlaceholderComponent, disableImageResize, allowSetImageDimensions, imagePreviewHandler, readOnly, EditImageToolbar] = useCellValues(
|
|
70
70
|
imagePlaceholder$,
|
|
71
71
|
disableImageResize$,
|
|
72
|
+
allowSetImageDimensions$,
|
|
72
73
|
imagePreviewHandler$,
|
|
73
74
|
readOnly$,
|
|
74
75
|
editImageToolbarComponent$
|
|
@@ -143,6 +144,13 @@ function ImageEditor({ src, title, alt, nodeKey, width, height, rest }) {
|
|
|
143
144
|
setImageSource(src);
|
|
144
145
|
}
|
|
145
146
|
}, [src, imagePreviewHandler, initialImagePath]);
|
|
147
|
+
React__default.useEffect(() => {
|
|
148
|
+
if (allowSetImageDimensions && imageRef.current) {
|
|
149
|
+
const { current: image } = imageRef;
|
|
150
|
+
syncDimensionWithImageResizer(image, "width", width);
|
|
151
|
+
syncDimensionWithImageResizer(image, "height", height);
|
|
152
|
+
}
|
|
153
|
+
}, [allowSetImageDimensions, width, height]);
|
|
146
154
|
React__default.useEffect(() => {
|
|
147
155
|
let isMounted = true;
|
|
148
156
|
const unregister = mergeRegister(
|
|
@@ -249,10 +257,19 @@ function ImageEditor({ src, title, alt, nodeKey, width, height, rest }) {
|
|
|
249
257
|
imageSource,
|
|
250
258
|
initialImagePath,
|
|
251
259
|
title: title ?? "",
|
|
252
|
-
alt: alt ?? ""
|
|
260
|
+
alt: alt ?? "",
|
|
261
|
+
width,
|
|
262
|
+
height
|
|
253
263
|
}
|
|
254
264
|
))) : null;
|
|
255
265
|
}
|
|
266
|
+
const syncDimensionWithImageResizer = (image, key, value) => {
|
|
267
|
+
if (typeof value === "number") {
|
|
268
|
+
image.style[key] = `${value}px`;
|
|
269
|
+
} else {
|
|
270
|
+
image.style.removeProperty(key);
|
|
271
|
+
}
|
|
272
|
+
};
|
|
256
273
|
export {
|
|
257
274
|
ImageEditor
|
|
258
275
|
};
|
|
@@ -13,7 +13,13 @@ import { MdastImageVisitor, MdastHtmlImageVisitor, MdastJsxImageVisitor } from "
|
|
|
13
13
|
const internalInsertImage$ = Signal((r) => {
|
|
14
14
|
r.sub(r.pipe(internalInsertImage$, withLatestFrom(activeEditor$)), ([values, theEditor]) => {
|
|
15
15
|
theEditor == null ? void 0 : theEditor.update(() => {
|
|
16
|
-
const imageNode = $createImageNode({
|
|
16
|
+
const imageNode = $createImageNode({
|
|
17
|
+
altText: values.altText ?? "",
|
|
18
|
+
src: values.src,
|
|
19
|
+
title: values.title ?? "",
|
|
20
|
+
width: parseImageDimension(values.width),
|
|
21
|
+
height: parseImageDimension(values.height)
|
|
22
|
+
});
|
|
17
23
|
$insertNodes([imageNode]);
|
|
18
24
|
if ($isRootOrShadowRoot(imageNode.getParentOrThrow())) {
|
|
19
25
|
$wrapNodeInElement(imageNode, $createParagraphNode).selectEnd();
|
|
@@ -44,8 +50,8 @@ const imageDialogState$ = Cell(
|
|
|
44
50
|
{ type: "inactive" },
|
|
45
51
|
(r) => {
|
|
46
52
|
r.sub(
|
|
47
|
-
r.pipe(saveImage$, withLatestFrom(activeEditor$, imageUploadHandler$, imageDialogState$)),
|
|
48
|
-
([values, theEditor, imageUploadHandler, dialogState]) => {
|
|
53
|
+
r.pipe(saveImage$, withLatestFrom(activeEditor$, imageUploadHandler$, imageDialogState$, allowSetImageDimensions$)),
|
|
54
|
+
([values, theEditor, imageUploadHandler, dialogState, allowSetImageDimensions]) => {
|
|
49
55
|
const handler = dialogState.type === "editing" ? (src) => {
|
|
50
56
|
theEditor == null ? void 0 : theEditor.update(() => {
|
|
51
57
|
const { nodeKey } = dialogState;
|
|
@@ -53,6 +59,11 @@ const imageDialogState$ = Cell(
|
|
|
53
59
|
imageNode.setTitle(values.title);
|
|
54
60
|
imageNode.setAltText(values.altText);
|
|
55
61
|
imageNode.setSrc(src);
|
|
62
|
+
if (allowSetImageDimensions) {
|
|
63
|
+
const width = parseImageDimension(values.width);
|
|
64
|
+
const height = parseImageDimension(values.height);
|
|
65
|
+
imageNode.setWidthAndHeight(width ?? "inherit", height ?? "inherit");
|
|
66
|
+
}
|
|
56
67
|
});
|
|
57
68
|
r.pub(imageDialogState$, { type: "inactive" });
|
|
58
69
|
} : (src) => {
|
|
@@ -158,8 +169,15 @@ const closeImageDialog$ = Action((r) => {
|
|
|
158
169
|
r.link(r.pipe(closeImageDialog$, mapTo({ type: "inactive" })), imageDialogState$);
|
|
159
170
|
});
|
|
160
171
|
const disableImageSettingsButton$ = Cell(false);
|
|
172
|
+
const allowSetImageDimensions$ = Cell(false);
|
|
161
173
|
const saveImage$ = Signal();
|
|
162
174
|
const editImageToolbarComponent$ = Cell(EditImageToolbar);
|
|
175
|
+
const parseImageDimension = (value) => {
|
|
176
|
+
if (typeof value === "undefined")
|
|
177
|
+
return void 0;
|
|
178
|
+
const parsed = parseInt(String(value), 10);
|
|
179
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
180
|
+
};
|
|
163
181
|
const imagePlugin = realmPlugin({
|
|
164
182
|
init(realm, params) {
|
|
165
183
|
realm.pubIn({
|
|
@@ -171,6 +189,7 @@ const imagePlugin = realmPlugin({
|
|
|
171
189
|
[imageAutocompleteSuggestions$]: (params == null ? void 0 : params.imageAutocompleteSuggestions) ?? [],
|
|
172
190
|
[disableImageResize$]: Boolean(params == null ? void 0 : params.disableImageResize),
|
|
173
191
|
[disableImageSettingsButton$]: Boolean(params == null ? void 0 : params.disableImageSettingsButton),
|
|
192
|
+
[allowSetImageDimensions$]: Boolean(params == null ? void 0 : params.allowSetImageDimensions),
|
|
174
193
|
[imagePreviewHandler$]: (params == null ? void 0 : params.imagePreviewHandler) ?? null,
|
|
175
194
|
[editImageToolbarComponent$]: (params == null ? void 0 : params.EditImageToolbar) ?? EditImageToolbar,
|
|
176
195
|
[imagePlaceholder$]: (params == null ? void 0 : params.imagePlaceholder) ?? ImagePlaceholder
|
|
@@ -182,6 +201,7 @@ const imagePlugin = realmPlugin({
|
|
|
182
201
|
[imageAutocompleteSuggestions$]: (params == null ? void 0 : params.imageAutocompleteSuggestions) ?? [],
|
|
183
202
|
[disableImageResize$]: Boolean(params == null ? void 0 : params.disableImageResize),
|
|
184
203
|
[imagePreviewHandler$]: (params == null ? void 0 : params.imagePreviewHandler) ?? null,
|
|
204
|
+
[allowSetImageDimensions$]: Boolean(params == null ? void 0 : params.allowSetImageDimensions),
|
|
185
205
|
[editImageToolbarComponent$]: (params == null ? void 0 : params.EditImageToolbar) ?? EditImageToolbar,
|
|
186
206
|
[imagePlaceholder$]: (params == null ? void 0 : params.imagePlaceholder) ?? ImagePlaceholder
|
|
187
207
|
});
|
|
@@ -331,6 +351,7 @@ export {
|
|
|
331
351
|
$isImageNode,
|
|
332
352
|
INSERT_IMAGE_COMMAND,
|
|
333
353
|
ImageNode,
|
|
354
|
+
allowSetImageDimensions$,
|
|
334
355
|
closeImageDialog$,
|
|
335
356
|
disableImageResize$,
|
|
336
357
|
disableImageSettingsButton$,
|
|
@@ -344,5 +365,6 @@ export {
|
|
|
344
365
|
insertImage$,
|
|
345
366
|
openEditImageDialog$,
|
|
346
367
|
openNewImageDialog$,
|
|
368
|
+
parseImageDimension,
|
|
347
369
|
saveImage$
|
|
348
370
|
};
|