mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
feat: enhance embed resizer
This commit is contained in:
@@ -48,7 +48,7 @@ export function useResolveCommentMutation() {
|
|||||||
resolvedAt: variables.resolved ? new Date() : null,
|
resolvedAt: variables.resolved ? new Date() : null,
|
||||||
resolvedById: variables.resolved ? "optimistic" : null,
|
resolvedById: variables.resolved ? "optimistic" : null,
|
||||||
resolvedBy: variables.resolved
|
resolvedBy: variables.resolved
|
||||||
? { id: "optimistic", name: "", avatarUrl: null }
|
? ({ id: "optimistic", name: "", avatarUrl: null } as IComment["resolvedBy"])
|
||||||
: null,
|
: null,
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -67,3 +67,9 @@
|
|||||||
.resizing .handleBar {
|
.resizing .handleBar {
|
||||||
background-color: light-dark(var(--mantine-color-blue-6), var(--mantine-color-blue-4));
|
background-color: light-dark(var(--mantine-color-blue-6), var(--mantine-color-blue-4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.handle {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
.wrapper {
|
.wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
overflow: visible;
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resizing {
|
.resizing {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
cursor: ns-resize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlay {
|
.overlay {
|
||||||
@@ -20,12 +18,118 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resizeHandleBottom {
|
.cornerHandle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
z-index: 2;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
touch-action: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 1px;
|
||||||
|
background-color: light-dark(
|
||||||
|
var(--mantine-color-blue-4),
|
||||||
|
var(--mantine-color-blue-5)
|
||||||
|
);
|
||||||
|
transition: background-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
width: 28px;
|
||||||
|
height: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
width: 3px;
|
||||||
|
height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover::before,
|
||||||
|
&:hover::after {
|
||||||
|
background-color: light-dark(
|
||||||
|
var(--mantine-color-blue-6),
|
||||||
|
var(--mantine-color-blue-4)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cornerHandleTL {
|
||||||
|
top: -2px;
|
||||||
|
left: -2px;
|
||||||
|
cursor: nwse-resize;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cornerHandleTR {
|
||||||
|
top: -2px;
|
||||||
|
right: -2px;
|
||||||
|
cursor: nesw-resize;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cornerHandleBL {
|
||||||
|
bottom: -2px;
|
||||||
|
left: -2px;
|
||||||
|
cursor: nesw-resize;
|
||||||
|
|
||||||
|
&::before {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cornerHandleBR {
|
||||||
|
bottom: -2px;
|
||||||
|
right: -2px;
|
||||||
|
cursor: nwse-resize;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
height: 24px;
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.resizeHandleBottom {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -4px;
|
||||||
|
left: 20px;
|
||||||
|
right: 20px;
|
||||||
|
height: 12px;
|
||||||
cursor: ns-resize;
|
cursor: ns-resize;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.2s ease;
|
transition: opacity 0.2s ease;
|
||||||
@@ -36,61 +140,53 @@
|
|||||||
touch-action: none;
|
touch-action: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
@mixin light {
|
|
||||||
background: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.05));
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin dark {
|
|
||||||
background: linear-gradient(
|
|
||||||
to bottom,
|
|
||||||
transparent,
|
|
||||||
rgba(255, 255, 255, 0.05)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
@mixin light {
|
|
||||||
background: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin dark {
|
|
||||||
background: linear-gradient(
|
|
||||||
to bottom,
|
|
||||||
transparent,
|
|
||||||
rgba(255, 255, 255, 0.1)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper:hover .resizeHandleBottom,
|
|
||||||
.resizing .resizeHandleBottom {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.resizeBar {
|
.resizeBar {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 4px;
|
height: 3px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.15s ease;
|
||||||
|
background-color: light-dark(
|
||||||
@mixin light {
|
var(--mantine-color-blue-4),
|
||||||
background-color: var(--mantine-color-gray-5);
|
var(--mantine-color-blue-5)
|
||||||
}
|
);
|
||||||
|
}
|
||||||
@mixin dark {
|
|
||||||
background-color: var(--mantine-color-gray-6);
|
.resizeHandleBottom:hover .resizeBar {
|
||||||
}
|
background-color: light-dark(
|
||||||
|
var(--mantine-color-blue-6),
|
||||||
|
var(--mantine-color-blue-4)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper:hover .cornerHandle,
|
||||||
|
.wrapper:hover .resizeHandleBottom,
|
||||||
|
.wrapper:global(.ProseMirror-selectednode) .cornerHandle,
|
||||||
|
.wrapper:global(.ProseMirror-selectednode) .resizeHandleBottom,
|
||||||
|
.resizing .cornerHandle,
|
||||||
|
.resizing .resizeHandleBottom {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resizing .cornerHandle::before,
|
||||||
|
.resizing .cornerHandle::after {
|
||||||
|
background-color: light-dark(
|
||||||
|
var(--mantine-color-blue-6),
|
||||||
|
var(--mantine-color-blue-4)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.resizeHandleBottom:hover .resizeBar,
|
|
||||||
.resizing .resizeBar {
|
.resizing .resizeBar {
|
||||||
@mixin light {
|
background-color: light-dark(
|
||||||
background-color: var(--mantine-color-gray-7);
|
var(--mantine-color-blue-6),
|
||||||
}
|
var(--mantine-color-blue-4)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@mixin dark {
|
@media print {
|
||||||
background-color: var(--mantine-color-gray-4);
|
.cornerHandle,
|
||||||
|
.resizeHandleBottom {
|
||||||
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,110 +2,162 @@ import React, { ReactNode, useCallback, useEffect, useRef, useState } from "reac
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import classes from "./resizable-wrapper.module.css";
|
import classes from "./resizable-wrapper.module.css";
|
||||||
|
|
||||||
|
type Handle = "tl" | "tr" | "bl" | "br" | "bottom";
|
||||||
|
|
||||||
|
const HANDLE_SIGN: Record<Handle, { x: number; y: number }> = {
|
||||||
|
br: { x: 1, y: 1 },
|
||||||
|
bl: { x: -1, y: 1 },
|
||||||
|
tr: { x: 1, y: -1 },
|
||||||
|
tl: { x: -1, y: -1 },
|
||||||
|
bottom: { x: 0, y: 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const HANDLE_CURSOR: Record<Handle, string> = {
|
||||||
|
br: "nwse-resize",
|
||||||
|
tl: "nwse-resize",
|
||||||
|
bl: "nesw-resize",
|
||||||
|
tr: "nesw-resize",
|
||||||
|
bottom: "ns-resize",
|
||||||
|
};
|
||||||
|
|
||||||
|
const CORNER_CLASSES: Record<string, string> = {
|
||||||
|
tl: classes.cornerHandleTL,
|
||||||
|
tr: classes.cornerHandleTR,
|
||||||
|
bl: classes.cornerHandleBL,
|
||||||
|
br: classes.cornerHandleBR,
|
||||||
|
};
|
||||||
|
|
||||||
interface ResizableWrapperProps {
|
interface ResizableWrapperProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
initialWidth?: number;
|
||||||
initialHeight?: number;
|
initialHeight?: number;
|
||||||
|
minWidth?: number;
|
||||||
|
maxWidth?: number;
|
||||||
minHeight?: number;
|
minHeight?: number;
|
||||||
maxHeight?: number;
|
maxHeight?: number;
|
||||||
onResize?: (height: number) => void;
|
onResize?: (width: number, height: number) => void;
|
||||||
isEditable?: boolean;
|
isEditable?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
showHandles?: "always" | "hover";
|
selected?: boolean;
|
||||||
direction?: "vertical" | "horizontal" | "both";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DragState = {
|
||||||
|
handle: Handle;
|
||||||
|
startX: number;
|
||||||
|
startY: number;
|
||||||
|
startWidth: number;
|
||||||
|
startHeight: number;
|
||||||
|
};
|
||||||
|
|
||||||
export const ResizableWrapper: React.FC<ResizableWrapperProps> = ({
|
export const ResizableWrapper: React.FC<ResizableWrapperProps> = ({
|
||||||
children,
|
children,
|
||||||
|
initialWidth = 640,
|
||||||
initialHeight = 480,
|
initialHeight = 480,
|
||||||
|
minWidth = 200,
|
||||||
|
maxWidth = 1200,
|
||||||
minHeight = 200,
|
minHeight = 200,
|
||||||
maxHeight = 1200,
|
maxHeight = 1200,
|
||||||
onResize,
|
onResize,
|
||||||
isEditable = true,
|
isEditable = true,
|
||||||
className,
|
className,
|
||||||
showHandles = "hover",
|
selected = false,
|
||||||
direction = "vertical",
|
|
||||||
}) => {
|
}) => {
|
||||||
const [resizeParams, setResizeParams] = useState<{
|
const [isResizing, setIsResizing] = useState(false);
|
||||||
initialSize: number;
|
|
||||||
initialClientY: number;
|
|
||||||
initialClientX: number;
|
|
||||||
} | null>(null);
|
|
||||||
const [currentHeight, setCurrentHeight] = useState(initialHeight);
|
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
const dragRef = useRef<DragState | null>(null);
|
||||||
if (!resizeParams) return;
|
const widthRef = useRef(initialWidth);
|
||||||
|
const heightRef = useRef(initialHeight);
|
||||||
|
const onResizeRef = useRef(onResize);
|
||||||
|
onResizeRef.current = onResize;
|
||||||
|
const constraintsRef = useRef({ minWidth, maxWidth, minHeight, maxHeight });
|
||||||
|
constraintsRef.current = { minWidth, maxWidth, minHeight, maxHeight };
|
||||||
|
|
||||||
const handleMouseMove = (e: MouseEvent) => {
|
const handleMouseMove = useRef((e: MouseEvent) => {
|
||||||
if (!wrapperRef.current) return;
|
const drag = dragRef.current;
|
||||||
|
if (!drag || !wrapperRef.current) return;
|
||||||
|
|
||||||
if (direction === "vertical" || direction === "both") {
|
const sign = HANDLE_SIGN[drag.handle];
|
||||||
const deltaY = e.clientY - resizeParams.initialClientY;
|
const { minWidth, maxWidth, minHeight, maxHeight } = constraintsRef.current;
|
||||||
const newHeight = Math.min(
|
|
||||||
Math.max(resizeParams.initialSize + deltaY, minHeight),
|
const deltaY = e.clientY - drag.startY;
|
||||||
maxHeight
|
const newHeight = Math.min(Math.max(drag.startHeight + deltaY * sign.y, minHeight), maxHeight);
|
||||||
);
|
heightRef.current = newHeight;
|
||||||
setCurrentHeight(newHeight);
|
|
||||||
wrapperRef.current.style.height = `${newHeight}px`;
|
wrapperRef.current.style.height = `${newHeight}px`;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleMouseUp = () => {
|
if (sign.x !== 0) {
|
||||||
setResizeParams(null);
|
const deltaX = e.clientX - drag.startX;
|
||||||
if (onResize && currentHeight !== initialHeight) {
|
const newWidth = Math.min(Math.max(drag.startWidth + deltaX * sign.x, minWidth), maxWidth);
|
||||||
onResize(currentHeight);
|
widthRef.current = newWidth;
|
||||||
|
wrapperRef.current.style.width = `${newWidth}px`;
|
||||||
}
|
}
|
||||||
|
}).current;
|
||||||
|
|
||||||
|
const handleMouseUp = useRef(() => {
|
||||||
|
dragRef.current = null;
|
||||||
|
setIsResizing(false);
|
||||||
document.body.style.cursor = "";
|
document.body.style.cursor = "";
|
||||||
document.body.style.userSelect = "";
|
document.body.style.userSelect = "";
|
||||||
};
|
document.removeEventListener("mousemove", handleMouseMove);
|
||||||
|
document.removeEventListener("mouseup", handleMouseUp);
|
||||||
|
onResizeRef.current?.(widthRef.current, heightRef.current);
|
||||||
|
}).current;
|
||||||
|
|
||||||
|
const handleResizeStart = useCallback((e: React.MouseEvent, handle: Handle) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
dragRef.current = {
|
||||||
|
handle,
|
||||||
|
startX: e.clientX,
|
||||||
|
startY: e.clientY,
|
||||||
|
startWidth: widthRef.current,
|
||||||
|
startHeight: heightRef.current,
|
||||||
|
};
|
||||||
|
setIsResizing(true);
|
||||||
|
document.body.style.cursor = HANDLE_CURSOR[handle];
|
||||||
|
document.body.style.userSelect = "none";
|
||||||
document.addEventListener("mousemove", handleMouseMove);
|
document.addEventListener("mousemove", handleMouseMove);
|
||||||
document.addEventListener("mouseup", handleMouseUp);
|
document.addEventListener("mouseup", handleMouseUp);
|
||||||
|
}, [handleMouseMove, handleMouseUp]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener("mousemove", handleMouseMove);
|
document.removeEventListener("mousemove", handleMouseMove);
|
||||||
document.removeEventListener("mouseup", handleMouseUp);
|
document.removeEventListener("mouseup", handleMouseUp);
|
||||||
};
|
};
|
||||||
}, [resizeParams, currentHeight, initialHeight, onResize, minHeight, maxHeight, direction]);
|
}, [handleMouseMove, handleMouseUp]);
|
||||||
|
|
||||||
const handleResizeStart = useCallback((e: React.MouseEvent) => {
|
const shouldShowHandles = isEditable && (isHovered || isResizing || selected);
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
setResizeParams({
|
|
||||||
initialSize: currentHeight,
|
|
||||||
initialClientY: e.clientY,
|
|
||||||
initialClientX: e.clientX,
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.style.cursor = "ns-resize";
|
|
||||||
document.body.style.userSelect = "none";
|
|
||||||
}, [currentHeight]);
|
|
||||||
|
|
||||||
const shouldShowHandles =
|
|
||||||
isEditable &&
|
|
||||||
(showHandles === "always" || (showHandles === "hover" && (isHovered || resizeParams)));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={wrapperRef}
|
ref={wrapperRef}
|
||||||
className={clsx(classes.wrapper, className, {
|
className={clsx(classes.wrapper, className, {
|
||||||
[classes.resizing]: !!resizeParams,
|
[classes.resizing]: isResizing,
|
||||||
})}
|
})}
|
||||||
style={{ height: currentHeight }}
|
style={{ width: widthRef.current, height: heightRef.current }}
|
||||||
onMouseEnter={() => setIsHovered(true)}
|
onMouseEnter={() => setIsHovered(true)}
|
||||||
onMouseLeave={() => setIsHovered(false)}
|
onMouseLeave={() => setIsHovered(false)}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
{!!resizeParams && <div className={classes.overlay} />}
|
{isResizing && <div className={classes.overlay} />}
|
||||||
{shouldShowHandles && direction === "vertical" && (
|
{shouldShowHandles && (
|
||||||
|
<>
|
||||||
|
{(["tl", "tr", "bl", "br"] as const).map((corner) => (
|
||||||
|
<div
|
||||||
|
key={corner}
|
||||||
|
className={clsx(classes.cornerHandle, CORNER_CLASSES[corner])}
|
||||||
|
onMouseDown={(e) => handleResizeStart(e, corner)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
<div
|
<div
|
||||||
className={classes.resizeHandleBottom}
|
className={classes.resizeHandleBottom}
|
||||||
onMouseDown={handleResizeStart}
|
onMouseDown={(e) => handleResizeStart(e, "bottom")}
|
||||||
>
|
>
|
||||||
<div className={classes.resizeBar} />
|
<div className={classes.resizeBar} />
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
:global(.ProseMirror .node-embed.ProseMirror-selectednode) {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.embedContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.embedWrapper {
|
.embedWrapper {
|
||||||
@mixin light {
|
@mixin light {
|
||||||
background-color: var(--mantine-color-gray-0);
|
background-color: var(--mantine-color-gray-0);
|
||||||
|
|||||||
@@ -27,16 +27,13 @@ import { ResizableWrapper } from "../common/resizable-wrapper";
|
|||||||
import classes from "./embed-view.module.css";
|
import classes from "./embed-view.module.css";
|
||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
url: z
|
url: z.url({ message: i18n.t("Please enter a valid url") }).trim(),
|
||||||
.string()
|
|
||||||
.trim()
|
|
||||||
.url({ message: i18n.t("Please enter a valid url") }),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function EmbedView(props: NodeViewProps) {
|
export default function EmbedView(props: NodeViewProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { node, selected, updateAttributes, editor } = props;
|
const { node, selected, updateAttributes, editor } = props;
|
||||||
const { src, provider, height: nodeHeight } = node.attrs;
|
const { src, provider, width: nodeWidth, height: nodeHeight } = node.attrs;
|
||||||
|
|
||||||
const embedUrl = useMemo(() => {
|
const embedUrl = useMemo(() => {
|
||||||
if (src) {
|
if (src) {
|
||||||
@@ -53,8 +50,8 @@ export default function EmbedView(props: NodeViewProps) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleResize = useCallback(
|
const handleResize = useCallback(
|
||||||
(newHeight: number) => {
|
(newWidth: number, newHeight: number) => {
|
||||||
updateAttributes({ height: newHeight });
|
updateAttributes({ width: newWidth, height: newHeight });
|
||||||
},
|
},
|
||||||
[updateAttributes],
|
[updateAttributes],
|
||||||
);
|
);
|
||||||
@@ -85,14 +82,19 @@ export default function EmbedView(props: NodeViewProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper data-drag-handle>
|
<NodeViewWrapper data-drag-handle className={classes.embedNodeView}>
|
||||||
{embedUrl ? (
|
{embedUrl ? (
|
||||||
|
<div className={classes.embedContainer}>
|
||||||
<ResizableWrapper
|
<ResizableWrapper
|
||||||
|
initialWidth={nodeWidth || 640}
|
||||||
initialHeight={nodeHeight || 480}
|
initialHeight={nodeHeight || 480}
|
||||||
|
minWidth={200}
|
||||||
|
maxWidth={1200}
|
||||||
minHeight={200}
|
minHeight={200}
|
||||||
maxHeight={1200}
|
maxHeight={1200}
|
||||||
onResize={handleResize}
|
onResize={handleResize}
|
||||||
isEditable={editor.isEditable}
|
isEditable={editor.isEditable}
|
||||||
|
selected={selected}
|
||||||
className={clsx(classes.embedWrapper, {
|
className={clsx(classes.embedWrapper, {
|
||||||
"ProseMirror-selectednode": selected,
|
"ProseMirror-selectednode": selected,
|
||||||
})}
|
})}
|
||||||
@@ -106,6 +108,7 @@ export default function EmbedView(props: NodeViewProps) {
|
|||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
/>
|
/>
|
||||||
</ResizableWrapper>
|
</ResizableWrapper>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Popover
|
<Popover
|
||||||
width={300}
|
width={300}
|
||||||
|
|||||||
Reference in New Issue
Block a user