@odoo/o-spreadsheet 18.2.7 → 18.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.2.7
6
- * @date 2025-04-14T17:19:31.011Z
7
- * @hash e187958
5
+ * @version 18.2.8
6
+ * @date 2025-04-18T16:26:20.673Z
7
+ * @hash 5da9ddc
8
8
  */
9
9
 
10
10
  'use strict';
@@ -6900,6 +6900,12 @@ function tokenizeString(chars) {
6900
6900
  }
6901
6901
  return null;
6902
6902
  }
6903
+ /**
6904
+ - \p{L} is for any letter (from any language)
6905
+ - \p{N} is for any number
6906
+ - the u flag at the end is for unicode, which enables the `\p{...}` syntax
6907
+ */
6908
+ const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
6903
6909
  const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
6904
6910
  /**
6905
6911
  * A "Symbol" is just basically any word-like element that can appear in a
@@ -6940,7 +6946,8 @@ function tokenizeSymbol(chars) {
6940
6946
  };
6941
6947
  }
6942
6948
  }
6943
- while (chars.current && SYMBOL_CHARS.has(chars.current)) {
6949
+ while (chars.current &&
6950
+ (SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
6944
6951
  result += chars.shift();
6945
6952
  }
6946
6953
  if (result.length) {
@@ -9247,7 +9254,7 @@ function transformZone(zone, executed) {
9247
9254
  if (executed.type === "ADD_COLUMNS_ROWS") {
9248
9255
  return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
9249
9256
  }
9250
- return { ...zone };
9257
+ return zone;
9251
9258
  }
9252
9259
  function transformRangeData(range, executed) {
9253
9260
  const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
@@ -33638,6 +33645,12 @@ function isMacOS() {
33638
33645
  function isCtrlKey(ev) {
33639
33646
  return isMacOS() ? ev.metaKey : ev.ctrlKey;
33640
33647
  }
33648
+ /**
33649
+ * Detects if the current browser is Firefox
33650
+ */
33651
+ function isBrowserFirefox() {
33652
+ return /Firefox/i.test(navigator.userAgent);
33653
+ }
33641
33654
 
