Skip to content

Commit 3c8df4b

Browse files
committed
[IMP] Grid: Snappy grid resizing
Currently, we detect the resize of the document viewport to trigger a resizing in the plugins,which in turn changes the dom dimensions, and it' s a loop of calls/get between the DOM and Model which ends up converging. However, this process is kind of slow because we need to wait for an animation frame at every iteration. This revision adds a "snappy" way to handle the resizing by capturing the top bar and bottom bar dimensions and instantly updating the size in the model to the final value that we are looking for. There is only one catch, and a pretty big one, the instant jump of size takes (of course) place before the drawing of the canvas, which means that we have one drawing frame where the visible part of the canvas does not match the part that is drawn. When the latter is smaller than the visible part, the undrawn part of the canvas is black -> it looks like a glitch. That being said, we could take some measures to draw some white background that spills outside of the visible part to account for those cases.
1 parent c838638 commit 3c8df4b

31 files changed

+1439
-1320
lines changed

src/components/dashboard/dashboard.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ css/* scss */ `
3232

3333
export class SpreadsheetDashboard extends Component<Props, SpreadsheetChildEnv> {
3434
static template = "o-spreadsheet-SpreadsheetDashboard";
35-
static props = {};
35+
static props = { getGridSize: Function };
3636
static components = {
3737
GridOverlay,
3838
GridPopover,

src/components/dashboard/dashboard.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
<GridOverlay
66
onGridResized.bind="onGridResized"
77
onGridMoved.bind="moveCanvas"
8-
gridOverlayDimensions="gridOverlayDimensions">
8+
gridOverlayDimensions="gridOverlayDimensions"
9+
getGridSize="props.getGridSize">
910
<div
1011
t-foreach="getClickableCells()"
1112
t-as="clickableCell"

src/components/grid/grid.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ const registries = {
112112

113113
interface Props {
114114
exposeFocus: (focus: () => void) => void;
115+
getGridSize: () => DOMDimension;
115116
}
116117

117118
// -----------------------------------------------------------------------------
@@ -121,6 +122,7 @@ export class Grid extends Component<Props, SpreadsheetChildEnv> {
121122
static template = "o-spreadsheet-Grid";
122123
static props = {
123124
exposeFocus: Function,
125+
getGridSize: Function,
124126
};
125127
static components = {
126128
GridComposer,
@@ -450,8 +452,8 @@ export class Grid extends Component<Props, SpreadsheetChildEnv> {
450452

451453
onGridResized({ height, width }: DOMDimension) {
452454
this.env.model.dispatch("RESIZE_SHEETVIEW", {
453-
width: width,
454-
height: height,
455+
width: width - HEADER_WIDTH,
456+
height: height - HEADER_HEIGHT,
455457
gridOffsetX: HEADER_WIDTH,
456458
gridOffsetY: HEADER_HEIGHT,
457459
});

src/components/grid/grid.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
onGridMoved.bind="moveCanvas"
1717
gridOverlayDimensions="gridOverlayDimensions"
1818
onFigureDeleted.bind="focusDefaultElement"
19+
getGridSize="props.getGridSize"
1920
/>
2021
<HeadersOverlay onOpenContextMenu="(type, x, y) => this.toggleContextMenu(type, x, y)"/>
2122
<GridComposer

src/components/grid_overlay/grid_overlay.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ interface Props {
146146
onGridMoved: (deltaX: Pixel, deltaY: Pixel) => void;
147147
gridOverlayDimensions: string;
148148
onFigureDeleted: () => void;
149+
getGridSize: () => { width: number; height: number };
149150
}
150151

151152
export class GridOverlay extends Component<Props, SpreadsheetChildEnv> {
@@ -159,6 +160,7 @@ export class GridOverlay extends Component<Props, SpreadsheetChildEnv> {
159160
onGridMoved: Function,
160161
gridOverlayDimensions: String,
161162
slots: { type: Object, optional: true },
163+
getGridSize: Function,
162164
};
163165
static components = {
164166
FiguresContainer,
@@ -180,11 +182,12 @@ export class GridOverlay extends Component<Props, SpreadsheetChildEnv> {
180182
useCellHovered(this.env, this.gridOverlay);
181183
const resizeObserver = new ResizeObserver(() => {
182184
const boundingRect = this.gridOverlayEl.getBoundingClientRect();
185+
const { width, height } = this.props.getGridSize();
183186
this.props.onGridResized({
184187
x: boundingRect.left,
185188
y: boundingRect.top,
186-
height: this.gridOverlayEl.clientHeight,
187-
width: this.gridOverlayEl.clientWidth,
189+
height: height,
190+
width: width,
188191
});
189192
});
190193
onMounted(() => {
@@ -291,7 +294,6 @@ export class GridOverlay extends Component<Props, SpreadsheetChildEnv> {
291294
const gridOverLayRect = getRefBoundingRect(this.gridOverlay);
292295
const x = ev.clientX - gridOverLayRect.x;
293296
const y = ev.clientY - gridOverLayRect.y;
294-
295297
const colIndex = this.env.model.getters.getColIndex(x);
296298
const rowIndex = this.env.model.getters.getRowIndex(y);
297299
return [colIndex, rowIndex];

src/components/small_bottom_bar/small_bottom_bar.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.o-spreadsheet .o-spreadsheet-small-bottom-bar {
22
.o-selection-button {
33
border-radius: 2px;
4+
background-color: #e7e9ed;
45
.o-icon {
56
width: 24px;
67
height: 24px;

src/components/spreadsheet/spreadsheet.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
PRIMARY_BUTTON_ACTIVE_BG,
3333
PRIMARY_BUTTON_BG,
3434
PRIMARY_BUTTON_HOVER_BG,
35+
SCROLLBAR_WIDTH,
3536
SEPARATOR_COLOR,
3637
TEXT_BODY,
3738
TEXT_BODY_MUTED,
@@ -421,7 +422,6 @@ export class Spreadsheet extends Component<SpreadsheetProps, SpreadsheetChildEnv
421422
);
422423

423424
useExternalListener(window, "resize", () => this.render(true));
424-
425425
// For some reason, the wheel event is not properly registered inside templates
426426
// in Chromium-based browsers based on chromium 125
427427
// This hack ensures the event declared in the template is properly registered/working
@@ -533,4 +533,28 @@ export class Spreadsheet extends Component<SpreadsheetProps, SpreadsheetChildEnv
533533
const sheetId = this.env.model.getters.getActiveSheetId();
534534
return this.env.model.getters.getVisibleGroupLayers(sheetId, "COL");
535535
}
536+
537+
getGridSize() {
538+
const topBarHeight =
539+
this.spreadsheetRef.el
540+
?.querySelector(".o-spreadsheet-topbar-wrapper")
541+
?.getBoundingClientRect().height || 0;
542+
const bottomBarHeight =
543+
this.spreadsheetRef.el
544+
?.querySelector(".o-spreadsheet-bottombar-wrapper")
545+
?.getBoundingClientRect().height || 0;
546+
547+
const gridWidth =
548+
this.spreadsheetRef.el?.querySelector(".o-grid")?.getBoundingClientRect().width || 0;
549+
const gridHeight =
550+
(this.spreadsheetRef.el?.getBoundingClientRect().height || 0) -
551+
(this.spreadsheetRef.el?.querySelector(".o-column-groups")?.getBoundingClientRect().height ||
552+
0) -
553+
topBarHeight -
554+
bottomBarHeight;
555+
return {
556+
width: Math.max(gridWidth - SCROLLBAR_WIDTH, 0),
557+
height: Math.max(gridHeight - SCROLLBAR_WIDTH, 0),
558+
};
559+
}
536560
}

src/components/spreadsheet/spreadsheet.xml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
<t t-name="o-spreadsheet-Spreadsheet">
33
<div class="o-spreadsheet h-100 w-100" t-ref="spreadsheet" t-att-style="getStyle()">
44
<t t-if="env.isDashboard()">
5-
<SpreadsheetDashboard/>
5+
<SpreadsheetDashboard getGridSize.bind="getGridSize"/>
66
<FullScreenChart/>
77
</t>
88
<t t-else="">
9-
<TopBar onClick="() => this.focusGrid()" dropdownMaxHeight="gridHeight"/>
9+
<div class="o-spreadsheet-topbar-wrapper o-two-columns">
10+
<TopBar onClick="() => this.focusGrid()" dropdownMaxHeight="gridHeight"/>
11+
</div>
1012
<div
1113
class="o-grid-container"
1214
t-att-class="{'o-two-columns': !sidePanel.isOpen}"
@@ -20,12 +22,14 @@
2022
<HeaderGroupContainer layers="rowLayers" dimension="'ROW'"/>
2123
</div>
2224
<div class="o-group-grid overflow-hidden">
23-
<Grid exposeFocus="(focus) => this._focusGrid = focus"/>
25+
<Grid exposeFocus="(focus) => this._focusGrid = focus" getGridSize.bind="getGridSize"/>
2426
</div>
2527
</div>
2628
<SidePanel/>
27-
<SmallBottomBar t-if="env.isSmall" onClick="() => this.focusGrid()"/>
28-
<BottomBar t-else="" onClick="() => this.focusGrid()"/>
29+
<div class="o-spreadsheet-bottombar-wrapper o-two-columns overflow-hidden">
30+
<SmallBottomBar t-if="env.isSmall" onClick="() => this.focusGrid()"/>
31+
<BottomBar t-else="" onClick="() => this.focusGrid()"/>
32+
</div>
2933
</t>
3034
</div>
3135
</t>

src/components/top_bar/top_bar.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<templates>
22
<t t-name="o-spreadsheet-TopBar">
33
<div
4-
class="o-spreadsheet-topbar o-two-columns d-flex flex-column user-select-none"
4+
class="o-spreadsheet-topbar d-flex flex-column user-select-none"
55
t-on-click="props.onClick">
66
<div t-if="!env.isSmall" class="o-topbar-top d-flex justify-content-between">
77
<!-- Menus -->

tests/__snapshots__/top_bar_component.test.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ exports[`TopBar component can set cell format 1`] = `
66
class="o-spreadsheet"
77
>
88
<div
9-
class="o-spreadsheet-topbar o-two-columns d-flex flex-column user-select-none"
9+
class="o-spreadsheet-topbar d-flex flex-column user-select-none"
1010
>
1111
<div
1212
class="o-topbar-top d-flex justify-content-between"
@@ -1122,7 +1122,7 @@ exports[`TopBar component can set cell format 1`] = `
11221122

11231123
exports[`TopBar component simple rendering 1`] = `
11241124
<div
1125-
class="o-spreadsheet-topbar o-two-columns d-flex flex-column user-select-none"
1125+
class="o-spreadsheet-topbar d-flex flex-column user-select-none"
11261126
>
11271127
<div
11281128
class="o-topbar-top d-flex justify-content-between"

0 commit comments

Comments
 (0)