@odoo/o-spreadsheet 18.0.23 → 18.0.24

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.0.23
6
- * @date 2025-04-14T17:16:35.374Z
7
- * @hash f560133
5
+ * @version 18.0.24
6
+ * @date 2025-04-18T16:23:09.320Z
7
+ * @hash aa18758
8
8
  */
9
9
 
10
10
  'use strict';
@@ -6736,6 +6736,12 @@ function tokenizeString(chars) {
6736
6736
  }
6737
6737
  return null;
6738
6738
  }
6739
+ /**
6740
+ - \p{L} is for any letter (from any language)
6741
+ - \p{N} is for any number
6742
+ - the u flag at the end is for unicode, which enables the `\p{...}` syntax
6743
+ */
6744
+ const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
6739
6745
  const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
6740
6746
  /**
6741
6747
  * A "Symbol" is just basically any word-like element that can appear in a
@@ -6776,7 +6782,8 @@ function tokenizeSymbol(chars) {
6776
6782
  };
6777
6783
  }
6778
6784
  }
6779
- while (chars.current && SYMBOL_CHARS.has(chars.current)) {
6785
+ while (chars.current &&
6786
+ (SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
6780
6787
  result += chars.shift();
6781
6788
  }
6782
6789
  if (result.length) {
@@ -9039,7 +9046,7 @@ function transformZone(zone, executed) {
9039
9046
  if (executed.type === "ADD_COLUMNS_ROWS") {
9040
9047
  return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
9041
9048
  }
9042
- return { ...zone };
9049
+ return zone;
9043
9050
  }
9044
9051
  function transformRangeData(range, executed) {
9045
9052
  const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
@@ -48010,39 +48017,6 @@ function useCellHovered(env, gridRef, callback) {
48010
48017
  }
48011
48018
  return hoveredPosition;
48012
48019
  }
48013
- function useTouchMove(gridRef, handler, canMoveUp) {
48014
- let x = null;
48015
- let y = null;
48016
- function onTouchStart(ev) {
48017
- if (ev.touches.length !== 1)
48018
- return;
48019
- x = ev.touches[0].clientX;
48020
- y = ev.touches[0].clientY;
48021
- }
48022
- function onTouchEnd() {
48023
- x = null;
48024
- y = null;
48025
- }
48026
- function onTouchMove(ev) {
48027
- if (ev.touches.length !== 1)
48028
- return;
48029
- // On mobile browsers, swiping down is often associated with "pull to refresh".
48030
- // We only want this behavior if the grid is already at the top.
48031
- // Otherwise we only want to move the canvas up, without triggering any refresh.
48032
- if (canMoveUp()) {
48033
- ev.preventDefault();
48034
- ev.stopPropagation();
48035
- }
48036
- const currentX = ev.touches[0].clientX;
48037
- const currentY = ev.touches[0].clientY;
48038
- handler(x - currentX, y - currentY);
48039
- x = currentX;
48040
- y = currentY;
48041
- }
48042
- useRefListener(gridRef, "touchstart", onTouchStart);
48043
- useRefListener(gridRef, "touchend", onTouchEnd);
48044
- useRefListener(gridRef, "touchmove", onTouchMove);
48045
- }
48046
48020
  class GridOverlay extends owl.Component {
48047
48021
  static template = "o-spreadsheet-GridOverlay";
48048
48022
  static props = {
@@ -48090,10 +48064,6 @@ class GridOverlay extends owl.Component {
48090
48064
  owl.onWillUnmount(() => {
48091
48065
  resizeObserver.disconnect();
48092
48066
  });
48093
- useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
48094
- const { scrollY } = this.env.model.getters.getActiveSheetDOMScrollInfo();
48095
- return scrollY > 0;
48096
- });
48097
48067
  this.cellPopovers = useStore(CellPopoverStore);
48098
48068
  this.paintFormatStore = useStore(PaintFormatStore);
48099
48069
  }
@@ -49442,6 +49412,73 @@ function useGridDrawing(refName, model, canvasSize) {
49442
49412
  }
49443
49413
  }
49444
49414
 
49415
+ const friction = 0.95;
49416
+ const verticalScrollFactor = 1;
49417
+ const horizontalScrollFactor = 1;
49418
+ function useTouchScroll(ref, updateScroll, canMoveUp) {
49419
+ let lastX = 0;
49420
+ let lastY = 0;
49421
+ let velocityX = 0;
49422
+ let velocityY = 0;
49423
+ let isMouseDown = false;
49424
+ let lastTime = 0;
49425
+ useRefListener(ref, "touchstart", onTouchStart, { capture: false });
49426
+ useRefListener(ref, "touchmove", onTouchMove, { capture: false });
49427
+ useRefListener(ref, "touchend", onTouchEnd, { capture: false });
49428
+ function onTouchStart(event) {
49429
+ isMouseDown = true;
49430
+ ({ clientX: lastX, clientY: lastY } = event.touches[0]);
49431
+ velocityX = 0;
49432
+ velocityY = 0;
49433
+ }
49434
+ function onTouchMove(event) {
49435
+ if (!isMouseDown)
49436
+ return;
49437
+ const currentTime = Date.now();
49438
+ const { clientX, clientY } = event.touches[0];
49439
+ let deltaX = lastX - clientX;
49440
+ let deltaY = lastY - clientY;
49441
+ const elapsedTime = currentTime - lastTime;
49442
+ velocityX = deltaX / elapsedTime;
49443
+ velocityY = deltaY / elapsedTime;
49444
+ lastX = clientX;
49445
+ lastY = clientY;
49446
+ lastTime = currentTime;
49447
+ if (canMoveUp()) {
49448
+ if (event.cancelable) {
49449
+ event.preventDefault();
49450
+ }
49451
+ event.stopPropagation();
49452
+ }
49453
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
49454
+ }
49455
+ function onTouchEnd(ev) {
49456
+ isMouseDown = false;
49457
+ lastX = lastY = 0;
49458
+ requestAnimationFrame(scroll);
49459
+ }
49460
+ function scroll() {
49461
+ if (Math.abs(velocityX) < 0.05) {
49462
+ velocityX = 0;
49463
+ }
49464
+ if (Math.abs(velocityY) < 0.05) {
49465
+ velocityY = 0;
49466
+ }
49467
+ if (!velocityX && !velocityY) {
49468
+ return;
49469
+ }
49470
+ const currentTime = Date.now();
49471
+ const elapsedTime = Math.abs(currentTime - lastTime);
49472
+ const deltaX = velocityX * elapsedTime;
49473
+ const deltaY = velocityY * elapsedTime;
49474
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
49475
+ lastTime = currentTime;
49476
+ velocityX *= friction;
49477
+ velocityY *= friction;
49478
+ requestAnimationFrame(scroll);
49479
+ }
49480
+ }
49481
+
49445
49482
  function useWheelHandler(handler) {
49446
49483
  function normalize(val, deltaMode) {
49447
49484
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
@@ -50062,6 +50099,10 @@ class Grid extends owl.Component {
50062
50099
  this.DOMFocusableElementStore.focusableElement?.focus();
50063
50100
  }
50064
50101
  }, () => [this.sidePanel.isOpen]);
50102
+ useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
50103
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
50104
+ return scrollY > 0;
50105
+ });
50065
50106
  }
50066
50107
  onCellHovered({ col, row }) {
50067
50108
  this.hoveredCell.hover({ col, row });
@@ -61388,10 +61429,8 @@ function mergeTransformation(toTransform, executed) {
61388
61429
  }
61389
61430
  const target = [];
61390
61431
  for (const zone1 of toTransform.target) {
61391
- for (const zone2 of executed.target) {
61392
- if (!overlap(zone1, zone2)) {
61393
- target.push({ ...zone1 });
61394
- }
61432
+ if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
61433
+ target.push(zone1);
61395
61434
  }
61396
61435
  }
61397
61436
  if (target.length) {
@@ -67619,6 +67658,10 @@ class SpreadsheetDashboard extends owl.Component {
67619
67658
  this.hoveredCell.clear();
67620
67659
  });
67621
67660
  this.cellPopovers = useStore(CellPopoverStore);
67661
+ useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
67662
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
67663
+ return scrollY > 0;
67664
+ });
67622
67665
  }
67623
67666
  onCellHovered({ col, row }) {
67624
67667
  this.hoveredCell.hover({ col, row });
@@ -73714,6 +73757,6 @@ exports.tokenColors = tokenColors;
73714
73757
  exports.tokenize = tokenize;
73715
73758
 
73716
73759
 
73717
- __info__.version = "18.0.23";
73718
- __info__.date = "2025-04-14T17:16:35.374Z";
73719
- __info__.hash = "f560133";
73760
+ __info__.version = "18.0.24";
73761
+ __info__.date = "2025-04-18T16:23:09.320Z";
73762
+ __info__.hash = "aa18758";
@@ -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.0.23
6
- * @date 2025-04-14T17:16:35.374Z
7
- * @hash f560133
5
+ * @version 18.0.24
6
+ * @date 2025-04-18T16:23:09.320Z
7
+ * @hash aa18758
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -6734,6 +6734,12 @@ function tokenizeString(chars) {
6734
6734
  }
6735
6735
  return null;
6736
6736
  }
6737
+ /**
6738
+ - \p{L} is for any letter (from any language)
6739
+ - \p{N} is for any number
6740
+ - the u flag at the end is for unicode, which enables the `\p{...}` syntax
6741
+ */
6742
+ const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
6737
6743
  const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