33642
33655
  /**
33643
33656
  * Repeatedly calls a callback function with a time delay between calls.
@@ -50433,39 +50446,6 @@ function useCellHovered(env, gridRef, callback) {
50433
50446
  }
50434
50447
  return hoveredPosition;
50435
50448
  }
50436
- function useTouchMove(gridRef, handler, canMoveUp) {
50437
- let x = null;
50438
- let y = null;
50439
- function onTouchStart(ev) {
50440
- if (ev.touches.length !== 1)
50441
- return;
50442
- x = ev.touches[0].clientX;
50443
- y = ev.touches[0].clientY;
50444
- }
50445
- function onTouchEnd() {
50446
- x = null;
50447
- y = null;
50448
- }
50449
- function onTouchMove(ev) {
50450
- if (ev.touches.length !== 1)
50451
- return;
50452
- // On mobile browsers, swiping down is often associated with "pull to refresh".
50453
- // We only want this behavior if the grid is already at the top.
50454
- // Otherwise we only want to move the canvas up, without triggering any refresh.
50455
- if (canMoveUp()) {
50456
- ev.preventDefault();
50457
- ev.stopPropagation();
50458
- }
50459
- const currentX = ev.touches[0].clientX;
50460
- const currentY = ev.touches[0].clientY;
50461
- handler(x - currentX, y - currentY);
50462
- x = currentX;
50463
- y = currentY;
50464
- }
50465
- useRefListener(gridRef, "touchstart", onTouchStart);
50466
- useRefListener(gridRef, "touchend", onTouchEnd);
50467
- useRefListener(gridRef, "touchmove", onTouchMove);
50468
- }
50469
50449
  class GridOverlay extends owl.Component {
50470
50450
  static template = "o-spreadsheet-GridOverlay";
50471
50451
  static props = {
@@ -50513,10 +50493,6 @@ class GridOverlay extends owl.Component {
50513
50493
  owl.onWillUnmount(() => {
50514
50494
  resizeObserver.disconnect();
50515
50495
  });
50516
- useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
50517
- const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
50518
- return scrollY > 0;
50519
- });
50520
50496
  this.cellPopovers = useStore(CellPopoverStore);
50521
50497
  this.paintFormatStore = useStore(PaintFormatStore);
50522
50498
  }
@@ -51988,6 +51964,73 @@ function useGridDrawing(refName, model, canvasSize) {
51988
51964
  }
51989
51965
  }
51990
51966
 
51967
+ const friction = 0.95;
51968
+ const verticalScrollFactor = 1;
51969
+ const horizontalScrollFactor = 1;
51970
+ function useTouchScroll(ref, updateScroll, canMoveUp) {
51971
+ let lastX = 0;
51972
+ let lastY = 0;
51973
+ let velocityX = 0;
51974
+ let velocityY = 0;
51975
+ let isMouseDown = false;
51976
+ let lastTime = 0;
51977
+ useRefListener(ref, "touchstart", onTouchStart, { capture: false });
51978
+ useRefListener(ref, "touchmove", onTouchMove, { capture: false });
51979
+ useRefListener(ref, "touchend", onTouchEnd, { capture: false });
51980
+ function onTouchStart(event) {
51981
+ isMouseDown = true;
51982
+ ({ clientX: lastX, clientY: lastY } = event.touches[0]);
51983
+ velocityX = 0;
51984
+ velocityY = 0;
51985
+ }
51986
+ function onTouchMove(event) {
51987
+ if (!isMouseDown)
51988
+ return;
51989
+ const currentTime = Date.now();
51990
+ const { clientX, clientY } = event.touches[0];
51991
+ let deltaX = lastX - clientX;
51992
+ let deltaY = lastY - clientY;
51993
+ const elapsedTime = currentTime - lastTime;
51994
+ velocityX = deltaX / elapsedTime;
51995
+ velocityY = deltaY / elapsedTime;
51996
+ lastX = clientX;
51997
+ lastY = clientY;
51998
+ lastTime = currentTime;
51999
+ if (canMoveUp()) {
52000
+ if (event.cancelable) {
52001
+ event.preventDefault();
52002
+ }
52003
+ event.stopPropagation();
52004
+ }
52005
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
52006
+ }
52007
+ function onTouchEnd(ev) {
52008
+ isMouseDown = false;
52009
+ lastX = lastY = 0;
52010
+ requestAnimationFrame(scroll);
52011
+ }
52012
+ function scroll() {
52013
+ if (Math.abs(velocityX) < 0.05) {
52014
+ velocityX = 0;
52015
+ }
52016
+ if (Math.abs(velocityY) < 0.05) {
52017
+ velocityY = 0;
52018
+ }
52019
+ if (!velocityX && !velocityY) {
52020
+ return;
52021
+ }
52022
+ const currentTime = Date.now();
52023
+ const elapsedTime = Math.abs(currentTime - lastTime);
52024
+ const deltaX = velocityX * elapsedTime;
52025
+ const deltaY = velocityY * elapsedTime;
52026
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
52027
+ lastTime = currentTime;
52028
+ velocityX *= friction;
52029
+ velocityY *= friction;
52030
+ requestAnimationFrame(scroll);
52031
+ }
52032
+ }
52033
+
51991
52034
  function useWheelHandler(handler) {
51992
52035
  function normalize(val, deltaMode) {
51993
52036
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
@@ -52328,7 +52371,7 @@ class HorizontalScrollBar extends owl.Component {
52328
52371
  left: `${this.props.leftOffset + x}px`,
52329
52372
  bottom: "0px",
52330
52373
  height: `${SCROLLBAR_WIDTH}px`,
52331
- right: `0px`,
52374
+ right: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
52332
52375
  };
52333
52376
  }
52334
52377
  onScroll(offset) {
@@ -52373,7 +52416,7 @@ class VerticalScrollBar extends owl.Component {
52373
52416
  top: `${this.props.topOffset + y}px`,
52374
52417
  right: "0px",
52375
52418
  width: `${SCROLLBAR_WIDTH}px`,
52376
- bottom: `0px`,
52419
+ bottom: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
52377
52420
  };
52378
52421
  }
52379
52422
  onScroll(offset) {
@@ -52609,6 +52652,10 @@ class Grid extends owl.Component {
52609
52652
  this.DOMFocusableElementStore.focusableElement?.focus();
52610
52653
  }
52611
52654
  }, () => [this.sidePanel.isOpen]);
52655
+ useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
52656
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
52657
+ return scrollY > 0;
52658
+ });
52612
52659
  }
52613
52660
  onCellHovered({ col, row }) {
52614
52661
  this.hoveredCell.hover({ col, row });
@@ -63854,10 +63901,8 @@ function mergeTransformation(toTransform, executed) {
63854
63901
  }
63855
63902
  const target = [];
63856
63903
  for (const zone1 of toTransform.target) {
63857
- for (const zone2 of executed.target) {
63858
- if (!overlap(zone1, zone2)) {
63859
- target.push({ ...zone1 });
63860
- }
63904
+ if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
63905
+ target.push(zone1);
63861
63906
  }
63862
63907
  }
63863
63908
  if (target.length) {
@@ -67989,24 +68034,14 @@ class InternalViewport {
67989
68034
  first: this.boundaries.top,
67990
68035
  last: this.boundaries.bottom,
67991
68036
  });
67992
- const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
67993
- const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
67994
- const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
67995
- const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
67996
- const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
67997
- const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
68037
+ const { end: lastColEnd } = this.getters.getColDimensions(this.sheetId, lastCol);
68038
+ const { end: lastRowEnd } = this.getters.getRowDimensions(this.sheetId, lastRow);
67998
68039
  let width = lastColEnd - this.offsetCorrectionX;
67999
68040
  if (this.canScrollHorizontally) {
68000
- width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
68001
- Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
68002
- );
68003
68041
  width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
68004
68042
  }
68005
68043
  let height = lastRowEnd - this.offsetCorrectionY;
68006
68044
  if (this.canScrollVertically) {
68007
- height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
68008
- Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
68009
- );
68010
68045
  height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
68011
68046
  if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
68012
68047
  height += FOOTER_HEIGHT;
@@ -68571,8 +68606,8 @@ class SheetViewPlugin extends UIPlugin {
68571
68606
  const { width, height } = this.getMainViewportRect();
68572
68607
  const viewport = this.getMainInternalViewport(sheetId);
68573
68608
  return {
68574
- maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
68575
- maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
68609
+ maxOffsetX: Math.max(0, width - viewport.viewportWidth),
68610
+ maxOffsetY: Math.max(0, height - viewport.viewportHeight),
68576
68611
  };
68577
68612
  }
68578
68613
  getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
@@ -70094,6 +70129,10 @@ class SpreadsheetDashboard extends owl.Component {
70094
70129
  this.hoveredCell.clear();
70095
70130
  });
70096
70131
  this.cellPopovers = useStore(CellPopoverStore);
70132
+ useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
70133
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
70134
+ return scrollY > 0;
70135
+ });
70097
70136
  }
70098
70137
  onCellHovered({ col, row }) {
70099
70138
  this.hoveredCell.hover({ col, row });
@@ -71484,6 +71523,7 @@ css /* scss */ `
71484
71523
  > canvas {
71485
71524
  box-sizing: content-box;
71486
71525
  border-bottom: 1px solid #e2e3e3;
71526
+ border-right: 1px solid #e2e3e3;
71487
71527
  }
71488
71528
 
71489
71529
  .o-grid-overlay {
@@ -76190,6 +76230,6 @@ exports.tokenColors = tokenColors;
76190
76230
  exports.tokenize = tokenize;
76191
76231
 
76192
76232
 
76193
- __info__.version = "18.2.7";
76194
- __info__.date = "2025-04-14T17:19:31.011Z";
76195
- __info__.hash = "e187958";
76233
+ __info__.version = "18.2.8";
76234
+ __info__.date = "2025-04-18T16:26:20.673Z";
76235
+ __info__.hash = "5da9ddc";
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.2.7
6
- * @date 2025-04-14T17:19:31.011Z
7
- * @hash e187958
5
+ * @version 18.2.8
6
+ * @date 2025-04-18T16:26:20.673Z
7
+ * @hash 5da9ddc
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -6898,6 +6898,12 @@ function tokenizeString(chars) {
6898
6898
  }
6899
6899
  return null;
6900
6900
  }
6901
+ /**
6902
+ - \p{L} is for any letter (from any language)
6903
+ - \p{N} is for any number
6904
+ - the u flag at the end is for unicode, which enables the `\p{...}` syntax
6905
+ */
6906
+ const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
6901
6907
  const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
6902
6908
  /**
6903
6909
  * A "Symbol" is just basically any word-like element that can appear in a
@@ -6938,7 +6944,8 @@ function tokenizeSymbol(chars) {
6938
6944
  };
6939
6945
  }
6940
6946
  }
6941
- while (chars.current && SYMBOL_CHARS.has(chars.current)) {
6947
+ while (chars.current &&
6948
+ (SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
6942
6949
  result += chars.shift();
6943
6950
  }
6944
6951
  if (result.length) {
@@ -9245,7 +9252,7 @@ function transformZone(zone, executed) {
9245
9252
  if (executed.type === "ADD_COLUMNS_ROWS") {
9246
9253
  return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
9247
9254
  }
9248
- return { ...zone };
9255
+ return zone;
9249
9256
  }
9250
9257
  function transformRangeData(range, executed) {
9251
9258
  const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
@@ -33636,6 +33643,12 @@ function isMacOS() {
33636
33643
  function isCtrlKey(ev) {
33637
33644
  return isMacOS() ? ev.metaKey : ev.ctrlKey;
33638
33645
  }
33646
+ /**
33647
+ * Detects if the current browser is Firefox
33648
+ */
33649
+ function isBrowserFirefox() {
33650
+ return /Firefox/i.test(navigator.userAgent);
33651
+ }
33639
33652
 
33640
33653
  /**
33641
33654
  * Repeatedly calls a callback function with a time delay between calls.
@@ -50431,39 +50444,6 @@ function useCellHovered(env, gridRef, callback) {
50431
50444
  }
50432
50445
  return hoveredPosition;
50433
50446
  }
50434
- function useTouchMove(gridRef, handler, canMoveUp) {
50435
- let x = null;
50436
- let y = null;
50437
- function onTouchStart(ev) {
50438
- if (ev.touches.length !== 1)
50439
- return;
50440
- x = ev.touches[0].clientX;
50441
- y = ev.touches[0].clientY;
50442
- }
50443
- function onTouchEnd() {
50444
- x = null;
50445
- y = null;
50446
- }
50447
- function onTouchMove(ev) {
50448
- if (ev.touches.length !== 1)
50449
- return;
50450
- // On mobile browsers, swiping down is often associated with "pull to refresh".
50451
- // We only want this behavior if the grid is already at the top.
50452
- // Otherwise we only want to move the canvas up, without triggering any refresh.
50453
- if (canMoveUp()) {
50454
- ev.preventDefault();
50455
- ev.stopPropagation();
50456
- }
50457
- const currentX = ev.touches[0].clientX;
50458
- const currentY = ev.touches[0].clientY;
50459
- handler(x - currentX, y - currentY);
50460
- x = currentX;
50461
- y = currentY;
50462
- }
50463
- useRefListener(gridRef, "touchstart", onTouchStart);
50464
- useRefListener(gridRef, "touchend", onTouchEnd);
50465
- useRefListener(gridRef, "touchmove", onTouchMove);
50466
- }
50467
50447
  class GridOverlay extends Component {
50468
50448
  static template = "o-spreadsheet-GridOverlay";
50469
50449
  static props = {
@@ -50511,10 +50491,6 @@ class GridOverlay extends Component {
50511
50491
  onWillUnmount(() => {
50512
50492
  resizeObserver.disconnect();
50513
50493
  });
50514
- useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
50515
- const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
50516
- return scrollY > 0;
50517
- });
50518
50494
  this.cellPopovers = useStore(CellPopoverStore);
50519
50495
  this.paintFormatStore = useStore(PaintFormatStore);
50520
50496
  }
@@ -51986,6 +51962,73 @@ function useGridDrawing(refName, model, canvasSize) {
51986
51962
  }
51987
51963
  }
51988
51964
 
51965
+ const friction = 0.95;
51966
+ const verticalScrollFactor = 1;
51967
+ const horizontalScrollFactor = 1;
51968
+ function useTouchScroll(ref, updateScroll, canMoveUp) {
51969
+ let lastX = 0;
51970
+ let lastY = 0;
51971
+ let velocityX = 0;
51972
+ let velocityY = 0;
51973
+ let isMouseDown = false;
51974
+ let lastTime = 0;
51975
+ useRefListener(ref, "touchstart", onTouchStart, { capture: false });
51976
+ useRefListener(ref, "touchmove", onTouchMove, { capture: false });
51977
+ useRefListener(ref, "touchend", onTouchEnd, { capture: false });
51978
+ function onTouchStart(event) {
51979
+ isMouseDown = true;
51980
+ ({ clientX: lastX, clientY: lastY } = event.touches[0]);
51981
+ velocityX = 0;
51982
+ velocityY = 0;
51983
+ }
51984
+ function onTouchMove(event) {
51985
+ if (!isMouseDown)
51986
+ return;
51987
+ const currentTime = Date.now();
51988
+ const { clientX, clientY } = event.touches[0];
51989
+ let deltaX = lastX - clientX;
51990
+ let deltaY = lastY - clientY;
51991
+ const elapsedTime = currentTime - lastTime;
51992
+ velocityX = deltaX / elapsedTime;
51993
+ velocityY = deltaY / elapsedTime;
51994
+ lastX = clientX;
51995
+ lastY = clientY;
51996
+ lastTime = currentTime;
51997
+ if (canMoveUp()) {
51998
+ if (event.cancelable) {
51999
+ event.preventDefault();
52000
+ }
52001
+ event.stopPropagation();
52002
+ }
52003
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
52004
+ }
52005
+ function onTouchEnd(ev) {
52006
+ isMouseDown = false;
52007
+ lastX = lastY = 0;
52008
+ requestAnimationFrame(scroll);
52009
+ }
52010
+ function scroll() {
52011
+ if (Math.abs(velocityX) < 0.05) {
52012
+ velocityX = 0;
52013
+ }
52014
+ if (Math.abs(velocityY) < 0.05) {
52015
+ velocityY = 0;
52016
+ }
52017
+ if (!velocityX && !velocityY) {
52018
+ return;
52019
+ }
52020
+ const currentTime = Date.now();
52021
+ const elapsedTime = Math.abs(currentTime - lastTime);
52022
+ const deltaX = velocityX * elapsedTime;
52023
+ const deltaY = velocityY * elapsedTime;
52024
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
52025
+ lastTime = currentTime;
52026
+ velocityX *= friction;
52027
+ velocityY *= friction;
52028
+ requestAnimationFrame(scroll);
52029
+ }
52030
+ }
52031
+
51989
52032
  function useWheelHandler(handler) {
51990
52033
  function normalize(val, deltaMode) {
51991
52034
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
@@ -52326,7 +52369,7 @@ class HorizontalScrollBar extends Component {
52326
52369
  left: `${this.props.leftOffset + x}px`,
52327
52370
  bottom: "0px",
52328
52371
  height: `${SCROLLBAR_WIDTH}px`,
52329
- right: `0px`,
52372
+ right: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
52330
52373
  };
52331
52374
  }
52332
52375
  onScroll(offset) {
@@ -52371,7 +52414,7 @@ class VerticalScrollBar extends Component {
52371
52414
  top: `${this.props.topOffset + y}px`,
52372
52415
  right: "0px",
52373
52416
  width: `${SCROLLBAR_WIDTH}px`,
52374
- bottom: `0px`,
52417
+ bottom: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
52375
52418
  };
52376
52419
  }
52377
52420
  onScroll(offset) {
@@ -52607,6 +52650,10 @@ class Grid extends Component {
52607
52650
  this.DOMFocusableElementStore.focusableElement?.focus();
52608
52651
  }
52609
52652
  }, () => [this.sidePanel.isOpen]);
52653
+ useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
52654
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
52655
+ return scrollY > 0;
52656
+ });
52610
52657
  }
52611
52658
  onCellHovered({ col, row }) {
52612
52659
  this.hoveredCell.hover({ col, row });
@@ -63852,10 +63899,8 @@ function mergeTransformation(toTransform, executed) {
63852
63899
  }
63853
63900
  const target = [];
63854
63901
  for (const zone1 of toTransform.target) {
63855
- for (const zone2 of executed.target) {
63856
- if (!overlap(zone1, zone2)) {
63857
- target.push({ ...zone1 });
63858
- }
63902
+ if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
63903
+ target.push(zone1);
63859
63904
  }
63860
63905
  }
63861
63906
  if (target.length) {
@@ -67987,24 +68032,14 @@ class InternalViewport {
67987
68032
  first: this.boundaries.top,
67988
68033
  last: this.boundaries.bottom,
67989
68034
  });
67990
- const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
67991
- const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
67992
- const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
67993
- const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
67994
- const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
67995
- const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
68035
+ const { end: lastColEnd } = this.getters.getColDimensions(this.sheetId, lastCol);
68036
+ const { end: lastRowEnd } = this.getters.getRowDimensions(this.sheetId, lastRow);
67996
68037
  let width = lastColEnd - this.offsetCorrectionX;
67997
68038
  if (this.canScrollHorizontally) {
67998
- width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
67999
- Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
68000
- );
68001
68039
  width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
68002
68040
  }
68003
68041
  let height = lastRowEnd - this.offsetCorrectionY;
68004
68042
  if (this.canScrollVertically) {
68005
- height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
68006
- Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
68007
- );
68008
68043
  height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
68009
68044
  if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
68010
68045
  height += FOOTER_HEIGHT;
@@ -68569,8 +68604,8 @@ class SheetViewPlugin extends UIPlugin {
68569
68604
  const { width, height } = this.getMainViewportRect();
68570
68605
  const viewport = this.getMainInternalViewport(sheetId);
68571
68606
  return {
68572
- maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
68573
- maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
68607
+ maxOffsetX: Math.max(0, width - viewport.viewportWidth),
68608
+ maxOffsetY: Math.max(0, height - viewport.viewportHeight),
68574
68609
  };
68575
68610
  }
68576
68611
  getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
@@ -70092,6 +70127,10 @@ class SpreadsheetDashboard extends Component {
70092
70127
  this.hoveredCell.clear();
70093
70128
  });
70094
70129
  this.cellPopovers = useStore(CellPopoverStore);
70130
+ useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
70131
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
70132
+ return scrollY > 0;
70133
+ });
70095
70134
  }
70096
70135
  onCellHovered({ col, row }) {
70097
70136
  this.hoveredCell.hover({ col, row });
@@ -71482,6 +71521,7 @@ css /* scss */ `
71482
71521
  > canvas {
71483
71522
  box-sizing: content-box;
71484
71523
  border-bottom: 1px solid #e2e3e3;
71524
+ border-right: 1px solid #e2e3e3;
71485
71525
  }
71486
71526
 
71487
71527
  .o-grid-overlay {
@@ -76143,6 +76183,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
76143
76183
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
76144
76184
 
76145
76185
 
76146
- __info__.version = "18.2.7";
76147
- __info__.date = "2025-04-14T17:19:31.011Z";
76148
- __info__.hash = "e187958";
76186
+ __info__.version = "18.2.8";
76187
+ __info__.date = "2025-04-18T16:26:20.673Z";
76188
+ __info__.hash = "5da9ddc";