diff --git a/packages/core/src/blocks/AudioBlockContent/AudioBlockContent.ts b/packages/core/src/blocks/AudioBlockContent/AudioBlockContent.ts index 7cdf9d2aa..59f36a6cb 100644 --- a/packages/core/src/blocks/AudioBlockContent/AudioBlockContent.ts +++ b/packages/core/src/blocks/AudioBlockContent/AudioBlockContent.ts @@ -64,12 +64,12 @@ export const audioRender = ( audio.contentEditable = "false"; audio.draggable = false; - const element = createFileAndCaptionWrapper(block, audio); + const fileAndCaptionWrapper = createFileAndCaptionWrapper(block, audio); return createFileBlockWrapper( block, editor, - element, + fileAndCaptionWrapper, editor.dictionary.file_blocks.audio.add_button_text, icon.firstElementChild as HTMLElement ); diff --git a/packages/core/src/blocks/FileBlockContent/FileBlockContent.ts b/packages/core/src/blocks/FileBlockContent/FileBlockContent.ts index 9e1e960c1..ba9a4d95a 100644 --- a/packages/core/src/blocks/FileBlockContent/FileBlockContent.ts +++ b/packages/core/src/blocks/FileBlockContent/FileBlockContent.ts @@ -43,9 +43,10 @@ export const fileRender = ( editor: BlockNoteEditor ) => { const file = createDefaultFilePreview(block).dom; - const element = createFileAndCaptionWrapper(block, file); - return createFileBlockWrapper(block, editor, element); + const fileAndCaptionWrapper = createFileAndCaptionWrapper(block, file); + + return createFileBlockWrapper(block, editor, fileAndCaptionWrapper); }; export const fileParse = (element: HTMLElement) => { diff --git a/packages/core/src/blocks/FileBlockContent/fileBlockHelpers.ts b/packages/core/src/blocks/FileBlockContent/fileBlockHelpers.ts index 58600671f..c08bd07a9 100644 --- a/packages/core/src/blocks/FileBlockContent/fileBlockHelpers.ts +++ b/packages/core/src/blocks/FileBlockContent/fileBlockHelpers.ts @@ -108,14 +108,6 @@ export const createFileAndCaptionWrapper = ( caption.className = "bn-file-caption"; caption.textContent = block.props.caption; - if ( - typeof block.props.previewWidth === "number" && - block.props.previewWidth > 0 && - block.props.caption !== undefined - ) { - caption.style.width = `${block.props.previewWidth}px`; - } - fileAndCaptionWrapper.appendChild(file); fileAndCaptionWrapper.appendChild(caption); @@ -250,9 +242,7 @@ export const createFigureWithCaption = ( export const createResizeHandlesWrapper = ( block: BlockFromConfig, editor: BlockNoteEditor, - element: HTMLElement, - getWidth: () => number, - setWidth: (width: number) => void + element: HTMLElement ): { dom: HTMLElement; destroy: () => void } => { if (!block.props.previewWidth) { throw new Error("Block must have a `previewWidth` prop."); @@ -260,14 +250,15 @@ export const createResizeHandlesWrapper = ( // Wrapper element for rendered element and resize handles. const wrapper = document.createElement("div"); - wrapper.className = "bn-visual-media-wrapper"; + wrapper.className = "bn-resize-handles-wrapper"; + wrapper.style.width = `${block.props.previewWidth}px`; // Resize handle elements. const leftResizeHandle = document.createElement("div"); - leftResizeHandle.className = "bn-visual-media-resize-handle"; + leftResizeHandle.className = "bn-resize-handle"; leftResizeHandle.style.left = "4px"; const rightResizeHandle = document.createElement("div"); - rightResizeHandle.className = "bn-visual-media-resize-handle"; + rightResizeHandle.className = "bn-resize-handle"; rightResizeHandle.style.right = "4px"; // Temporary parameters set when the user begins resizing the element, used to @@ -328,11 +319,13 @@ export const createResizeHandlesWrapper = ( // Ensures the element is not wider than the editor and not smaller than a // predetermined minimum width. if (newWidth < minWidth) { - setWidth(minWidth); + wrapper.style.width = `${minWidth}`; } else if (newWidth > editor.domElement.firstElementChild!.clientWidth) { - setWidth(editor.domElement.firstElementChild!.clientWidth); + wrapper.style.width = `${ + editor.domElement.firstElementChild!.clientWidth + }px`; } else { - setWidth(newWidth); + wrapper.style.width = `${newWidth}px`; } }; // Stops mouse movements from resizing the element and updates the block's @@ -358,7 +351,7 @@ export const createResizeHandlesWrapper = ( editor.updateBlock(block, { props: { - previewWidth: getWidth(), + previewWidth: parseInt(wrapper.style.width.replace("px", "")), }, }); }; diff --git a/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts b/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts index 32ad7df41..623a95031 100644 --- a/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts +++ b/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts @@ -57,6 +57,17 @@ export const imageRender = ( block: BlockFromConfig, editor: BlockNoteEditor ) => { + // Immediately updates & re-renders the block if it's wider than the editor. + if ( + block.props.previewWidth > editor.domElement.firstElementChild!.clientWidth + ) { + editor.updateBlock(block, { + props: { + previewWidth: editor.domElement.firstElementChild!.clientWidth, + }, + }); + } + const icon = document.createElement("div"); icon.innerHTML = FILE_IMAGE_ICON_SVG; @@ -68,25 +79,19 @@ export const imageRender = ( image.alt = block.props.name || block.props.caption || "BlockNote image"; image.contentEditable = "false"; image.draggable = false; - image.width = Math.min( - block.props.previewWidth, - editor.domElement.firstElementChild!.clientWidth - ); - const file = createResizeHandlesWrapper( + const fileAndCaptionWrapper = createFileAndCaptionWrapper(block, image); + + const resizeHandlesWrapper = createResizeHandlesWrapper( block, editor, - image, - () => image.width, - (width) => (image.width = width) + fileAndCaptionWrapper.dom ); - const element = createFileAndCaptionWrapper(block, file.dom); - return createFileBlockWrapper( block, editor, - element, + resizeHandlesWrapper, editor.dictionary.file_blocks.image.add_button_text, icon.firstElementChild as HTMLElement ); diff --git a/packages/core/src/blocks/VideoBlockContent/VideoBlockContent.ts b/packages/core/src/blocks/VideoBlockContent/VideoBlockContent.ts index 5dacc6ae7..161a995ef 100644 --- a/packages/core/src/blocks/VideoBlockContent/VideoBlockContent.ts +++ b/packages/core/src/blocks/VideoBlockContent/VideoBlockContent.ts @@ -58,6 +58,17 @@ export const videoRender = ( block: BlockFromConfig, editor: BlockNoteEditor ) => { + // Immediately updates & re-renders the block if it's wider than the editor. + if ( + block.props.previewWidth > editor.domElement.firstElementChild!.clientWidth + ) { + editor.updateBlock(block, { + props: { + previewWidth: editor.domElement.firstElementChild!.clientWidth, + }, + }); + } + const icon = document.createElement("div"); icon.innerHTML = FILE_VIDEO_ICON_SVG; @@ -67,25 +78,19 @@ export const videoRender = ( video.controls = true; video.contentEditable = "false"; video.draggable = false; - video.width = Math.min( - block.props.previewWidth, - editor.domElement.firstElementChild!.clientWidth - ); - const file = createResizeHandlesWrapper( + const fileAndCaptionWrapper = createFileAndCaptionWrapper(block, video); + + const resizeHandlesWrapper = createResizeHandlesWrapper( block, editor, - video, - () => video.width, - (width) => (video.width = width) + fileAndCaptionWrapper.dom ); - const element = createFileAndCaptionWrapper(block, file.dom); - return createFileBlockWrapper( block, editor, - element, + resizeHandlesWrapper, editor.dictionary.file_blocks.video.add_button_text, icon.firstElementChild as HTMLElement ); diff --git a/packages/core/src/editor/Block.css b/packages/core/src/editor/Block.css index 7ec40dc94..f385f5741 100644 --- a/packages/core/src/editor/Block.css +++ b/packages/core/src/editor/Block.css @@ -350,6 +350,7 @@ NESTED BLOCKS display: flex; flex-direction: column; border-radius: 4px; + width: 100%; } [data-file-block] .bn-file-default-preview { @@ -372,12 +373,11 @@ NESTED BLOCKS height: 24px; } -[data-file-block] .bn-visual-media-wrapper { +[data-file-block] .bn-resize-handles-wrapper { display: flex; flex-direction: row; align-items: center; position: relative; - width: fit-content; } [data-file-block] .bn-visual-media { @@ -385,7 +385,7 @@ NESTED BLOCKS max-width: 100%; } -[data-file-block] .bn-visual-media-resize-handle { +[data-file-block] .bn-resize-handle { position: absolute; width: 8px; height: 30px; diff --git a/packages/react/src/blocks/AudioBlockContent/AudioBlockContent.tsx b/packages/react/src/blocks/AudioBlockContent/AudioBlockContent.tsx index 958db0c85..9f0299b8a 100644 --- a/packages/react/src/blocks/AudioBlockContent/AudioBlockContent.tsx +++ b/packages/react/src/blocks/AudioBlockContent/AudioBlockContent.tsx @@ -8,6 +8,7 @@ import { } from "../../schema/ReactBlockSpec.js"; import { FigureWithCaption, + FileAndCaptionWrapper, FileBlockWrapper, LinkWithCaption, } from "../FileBlockContent/fileBlockHelpers.js"; @@ -26,13 +27,15 @@ export const AudioPreview = ( } return ( -