-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Environment
- Univer version: 0.15.3
- Browser: Chrome (latest)
- OS: macOS
Description
When Univer is embedded inside a scrollable page (e.g., documentation site, dashboard, or any page where the Univer container does NOT occupy the full browser viewport), the cell editor's maximum height calculation is incorrect. This causes the editing border/overlay to extend beyond the actual canvas boundaries, resulting in visual distortion when editing cells in lower rows (e.g., starting around row 17 in a 600px-tall container).
Root Cause Analysis
The issue is in packages/sheets-ui/src/services/editor/cell-editor-resize.service.ts, specifically the _getEditorMaxSize method (lines 249-254):
const clientHeight =
document.body.clientHeight -
startY -
footerBarHeight -
canvasOffset.top -
EDITOR_BORDER_SIZE * 2;This calculation uses document.body.clientHeight (browser viewport height) to determine the available space for the cell editor. However, this assumes Univer occupies the full viewport, which is NOT true in embedded scenarios.
Example calculation (600px container on a scrollable doc page):
| Variable | Value | Description |
|---|---|---|
document.body.clientHeight |
720px | Browser viewport height |
startY |
324px | Cell E17 position in canvas coordinates |
canvasOffset.top |
68px | Canvas position relative to viewport (varies with scroll) |
footerBarHeight |
28px | Sheet footer bar height |
EDITOR_BORDER_SIZE * 2 |
4px | Editor border |
Calculated clientHeight |
296px | What Univer thinks is available |
| Actual remaining canvas space | 171px | canvas.height(495) - startY(324) |
The calculated clientHeight (296px) is 125px larger than the actual remaining canvas space (171px), causing the editor to render beyond the canvas boundaries.
Why document.body.clientHeight is incorrect here:
- When the page is scrollable,
canvasOffset.topchanges with scroll position (viagetBoundingClientRect()), butdocument.body.clientHeightremains constant - The formula assumes
document.body.clientHeight - canvasOffset.topgives the distance from canvas top to viewport bottom, which is only valid when Univer fills the entire viewport - In embedded scenarios, the actual available space should be constrained by the canvas container height, not the body height
Steps to Reproduce
- Create a scrollable HTML page
- Embed a Univer Sheets instance inside a container with a fixed height (e.g.,
height: 600px) - Ensure the page has content above and below the Univer container, making the page scrollable
- Double-click on a cell in a lower row (e.g., row 17 or beyond)
- Observe that the cell editor border/overlay extends beyond the visible canvas area
Minimal reproduction:
<!DOCTYPE html>
<html>
<body style="height: 2000px; padding: 200px 50px;">
<h1>Content above Univer</h1>
<div id="univer-container" style="height: 600px; width: 800px;"></div>
<h1>Content below Univer</h1>
<script type="module">
import { createUniver, defaultTheme, LocaleType, UniverSheetsCorePreset } from '@univerjs/presets';
import '@univerjs/presets/lib/styles/preset-sheets-core.css';
const { univerAPI } = createUniver({
locale: LocaleType.EN_US,
theme: defaultTheme,
presets: [UniverSheetsCorePreset()],
});
univerAPI.createWorkbook({ sheets: [{ id: 'sheet1', name: 'Sheet1', rowCount: 100, columnCount: 26 }] });
</script>
</body>
</html>Expected Behavior
The cell editor should be constrained within the actual canvas area, regardless of where Univer is positioned on the page. The editor should NOT extend beyond the canvas boundaries.
Actual Behavior
The cell editor's height calculation overestimates available space, causing the editor overlay to extend beyond the canvas boundaries. This results in:
- Editor border appearing outside the spreadsheet area
- Visual distortion when editing lower rows
- The issue worsens the further down the row is (more rows below = more overflow)
Suggested Fix
Replace document.body.clientHeight with the actual canvas container's available height:
// Current (broken in embedded scenarios):
const clientHeight = document.body.clientHeight - startY - footerBarHeight - canvasOffset.top - EDITOR_BORDER_SIZE * 2;
// Suggested fix:
const canvasContainerHeight = canvasElement.parentElement.getBoundingClientRect().height;
const clientHeight = canvasContainerHeight - startY - footerBarHeight - EDITOR_BORDER_SIZE * 2;This would correctly constrain the editor within the canvas boundaries regardless of the page layout.