6738
6744
  /**
6739
6745
  * A "Symbol" is just basically any word-like element that can appear in a
@@ -6774,7 +6780,8 @@ function tokenizeSymbol(chars) {
6774
6780
  };
6775
6781
  }
6776
6782
  }
6777
- while (chars.current && SYMBOL_CHARS.has(chars.current)) {
6783
+ while (chars.current &&
6784
+ (SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
6778
6785
  result += chars.shift();
6779
6786
  }
6780
6787
  if (result.length) {
@@ -9037,7 +9044,7 @@ function transformZone(zone, executed) {
9037
9044
  if (executed.type === "ADD_COLUMNS_ROWS") {
9038
9045
  return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
9039
9046
  }
9040
- return { ...zone };
9047
+ return zone;
9041
9048
  }
9042
9049
  function transformRangeData(range, executed) {
9043
9050
  const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
@@ -48008,39 +48015,6 @@ function useCellHovered(env, gridRef, callback) {
48008
48015
  }
48009
48016
  return hoveredPosition;
48010
48017
  }
48011
- function useTouchMove(gridRef, handler, canMoveUp) {
48012
- let x = null;
48013
- let y = null;
48014
- function onTouchStart(ev) {
48015
- if (ev.touches.length !== 1)
48016
- return;
48017
- x = ev.touches[0].clientX;
48018
- y = ev.touches[0].clientY;
48019
- }
48020
- function onTouchEnd() {
48021
- x = null;
48022
- y = null;
48023
- }
48024
- function onTouchMove(ev) {
48025
- if (ev.touches.length !== 1)
48026
- return;
48027
- // On mobile browsers, swiping down is often associated with "pull to refresh".
48028
- // We only want this behavior if the grid is already at the top.
48029
- // Otherwise we only want to move the canvas up, without triggering any refresh.
48030
- if (canMoveUp()) {
48031
- ev.preventDefault();
48032
- ev.stopPropagation();
48033
- }
48034
- const currentX = ev.touches[0].clientX;
48035
- const currentY = ev.touches[0].clientY;
48036
- handler(x - currentX, y - currentY);
48037
- x = currentX;
48038
- y = currentY;
48039
- }
48040
- useRefListener(gridRef, "touchstart", onTouchStart);
48041
- useRefListener(gridRef, "touchend", onTouchEnd);
48042
- useRefListener(gridRef, "touchmove", onTouchMove);
48043
- }
48044
48018
  class GridOverlay extends Component {
48045
48019
  static template = "o-spreadsheet-GridOverlay";
48046
48020
  static props = {
@@ -48088,10 +48062,6 @@ class GridOverlay extends Component {
48088
48062
  onWillUnmount(() => {
48089
48063
  resizeObserver.disconnect();
48090
48064
  });
48091
- useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
48092
- const { scrollY } = this.env.model.getters.getActiveSheetDOMScrollInfo();
48093
- return scrollY > 0;
48094
- });
48095
48065
  this.cellPopovers = useStore(CellPopoverStore);
48096
48066
  this.paintFormatStore = useStore(PaintFormatStore);
48097
48067
  }
@@ -49440,6 +49410,73 @@ function useGridDrawing(refName, model, canvasSize) {
49440
49410
  }
49441
49411
  }
49442
49412
 
49413
+ const friction = 0.95;
49414
+ const verticalScrollFactor = 1;
49415
+ const horizontalScrollFactor = 1;
49416
+ function useTouchScroll(ref, updateScroll, canMoveUp) {
49417
+ let lastX = 0;
49418
+ let lastY = 0;
49419
+ let velocityX = 0;
49420
+ let velocityY = 0;
49421
+ let isMouseDown = false;
49422
+ let lastTime = 0;
49423
+ useRefListener(ref, "touchstart", onTouchStart, { capture: false });
49424
+ useRefListener(ref, "touchmove", onTouchMove, { capture: false });
49425
+ useRefListener(ref, "touchend", onTouchEnd, { capture: false });
49426
+ function onTouchStart(event) {
49427
+ isMouseDown = true;
49428
+ ({ clientX: lastX, clientY: lastY } = event.touches[0]);
49429
+ velocityX = 0;
49430
+ velocityY = 0;
49431
+ }
49432
+ function onTouchMove(event) {
49433
+ if (!isMouseDown)
49434
+ return;
49435
+ const currentTime = Date.now();
49436
+ const { clientX, clientY } = event.touches[0];
49437
+ let deltaX = lastX - clientX;
49438
+ let deltaY = lastY - clientY;
49439
+ const elapsedTime = currentTime - lastTime;
49440
+ velocityX = deltaX / elapsedTime;
49441
+ velocityY = deltaY / elapsedTime;
49442
+ lastX = clientX;
49443
+ lastY = clientY;
49444
+ lastTime = currentTime;
49445
+ if (canMoveUp()) {
49446
+ if (event.cancelable) {
49447
+ event.preventDefault();
49448
+ }
49449
+ event.stopPropagation();
49450
+ }
49451
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
49452
+ }
49453
+ function onTouchEnd(ev) {
49454
+ isMouseDown = false;
49455
+ lastX = lastY = 0;
49456
+ requestAnimationFrame(scroll);
49457
+ }
49458
+ function scroll() {
49459
+ if (Math.abs(velocityX) < 0.05) {
49460
+ velocityX = 0;
49461
+ }
49462
+ if (Math.abs(velocityY) < 0.05) {
49463
+ velocityY = 0;
49464
+ }
49465
+ if (!velocityX && !velocityY) {
49466
+ return;
49467
+ }
49468
+ const currentTime = Date.now();
49469
+ const elapsedTime = Math.abs(currentTime - lastTime);
49470
+ const deltaX = velocityX * elapsedTime;
49471
+ const deltaY = velocityY * elapsedTime;
49472
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
49473
+ lastTime = currentTime;
49474
+ velocityX *= friction;
49475
+ velocityY *= friction;
49476
+ requestAnimationFrame(scroll);
49477
+ }
49478
+ }
49479
+
49443
49480
  function useWheelHandler(handler) {
49444
49481
  function normalize(val, deltaMode) {
49445
49482
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
@@ -50060,6 +50097,10 @@ class Grid extends Component {
50060
50097
  this.DOMFocusableElementStore.focusableElement?.focus();
50061
50098
  }
50062
50099
  }, () => [this.sidePanel.isOpen]);
50100
+ useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
50101
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
50102
+ return scrollY > 0;
50103
+ });
50063
50104
  }
50064
50105
  onCellHovered({ col, row }) {
50065
50106
  this.hoveredCell.hover({ col, row });
@@ -61386,10 +61427,8 @@ function mergeTransformation(toTransform, executed) {
61386
61427
  }
61387
61428
  const target = [];
61388
61429
  for (const zone1 of toTransform.target) {
61389
- for (const zone2 of executed.target) {
61390
- if (!overlap(zone1, zone2)) {
61391
- target.push({ ...zone1 });
61392
- }
61430
+ if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
61431
+ target.push(zone1);
61393
61432
  }
61394
61433
  }
61395
61434
  if (target.length) {
@@ -67617,6 +67656,10 @@ class SpreadsheetDashboard extends Component {
67617
67656
  this.hoveredCell.clear();
67618
67657
  });
67619
67658
  this.cellPopovers = useStore(CellPopoverStore);
67659
+ useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
67660
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
67661
+ return scrollY > 0;
67662
+ });
67620
67663
  }
67621
67664
  onCellHovered({ col, row }) {
67622
67665
  this.hoveredCell.hover({ col, row });
@@ -73669,6 +73712,6 @@ const constants = {
73669
73712
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, 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 };
73670
73713
 
73671
73714
 
73672
- __info__.version = "18.0.23";
73673
- __info__.date = "2025-04-14T17:16:35.374Z";
73674
- __info__.hash = "f560133";
73715
+ __info__.version = "18.0.24";
73716
+ __info__.date = "2025-04-18T16:23:09.320Z";
73717
+ __info__.hash = "aa18758";
@@ -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.0.23
6
- * @date 2025-04-14T17:16:35.374Z
7
- * @hash f560133
5
+ * @version 18.0.24
6
+ * @date 2025-04-18T16:23:09.320Z
7
+ * @hash aa18758
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -6735,6 +6735,12 @@
6735
6735
  }
6736
6736
  return null;
6737
6737
  }
6738
+ /**
6739
+ - \p{L} is for any letter (from any language)
6740
+ - \p{N} is for any number
6741
+ - the u flag at the end is for unicode, which enables the `\p{...}` syntax
6742
+ */
6743
+ const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
6738
6744
  const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
