@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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import styles from "../../styles/ui.module.css.js";
|
|
4
|
+
import classNames from "classnames";
|
|
5
|
+
function clamp(value, min, max) {
|
|
6
|
+
return Math.min(Math.max(value, min), max);
|
|
7
|
+
}
|
|
8
|
+
const Direction = {
|
|
9
|
+
east: 1 << 0,
|
|
10
|
+
north: 1 << 3,
|
|
11
|
+
south: 1 << 1,
|
|
12
|
+
west: 1 << 2
|
|
13
|
+
};
|
|
14
|
+
function ImageResizer({
|
|
15
|
+
onResizeStart,
|
|
16
|
+
onResizeEnd,
|
|
17
|
+
imageRef,
|
|
18
|
+
maxWidth,
|
|
19
|
+
editor
|
|
20
|
+
}) {
|
|
21
|
+
const controlWrapperRef = useRef(null);
|
|
22
|
+
const userSelect = useRef({
|
|
23
|
+
priority: "",
|
|
24
|
+
value: "default"
|
|
25
|
+
});
|
|
26
|
+
const positioningRef = useRef({
|
|
27
|
+
currentHeight: 0,
|
|
28
|
+
currentWidth: 0,
|
|
29
|
+
direction: 0,
|
|
30
|
+
isResizing: false,
|
|
31
|
+
ratio: 0,
|
|
32
|
+
startHeight: 0,
|
|
33
|
+
startWidth: 0,
|
|
34
|
+
startX: 0,
|
|
35
|
+
startY: 0
|
|
36
|
+
});
|
|
37
|
+
const editorRootElement = editor.getRootElement();
|
|
38
|
+
const maxWidthContainer = maxWidth ? maxWidth : editorRootElement !== null ? editorRootElement.getBoundingClientRect().width - 20 : 100;
|
|
39
|
+
const maxHeightContainer = editorRootElement !== null ? editorRootElement.getBoundingClientRect().height - 20 : 100;
|
|
40
|
+
const minWidth = 100;
|
|
41
|
+
const minHeight = 100;
|
|
42
|
+
const setStartCursor = (direction) => {
|
|
43
|
+
const ew = direction === Direction.east || direction === Direction.west;
|
|
44
|
+
const ns = direction === Direction.north || direction === Direction.south;
|
|
45
|
+
const nwse = direction & Direction.north && direction & Direction.west || direction & Direction.south && direction & Direction.east;
|
|
46
|
+
const cursorDir = ew ? "ew" : ns ? "ns" : nwse ? "nwse" : "nesw";
|
|
47
|
+
if (editorRootElement !== null) {
|
|
48
|
+
editorRootElement.style.setProperty("cursor", `${cursorDir}-resize`, "important");
|
|
49
|
+
}
|
|
50
|
+
if (document.body !== null) {
|
|
51
|
+
document.body.style.setProperty("cursor", `${cursorDir}-resize`, "important");
|
|
52
|
+
userSelect.current.value = document.body.style.getPropertyValue("-webkit-user-select");
|
|
53
|
+
userSelect.current.priority = document.body.style.getPropertyPriority("-webkit-user-select");
|
|
54
|
+
document.body.style.setProperty("-webkit-user-select", `none`, "important");
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const setEndCursor = () => {
|
|
58
|
+
if (editorRootElement !== null) {
|
|
59
|
+
editorRootElement.style.setProperty("cursor", "text");
|
|
60
|
+
}
|
|
61
|
+
if (document.body !== null) {
|
|
62
|
+
document.body.style.setProperty("cursor", "default");
|
|
63
|
+
document.body.style.setProperty("-webkit-user-select", userSelect.current.value, userSelect.current.priority);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const handlePointerDown = (event, direction) => {
|
|
67
|
+
if (!editor.isEditable()) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const image = imageRef.current;
|
|
71
|
+
const controlWrapper = controlWrapperRef.current;
|
|
72
|
+
if (image !== null && controlWrapper !== null) {
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
const { width, height } = image.getBoundingClientRect();
|
|
75
|
+
const positioning = positioningRef.current;
|
|
76
|
+
positioning.startWidth = width;
|
|
77
|
+
positioning.startHeight = height;
|
|
78
|
+
positioning.ratio = width / height;
|
|
79
|
+
positioning.currentWidth = width;
|
|
80
|
+
positioning.currentHeight = height;
|
|
81
|
+
positioning.startX = event.clientX;
|
|
82
|
+
positioning.startY = event.clientY;
|
|
83
|
+
positioning.isResizing = true;
|
|
84
|
+
positioning.direction = direction;
|
|
85
|
+
setStartCursor(direction);
|
|
86
|
+
onResizeStart();
|
|
87
|
+
controlWrapper.classList.add(styles.imageControlWrapperResizing);
|
|
88
|
+
image.style.height = `${height}px`;
|
|
89
|
+
image.style.width = `${width}px`;
|
|
90
|
+
document.addEventListener("pointermove", handlePointerMove);
|
|
91
|
+
document.addEventListener("pointerup", handlePointerUp);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const handlePointerMove = (event) => {
|
|
95
|
+
const image = imageRef.current;
|
|
96
|
+
const positioning = positioningRef.current;
|
|
97
|
+
const isHorizontal = positioning.direction & (Direction.east | Direction.west);
|
|
98
|
+
const isVertical = positioning.direction & (Direction.south | Direction.north);
|
|
99
|
+
if (image !== null && positioning.isResizing) {
|
|
100
|
+
if (isHorizontal && isVertical) {
|
|
101
|
+
let diff = Math.floor(positioning.startX - event.clientX);
|
|
102
|
+
diff = positioning.direction & Direction.east ? -diff : diff;
|
|
103
|
+
const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
|
|
104
|
+
const height = width / positioning.ratio;
|
|
105
|
+
image.style.width = `${width}px`;
|
|
106
|
+
image.style.height = `${height}px`;
|
|
107
|
+
positioning.currentHeight = height;
|
|
108
|
+
positioning.currentWidth = width;
|
|
109
|
+
} else if (isVertical) {
|
|
110
|
+
let diff = Math.floor(positioning.startY - event.clientY);
|
|
111
|
+
diff = positioning.direction & Direction.south ? -diff : diff;
|
|
112
|
+
const height = clamp(positioning.startHeight + diff, minHeight, maxHeightContainer);
|
|
113
|
+
image.style.height = `${height}px`;
|
|
114
|
+
positioning.currentHeight = height;
|
|
115
|
+
} else {
|
|
116
|
+
let diff = Math.floor(positioning.startX - event.clientX);
|
|
117
|
+
diff = positioning.direction & Direction.east ? -diff : diff;
|
|
118
|
+
const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
|
|
119
|
+
image.style.width = `${width}px`;
|
|
120
|
+
positioning.currentWidth = width;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const handlePointerUp = () => {
|
|
125
|
+
const image = imageRef.current;
|
|
126
|
+
const positioning = positioningRef.current;
|
|
127
|
+
const controlWrapper = controlWrapperRef.current;
|
|
128
|
+
if (image !== null && controlWrapper !== null && positioning.isResizing) {
|
|
129
|
+
const width = positioning.currentWidth;
|
|
130
|
+
const height = positioning.currentHeight;
|
|
131
|
+
positioning.startWidth = 0;
|
|
132
|
+
positioning.startHeight = 0;
|
|
133
|
+
positioning.ratio = 0;
|
|
134
|
+
positioning.startX = 0;
|
|
135
|
+
positioning.startY = 0;
|
|
136
|
+
positioning.currentWidth = 0;
|
|
137
|
+
positioning.currentHeight = 0;
|
|
138
|
+
positioning.isResizing = false;
|
|
139
|
+
controlWrapper.classList.remove(styles.imageControlWrapperResizing);
|
|
140
|
+
setEndCursor();
|
|
141
|
+
onResizeEnd(width, height);
|
|
142
|
+
document.removeEventListener("pointermove", handlePointerMove);
|
|
143
|
+
document.removeEventListener("pointerup", handlePointerUp);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
return /* @__PURE__ */ React.createElement("div", { ref: controlWrapperRef }, /* @__PURE__ */ React.createElement(
|
|
147
|
+
"div",
|
|
148
|
+
{
|
|
149
|
+
className: classNames(styles.imageResizer, styles.imageResizerN),
|
|
150
|
+
onPointerDown: (event) => {
|
|
151
|
+
handlePointerDown(event, Direction.north);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
), /* @__PURE__ */ React.createElement(
|
|
155
|
+
"div",
|
|
156
|
+
{
|
|
157
|
+
className: classNames(styles.imageResizer, styles.imageResizerNe),
|
|
158
|
+
onPointerDown: (event) => {
|
|
159
|
+
handlePointerDown(event, Direction.north | Direction.east);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
), /* @__PURE__ */ React.createElement(
|
|
163
|
+
"div",
|
|
164
|
+
{
|
|
165
|
+
className: classNames(styles.imageResizer, styles.imageResizerE),
|
|
166
|
+
onPointerDown: (event) => {
|
|
167
|
+
handlePointerDown(event, Direction.east);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
), /* @__PURE__ */ React.createElement(
|
|
171
|
+
"div",
|
|
172
|
+
{
|
|
173
|
+
className: classNames(styles.imageResizer, styles.imageResizerSe),
|
|
174
|
+
onPointerDown: (event) => {
|
|
175
|
+
handlePointerDown(event, Direction.south | Direction.east);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
), /* @__PURE__ */ React.createElement(
|
|
179
|
+
"div",
|
|
180
|
+
{
|
|
181
|
+
className: classNames(styles.imageResizer, styles.imageResizerS),
|
|
182
|
+
onPointerDown: (event) => {
|
|
183
|
+
handlePointerDown(event, Direction.south);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
), /* @__PURE__ */ React.createElement(
|
|
187
|
+
"div",
|
|
188
|
+
{
|
|
189
|
+
className: classNames(styles.imageResizer, styles.imageResizerSw),
|
|
190
|
+
onPointerDown: (event) => {
|
|
191
|
+
handlePointerDown(event, Direction.south | Direction.west);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
), /* @__PURE__ */ React.createElement(
|
|
195
|
+
"div",
|
|
196
|
+
{
|
|
197
|
+
className: classNames(styles.imageResizer, styles.imageResizerW),
|
|
198
|
+
onPointerDown: (event) => {
|
|
199
|
+
handlePointerDown(event, Direction.west);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
), /* @__PURE__ */ React.createElement(
|
|
203
|
+
"div",
|
|
204
|
+
{
|
|
205
|
+
className: classNames(styles.imageResizer, styles.imageResizerNw),
|
|
206
|
+
onPointerDown: (event) => {
|
|
207
|
+
handlePointerDown(event, Direction.north | Direction.west);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
));
|
|
211
|
+
}
|
|
212
|
+
export {
|
|
213
|
+
ImageResizer as default
|
|
214
|
+
};
|
|
@@ -2,12 +2,33 @@ import { $isImageNode } from "./ImageNode.js";
|
|
|
2
2
|
const LexicalImageVisitor = {
|
|
3
3
|
testLexicalNode: $isImageNode,
|
|
4
4
|
visitLexicalNode({ mdastParent, lexicalNode, actions }) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
if (lexicalNode.hasExplicitDimensions()) {
|
|
6
|
+
const img = new Image();
|
|
7
|
+
if (lexicalNode.getHeight() !== "inherit") {
|
|
8
|
+
img.height = lexicalNode.getHeight();
|
|
9
|
+
}
|
|
10
|
+
if (lexicalNode.getWidth() !== "inherit") {
|
|
11
|
+
img.width = lexicalNode.getWidth();
|
|
12
|
+
}
|
|
13
|
+
img.src = lexicalNode.getSrc();
|
|
14
|
+
if (lexicalNode.getAltText()) {
|
|
15
|
+
img.alt = lexicalNode.getAltText();
|
|
16
|
+
}
|
|
17
|
+
if (lexicalNode.getTitle()) {
|
|
18
|
+
img.title = lexicalNode.getTitle();
|
|
19
|
+
}
|
|
20
|
+
actions.appendToParent(mdastParent, {
|
|
21
|
+
type: "html",
|
|
22
|
+
value: img.outerHTML.replace(/>$/, "/>")
|
|
23
|
+
});
|
|
24
|
+
} else {
|
|
25
|
+
actions.appendToParent(mdastParent, {
|
|
26
|
+
type: "image",
|
|
27
|
+
url: lexicalNode.getSrc(),
|
|
28
|
+
alt: lexicalNode.getAltText(),
|
|
29
|
+
title: lexicalNode.getTitle()
|
|
30
|
+
});
|
|
31
|
+
}
|
|
11
32
|
}
|
|
12
33
|
};
|
|
13
34
|
export {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import * as Mdast from 'mdast';
|
|
2
2
|
import { MdastImportVisitor } from '../../importMarkdownToLexical';
|
|
3
|
+
import { MdxJsxTextElement, MdxJsxFlowElement } from 'mdast-util-mdx';
|
|
3
4
|
export declare const MdastImageVisitor: MdastImportVisitor<Mdast.Image>;
|
|
5
|
+
export declare const MdastHtmlImageVisitor: MdastImportVisitor<Mdast.HTML>;
|
|
6
|
+
export declare const MdastJsxImageVisitor: MdastImportVisitor<MdxJsxTextElement | MdxJsxFlowElement>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { $createImageNode } from "./ImageNode.js";
|
|
2
|
+
import { $createParagraphNode } from "lexical";
|
|
2
3
|
const MdastImageVisitor = {
|
|
3
4
|
testNode: "image",
|
|
4
5
|
visitNode({ mdastNode, actions }) {
|
|
@@ -11,6 +12,76 @@ const MdastImageVisitor = {
|
|
|
11
12
|
);
|
|
12
13
|
}
|
|
13
14
|
};
|
|
15
|
+
const MdastHtmlImageVisitor = {
|
|
16
|
+
testNode: (node) => {
|
|
17
|
+
return node.type === "html" && node.value.trim().startsWith("<img");
|
|
18
|
+
},
|
|
19
|
+
visitNode({ mdastNode, lexicalParent }) {
|
|
20
|
+
const wrapper = document.createElement("div");
|
|
21
|
+
wrapper.innerHTML = mdastNode.value;
|
|
22
|
+
const img = wrapper.querySelector("img");
|
|
23
|
+
if (!img) {
|
|
24
|
+
throw new Error("Invalid HTML image");
|
|
25
|
+
}
|
|
26
|
+
const src = img.src;
|
|
27
|
+
const altText = img.alt;
|
|
28
|
+
const title = img.title;
|
|
29
|
+
const width = img.width;
|
|
30
|
+
const height = img.height;
|
|
31
|
+
const image = $createImageNode({
|
|
32
|
+
src: src || "",
|
|
33
|
+
altText,
|
|
34
|
+
title,
|
|
35
|
+
width,
|
|
36
|
+
height
|
|
37
|
+
});
|
|
38
|
+
if (lexicalParent.getType() === "root") {
|
|
39
|
+
const paragraph = $createParagraphNode();
|
|
40
|
+
paragraph.append(image);
|
|
41
|
+
lexicalParent.append(paragraph);
|
|
42
|
+
} else {
|
|
43
|
+
lexicalParent.append(image);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
function getAttributeValue(node, attributeName) {
|
|
48
|
+
const attribute = node.attributes.find((a) => a.type === "mdxJsxAttribute" && a.name === attributeName);
|
|
49
|
+
if (!attribute) {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
return attribute.value;
|
|
53
|
+
}
|
|
54
|
+
const MdastJsxImageVisitor = {
|
|
55
|
+
testNode: (node) => {
|
|
56
|
+
return (node.type === "mdxJsxTextElement" || node.type === "mdxJsxFlowElement") && node.name === "img";
|
|
57
|
+
},
|
|
58
|
+
visitNode({ mdastNode, lexicalParent }) {
|
|
59
|
+
const src = getAttributeValue(mdastNode, "src");
|
|
60
|
+
if (!src) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const altText = getAttributeValue(mdastNode, "alt") || "";
|
|
64
|
+
const title = getAttributeValue(mdastNode, "title");
|
|
65
|
+
const height = getAttributeValue(mdastNode, "height");
|
|
66
|
+
const width = getAttributeValue(mdastNode, "width");
|
|
67
|
+
const image = $createImageNode({
|
|
68
|
+
src,
|
|
69
|
+
altText,
|
|
70
|
+
title,
|
|
71
|
+
width: width ? parseInt(width, 10) : void 0,
|
|
72
|
+
height: height ? parseInt(height, 10) : void 0
|
|
73
|
+
});
|
|
74
|
+
if (lexicalParent.getType() === "root") {
|
|
75
|
+
const paragraph = $createParagraphNode();
|
|
76
|
+
paragraph.append(image);
|
|
77
|
+
lexicalParent.append(paragraph);
|
|
78
|
+
} else {
|
|
79
|
+
lexicalParent.append(image);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
14
83
|
export {
|
|
15
|
-
|
|
84
|
+
MdastHtmlImageVisitor,
|
|
85
|
+
MdastImageVisitor,
|
|
86
|
+
MdastJsxImageVisitor
|
|
16
87
|
};
|
|
@@ -530,7 +530,11 @@ imagePluginHooks: {
|
|
|
530
530
|
insertDecoratorNode: import("../../gurx").RealmNode<() => import("lexical").DecoratorNode<unknown>>;
|
|
531
531
|
}, K_2>) => void;
|
|
532
532
|
};
|
|
533
|
+
/** @internal */
|
|
533
534
|
export type InsertImagePayload = Readonly<CreateImageNodeOptions>;
|
|
535
|
+
/**
|
|
536
|
+
* @internal
|
|
537
|
+
*/
|
|
534
538
|
export declare const INSERT_IMAGE_COMMAND: LexicalCommand<InsertImagePayload>;
|
|
535
539
|
declare global {
|
|
536
540
|
interface DragEvent {
|
|
@@ -3,7 +3,7 @@ import { createCommand, $insertNodes, $isRootOrShadowRoot, $createParagraphNode,
|
|
|
3
3
|
import { coreSystem } from "../core/index.js";
|
|
4
4
|
import { $createImageNode, $isImageNode, ImageNode } from "./ImageNode.js";
|
|
5
5
|
import { LexicalImageVisitor } from "./LexicalImageVisitor.js";
|
|
6
|
-
import { MdastImageVisitor } from "./MdastImageVisitor.js";
|
|
6
|
+
import { MdastImageVisitor, MdastHtmlImageVisitor, MdastJsxImageVisitor } from "./MdastImageVisitor.js";
|
|
7
7
|
import { CAN_USE_DOM } from "../../utils/detectMac.js";
|
|
8
8
|
import { system } from "../../gurx/realmFactory.js";
|
|
9
9
|
import { realmPlugin } from "../../gurx/react.js";
|
|
@@ -106,6 +106,8 @@ const [
|
|
|
106
106
|
},
|
|
107
107
|
init: (realm) => {
|
|
108
108
|
realm.pubKey("addImportVisitor", MdastImageVisitor);
|
|
109
|
+
realm.pubKey("addImportVisitor", MdastHtmlImageVisitor);
|
|
110
|
+
realm.pubKey("addImportVisitor", MdastJsxImageVisitor);
|
|
109
111
|
realm.pubKey("addLexicalNode", ImageNode);
|
|
110
112
|
realm.pubKey("addExportVisitor", LexicalImageVisitor);
|
|
111
113
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { $createLexicalJsxNode } from "./LexicalJsxNode.js";
|
|
2
2
|
const MdastMdxJsxElementVisitor = {
|
|
3
3
|
testNode: (node) => {
|
|
4
|
-
return node.type === "mdxJsxTextElement" || node.type === "mdxJsxFlowElement";
|
|
4
|
+
return (node.type === "mdxJsxTextElement" || node.type === "mdxJsxFlowElement") && node.name !== "img";
|
|
5
5
|
},
|
|
6
6
|
visitNode({ lexicalParent, mdastNode }) {
|
|
7
7
|
lexicalParent.append($createLexicalJsxNode(mdastNode));
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { MdxJsxFlowElement, MdxJsxTextElement } from 'mdast-util-mdx-jsx';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
3
6
|
export type MdastJsx = MdxJsxTextElement | MdxJsxFlowElement;
|
|
4
7
|
/**
|
|
5
8
|
* Defines the structure of a JSX component property.
|
|
@@ -109,7 +112,13 @@ export declare const jsxSystem: import("../../gurx").SystemSpec<[import("../../g
|
|
|
109
112
|
convertSelectionToNode: import("../../gurx").RealmNode<() => import("lexical").ElementNode>;
|
|
110
113
|
insertDecoratorNode: import("../../gurx").RealmNode<() => import("lexical").DecoratorNode<unknown>>;
|
|
111
114
|
}>], (_: import("../../gurx").Realm) => {}>;
|
|
115
|
+
/**
|
|
116
|
+
* The parameters of the `jsxPlugin`.
|
|
117
|
+
*/
|
|
112
118
|
export interface JsxPluginParams {
|
|
119
|
+
/**
|
|
120
|
+
* A set of descriptors that document the JSX elements used in the document.
|
|
121
|
+
*/
|
|
113
122
|
jsxComponentDescriptors: JsxComponentDescriptor[];
|
|
114
123
|
}
|
|
115
124
|
export declare const
|
|
@@ -77,18 +77,26 @@ const TableEditor = ({ mdastNode, parentEditor, lexicalTable }) => {
|
|
|
77
77
|
React__default.useEffect(() => {
|
|
78
78
|
lexicalTable.focusEmitter.subscribe(setActiveCellWithBoundaries);
|
|
79
79
|
}, [lexicalTable, setActiveCellWithBoundaries]);
|
|
80
|
-
const addRowToBottom = React__default.useCallback(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
80
|
+
const addRowToBottom = React__default.useCallback(
|
|
81
|
+
(e) => {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
parentEditor.update(() => {
|
|
84
|
+
lexicalTable.addRowToBottom();
|
|
85
|
+
setActiveCell([0, lexicalTable.getRowCount()]);
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
[parentEditor, lexicalTable]
|
|
89
|
+
);
|
|
90
|
+
const addColumnToRight = React__default.useCallback(
|
|
91
|
+
(e) => {
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
parentEditor.update(() => {
|
|
94
|
+
lexicalTable.addColumnToRight();
|
|
95
|
+
setActiveCell([lexicalTable.getColCount(), 0]);
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
[parentEditor, lexicalTable]
|
|
99
|
+
);
|
|
92
100
|
const [highlightedCoordinates, setHighlightedCoordinates] = React__default.useState([-1, -1]);
|
|
93
101
|
const onTableMouseOver = React__default.useCallback((e) => {
|
|
94
102
|
let tableCell = e.target;
|
|
@@ -116,8 +124,10 @@ const TableEditor = ({ mdastNode, parentEditor, lexicalTable }) => {
|
|
|
116
124
|
"button",
|
|
117
125
|
{
|
|
118
126
|
className: styles.iconButton,
|
|
127
|
+
type: "button",
|
|
119
128
|
title: "Delete table",
|
|
120
|
-
onClick: () => {
|
|
129
|
+
onClick: (e) => {
|
|
130
|
+
e.preventDefault();
|
|
121
131
|
parentEditor.update(() => {
|
|
122
132
|
lexicalTable.selectNext();
|
|
123
133
|
lexicalTable.remove();
|
|
@@ -158,8 +168,8 @@ const TableEditor = ({ mdastNode, parentEditor, lexicalTable }) => {
|
|
|
158
168
|
}
|
|
159
169
|
}
|
|
160
170
|
);
|
|
161
|
-
}), rowIndex === 0 && /* @__PURE__ */ React__default.createElement("th", { rowSpan: lexicalTable.getRowCount(), "data-tool-cell": true }, /* @__PURE__ */ React__default.createElement("button", { className: styles.addColumnButton, onClick: addColumnToRight }, /* @__PURE__ */ React__default.createElement(AddColumnIcon, null))));
|
|
162
|
-
})), /* @__PURE__ */ React__default.createElement("tfoot", null, /* @__PURE__ */ React__default.createElement("tr", null, /* @__PURE__ */ React__default.createElement("th", null), /* @__PURE__ */ React__default.createElement("th", { colSpan: lexicalTable.getColCount() }, /* @__PURE__ */ React__default.createElement("button", { className: styles.addRowButton, onClick: addRowToBottom }, /* @__PURE__ */ React__default.createElement(AddRowIcon, null))), /* @__PURE__ */ React__default.createElement("th", null))));
|
|
171
|
+
}), rowIndex === 0 && /* @__PURE__ */ React__default.createElement("th", { rowSpan: lexicalTable.getRowCount(), "data-tool-cell": true }, /* @__PURE__ */ React__default.createElement("button", { type: "button", className: styles.addColumnButton, onClick: addColumnToRight }, /* @__PURE__ */ React__default.createElement(AddColumnIcon, null))));
|
|
172
|
+
})), /* @__PURE__ */ React__default.createElement("tfoot", null, /* @__PURE__ */ React__default.createElement("tr", null, /* @__PURE__ */ React__default.createElement("th", null), /* @__PURE__ */ React__default.createElement("th", { colSpan: lexicalTable.getColCount() }, /* @__PURE__ */ React__default.createElement("button", { type: "button", className: styles.addRowButton, onClick: addRowToBottom }, /* @__PURE__ */ React__default.createElement(AddRowIcon, null))), /* @__PURE__ */ React__default.createElement("th", null))));
|
|
163
173
|
};
|
|
164
174
|
const Cell = ({ align, ...props }) => {
|
|
165
175
|
const { activeCell, setActiveCell } = props;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A component that allows the user to change the admonition type of the current selection.
|
|
4
|
+
* For this component to work, you must pass the {@link AdmonitionDirectiveDescriptor} to the `directivesPlugin` `directiveDescriptors` parameter.
|
|
5
|
+
*/
|
|
2
6
|
export declare const ChangeAdmonitionType: () => React.JSX.Element;
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A component that allows the user to change the code block language of the current selection.
|
|
4
|
+
* For this component to work, you must enable the `codeMirrorPlugin` for the editor.
|
|
5
|
+
* See {@link ConditionalContents} for an example on how to display the dropdown only when a code block is in focus.
|
|
6
|
+
*/
|
|
2
7
|
export declare const ChangeCodeMirrorLanguage: () => React.JSX.Element;
|
|
@@ -21,8 +21,8 @@ const ChangeCodeMirrorLanguage = () => {
|
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
},
|
|
24
|
-
triggerTitle: "Select
|
|
25
|
-
placeholder: "
|
|
24
|
+
triggerTitle: "Select code block language",
|
|
25
|
+
placeholder: "Code block language",
|
|
26
26
|
items: Object.entries(codeBlockLanguages).map(([value, label]) => ({ value, label }))
|
|
27
27
|
}
|
|
28
28
|
));
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A wrapper element for the toolbar contents that lets the user toggle between rich text, diff and source mode.
|
|
4
|
+
* Put the rich text toolbar contents as children of this component.
|
|
5
|
+
* For this component to work, you must include the `diffSourcePlugin`.
|
|
6
|
+
*/
|
|
2
7
|
export declare const DiffSourceToggleWrapper: React.FC<{
|
|
3
8
|
children: React.ReactNode;
|
|
4
9
|
}>;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A toolbar dropdown button that allows the user to insert admonitions.
|
|
4
|
+
* For this to work, you need to have the `directives` plugin enabled with the {@link AdmonitionDirectiveDescriptor} configured.
|
|
5
|
+
*/
|
|
2
6
|
export declare const InsertAdmonition: () => React.JSX.Element;
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A toolbar button that allows the user to insert a fenced code block.
|
|
4
|
+
* Once the code block is focused, you can construct a special code block toolbar for it, using the {@link ConditionalContents} primitive.
|
|
5
|
+
* See the {@link ConditionalContents} documentation for an example.
|
|
6
|
+
*/
|
|
2
7
|
export declare const InsertCodeBlock: React.FC;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A toolbar button that allows the user to insert a {@link https://jekyllrb.com/docs/front-matter/ | front-matter} editor (if one is not already present).
|
|
4
|
+
* For this to work, you need to have the `frontmatterPlugin` plugin enabled.
|
|
5
|
+
*/
|
|
2
6
|
export declare const InsertFrontmatter: React.FC;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A toolbar button that allows the user to insert an image from an URL.
|
|
4
|
+
* For the button to work, you need to have the `imagePlugin` plugin enabled.
|
|
5
|
+
*/
|
|
2
6
|
export declare const InsertImage: React.ForwardRefExoticComponent<Omit<Record<string, never>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A dropdown button that allows the user to insert a live code block into the editor. The dropdown offers a list of presets that are defined in the sandpack plugin config.
|
|
4
|
+
* For this to work, you need to have the `sandpackPlugin` installed.
|
|
5
|
+
*/
|
|
2
6
|
export declare const InsertSandpack: () => React.JSX.Element;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A toolbar button that allows the user to insert a thematic break (rendered as an HR HTML element).
|
|
4
|
+
* For this button to work, you need to have the `thematicBreakPlugin` plugin enabled.
|
|
5
|
+
*/
|
|
2
6
|
export declare const InsertThematicBreak: React.FC;
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A toolbar component that includes all toolbar components.
|
|
4
|
+
* Notice that some of the buttons will work only if you have the corresponding plugin enabled, so you should use it only for testing purposes.
|
|
5
|
+
* You'll probably want to create your own toolbar component that includes only the buttons that you need.
|
|
6
|
+
*/
|
|
2
7
|
export declare const KitchenSinkToolbar: React.FC;
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A toolbar toggle that allows the user to toggle between bulleted and numbered lists.
|
|
4
|
+
* Pressing the selected button will convert the current list to the other type. Pressing it again will remove the list.
|
|
5
|
+
* For this button to work, you need to have the `listsPlugin` plugin enabled.
|
|
6
|
+
*/
|
|
2
7
|
export declare const ListsToggle: React.FC;
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A component that displays the focused live code block's name.
|
|
4
|
+
* For this component to work, you must enable the `sandpackPlugin` for the editor.
|
|
5
|
+
* See {@link ConditionalContents} for an example on how to display the dropdown only when a sandpack editor is in focus.
|
|
6
|
+
*/
|
|
2
7
|
export declare const ShowSandpackInfo: () => React.JSX.Element;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A small styled wrapper around the radix-ui tooltip, that lets you display an instan tooltip on hover.
|
|
4
|
+
*/
|
|
2
5
|
export declare const TooltipWrap: React.ForwardRefExoticComponent<{
|
|
3
6
|
title: string;
|
|
4
7
|
children: ReactNode;
|