@notum-cz/strapi-plugin-tiptap-editor 1.1.1 → 1.2.1
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 +82 -8
- package/dist/_chunks/{RichTextInput-EtL-yFqV.js → RichTextInput-1uZSm3Nc.js} +225 -18
- package/dist/_chunks/{RichTextInput-B8CLPOyo.mjs → RichTextInput-B4D0Djcf.mjs} +227 -20
- package/dist/_chunks/{index-sX8SY6P-.mjs → index-BVPd2eP4.mjs} +1 -1
- package/dist/_chunks/{index-yXpX_VsO.js → index-CTcKIvYv.js} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/ImageAltPopover.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
- [Text Alignment](#text-alignment)
|
|
91
91
|
- [Text Color \& Highlight Color](#text-color--highlight-color)
|
|
92
92
|
- [Images](#images)
|
|
93
|
+
- [Rendering images on the frontend](#rendering-images-on-the-frontend)
|
|
93
94
|
- [Theme](#theme)
|
|
94
95
|
- [Colors](#colors)
|
|
95
96
|
- [Custom Stylesheet](#custom-stylesheet)
|
|
@@ -415,18 +416,22 @@ Both features use a color picker popover that displays the colors defined in the
|
|
|
415
416
|
|
|
416
417
|
### Images
|
|
417
418
|
|
|
418
|
-
| Key | Description | Toolbar
|
|
419
|
-
| -------------- | -------------------------------- |
|
|
420
|
-
| `mediaLibrary` | Images from Strapi Media Library | Image button + alt text popover + alignment |
|
|
419
|
+
| Key | Description | Toolbar |
|
|
420
|
+
| -------------- | -------------------------------- | --------------------------------------------------------- |
|
|
421
|
+
| `mediaLibrary` | Images from Strapi Media Library | Image button + alt text popover + alignment + resize handle |
|
|
421
422
|
|
|
422
423
|
Enables image insertion from the Strapi Media Library. When enabled, the toolbar shows an image button that opens the Media Library picker. After selecting an image:
|
|
423
424
|
|
|
424
425
|
- The image appears in the editor at its natural size (constrained to editor width)
|
|
425
426
|
- Alt text is prefilled from the asset's `alternativeText` metadata
|
|
426
|
-
- Clicking a selected image opens a popover
|
|
427
|
-
- Three alignment buttons (left, center, right)
|
|
427
|
+
- Clicking a selected image opens a popover with:
|
|
428
|
+
- Three **alignment** buttons (left, center, right)
|
|
429
|
+
- **Width** and **Height** inputs (in pixels) for precise sizing
|
|
430
|
+
- A **reset** button to restore the original dimensions
|
|
431
|
+
- **Alt text** input and a **delete** button
|
|
432
|
+
- A **resize handle** (blue dot) appears at the bottom-right corner on hover — drag it to resize the image
|
|
428
433
|
|
|
429
|
-
The image stores
|
|
434
|
+
The image stores the URL (`src`), Strapi asset ID (`data-asset-id`), alignment (`data-align`), and dimensions (`width`, `height`) in the Tiptap JSON output.
|
|
430
435
|
|
|
431
436
|
**Content safety:** If you remove `mediaLibrary` from a preset, existing images in content are preserved and rendered read-only — they are never silently deleted.
|
|
432
437
|
|
|
@@ -436,6 +441,73 @@ The image stores both the URL (`src`) and the Strapi asset ID (`data-asset-id`)
|
|
|
436
441
|
}
|
|
437
442
|
```
|
|
438
443
|
|
|
444
|
+
**Resize** is configured through the `resize` key inside `mediaLibrary`. The options match the standard `@tiptap/extension-image` `resize` configuration. When `resize` is omitted or set to `false`, the resize handle and dimension controls are hidden.
|
|
445
|
+
|
|
446
|
+
```ts
|
|
447
|
+
{
|
|
448
|
+
mediaLibrary: {
|
|
449
|
+
resize: {
|
|
450
|
+
enabled: true,
|
|
451
|
+
alwaysPreserveAspectRatio: true,
|
|
452
|
+
minWidth: 50,
|
|
453
|
+
minHeight: 50,
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
}
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
| Option | Default | Description |
|
|
460
|
+
| ----------------------------------- | ------- | ----------------------------------------------------- |
|
|
461
|
+
| `resize` | _none_ | Set to `false` or omit to disable resize entirely |
|
|
462
|
+
| `resize.enabled` | `true` | Enable or disable resize when the object is present |
|
|
463
|
+
| `resize.alwaysPreserveAspectRatio` | `true` | Lock aspect ratio when resizing or editing dimensions |
|
|
464
|
+
| `resize.minWidth` | `50` | Minimum allowed width in pixels |
|
|
465
|
+
| `resize.minHeight` | `50` | Minimum allowed height in pixels |
|
|
466
|
+
|
|
467
|
+
#### Rendering images on the frontend
|
|
468
|
+
|
|
469
|
+
The plugin stores content as **Tiptap/ProseMirror JSON**. The `width`, `height`, `src`, `alt`, and `title` attributes are standard and will render automatically with `@tiptap/extension-image`. However, the custom `data-align` and `data-asset-id` attributes require extending the Image extension on your frontend:
|
|
470
|
+
|
|
471
|
+
```ts
|
|
472
|
+
import { generateHTML } from '@tiptap/html';
|
|
473
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
474
|
+
import Image from '@tiptap/extension-image';
|
|
475
|
+
|
|
476
|
+
// Extend with the custom attributes used by this plugin
|
|
477
|
+
const StrapiImage = Image.extend({
|
|
478
|
+
addAttributes() {
|
|
479
|
+
return {
|
|
480
|
+
...this.parent?.(),
|
|
481
|
+
'data-align': { default: null },
|
|
482
|
+
'data-asset-id': { default: null },
|
|
483
|
+
};
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// Convert the JSON from the Strapi API to HTML
|
|
488
|
+
const html = generateHTML(apiResponse.content, [
|
|
489
|
+
StarterKit,
|
|
490
|
+
StrapiImage,
|
|
491
|
+
// ...other extensions you use
|
|
492
|
+
]);
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Then add CSS for alignment on your frontend:
|
|
496
|
+
|
|
497
|
+
```css
|
|
498
|
+
img[data-align="center"] {
|
|
499
|
+
display: block;
|
|
500
|
+
margin-left: auto;
|
|
501
|
+
margin-right: auto;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
img[data-align="right"] {
|
|
505
|
+
display: block;
|
|
506
|
+
margin-left: auto;
|
|
507
|
+
margin-right: 0;
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
439
511
|
## Theme
|
|
440
512
|
|
|
441
513
|
The `theme` key in the plugin config lets you define colors for the color pickers and inject custom CSS into the editor.
|
|
@@ -577,8 +649,10 @@ export default () => ({
|
|
|
577
649
|
textColor: true,
|
|
578
650
|
highlightColor: true,
|
|
579
651
|
|
|
580
|
-
// Images from Strapi Media Library
|
|
581
|
-
mediaLibrary:
|
|
652
|
+
// Images from Strapi Media Library with resize enabled
|
|
653
|
+
mediaLibrary: {
|
|
654
|
+
resize: { enabled: true },
|
|
655
|
+
},
|
|
582
656
|
},
|
|
583
657
|
},
|
|
584
658
|
},
|
|
@@ -8,7 +8,7 @@ const ReactDOM = require("react-dom");
|
|
|
8
8
|
const styled = require("styled-components");
|
|
9
9
|
const admin = require("@strapi/strapi/admin");
|
|
10
10
|
const icons = require("@strapi/icons");
|
|
11
|
-
const index = require("./index-
|
|
11
|
+
const index = require("./index-CTcKIvYv.js");
|
|
12
12
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
13
13
|
const React__default = /* @__PURE__ */ _interopDefault(React);
|
|
14
14
|
const ReactDOM__default = /* @__PURE__ */ _interopDefault(ReactDOM);
|
|
@@ -19909,19 +19909,53 @@ const TiptapInputStyles = styled__default.default.div`
|
|
|
19909
19909
|
margin: 0.75em 0;
|
|
19910
19910
|
}
|
|
19911
19911
|
|
|
19912
|
-
/* Image alignment —
|
|
19913
|
-
[data-align="center"]
|
|
19914
|
-
|
|
19915
|
-
margin-right: auto;
|
|
19912
|
+
/* Image alignment — text-align on the node wrapper centres the inline-block image container */
|
|
19913
|
+
[data-align="center"] {
|
|
19914
|
+
text-align: center;
|
|
19916
19915
|
}
|
|
19917
19916
|
|
|
19918
|
-
[data-align="right"]
|
|
19919
|
-
|
|
19920
|
-
margin-right: 0;
|
|
19917
|
+
[data-align="right"] {
|
|
19918
|
+
text-align: right;
|
|
19921
19919
|
}
|
|
19922
19920
|
|
|
19923
19921
|
/* data-align="left" and null: natural left flow, no rule needed */
|
|
19924
19922
|
|
|
19923
|
+
/* Inline-block wrapper for positioning the resize handle relative to the image */
|
|
19924
|
+
.image-wrapper {
|
|
19925
|
+
position: relative;
|
|
19926
|
+
display: inline-block;
|
|
19927
|
+
max-width: 100%;
|
|
19928
|
+
line-height: 0; /* prevent extra space below img */
|
|
19929
|
+
}
|
|
19930
|
+
|
|
19931
|
+
.image-wrapper img {
|
|
19932
|
+
display: block;
|
|
19933
|
+
max-width: 100%;
|
|
19934
|
+
height: auto;
|
|
19935
|
+
}
|
|
19936
|
+
|
|
19937
|
+
/* Resize handle — bottom-right corner */
|
|
19938
|
+
.image-resize-handle {
|
|
19939
|
+
position: absolute;
|
|
19940
|
+
right: -4px;
|
|
19941
|
+
bottom: -4px;
|
|
19942
|
+
width: 12px;
|
|
19943
|
+
height: 12px;
|
|
19944
|
+
background: #4945ff;
|
|
19945
|
+
border: 2px solid #fff;
|
|
19946
|
+
border-radius: 50%;
|
|
19947
|
+
cursor: nwse-resize;
|
|
19948
|
+
opacity: 0;
|
|
19949
|
+
transition: opacity 0.15s;
|
|
19950
|
+
z-index: 1;
|
|
19951
|
+
}
|
|
19952
|
+
|
|
19953
|
+
.image-wrapper:hover .image-resize-handle,
|
|
19954
|
+
.image-wrapper[data-selected] .image-resize-handle,
|
|
19955
|
+
.ProseMirror-selectednode .image-resize-handle {
|
|
19956
|
+
opacity: 1;
|
|
19957
|
+
}
|
|
19958
|
+
|
|
19925
19959
|
// Source: https://tiptap.dev/docs/editor/extensions/nodes/table
|
|
19926
19960
|
|
|
19927
19961
|
.ProseMirror {
|
|
@@ -20893,19 +20927,43 @@ function TextAlignRight(props) {
|
|
|
20893
20927
|
}
|
|
20894
20928
|
);
|
|
20895
20929
|
}
|
|
20896
|
-
function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode: deleteNode2 }) {
|
|
20930
|
+
function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode: deleteNode2, selected, extension }) {
|
|
20897
20931
|
const { formatMessage } = reactIntl.useIntl();
|
|
20898
20932
|
const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
|
|
20899
20933
|
const [altText, setAltText] = React.useState(node.attrs.alt ?? "");
|
|
20934
|
+
const imgRef = React.useRef(null);
|
|
20935
|
+
const isResizingRef = React.useRef(false);
|
|
20936
|
+
const resizeCleanupRef = React.useRef(null);
|
|
20937
|
+
const rawResize = extension.options.resize;
|
|
20938
|
+
const resizeEnabled = typeof rawResize === "object" && !!rawResize ? rawResize.enabled : !!rawResize;
|
|
20939
|
+
const resizeOpts = resizeEnabled && typeof rawResize === "object" ? rawResize : void 0;
|
|
20940
|
+
const preserveAspectRatio = resizeOpts?.alwaysPreserveAspectRatio ?? true;
|
|
20941
|
+
const minWidth = resizeOpts?.minWidth ?? 50;
|
|
20942
|
+
const minHeight = resizeOpts?.minHeight ?? 50;
|
|
20943
|
+
const currentWidth = node.attrs.width;
|
|
20944
|
+
const currentHeight = node.attrs.height;
|
|
20945
|
+
const [widthInput, setWidthInput] = React.useState(currentWidth ? String(currentWidth) : "");
|
|
20946
|
+
const [heightInput, setHeightInput] = React.useState(currentHeight ? String(currentHeight) : "");
|
|
20900
20947
|
React.useEffect(() => {
|
|
20901
20948
|
setAltText(node.attrs.alt ?? "");
|
|
20902
20949
|
}, [node.attrs.alt]);
|
|
20950
|
+
React.useEffect(() => {
|
|
20951
|
+
setWidthInput(node.attrs.width ? String(node.attrs.width) : "");
|
|
20952
|
+
}, [node.attrs.width]);
|
|
20953
|
+
React.useEffect(() => {
|
|
20954
|
+
setHeightInput(node.attrs.height ? String(node.attrs.height) : "");
|
|
20955
|
+
}, [node.attrs.height]);
|
|
20903
20956
|
React.useEffect(() => {
|
|
20904
20957
|
if (!isPopoverOpen) return;
|
|
20905
20958
|
const handleScroll = () => setIsPopoverOpen(false);
|
|
20906
20959
|
document.addEventListener("scroll", handleScroll, true);
|
|
20907
20960
|
return () => document.removeEventListener("scroll", handleScroll, true);
|
|
20908
20961
|
}, [isPopoverOpen]);
|
|
20962
|
+
React.useEffect(() => {
|
|
20963
|
+
return () => {
|
|
20964
|
+
resizeCleanupRef.current?.();
|
|
20965
|
+
};
|
|
20966
|
+
}, []);
|
|
20909
20967
|
const currentAlign = node.attrs["data-align"];
|
|
20910
20968
|
function handleAlign(value) {
|
|
20911
20969
|
const current = node.attrs["data-align"];
|
|
@@ -20920,15 +20978,117 @@ function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode:
|
|
|
20920
20978
|
e.currentTarget.blur();
|
|
20921
20979
|
}
|
|
20922
20980
|
}
|
|
20981
|
+
function getAspectRatio() {
|
|
20982
|
+
const img = imgRef.current;
|
|
20983
|
+
if (!img || !img.naturalWidth || !img.naturalHeight) return null;
|
|
20984
|
+
return img.naturalWidth / img.naturalHeight;
|
|
20985
|
+
}
|
|
20986
|
+
function handleWidthCommit() {
|
|
20987
|
+
if (widthInput === "") {
|
|
20988
|
+
updateAttributes2({ width: null, height: null });
|
|
20989
|
+
return;
|
|
20990
|
+
}
|
|
20991
|
+
const num = parseInt(widthInput, 10);
|
|
20992
|
+
if (!isNaN(num) && num >= minWidth) {
|
|
20993
|
+
const ratio = getAspectRatio();
|
|
20994
|
+
if (preserveAspectRatio && ratio) {
|
|
20995
|
+
const newHeight = Math.round(num / ratio);
|
|
20996
|
+
updateAttributes2({ width: num, height: newHeight });
|
|
20997
|
+
} else {
|
|
20998
|
+
updateAttributes2({ width: num });
|
|
20999
|
+
}
|
|
21000
|
+
} else {
|
|
21001
|
+
setWidthInput(node.attrs.width ? String(node.attrs.width) : "");
|
|
21002
|
+
}
|
|
21003
|
+
}
|
|
21004
|
+
function handleHeightCommit() {
|
|
21005
|
+
if (heightInput === "") {
|
|
21006
|
+
updateAttributes2({ height: null, width: null });
|
|
21007
|
+
return;
|
|
21008
|
+
}
|
|
21009
|
+
const num = parseInt(heightInput, 10);
|
|
21010
|
+
if (!isNaN(num) && num >= minHeight) {
|
|
21011
|
+
const ratio = getAspectRatio();
|
|
21012
|
+
if (preserveAspectRatio && ratio) {
|
|
21013
|
+
const newWidth = Math.round(num * ratio);
|
|
21014
|
+
updateAttributes2({ width: newWidth, height: num });
|
|
21015
|
+
} else {
|
|
21016
|
+
updateAttributes2({ height: num });
|
|
21017
|
+
}
|
|
21018
|
+
} else {
|
|
21019
|
+
setHeightInput(node.attrs.height ? String(node.attrs.height) : "");
|
|
21020
|
+
}
|
|
21021
|
+
}
|
|
21022
|
+
const handleResizeStart = React.useCallback(
|
|
21023
|
+
(e) => {
|
|
21024
|
+
e.preventDefault();
|
|
21025
|
+
e.stopPropagation();
|
|
21026
|
+
isResizingRef.current = true;
|
|
21027
|
+
const startX = e.clientX;
|
|
21028
|
+
const img = imgRef.current;
|
|
21029
|
+
if (!img) return;
|
|
21030
|
+
const startWidth = img.offsetWidth;
|
|
21031
|
+
const ratio = img.naturalWidth && img.naturalHeight ? img.naturalWidth / img.naturalHeight : null;
|
|
21032
|
+
function onMouseMove(moveEvent) {
|
|
21033
|
+
const diff = moveEvent.clientX - startX;
|
|
21034
|
+
const newWidth = Math.max(minWidth, startWidth + diff);
|
|
21035
|
+
if (img) {
|
|
21036
|
+
img.style.width = `${newWidth}px`;
|
|
21037
|
+
if (preserveAspectRatio && ratio) {
|
|
21038
|
+
img.style.height = `${Math.round(newWidth / ratio)}px`;
|
|
21039
|
+
}
|
|
21040
|
+
}
|
|
21041
|
+
}
|
|
21042
|
+
function cleanup() {
|
|
21043
|
+
document.removeEventListener("mousemove", onMouseMove);
|
|
21044
|
+
document.removeEventListener("mouseup", onMouseUp);
|
|
21045
|
+
resizeCleanupRef.current = null;
|
|
21046
|
+
}
|
|
21047
|
+
function onMouseUp() {
|
|
21048
|
+
cleanup();
|
|
21049
|
+
if (img) {
|
|
21050
|
+
updateAttributes2({
|
|
21051
|
+
width: Math.round(img.offsetWidth),
|
|
21052
|
+
height: Math.round(img.offsetHeight)
|
|
21053
|
+
});
|
|
21054
|
+
}
|
|
21055
|
+
requestAnimationFrame(() => {
|
|
21056
|
+
isResizingRef.current = false;
|
|
21057
|
+
});
|
|
21058
|
+
}
|
|
21059
|
+
document.addEventListener("mousemove", onMouseMove);
|
|
21060
|
+
document.addEventListener("mouseup", onMouseUp);
|
|
21061
|
+
resizeCleanupRef.current = cleanup;
|
|
21062
|
+
},
|
|
21063
|
+
[updateAttributes2, preserveAspectRatio, minWidth]
|
|
21064
|
+
);
|
|
20923
21065
|
return /* @__PURE__ */ jsxRuntime.jsx(NodeViewWrapper, { "data-drag-handle": true, "data-align": node.attrs["data-align"] ?? void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { open: isPopoverOpen, onOpenChange: setIsPopoverOpen, children: [
|
|
20924
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Anchor, { children: /* @__PURE__ */ jsxRuntime.
|
|
20925
|
-
"
|
|
21066
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Anchor, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21067
|
+
"div",
|
|
20926
21068
|
{
|
|
20927
|
-
|
|
20928
|
-
|
|
20929
|
-
|
|
20930
|
-
|
|
20931
|
-
|
|
21069
|
+
className: "image-wrapper",
|
|
21070
|
+
"data-selected": selected || isPopoverOpen || void 0,
|
|
21071
|
+
children: [
|
|
21072
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21073
|
+
"img",
|
|
21074
|
+
{
|
|
21075
|
+
ref: imgRef,
|
|
21076
|
+
src: node.attrs.src,
|
|
21077
|
+
alt: node.attrs.alt ?? "",
|
|
21078
|
+
style: {
|
|
21079
|
+
display: "block",
|
|
21080
|
+
maxWidth: "100%",
|
|
21081
|
+
width: currentWidth ? `${currentWidth}px` : void 0,
|
|
21082
|
+
height: currentHeight ? `${currentHeight}px` : "auto"
|
|
21083
|
+
},
|
|
21084
|
+
draggable: false,
|
|
21085
|
+
onClick: () => {
|
|
21086
|
+
if (!isResizingRef.current) setIsPopoverOpen(true);
|
|
21087
|
+
}
|
|
21088
|
+
}
|
|
21089
|
+
),
|
|
21090
|
+
resizeEnabled && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "image-resize-handle", onMouseDown: handleResizeStart })
|
|
21091
|
+
]
|
|
20932
21092
|
}
|
|
20933
21093
|
) }),
|
|
20934
21094
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Content, { side: "bottom", children: [
|
|
@@ -20967,6 +21127,43 @@ function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode:
|
|
|
20967
21127
|
}
|
|
20968
21128
|
)
|
|
20969
21129
|
] }),
|
|
21130
|
+
resizeEnabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px", padding: "8px", paddingBottom: "0" }, children: [
|
|
21131
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21132
|
+
designSystem.TextInput,
|
|
21133
|
+
{
|
|
21134
|
+
type: "number",
|
|
21135
|
+
placeholder: "W",
|
|
21136
|
+
value: widthInput,
|
|
21137
|
+
onChange: (e) => setWidthInput(e.target.value),
|
|
21138
|
+
onBlur: handleWidthCommit,
|
|
21139
|
+
onKeyDown: handleKeyDown2,
|
|
21140
|
+
"aria-label": formatMessage({ id: "tiptap-editor.image.width", defaultMessage: "Width (px)" }),
|
|
21141
|
+
style: { minWidth: "62px", flexGrow: 1 }
|
|
21142
|
+
}
|
|
21143
|
+
),
|
|
21144
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "1.1rem", color: "#999" }, children: "×" }),
|
|
21145
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21146
|
+
designSystem.TextInput,
|
|
21147
|
+
{
|
|
21148
|
+
type: "number",
|
|
21149
|
+
placeholder: "H",
|
|
21150
|
+
value: heightInput,
|
|
21151
|
+
onChange: (e) => setHeightInput(e.target.value),
|
|
21152
|
+
onBlur: handleHeightCommit,
|
|
21153
|
+
onKeyDown: handleKeyDown2,
|
|
21154
|
+
"aria-label": formatMessage({ id: "tiptap-editor.image.height", defaultMessage: "Height (px)" }),
|
|
21155
|
+
style: { minWidth: "62px", flexGrow: 1 }
|
|
21156
|
+
}
|
|
21157
|
+
),
|
|
21158
|
+
(currentWidth || currentHeight) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
21159
|
+
designSystem.IconButton,
|
|
21160
|
+
{
|
|
21161
|
+
onClick: () => updateAttributes2({ width: null, height: null }),
|
|
21162
|
+
label: formatMessage({ id: "tiptap-editor.image.resetSize", defaultMessage: "Reset size" }),
|
|
21163
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {})
|
|
21164
|
+
}
|
|
21165
|
+
)
|
|
21166
|
+
] }),
|
|
20970
21167
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", padding: "8px" }, children: [
|
|
20971
21168
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20972
21169
|
designSystem.TextInput,
|
|
@@ -20992,12 +21189,21 @@ function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode:
|
|
|
20992
21189
|
] }) });
|
|
20993
21190
|
}
|
|
20994
21191
|
function ImageNodeViewReadOnly({ node }) {
|
|
21192
|
+
const rawWidth = node.attrs.width;
|
|
21193
|
+
const rawHeight = node.attrs.height;
|
|
21194
|
+
const width = typeof rawWidth === "number" ? rawWidth : null;
|
|
21195
|
+
const height = typeof rawHeight === "number" ? rawHeight : null;
|
|
20995
21196
|
return /* @__PURE__ */ jsxRuntime.jsx(NodeViewWrapper, { "data-drag-handle": true, "data-align": node.attrs["data-align"] ?? void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
20996
21197
|
"img",
|
|
20997
21198
|
{
|
|
20998
21199
|
src: node.attrs.src,
|
|
20999
21200
|
alt: node.attrs.alt ?? "",
|
|
21000
|
-
style: {
|
|
21201
|
+
style: {
|
|
21202
|
+
maxWidth: width ? void 0 : "100%",
|
|
21203
|
+
display: "block",
|
|
21204
|
+
width: width ? `${width}px` : void 0,
|
|
21205
|
+
height: height ? `${height}px` : void 0
|
|
21206
|
+
},
|
|
21001
21207
|
draggable: false
|
|
21002
21208
|
}
|
|
21003
21209
|
) });
|
|
@@ -29500,7 +29706,8 @@ function buildExtensions(config) {
|
|
|
29500
29706
|
extensions.push(index_default.configure({ multicolor: true }));
|
|
29501
29707
|
}
|
|
29502
29708
|
if (isFeatureEnabled(config.mediaLibrary)) {
|
|
29503
|
-
|
|
29709
|
+
const mediaOpts = getFeatureOptions(config.mediaLibrary, {});
|
|
29710
|
+
extensions.push(StrapiImage.configure(mediaOpts ?? {}));
|
|
29504
29711
|
} else {
|
|
29505
29712
|
extensions.push(StrapiImage.configure({ enableContentCheck: true }));
|
|
29506
29713
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
|
|
2
|
-
import React, { useRef, useState, useDebugValue, useEffect, useLayoutEffect, forwardRef, createRef, memo, createElement, createContext, version, useContext, useMemo, Component } from "react";
|
|
2
|
+
import React, { useRef, useState, useDebugValue, useEffect, useLayoutEffect, forwardRef, createRef, memo, createElement, createContext, version, useContext, useMemo, Component, useCallback } from "react";
|
|
3
3
|
import { useIntl } from "react-intl";
|
|
4
4
|
import { Field, Box, Status, Typography, Flex, Button, Tooltip, Dialog, TextInput, SingleSelect, SingleSelectOption, Popover, IconButton } from "@strapi/design-system";
|
|
5
5
|
import ReactDOM, { flushSync } from "react-dom";
|
|
6
6
|
import styled from "styled-components";
|
|
7
7
|
import { useField, useFetchClient } from "@strapi/strapi/admin";
|
|
8
|
-
import { Quotes, Code as Code$1, NumberList, BulletList as BulletList$1, StrikeThrough, Underline as Underline$1, Italic as Italic$1, Bold as Bold$1, Link as Link$1, Trash, Image as Image$1, GridNine } from "@strapi/icons";
|
|
9
|
-
import { g as getMediaLibraryComponent, a as getThemeCache } from "./index-
|
|
8
|
+
import { Quotes, Code as Code$1, NumberList, BulletList as BulletList$1, StrikeThrough, Underline as Underline$1, Italic as Italic$1, Bold as Bold$1, Link as Link$1, Cross, Trash, Image as Image$1, GridNine } from "@strapi/icons";
|
|
9
|
+
import { g as getMediaLibraryComponent, a as getThemeCache } from "./index-BVPd2eP4.mjs";
|
|
10
10
|
var shim = { exports: {} };
|
|
11
11
|
var useSyncExternalStoreShim_production = {};
|
|
12
12
|
/**
|
|
@@ -19903,19 +19903,53 @@ const TiptapInputStyles = styled.div`
|
|
|
19903
19903
|
margin: 0.75em 0;
|
|
19904
19904
|
}
|
|
19905
19905
|
|
|
19906
|
-
/* Image alignment —
|
|
19907
|
-
[data-align="center"]
|
|
19908
|
-
|
|
19909
|
-
margin-right: auto;
|
|
19906
|
+
/* Image alignment — text-align on the node wrapper centres the inline-block image container */
|
|
19907
|
+
[data-align="center"] {
|
|
19908
|
+
text-align: center;
|
|
19910
19909
|
}
|
|
19911
19910
|
|
|
19912
|
-
[data-align="right"]
|
|
19913
|
-
|
|
19914
|
-
margin-right: 0;
|
|
19911
|
+
[data-align="right"] {
|
|
19912
|
+
text-align: right;
|
|
19915
19913
|
}
|
|
19916
19914
|
|
|
19917
19915
|
/* data-align="left" and null: natural left flow, no rule needed */
|
|
19918
19916
|
|
|
19917
|
+
/* Inline-block wrapper for positioning the resize handle relative to the image */
|
|
19918
|
+
.image-wrapper {
|
|
19919
|
+
position: relative;
|
|
19920
|
+
display: inline-block;
|
|
19921
|
+
max-width: 100%;
|
|
19922
|
+
line-height: 0; /* prevent extra space below img */
|
|
19923
|
+
}
|
|
19924
|
+
|
|
19925
|
+
.image-wrapper img {
|
|
19926
|
+
display: block;
|
|
19927
|
+
max-width: 100%;
|
|
19928
|
+
height: auto;
|
|
19929
|
+
}
|
|
19930
|
+
|
|
19931
|
+
/* Resize handle — bottom-right corner */
|
|
19932
|
+
.image-resize-handle {
|
|
19933
|
+
position: absolute;
|
|
19934
|
+
right: -4px;
|
|
19935
|
+
bottom: -4px;
|
|
19936
|
+
width: 12px;
|
|
19937
|
+
height: 12px;
|
|
19938
|
+
background: #4945ff;
|
|
19939
|
+
border: 2px solid #fff;
|
|
19940
|
+
border-radius: 50%;
|
|
19941
|
+
cursor: nwse-resize;
|
|
19942
|
+
opacity: 0;
|
|
19943
|
+
transition: opacity 0.15s;
|
|
19944
|
+
z-index: 1;
|
|
19945
|
+
}
|
|
19946
|
+
|
|
19947
|
+
.image-wrapper:hover .image-resize-handle,
|
|
19948
|
+
.image-wrapper[data-selected] .image-resize-handle,
|
|
19949
|
+
.ProseMirror-selectednode .image-resize-handle {
|
|
19950
|
+
opacity: 1;
|
|
19951
|
+
}
|
|
19952
|
+
|
|
19919
19953
|
// Source: https://tiptap.dev/docs/editor/extensions/nodes/table
|
|
19920
19954
|
|
|
19921
19955
|
.ProseMirror {
|
|
@@ -20887,19 +20921,43 @@ function TextAlignRight(props) {
|
|
|
20887
20921
|
}
|
|
20888
20922
|
);
|
|
20889
20923
|
}
|
|
20890
|
-
function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode: deleteNode2 }) {
|
|
20924
|
+
function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode: deleteNode2, selected, extension }) {
|
|
20891
20925
|
const { formatMessage } = useIntl();
|
|
20892
20926
|
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
|
|
20893
20927
|
const [altText, setAltText] = useState(node.attrs.alt ?? "");
|
|
20928
|
+
const imgRef = useRef(null);
|
|
20929
|
+
const isResizingRef = useRef(false);
|
|
20930
|
+
const resizeCleanupRef = useRef(null);
|
|
20931
|
+
const rawResize = extension.options.resize;
|
|
20932
|
+
const resizeEnabled = typeof rawResize === "object" && !!rawResize ? rawResize.enabled : !!rawResize;
|
|
20933
|
+
const resizeOpts = resizeEnabled && typeof rawResize === "object" ? rawResize : void 0;
|
|
20934
|
+
const preserveAspectRatio = resizeOpts?.alwaysPreserveAspectRatio ?? true;
|
|
20935
|
+
const minWidth = resizeOpts?.minWidth ?? 50;
|
|
20936
|
+
const minHeight = resizeOpts?.minHeight ?? 50;
|
|
20937
|
+
const currentWidth = node.attrs.width;
|
|
20938
|
+
const currentHeight = node.attrs.height;
|
|
20939
|
+
const [widthInput, setWidthInput] = useState(currentWidth ? String(currentWidth) : "");
|
|
20940
|
+
const [heightInput, setHeightInput] = useState(currentHeight ? String(currentHeight) : "");
|
|
20894
20941
|
useEffect(() => {
|
|
20895
20942
|
setAltText(node.attrs.alt ?? "");
|
|
20896
20943
|
}, [node.attrs.alt]);
|
|
20944
|
+
useEffect(() => {
|
|
20945
|
+
setWidthInput(node.attrs.width ? String(node.attrs.width) : "");
|
|
20946
|
+
}, [node.attrs.width]);
|
|
20947
|
+
useEffect(() => {
|
|
20948
|
+
setHeightInput(node.attrs.height ? String(node.attrs.height) : "");
|
|
20949
|
+
}, [node.attrs.height]);
|
|
20897
20950
|
useEffect(() => {
|
|
20898
20951
|
if (!isPopoverOpen) return;
|
|
20899
20952
|
const handleScroll = () => setIsPopoverOpen(false);
|
|
20900
20953
|
document.addEventListener("scroll", handleScroll, true);
|
|
20901
20954
|
return () => document.removeEventListener("scroll", handleScroll, true);
|
|
20902
20955
|
}, [isPopoverOpen]);
|
|
20956
|
+
useEffect(() => {
|
|
20957
|
+
return () => {
|
|
20958
|
+
resizeCleanupRef.current?.();
|
|
20959
|
+
};
|
|
20960
|
+
}, []);
|
|
20903
20961
|
const currentAlign = node.attrs["data-align"];
|
|
20904
20962
|
function handleAlign(value) {
|
|
20905
20963
|
const current = node.attrs["data-align"];
|
|
@@ -20914,15 +20972,117 @@ function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode:
|
|
|
20914
20972
|
e.currentTarget.blur();
|
|
20915
20973
|
}
|
|
20916
20974
|
}
|
|
20975
|
+
function getAspectRatio() {
|
|
20976
|
+
const img = imgRef.current;
|
|
20977
|
+
if (!img || !img.naturalWidth || !img.naturalHeight) return null;
|
|
20978
|
+
return img.naturalWidth / img.naturalHeight;
|
|
20979
|
+
}
|
|
20980
|
+
function handleWidthCommit() {
|
|
20981
|
+
if (widthInput === "") {
|
|
20982
|
+
updateAttributes2({ width: null, height: null });
|
|
20983
|
+
return;
|
|
20984
|
+
}
|
|
20985
|
+
const num = parseInt(widthInput, 10);
|
|
20986
|
+
if (!isNaN(num) && num >= minWidth) {
|
|
20987
|
+
const ratio = getAspectRatio();
|
|
20988
|
+
if (preserveAspectRatio && ratio) {
|
|
20989
|
+
const newHeight = Math.round(num / ratio);
|
|
20990
|
+
updateAttributes2({ width: num, height: newHeight });
|
|
20991
|
+
} else {
|
|
20992
|
+
updateAttributes2({ width: num });
|
|
20993
|
+
}
|
|
20994
|
+
} else {
|
|
20995
|
+
setWidthInput(node.attrs.width ? String(node.attrs.width) : "");
|
|
20996
|
+
}
|
|
20997
|
+
}
|
|
20998
|
+
function handleHeightCommit() {
|
|
20999
|
+
if (heightInput === "") {
|
|
21000
|
+
updateAttributes2({ height: null, width: null });
|
|
21001
|
+
return;
|
|
21002
|
+
}
|
|
21003
|
+
const num = parseInt(heightInput, 10);
|
|
21004
|
+
if (!isNaN(num) && num >= minHeight) {
|
|
21005
|
+
const ratio = getAspectRatio();
|
|
21006
|
+
if (preserveAspectRatio && ratio) {
|
|
21007
|
+
const newWidth = Math.round(num * ratio);
|
|
21008
|
+
updateAttributes2({ width: newWidth, height: num });
|
|
21009
|
+
} else {
|
|
21010
|
+
updateAttributes2({ height: num });
|
|
21011
|
+
}
|
|
21012
|
+
} else {
|
|
21013
|
+
setHeightInput(node.attrs.height ? String(node.attrs.height) : "");
|
|
21014
|
+
}
|
|
21015
|
+
}
|
|
21016
|
+
const handleResizeStart = useCallback(
|
|
21017
|
+
(e) => {
|
|
21018
|
+
e.preventDefault();
|
|
21019
|
+
e.stopPropagation();
|
|
21020
|
+
isResizingRef.current = true;
|
|
21021
|
+
const startX = e.clientX;
|
|
21022
|
+
const img = imgRef.current;
|
|
21023
|
+
if (!img) return;
|
|
21024
|
+
const startWidth = img.offsetWidth;
|
|
21025
|
+
const ratio = img.naturalWidth && img.naturalHeight ? img.naturalWidth / img.naturalHeight : null;
|
|
21026
|
+
function onMouseMove(moveEvent) {
|
|
21027
|
+
const diff = moveEvent.clientX - startX;
|
|
21028
|
+
const newWidth = Math.max(minWidth, startWidth + diff);
|
|
21029
|
+
if (img) {
|
|
21030
|
+
img.style.width = `${newWidth}px`;
|
|
21031
|
+
if (preserveAspectRatio && ratio) {
|
|
21032
|
+
img.style.height = `${Math.round(newWidth / ratio)}px`;
|
|
21033
|
+
}
|
|
21034
|
+
}
|
|
21035
|
+
}
|
|
21036
|
+
function cleanup() {
|
|
21037
|
+
document.removeEventListener("mousemove", onMouseMove);
|
|
21038
|
+
document.removeEventListener("mouseup", onMouseUp);
|
|
21039
|
+
resizeCleanupRef.current = null;
|
|
21040
|
+
}
|
|
21041
|
+
function onMouseUp() {
|
|
21042
|
+
cleanup();
|
|
21043
|
+
if (img) {
|
|
21044
|
+
updateAttributes2({
|
|
21045
|
+
width: Math.round(img.offsetWidth),
|
|
21046
|
+
height: Math.round(img.offsetHeight)
|
|
21047
|
+
});
|
|
21048
|
+
}
|
|
21049
|
+
requestAnimationFrame(() => {
|
|
21050
|
+
isResizingRef.current = false;
|
|
21051
|
+
});
|
|
21052
|
+
}
|
|
21053
|
+
document.addEventListener("mousemove", onMouseMove);
|
|
21054
|
+
document.addEventListener("mouseup", onMouseUp);
|
|
21055
|
+
resizeCleanupRef.current = cleanup;
|
|
21056
|
+
},
|
|
21057
|
+
[updateAttributes2, preserveAspectRatio, minWidth]
|
|
21058
|
+
);
|
|
20917
21059
|
return /* @__PURE__ */ jsx(NodeViewWrapper, { "data-drag-handle": true, "data-align": node.attrs["data-align"] ?? void 0, children: /* @__PURE__ */ jsxs(Popover.Root, { open: isPopoverOpen, onOpenChange: setIsPopoverOpen, children: [
|
|
20918
|
-
/* @__PURE__ */ jsx(Popover.Anchor, { children: /* @__PURE__ */
|
|
20919
|
-
"
|
|
21060
|
+
/* @__PURE__ */ jsx(Popover.Anchor, { children: /* @__PURE__ */ jsxs(
|
|
21061
|
+
"div",
|
|
20920
21062
|
{
|
|
20921
|
-
|
|
20922
|
-
|
|
20923
|
-
|
|
20924
|
-
|
|
20925
|
-
|
|
21063
|
+
className: "image-wrapper",
|
|
21064
|
+
"data-selected": selected || isPopoverOpen || void 0,
|
|
21065
|
+
children: [
|
|
21066
|
+
/* @__PURE__ */ jsx(
|
|
21067
|
+
"img",
|
|
21068
|
+
{
|
|
21069
|
+
ref: imgRef,
|
|
21070
|
+
src: node.attrs.src,
|
|
21071
|
+
alt: node.attrs.alt ?? "",
|
|
21072
|
+
style: {
|
|
21073
|
+
display: "block",
|
|
21074
|
+
maxWidth: "100%",
|
|
21075
|
+
width: currentWidth ? `${currentWidth}px` : void 0,
|
|
21076
|
+
height: currentHeight ? `${currentHeight}px` : "auto"
|
|
21077
|
+
},
|
|
21078
|
+
draggable: false,
|
|
21079
|
+
onClick: () => {
|
|
21080
|
+
if (!isResizingRef.current) setIsPopoverOpen(true);
|
|
21081
|
+
}
|
|
21082
|
+
}
|
|
21083
|
+
),
|
|
21084
|
+
resizeEnabled && /* @__PURE__ */ jsx("div", { className: "image-resize-handle", onMouseDown: handleResizeStart })
|
|
21085
|
+
]
|
|
20926
21086
|
}
|
|
20927
21087
|
) }),
|
|
20928
21088
|
/* @__PURE__ */ jsxs(Popover.Content, { side: "bottom", children: [
|
|
@@ -20961,6 +21121,43 @@ function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode:
|
|
|
20961
21121
|
}
|
|
20962
21122
|
)
|
|
20963
21123
|
] }),
|
|
21124
|
+
resizeEnabled && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px", padding: "8px", paddingBottom: "0" }, children: [
|
|
21125
|
+
/* @__PURE__ */ jsx(
|
|
21126
|
+
TextInput,
|
|
21127
|
+
{
|
|
21128
|
+
type: "number",
|
|
21129
|
+
placeholder: "W",
|
|
21130
|
+
value: widthInput,
|
|
21131
|
+
onChange: (e) => setWidthInput(e.target.value),
|
|
21132
|
+
onBlur: handleWidthCommit,
|
|
21133
|
+
onKeyDown: handleKeyDown2,
|
|
21134
|
+
"aria-label": formatMessage({ id: "tiptap-editor.image.width", defaultMessage: "Width (px)" }),
|
|
21135
|
+
style: { minWidth: "62px", flexGrow: 1 }
|
|
21136
|
+
}
|
|
21137
|
+
),
|
|
21138
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "1.1rem", color: "#999" }, children: "×" }),
|
|
21139
|
+
/* @__PURE__ */ jsx(
|
|
21140
|
+
TextInput,
|
|
21141
|
+
{
|
|
21142
|
+
type: "number",
|
|
21143
|
+
placeholder: "H",
|
|
21144
|
+
value: heightInput,
|
|
21145
|
+
onChange: (e) => setHeightInput(e.target.value),
|
|
21146
|
+
onBlur: handleHeightCommit,
|
|
21147
|
+
onKeyDown: handleKeyDown2,
|
|
21148
|
+
"aria-label": formatMessage({ id: "tiptap-editor.image.height", defaultMessage: "Height (px)" }),
|
|
21149
|
+
style: { minWidth: "62px", flexGrow: 1 }
|
|
21150
|
+
}
|
|
21151
|
+
),
|
|
21152
|
+
(currentWidth || currentHeight) && /* @__PURE__ */ jsx(
|
|
21153
|
+
IconButton,
|
|
21154
|
+
{
|
|
21155
|
+
onClick: () => updateAttributes2({ width: null, height: null }),
|
|
21156
|
+
label: formatMessage({ id: "tiptap-editor.image.resetSize", defaultMessage: "Reset size" }),
|
|
21157
|
+
children: /* @__PURE__ */ jsx(Cross, {})
|
|
21158
|
+
}
|
|
21159
|
+
)
|
|
21160
|
+
] }),
|
|
20964
21161
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", padding: "8px" }, children: [
|
|
20965
21162
|
/* @__PURE__ */ jsx(
|
|
20966
21163
|
TextInput,
|
|
@@ -20986,12 +21183,21 @@ function ImageNodeView({ node, updateAttributes: updateAttributes2, deleteNode:
|
|
|
20986
21183
|
] }) });
|
|
20987
21184
|
}
|
|
20988
21185
|
function ImageNodeViewReadOnly({ node }) {
|
|
21186
|
+
const rawWidth = node.attrs.width;
|
|
21187
|
+
const rawHeight = node.attrs.height;
|
|
21188
|
+
const width = typeof rawWidth === "number" ? rawWidth : null;
|
|
21189
|
+
const height = typeof rawHeight === "number" ? rawHeight : null;
|
|
20989
21190
|
return /* @__PURE__ */ jsx(NodeViewWrapper, { "data-drag-handle": true, "data-align": node.attrs["data-align"] ?? void 0, children: /* @__PURE__ */ jsx(
|
|
20990
21191
|
"img",
|
|
20991
21192
|
{
|
|
20992
21193
|
src: node.attrs.src,
|
|
20993
21194
|
alt: node.attrs.alt ?? "",
|
|
20994
|
-
style: {
|
|
21195
|
+
style: {
|
|
21196
|
+
maxWidth: width ? void 0 : "100%",
|
|
21197
|
+
display: "block",
|
|
21198
|
+
width: width ? `${width}px` : void 0,
|
|
21199
|
+
height: height ? `${height}px` : void 0
|
|
21200
|
+
},
|
|
20995
21201
|
draggable: false
|
|
20996
21202
|
}
|
|
20997
21203
|
) });
|
|
@@ -29494,7 +29700,8 @@ function buildExtensions(config) {
|
|
|
29494
29700
|
extensions.push(index_default.configure({ multicolor: true }));
|
|
29495
29701
|
}
|
|
29496
29702
|
if (isFeatureEnabled(config.mediaLibrary)) {
|
|
29497
|
-
|
|
29703
|
+
const mediaOpts = getFeatureOptions(config.mediaLibrary, {});
|
|
29704
|
+
extensions.push(StrapiImage.configure(mediaOpts ?? {}));
|
|
29498
29705
|
} else {
|
|
29499
29706
|
extensions.push(StrapiImage.configure({ enableContentCheck: true }));
|
|
29500
29707
|
}
|
|
@@ -146,7 +146,7 @@ const richTextField = {
|
|
|
146
146
|
},
|
|
147
147
|
icon: Paragraph,
|
|
148
148
|
components: {
|
|
149
|
-
Input: async () => import("./RichTextInput-
|
|
149
|
+
Input: async () => import("./RichTextInput-B4D0Djcf.mjs").then((m) => ({ default: m.default }))
|
|
150
150
|
},
|
|
151
151
|
options: {
|
|
152
152
|
advanced: [
|
|
@@ -147,7 +147,7 @@ const richTextField = {
|
|
|
147
147
|
},
|
|
148
148
|
icon: icons.Paragraph,
|
|
149
149
|
components: {
|
|
150
|
-
Input: async () => Promise.resolve().then(() => require("./RichTextInput-
|
|
150
|
+
Input: async () => Promise.resolve().then(() => require("./RichTextInput-1uZSm3Nc.js")).then((m) => ({ default: m.default }))
|
|
151
151
|
},
|
|
152
152
|
options: {
|
|
153
153
|
advanced: [
|
package/dist/admin/index.js
CHANGED
package/dist/admin/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { NodeViewProps } from '@tiptap/react';
|
|
2
|
-
export declare function ImageNodeView({ node, updateAttributes, deleteNode }: NodeViewProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function ImageNodeView({ node, updateAttributes, deleteNode, selected, extension }: NodeViewProps): import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
export default ImageNodeView;
|
package/package.json
CHANGED