Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions packages/lexical-playground/__tests__/e2e/Images.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -819,4 +819,44 @@ test.describe('Images', () => {
`,
);
});

test('Dimensionless SVG renders with a visible bounding box instead of collapsing', async ({
page,
isRichText,
}) => {
test.skip(!isRichText);
await initialize({page});
await focusEditor(page);

// 1. Create a raw SVG without width/height attributes
const svgContent = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="red"/></svg>`;
const base64Svg = Buffer.from(svgContent).toString('base64');
const htmlContent = `<img src="data:image/svg+xml;base64,${base64Svg}" alt="dimensionless-svg" />`;

// 2. Simulate pasting the image into the editor
await page.evaluate((htmlPage) => {
const clipboardData = new DataTransfer();
clipboardData.setData('text/html', htmlPage);
const event = new ClipboardEvent('paste', {
bubbles: true,
cancelable: true,
clipboardData,
});
document.querySelector('[data-lexical-editor]')?.dispatchEvent(event);
}, htmlContent);

// 3. Wait for the image to be mounted in the DOM
const imageLocator = page.locator(
'[data-lexical-editor] img[alt="dimensionless-svg"]',
);
await imageLocator.waitFor({state: 'attached'});

// 4. Verification: The bounding box should NOT be 0x0
const boundingBox = await imageLocator.boundingBox();
expect(boundingBox).not.toBeNull();

// On the current main branch, this will FAIL because width/height collapse to 0
expect(boundingBox.width).toBeGreaterThan(0);
expect(boundingBox.height).toBeGreaterThan(0);
});
});
20 changes: 16 additions & 4 deletions packages/lexical-playground/src/nodes/ImageComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ function LazyImage({
width: 'inherit' | number;
onError: () => void;
}): JSX.Element {
const isSVGImage = isSVG(src);
const status = useSuspenseImage(src);

useEffect(() => {
Expand All @@ -155,7 +154,19 @@ function LazyImage({

// Calculate final dimensions with proper scaling
const calculateDimensions = () => {
if (!isSVGImage) {
if (width !== 'inherit' && height !== 'inherit') {
return {
height,
maxWidth,
width,
};
}

const isActuallySVG =
isSVG(src) || src.toLowerCase().startsWith('data:image/svg+xml');
Comment on lines +165 to +166
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not change isSVG accordingly?


// For standard images, Lexical expects 'inherit'
if (!isActuallySVG) {
return {
height,
maxWidth,
Expand All @@ -167,8 +178,9 @@ function LazyImage({
const naturalWidth = status.width;
const naturalHeight = status.height;

let finalWidth = naturalWidth;
let finalHeight = naturalHeight;
// If SVG has no intrinsic dimensions (0), fallback to a sensible default (maxWidth)
let finalWidth = naturalWidth || maxWidth;
let finalHeight = naturalHeight || finalWidth;

// Scale down if width exceeds maxWidth while maintaining aspect ratio
if (finalWidth > maxWidth) {
Expand Down
Loading