@edifice.io/react 2.3.0-develop-pedago.20250910143701 → 2.3.0-develop-pedago.20250910164231
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/editor.js +18 -16
- package/dist/modules/editor/components/NodeView/IframeNodeView.d.ts +2 -0
- package/dist/modules/editor/components/NodeView/IframeNodeView.js +10 -0
- package/dist/modules/editor/components/NodeView/index.d.ts +1 -0
- package/dist/modules/editor/components/Renderer/MediaRenderer.js +28 -9
- package/dist/modules/editor/hooks/useResizeMedia.d.ts +4 -1
- package/dist/modules/editor/hooks/useResizeMedia.js +33 -21
- package/dist/modules/editor/hooks/useTipTapEditor.js +2 -2
- package/package.json +6 -6
package/dist/editor.js
CHANGED
|
@@ -10,14 +10,15 @@ import { default as default9 } from "./modules/editor/components/NodeView/ImageN
|
|
|
10
10
|
import { default as default10 } from "./modules/editor/components/NodeView/LinkerNodeView.js";
|
|
11
11
|
import { default as default11 } from "./modules/editor/components/NodeView/VideoNodeView.js";
|
|
12
12
|
import { default as default12 } from "./modules/editor/components/NodeView/InformationPaneNodeView.js";
|
|
13
|
-
import { default as default13 } from "./modules/editor/components/
|
|
14
|
-
import { default as default14 } from "./modules/editor/components/Renderer/
|
|
15
|
-
import { default as default15 } from "./modules/editor/components/Renderer/
|
|
16
|
-
import { default as default16 } from "./modules/editor/components/Renderer/
|
|
17
|
-
import { default as default17 } from "./modules/editor/components/Renderer/
|
|
18
|
-
import { default as default18 } from "./modules/editor/components/Renderer/
|
|
19
|
-
import { default as default19 } from "./modules/editor/components/
|
|
20
|
-
import { default as default20 } from "./modules/editor/components/Toolbar/
|
|
13
|
+
import { default as default13 } from "./modules/editor/components/NodeView/IframeNodeView.js";
|
|
14
|
+
import { default as default14 } from "./modules/editor/components/Renderer/AttachmentRenderer.js";
|
|
15
|
+
import { default as default15 } from "./modules/editor/components/Renderer/AudioRenderer.js";
|
|
16
|
+
import { default as default16 } from "./modules/editor/components/Renderer/ConversationHistoryRenderer.js";
|
|
17
|
+
import { default as default17 } from "./modules/editor/components/Renderer/LinkerRenderer.js";
|
|
18
|
+
import { default as default18 } from "./modules/editor/components/Renderer/MediaRenderer.js";
|
|
19
|
+
import { default as default19 } from "./modules/editor/components/Renderer/InformationPaneRenderer.js";
|
|
20
|
+
import { default as default20 } from "./modules/editor/components/Toolbar/TableToolbar.js";
|
|
21
|
+
import { default as default21 } from "./modules/editor/components/Toolbar/LinkToolbar.js";
|
|
21
22
|
import { EditorToolbar } from "./modules/editor/components/EditorToolbar/EditorToolbar.js";
|
|
22
23
|
import { useActionOptions } from "./modules/editor/hooks/useActionOptions.js";
|
|
23
24
|
import { useCommentEditor } from "./modules/editor/hooks/useCommentEditor.js";
|
|
@@ -34,27 +35,28 @@ import { useTipTapEditor } from "./modules/editor/hooks/useTipTapEditor.js";
|
|
|
34
35
|
import { useCantooEditor } from "./modules/editor/hooks/useCantooEditor.js";
|
|
35
36
|
export {
|
|
36
37
|
default6 as AttachmentNodeView,
|
|
37
|
-
|
|
38
|
+
default14 as AttachmentRenderer,
|
|
38
39
|
default7 as AudioNodeView,
|
|
39
|
-
|
|
40
|
+
default15 as AudioRenderer,
|
|
40
41
|
default5 as BubbleMenuEditImage,
|
|
41
42
|
default8 as ConversationHistoryNodeView,
|
|
42
|
-
|
|
43
|
+
default16 as ConversationHistoryRenderer,
|
|
43
44
|
default3 as Editor,
|
|
44
45
|
EditorContent,
|
|
45
46
|
EditorContext,
|
|
46
47
|
Editor as EditorInstance,
|
|
47
48
|
default4 as EditorSkeleton,
|
|
48
49
|
EditorToolbar,
|
|
50
|
+
default13 as IframeNodeView,
|
|
49
51
|
default9 as ImageNodeView,
|
|
50
52
|
default12 as InformationPaneNodeView,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
default19 as InformationPaneRenderer,
|
|
54
|
+
default21 as LinkToolbar,
|
|
53
55
|
default10 as LinkerNodeView,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
default17 as LinkerRenderer,
|
|
57
|
+
default18 as MediaRenderer,
|
|
56
58
|
default2 as StarterKit,
|
|
57
|
-
|
|
59
|
+
default20 as TableToolbar,
|
|
58
60
|
default11 as VideoNodeView,
|
|
59
61
|
useActionOptions,
|
|
60
62
|
useCantooEditor,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Iframe } from "@edifice.io/tiptap-extensions/iframe";
|
|
2
|
+
import { ReactNodeViewRenderer } from "@tiptap/react";
|
|
3
|
+
const IframeNodeView = (Component) => Iframe.extend({
|
|
4
|
+
addNodeView() {
|
|
5
|
+
return ReactNodeViewRenderer(Component);
|
|
6
|
+
}
|
|
7
|
+
});
|
|
8
|
+
export {
|
|
9
|
+
IframeNodeView as default
|
|
10
|
+
};
|
|
@@ -5,3 +5,4 @@ export { default as ImageNodeView } from './ImageNodeView';
|
|
|
5
5
|
export { default as LinkerNodeView } from './LinkerNodeView';
|
|
6
6
|
export { default as VideoNodeView } from './VideoNodeView';
|
|
7
7
|
export { default as InformationPaneNodeView } from './InformationPaneNodeView';
|
|
8
|
+
export { default as IframeNodeView } from './IframeNodeView';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useRef, useEffect } from "react";
|
|
2
|
+
import { useRef, useState, useEffect } from "react";
|
|
3
3
|
import { odeServices } from "@edifice.io/client";
|
|
4
4
|
import { NodeViewWrapper } from "@tiptap/react";
|
|
5
5
|
import { useTranslation } from "react-i18next";
|
|
@@ -18,7 +18,7 @@ const MediaRenderer = (props) => {
|
|
|
18
18
|
startVerticalResize,
|
|
19
19
|
stopVerticalResize,
|
|
20
20
|
isVerticalResizeActive
|
|
21
|
-
} = useResizeMedia(props, resizableMedia), alignContent = (textalign) => {
|
|
21
|
+
} = useResizeMedia(props, resizableMedia), [showOverlay, setShowOverlay] = useState(!1), width = node.attrs.width || 560, height = node.attrs.height || Math.round(width * 9 / 16), alignContent = (textalign) => {
|
|
22
22
|
switch (textalign) {
|
|
23
23
|
case "center":
|
|
24
24
|
case "justify":
|
|
@@ -53,15 +53,34 @@ const MediaRenderer = (props) => {
|
|
|
53
53
|
element.removeEventListener("play", onVideoPlay);
|
|
54
54
|
};
|
|
55
55
|
}, []), /* @__PURE__ */ jsx(NodeViewWrapper, { style: alignContent(node.attrs.textAlign), children: /* @__PURE__ */ jsxs("div", { className: "media-node-view", children: [
|
|
56
|
-
/* @__PURE__ */ jsx("div", { "data-drag-handle": !0, children:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
/* @__PURE__ */ jsx("div", { "data-drag-handle": !0, children: (() => {
|
|
57
|
+
switch (node.type.name) {
|
|
58
|
+
case "custom-image":
|
|
59
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
60
|
+
/* @__PURE__ */ jsx(Image, { src: node.attrs.src, alt: node.attrs.alt, title: node.attrs.title, width: node.attrs.width, style: node.attrs.style, height: node.attrs.height, className: "custom-image", ref: resizableMedia }),
|
|
61
|
+
node.attrs.title && // Display legend (set in title attribute) if it exists
|
|
62
|
+
/* @__PURE__ */ jsx("em", { className: "custom-image-legend caption text-align-left", children: node.attrs.title })
|
|
63
|
+
] });
|
|
64
|
+
case "video":
|
|
65
|
+
return /* @__PURE__ */ jsx("video", { ref: resizableMedia, controls: node.attrs.controls === "true", src: node.attrs.src, width: node.attrs.width, height: node.attrs.height, "data-video-resolution": `${node.attrs.width}x${node.attrs.height}`, "data-document-id": node.attrs.documentId, "data-document-is-captation": node.attrs.isCaptation, children: /* @__PURE__ */ jsx("source", { src: node.attrs.src }) });
|
|
66
|
+
case "iframe":
|
|
67
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
68
|
+
showOverlay && /* @__PURE__ */ jsx("div", { style: {
|
|
69
|
+
position: "absolute",
|
|
70
|
+
inset: 0,
|
|
71
|
+
cursor: "ew-resize",
|
|
72
|
+
zIndex: 2
|
|
73
|
+
} }),
|
|
74
|
+
/* @__PURE__ */ jsx("iframe", { ref: resizableMedia, src: node.attrs.src, width, height, allowFullScreen: node.attrs.allowfullscreen ?? !0, style: node.attrs.style })
|
|
75
|
+
] });
|
|
76
|
+
default:
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
})() }),
|
|
61
80
|
/* @__PURE__ */ jsx("div", { className: `vertical-resize-handle ${isVerticalResizeActive ? "vertical-resize-active" : ""}`, title: t("tiptap.media.resize"), onMouseDown: (e) => {
|
|
62
|
-
e.stopPropagation(), startVerticalResize(e);
|
|
81
|
+
e.stopPropagation(), setShowOverlay(!0), startVerticalResize(e);
|
|
63
82
|
}, onMouseUp: (e) => {
|
|
64
|
-
e.stopPropagation(), stopVerticalResize();
|
|
83
|
+
e.stopPropagation(), setShowOverlay(!1), stopVerticalResize();
|
|
65
84
|
} })
|
|
66
85
|
] }) });
|
|
67
86
|
};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { Editor } from '@tiptap/react';
|
|
2
2
|
export interface MediaResizeProps {
|
|
3
3
|
editor: Editor;
|
|
4
|
+
updateAttributes: (attrs: Record<string, any>) => void;
|
|
4
5
|
[x: string]: any;
|
|
5
6
|
}
|
|
6
|
-
|
|
7
|
+
type ResizableElt = HTMLImageElement | HTMLVideoElement | HTMLIFrameElement;
|
|
8
|
+
export declare const useResizeMedia: (props: MediaResizeProps, refResizable: React.RefObject<ResizableElt>, forcedAspectRatio?: number) => {
|
|
7
9
|
startVerticalResize: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
|
8
10
|
stopVerticalResize: () => void;
|
|
9
11
|
isVerticalResizeActive: import('react').MutableRefObject<boolean>;
|
|
10
12
|
};
|
|
13
|
+
export {};
|
|
@@ -1,27 +1,39 @@
|
|
|
1
1
|
import { useRef, useEffect } from "react";
|
|
2
|
-
const MIN_WIDTH = 80, useResizeMedia = (props, refResizable) => {
|
|
3
|
-
const aspectRatio = useRef(0), lastCursorX = useRef(-1), isVerticalResizeActive = useRef(!1), proseMirrorContainerWidth = useRef(0),
|
|
2
|
+
const MIN_WIDTH = 80, useResizeMedia = (props, refResizable, forcedAspectRatio) => {
|
|
3
|
+
const aspectRatio = useRef(0), lastCursorX = useRef(-1), isVerticalResizeActive = useRef(!1), proseMirrorContainerWidth = useRef(0), limitWidth = (width) => width < MIN_WIDTH, readCurrentPixelWidth = () => {
|
|
4
|
+
const el = refResizable.current;
|
|
5
|
+
if (!el) return 0;
|
|
6
|
+
const rect = el.getBoundingClientRect();
|
|
7
|
+
return Math.round(rect.width || el.width || 0);
|
|
8
|
+
}, readCurrentPixelHeight = () => {
|
|
9
|
+
const el = refResizable.current;
|
|
10
|
+
if (!el) return 0;
|
|
11
|
+
const rect = el.getBoundingClientRect();
|
|
12
|
+
return Math.round(rect.height || el.height || 0);
|
|
13
|
+
};
|
|
4
14
|
useEffect(() => {
|
|
5
15
|
const proseMirrorContainerDiv = document.querySelector(".ProseMirror");
|
|
6
|
-
proseMirrorContainerDiv && (proseMirrorContainerWidth.current = proseMirrorContainerDiv
|
|
16
|
+
if (proseMirrorContainerDiv && (proseMirrorContainerWidth.current = proseMirrorContainerDiv.clientWidth), forcedAspectRatio && forcedAspectRatio > 0)
|
|
17
|
+
aspectRatio.current = forcedAspectRatio;
|
|
18
|
+
else {
|
|
19
|
+
const w = readCurrentPixelWidth(), h = readCurrentPixelHeight();
|
|
20
|
+
w > 0 && h > 0 ? aspectRatio.current = w / h : aspectRatio.current = 16 / 9;
|
|
21
|
+
}
|
|
7
22
|
}, []);
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
23
|
+
const clampWidth = (w) => {
|
|
24
|
+
let width = w;
|
|
25
|
+
return proseMirrorContainerWidth.current > 0 && width > proseMirrorContainerWidth.current && (width = proseMirrorContainerWidth.current), limitWidth(width) && (width = MIN_WIDTH), Math.round(width);
|
|
26
|
+
}, onVerticalResize = (direction, diff) => {
|
|
27
|
+
const currWidth = readCurrentPixelWidth();
|
|
28
|
+
if (!currWidth) return;
|
|
29
|
+
let newWidth = direction === "left" ? currWidth - Math.abs(diff) : currWidth + Math.abs(diff);
|
|
30
|
+
newWidth = clampWidth(newWidth);
|
|
31
|
+
const ratio = aspectRatio.current || 16 / 9, newHeight = Math.round(newWidth / ratio);
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
props.updateAttributes({
|
|
34
|
+
width: newWidth,
|
|
35
|
+
height: newHeight
|
|
13
36
|
});
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
const currentMediaDimensions = {
|
|
17
|
-
width: (_a = refResizable.current) == null ? void 0 : _a.width,
|
|
18
|
-
height: (_b = refResizable.current) == null ? void 0 : _b.height
|
|
19
|
-
}, newMediaDimensions = {
|
|
20
|
-
width: -1,
|
|
21
|
-
height: -1
|
|
22
|
-
};
|
|
23
|
-
currentMediaDimensions.width && (directionOfMouseMove === "left" ? newMediaDimensions.width = currentMediaDimensions.width - Math.abs(diff) : newMediaDimensions.width = currentMediaDimensions.width + Math.abs(diff)), newMediaDimensions.width > proseMirrorContainerWidth.current && (newMediaDimensions.width = proseMirrorContainerWidth.current), diff !== 0 && limitWidthOrHeight(newMediaDimensions.width) && (newMediaDimensions.width = MIN_WIDTH), newMediaDimensions.height = newMediaDimensions.width / aspectRatio.current, setTimeout(() => {
|
|
24
|
-
props.updateAttributes(newMediaDimensions);
|
|
25
37
|
});
|
|
26
38
|
}, onVerticalMouseMove = (event) => {
|
|
27
39
|
if (!isVerticalResizeActive.current) return;
|
|
@@ -29,8 +41,8 @@ const MIN_WIDTH = 80, useResizeMedia = (props, refResizable) => {
|
|
|
29
41
|
clientX
|
|
30
42
|
} = event, diff = lastCursorX.current - clientX;
|
|
31
43
|
if (lastCursorX.current = clientX, diff === 0) return;
|
|
32
|
-
const
|
|
33
|
-
onVerticalResize(
|
|
44
|
+
const direction = diff > 0 ? "left" : "right";
|
|
45
|
+
onVerticalResize(direction, Math.abs(diff));
|
|
34
46
|
}, startVerticalResize = (event) => {
|
|
35
47
|
isVerticalResizeActive.current = !0, lastCursorX.current = event.clientX, document.addEventListener("mousemove", onVerticalMouseMove), document.addEventListener("mouseup", stopVerticalResize);
|
|
36
48
|
}, stopVerticalResize = () => {
|
|
@@ -4,7 +4,6 @@ import { FontSize } from "@edifice.io/tiptap-extensions/font-size";
|
|
|
4
4
|
import { CustomHeading } from "@edifice.io/tiptap-extensions/heading";
|
|
5
5
|
import { CustomHighlight } from "@edifice.io/tiptap-extensions/highlight";
|
|
6
6
|
import { Hyperlink } from "@edifice.io/tiptap-extensions/hyperlink";
|
|
7
|
-
import { Iframe } from "@edifice.io/tiptap-extensions/iframe";
|
|
8
7
|
import { SpeechRecognition } from "@edifice.io/tiptap-extensions/speech-recognition";
|
|
9
8
|
import { SpeechSynthesis } from "@edifice.io/tiptap-extensions/speech-synthesis";
|
|
10
9
|
import { TableCell } from "@edifice.io/tiptap-extensions/table-cell";
|
|
@@ -27,6 +26,7 @@ import StarterKit from "@tiptap/starter-kit";
|
|
|
27
26
|
import { useTranslation } from "react-i18next";
|
|
28
27
|
import { useEdificeClient } from "../../../providers/EdificeClientProvider/EdificeClientProvider.hook.js";
|
|
29
28
|
import useUpload from "../../../hooks/useUpload/useUpload.js";
|
|
29
|
+
import IframeNodeView from "../components/NodeView/IframeNodeView.js";
|
|
30
30
|
import VideoNodeView from "../components/NodeView/VideoNodeView.js";
|
|
31
31
|
import AudioNodeView from "../components/NodeView/AudioNodeView.js";
|
|
32
32
|
import LinkerNodeView from "../components/NodeView/LinkerNodeView.js";
|
|
@@ -65,7 +65,7 @@ const useTipTapEditor = (editable, content, focus, placeholder, onContentChange,
|
|
|
65
65
|
levels: [1, 2]
|
|
66
66
|
}), Typography, FontSize, SpeechRecognition, SpeechSynthesis.configure({
|
|
67
67
|
lang: (currentLanguage == null ? void 0 : currentLanguage.length) === 2 ? `${currentLanguage}-${currentLanguage.toUpperCase()}` : "fr-FR"
|
|
68
|
-
}),
|
|
68
|
+
}), Hyperlink, FontFamily, Mathematics, Alert, IframeNodeView(MediaRenderer), VideoNodeView(MediaRenderer), AudioNodeView(AudioRenderer), LinkerNodeView(LinkerRenderer), ImageNodeView(MediaRenderer, uploadFile), AttachmentNodeView(AttachmentRenderer), InformationPaneNodeView(InformationPaneRenderer), ...extensions || []],
|
|
69
69
|
content,
|
|
70
70
|
// If the onContentChange callback is provided, we call it on every content change.
|
|
71
71
|
...onContentChange ? {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edifice.io/react",
|
|
3
|
-
"version": "2.3.0-develop-pedago.
|
|
3
|
+
"version": "2.3.0-develop-pedago.20250910164231",
|
|
4
4
|
"description": "Edifice React Library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -130,9 +130,9 @@
|
|
|
130
130
|
"react-slugify": "^3.0.3",
|
|
131
131
|
"swiper": "^10.1.0",
|
|
132
132
|
"ua-parser-js": "^1.0.36",
|
|
133
|
-
"@edifice.io/bootstrap": "2.3.0-develop-pedago.
|
|
134
|
-
"@edifice.io/tiptap-extensions": "2.3.0-develop-pedago.
|
|
135
|
-
"@edifice.io/utilities": "2.3.0-develop-pedago.
|
|
133
|
+
"@edifice.io/bootstrap": "2.3.0-develop-pedago.20250910164231",
|
|
134
|
+
"@edifice.io/tiptap-extensions": "2.3.0-develop-pedago.20250910164231",
|
|
135
|
+
"@edifice.io/utilities": "2.3.0-develop-pedago.20250910164231"
|
|
136
136
|
},
|
|
137
137
|
"devDependencies": {
|
|
138
138
|
"@babel/plugin-transform-react-pure-annotations": "^7.23.3",
|
|
@@ -163,8 +163,8 @@
|
|
|
163
163
|
"vite": "^5.4.11",
|
|
164
164
|
"vite-plugin-dts": "^4.1.0",
|
|
165
165
|
"vite-tsconfig-paths": "^5.0.1",
|
|
166
|
-
"@edifice.io/client": "2.3.0-develop-pedago.
|
|
167
|
-
"@edifice.io/config": "2.3.0-develop-pedago.
|
|
166
|
+
"@edifice.io/client": "2.3.0-develop-pedago.20250910164231",
|
|
167
|
+
"@edifice.io/config": "2.3.0-develop-pedago.20250910164231"
|
|
168
168
|
},
|
|
169
169
|
"peerDependencies": {
|
|
170
170
|
"@react-spring/web": "^9.7.5",
|