6739
6745
  /**
6740
6746
  * A "Symbol" is just basically any word-like element that can appear in a
@@ -6775,7 +6781,8 @@
6775
6781
  };
6776
6782
  }
6777
6783
  }
6778
- while (chars.current && SYMBOL_CHARS.has(chars.current)) {
6784
+ while (chars.current &&
6785
+ (SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
6779
6786
  result += chars.shift();
6780
6787
  }
6781
6788
  if (result.length) {
@@ -9038,7 +9045,7 @@
9038
9045
  if (executed.type === "ADD_COLUMNS_ROWS") {
9039
9046
  return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
9040
9047
  }
9041
- return { ...zone };
9048
+ return zone;
9042
9049
  }
9043
9050
  function transformRangeData(range, executed) {
9044
9051
  const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
@@ -48009,39 +48016,6 @@ stores.inject(MyMetaStore, storeInstance);
48009
48016
  }
48010
48017
  return hoveredPosition;
48011
48018
  }
48012
- function useTouchMove(gridRef, handler, canMoveUp) {
48013
- let x = null;
48014
- let y = null;
48015
- function onTouchStart(ev) {
48016
- if (ev.touches.length !== 1)
48017
- return;
48018
- x = ev.touches[0].clientX;
48019
- y = ev.touches[0].clientY;
48020
- }
48021
- function onTouchEnd() {
48022
- x = null;
48023
- y = null;
48024
- }
48025
- function onTouchMove(ev) {
48026
- if (ev.touches.length !== 1)
48027
- return;
48028
- // On mobile browsers, swiping down is often associated with "pull to refresh".
48029
- // We only want this behavior if the grid is already at the top.
48030
- // Otherwise we only want to move the canvas up, without triggering any refresh.
48031
- if (canMoveUp()) {
48032
- ev.preventDefault();
48033
- ev.stopPropagation();
48034
- }
48035
- const currentX = ev.touches[0].clientX;
48036
- const currentY = ev.touches[0].clientY;
48037
- handler(x - currentX, y - currentY);
48038
- x = currentX;
48039
- y = currentY;
48040
- }
48041
- useRefListener(gridRef, "touchstart", onTouchStart);
48042
- useRefListener(gridRef, "touchend", onTouchEnd);
48043
- useRefListener(gridRef, "touchmove", onTouchMove);
48044
- }
48045
48019
  class GridOverlay extends owl.Component {
48046
48020
  static template = "o-spreadsheet-GridOverlay";
48047
48021
  static props = {
@@ -48089,10 +48063,6 @@ stores.inject(MyMetaStore, storeInstance);
48089
48063
  owl.onWillUnmount(() => {
48090
48064
  resizeObserver.disconnect();
48091
48065
  });
48092
- useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
48093
- const { scrollY } = this.env.model.getters.getActiveSheetDOMScrollInfo();
48094
- return scrollY > 0;
48095
- });
48096
48066
  this.cellPopovers = useStore(CellPopoverStore);
48097
48067
  this.paintFormatStore = useStore(PaintFormatStore);
48098
48068
  }
@@ -49441,6 +49411,73 @@ stores.inject(MyMetaStore, storeInstance);
49441
49411
  }
49442
49412
  }
49443
49413
 
49414
+ const friction = 0.95;
49415
+ const verticalScrollFactor = 1;
49416
+ const horizontalScrollFactor = 1;
49417
+ function useTouchScroll(ref, updateScroll, canMoveUp) {
49418
+ let lastX = 0;
49419
+ let lastY = 0;
49420
+ let velocityX = 0;
49421
+ let velocityY = 0;
49422
+ let isMouseDown = false;
49423
+ let lastTime = 0;
49424
+ useRefListener(ref, "touchstart", onTouchStart, { capture: false });
49425
+ useRefListener(ref, "touchmove", onTouchMove, { capture: false });
49426
+ useRefListener(ref, "touchend", onTouchEnd, { capture: false });
49427
+ function onTouchStart(event) {
49428
+ isMouseDown = true;
49429
+ ({ clientX: lastX, clientY: lastY } = event.touches[0]);
49430
+ velocityX = 0;
49431
+ velocityY = 0;
49432
+ }
49433
+ function onTouchMove(event) {
49434
+ if (!isMouseDown)
49435
+ return;
49436
+ const currentTime = Date.now();
49437
+ const { clientX, clientY } = event.touches[0];
49438
+ let deltaX = lastX - clientX;
49439
+ let deltaY = lastY - clientY;
49440
+ const elapsedTime = currentTime - lastTime;
49441
+ velocityX = deltaX / elapsedTime;
49442
+ velocityY = deltaY / elapsedTime;
49443
+ lastX = clientX;
49444
+ lastY = clientY;
49445
+ lastTime = currentTime;
49446
+ if (canMoveUp()) {
49447
+ if (event.cancelable) {
49448
+ event.preventDefault();
49449
+ }
49450
+ event.stopPropagation();
49451
+ }
49452
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
49453
+ }
49454
+ function onTouchEnd(ev) {
49455
+ isMouseDown = false;
49456
+ lastX = lastY = 0;
49457
+ requestAnimationFrame(scroll);
49458
+ }
49459
+ function scroll() {
49460
+ if (Math.abs(velocityX) < 0.05) {
49461
+ velocityX = 0;
49462
+ }
49463
+ if (Math.abs(velocityY) < 0.05) {
49464
+ velocityY = 0;
49465
+ }
49466
+ if (!velocityX && !velocityY) {
49467
+ return;
49468
+ }
49469
+ const currentTime = Date.now();
49470
+ const elapsedTime = Math.abs(currentTime - lastTime);
49471
+ const deltaX = velocityX * elapsedTime;
49472
+ const deltaY = velocityY * elapsedTime;
49473
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
49474
+ lastTime = currentTime;
49475
+ velocityX *= friction;
49476
+ velocityY *= friction;
49477
+ requestAnimationFrame(scroll);
49478
+ }
49479
+ }
49480
+
49444
49481
  function useWheelHandler(handler) {
49445
49482
  function normalize(val, deltaMode) {
49446
49483
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
@@ -50061,6 +50098,10 @@ stores.inject(MyMetaStore, storeInstance);
50061
50098
  this.DOMFocusableElementStore.focusableElement?.focus();
50062
50099
  }
50063
50100
  }, () => [this.sidePanel.isOpen]);
50101
+ useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
50102
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
50103
+ return scrollY > 0;
50104
+ });
50064
50105
  }
50065
50106
  onCellHovered({ col, row }) {
50066
50107
  this.hoveredCell.hover({ col, row });
@@ -61387,10 +61428,8 @@ stores.inject(MyMetaStore, storeInstance);
61387
61428
  }
61388
61429
  const target = [];
61389
61430
  for (const zone1 of toTransform.target) {
61390
- for (const zone2 of executed.target) {
61391
- if (!overlap(zone1, zone2)) {
61392
- target.push({ ...zone1 });
61393
- }
61431
+ if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
61432
+ target.push(zone1);
61394
61433
  }
61395
61434
  }
61396
61435
  if (target.length) {
@@ -67618,6 +67657,10 @@ stores.inject(MyMetaStore, storeInstance);
67618
67657
  this.hoveredCell.clear();
67619
67658
  });
67620
67659
  this.cellPopovers = useStore(CellPopoverStore);
67660
+ useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
67661
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
67662
+ return scrollY > 0;
67663
+ });
67621
67664
  }
67622
67665
  onCellHovered({ col, row }) {
67623
67666
  this.hoveredCell.hover({ col, row });
@@ -73713,9 +73756,9 @@ stores.inject(MyMetaStore, storeInstance);
73713
73756
  exports.tokenize = tokenize;
73714
73757
 
73715
73758
 
73716
- __info__.version = "18.0.23";
73717
- __info__.date = "2025-04-14T17:16:35.374Z";
73718
- __info__.hash = "f560133";
73759
+ __info__.version = "18.0.24";
73760
+ __info__.date = "2025-04-18T16:23:09.320Z";
73761
+ __info__.hash = "aa18758";
73719
73762
 
73720
73763
 
73721
73764
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);