@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 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/Renderer/AttachmentRenderer.js";
14
- import { default as default14 } from "./modules/editor/components/Renderer/AudioRenderer.js";
15
- import { default as default15 } from "./modules/editor/components/Renderer/ConversationHistoryRenderer.js";
16
- import { default as default16 } from "./modules/editor/components/Renderer/LinkerRenderer.js";
17
- import { default as default17 } from "./modules/editor/components/Renderer/MediaRenderer.js";
18
- import { default as default18 } from "./modules/editor/components/Renderer/InformationPaneRenderer.js";
19
- import { default as default19 } from "./modules/editor/components/Toolbar/TableToolbar.js";
20
- import { default as default20 } from "./modules/editor/components/Toolbar/LinkToolbar.js";
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
- default13 as AttachmentRenderer,
38
+ default14 as AttachmentRenderer,
38
39
  default7 as AudioNodeView,
39
- default14 as AudioRenderer,
40
+ default15 as AudioRenderer,
40
41
  default5 as BubbleMenuEditImage,
41
42
  default8 as ConversationHistoryNodeView,
42
- default15 as ConversationHistoryRenderer,
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
- default18 as InformationPaneRenderer,
52
- default20 as LinkToolbar,
53
+ default19 as InformationPaneRenderer,
54
+ default21 as LinkToolbar,
53
55
  default10 as LinkerNodeView,
54
- default16 as LinkerRenderer,
55
- default17 as MediaRenderer,
56
+ default17 as LinkerRenderer,
57
+ default18 as MediaRenderer,
56
58
  default2 as StarterKit,
57
- default19 as TableToolbar,
59
+ default20 as TableToolbar,
58
60
  default11 as VideoNodeView,
59
61
  useActionOptions,
60
62
  useCantooEditor,
@@ -0,0 +1,2 @@
1
+ declare const IframeNodeView: (Component: any) => import('@tiptap/core').Node<import('@edifice.io/tiptap-extensions/iframe').IframeOptions, any>;
2
+ export default IframeNodeView;
@@ -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: node.type.name === "custom-image" ? /* @__PURE__ */ jsxs(Fragment, { children: [
57
- /* @__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 }),
58
- node.attrs.title && // Display legend (set in title attribute) if it exists
59
- /* @__PURE__ */ jsx("em", { className: "custom-image-legend caption text-align-left", children: node.attrs.title })
60
- ] }) : /* @__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 }) }) }),
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
- export declare const useResizeMedia: (props: MediaResizeProps, refResizable: React.RefObject<HTMLImageElement | HTMLVideoElement>) => {
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), limitWidthOrHeight = (width) => width < MIN_WIDTH;
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 == null ? void 0 : proseMirrorContainerDiv.clientWidth), refResizable && (aspectRatio.current = 1.5);
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 onVerticalResize = (directionOfMouseMove, diff) => {
9
- var _a, _b;
10
- if (!refResizable) {
11
- console.error("Media ref is undefined|null", {
12
- refResizable
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 directionOfMouseMove = diff > 0 ? "left" : "right";
33
- onVerticalResize(directionOfMouseMove, Math.abs(diff));
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
- }), Iframe, Hyperlink, FontFamily, Mathematics, Alert, VideoNodeView(MediaRenderer), AudioNodeView(AudioRenderer), LinkerNodeView(LinkerRenderer), ImageNodeView(MediaRenderer, uploadFile), AttachmentNodeView(AttachmentRenderer), InformationPaneNodeView(InformationPaneRenderer), ...extensions || []],
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.20250910143701",
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.20250910143701",
134
- "@edifice.io/tiptap-extensions": "2.3.0-develop-pedago.20250910143701",
135
- "@edifice.io/utilities": "2.3.0-develop-pedago.20250910143701"
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.20250910143701",
167
- "@edifice.io/config": "2.3.0-develop-pedago.20250910143701"
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",