@odoo/o-spreadsheet 18.3.60 → 18.3.62

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.3.60
6
- * @date 2026-08-21T15:28:08.047Z
7
- * @hash ab0ffc5
5
+ * @version 18.3.62
6
+ * @date 2026-09-04T07:18:12.683Z
7
+ * @hash aaaa064
8
8
  */
9
9
  /* Originates from src/components/top_bar/top_bar.scss */
10
10
  @media (max-width: 900px) {
@@ -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.3.60
6
- * @date 2026-08-21T15:28:06.523Z
7
- * @hash ab0ffc5
5
+ * @version 18.3.62
6
+ * @date 2026-09-04T07:18:11.182Z
7
+ * @hash aaaa064
8
8
  */
9
9
 
10
10
  import { App, Component, blockDom, markRaw, onMounted, onPatched, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, xml } from "@odoo/owl";
@@ -17684,10 +17684,10 @@ const chartShowValuesPlugin = {
17684
17684
  case "bar":
17685
17685
  case "line":
17686
17686
  case "radar":
17687
- options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
17687
+ options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: true }) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
17688
17688
  break;
17689
17689
  case "funnel":
17690
- drawHorizontalBarChartValues(chart, options, ctx);
17690
+ drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: false });
17691
17691
  break;
17692
17692
  }
17693
17693
  ctx.restore();
@@ -17728,7 +17728,7 @@ function drawLineOrBarOrRadarChartValues(chart, options, ctx) {
17728
17728
  }
17729
17729
  }
17730
17730
  }
17731
- function drawHorizontalBarChartValues(chart, options, ctx) {
17731
+ function drawHorizontalBarChartValues(chart, options, ctx, args) {
17732
17732
  const textsPositions = {};
17733
17733
  for (const dataset of chart._metasets) {
17734
17734
  if (isTrendLineAxis(dataset.xAxisID)) return;
@@ -17743,7 +17743,7 @@ function drawHorizontalBarChartValues(chart, options, ctx) {
17743
17743
  const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
17744
17744
  const PADDING = 3;
17745
17745
  let xPosition;
17746
- if (distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
17746
+ if (args.offsetFromAxisOrigin && distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
17747
17747
  else xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
17748
17748
  if (!textsPositions[yPosition]) textsPositions[yPosition] = [];
17749
17749
  for (const otherPosition of textsPositions[yPosition]) if (Math.abs(otherPosition - xPosition) < textWidth) xPosition = value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
@@ -17976,7 +17976,8 @@ function getRadarChartDatasets(definition, args) {
17976
17976
  data,
17977
17977
  hidden,
17978
17978
  borderColor,
17979
- backgroundColor: borderColor
17979
+ backgroundColor: borderColor,
17980
+ pointBackgroundColor: borderColor
17980
17981
  };
17981
17982
  if (fill) {
17982
17983
  dataset.backgroundColor = setColorAlpha(borderColor, LINE_FILL_TRANSPARENCY);
@@ -31033,12 +31034,48 @@ const ErrorToolTipPopoverBuilder = { onHover: (position, getters) => {
31033
31034
  } };
31034
31035
 
31035
31036
  //#endregion
31036
- //#region src/components/side_panel/components/checkbox/checkbox.ts
31037
+ //#region src/components/icons/raw_svgs.ts
31038
+ /**
31039
+ * SVG markup used in `css` tagged templates as `data:image/svg+xml` URIs.
31040
+ *
31041
+ * Keep these values in a separate module so Rolldown references them instead
31042
+ * of inlining them into template literals. Inlining produces nested template
31043
+ * literals, which the downstream `rjsmin` minifier cannot parse correctly
31044
+ * because it relies on regular expressions.
31045
+ *
31046
+ * Do not inline these constants.
31047
+ */
31037
31048
  const CHECK_SVG = `
31038
31049
  <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'>
31039
31050
  <path fill='none' stroke='#FFF' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/>
31040
31051
  </svg>
31041
31052
  `;
31053
+ const CIRCLE_SVG = `
31054
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'>
31055
+ <circle r="2" fill="#FFF"/>
31056
+ </svg>
31057
+ `;
31058
+ const FX_SVG = `
31059
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
31060
+ <path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
31061
+ </svg>
31062
+ `;
31063
+ const TRANSPARENT_BACKGROUND_SVG = `
31064
+ <svg xmlns="http://www.w3.org/2000/svg" width="10" height="10">
31065
+ <path fill="#d9d9d9" d="M5 5h5v5H5zH0V0h5"/>
31066
+ </svg>
31067
+ `;
31068
+ const CURSOR_SVG = `
31069
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="16"><path d="M6.5.4c1.3-.8 2.9-.1 3.8 1.4l2.9 5.1c.2.4.9 1.6-.4 2.3l-1.6.9 1.8 3.1c.2.4.1 1-.2 1.2l-1.6 1c-.3.1-.9 0-1.1-.4l-1.8-3.1-1.6 1c-.6.4-1.7 0-2.2-.8L0 4.3"/><path fill="#fff" d="M9.1 2a1.4 1.1 60 0 0-1.7-.6L5.5 2.5l.9 1.6-1 .6-.9-1.6-.6.4 1.8 3.1-1.3.7-1.8-3.1-1 .6 3.8 6.6 6.8-3.98M3.9 8.8 10.82 5l.795 1.4-6.81 3.96"/></svg>
31070
+ `;
31071
+ const CARET_DOWN_SVG = `
31072
+ <svg xmlns='http://www.w3.org/2000/svg' width='7' height='4' viewBox='0 0 7 4'>
31073
+ <polygon fill='%23374151' points='3.5 4 7 0 0 0'/>
31074
+ </svg>
31075
+ `;
31076
+
31077
+ //#endregion
31078
+ //#region src/components/side_panel/components/checkbox/checkbox.ts
31042
31079
  const CHECKBOX_WIDTH = 14;
31043
31080
  css`
31044
31081
  label.o-checkbox {
@@ -37318,14 +37355,16 @@ css`
37318
37355
  border-radius: 8px;
37319
37356
 
37320
37357
  &:checked {
37321
- background: url("data:image/svg+xml,${encodeURIComponent(`
37322
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'>
37323
- <circle r="2" fill="#FFF"/>
37324
- </svg>
37325
- `)}");
37358
+ background: url("data:image/svg+xml,${encodeURIComponent(CIRCLE_SVG)}");
37326
37359
  background-color: ${ACTION_COLOR};
37327
37360
  border-color: ${ACTION_COLOR};
37328
37361
  }
37362
+
37363
+ &:focus {
37364
+ outline: none;
37365
+ box-shadow: 0 0 0 0.25rem rgba(113, 75, 103, 0.25);
37366
+ border-color: ${ACTION_COLOR};
37367
+ }
37329
37368
  }
37330
37369
  }
37331
37370
  `;
@@ -37353,11 +37392,7 @@ css`
37353
37392
  cursor: pointer;
37354
37393
  border: 1px solid ${GRAY_300};
37355
37394
  background-position: 1px 1px;
37356
- background-image: url("data:image/svg+xml,${encodeURIComponent(`
37357
- <svg xmlns="http://www.w3.org/2000/svg" width="10" height="10">
37358
- <path fill="#d9d9d9" d="M5 5h5v5H5zH0V0h5"/>
37359
- </svg>
37360
- `)}");
37395
+ background-image: url("data:image/svg+xml,${encodeURIComponent(TRANSPARENT_BACKGROUND_SVG)}");
37361
37396
  }
37362
37397
  `;
37363
37398
  var RoundColorPicker = class extends Component {
@@ -38362,9 +38397,10 @@ var Composer = class extends Component {
38362
38397
  compositionActive = false;
38363
38398
  spreadsheetRect = useSpreadsheetRect();
38364
38399
  lastHoveredTokenIndex = void 0;
38365
- debouncedHover = debounce((tokenIndex, hoveredRect) => {
38400
+ debouncedHover = debounce((tokenIndex, composerContent, hoveredRect) => {
38366
38401
  const selection = this.contentHelper.getCurrentSelection();
38367
- if (selection.start !== selection.end) return;
38402
+ const currentContent = this.props.composerStore.currentContent;
38403
+ if (selection.start !== selection.end || currentContent !== composerContent) return;
38368
38404
  const currentHoveredContext = this.props.composerStore.hoveredTokens;
38369
38405
  this.props.composerStore.hoverToken(tokenIndex);
38370
38406
  if (!deepEquals(currentHoveredContext, this.props.composerStore.hoveredTokens)) this.composerState.hoveredRect = hoveredRect;
@@ -38706,7 +38742,8 @@ var Composer = class extends Component {
38706
38742
  onTokenHover(tokenIndex, hoveredRect) {
38707
38743
  if (this.lastHoveredTokenIndex !== tokenIndex) {
38708
38744
  this.lastHoveredTokenIndex = tokenIndex;
38709
- this.debouncedHover(tokenIndex, hoveredRect);
38745
+ const composerContent = this.props.composerStore.currentContent;
38746
+ this.debouncedHover(tokenIndex, composerContent, hoveredRect);
38710
38747
  }
38711
38748
  }
38712
38749
  /**
@@ -44974,7 +45011,13 @@ var PivotSpreadsheetSidePanel = class extends Component {
44974
45011
  }
44975
45012
  onSelectionChanged(ranges) {
44976
45013
  this.state.rangeHasChanged = true;
44977
- this.state.range = ranges[0];
45014
+ if (ranges.length === 0) {
45015
+ this.state.range = void 0;
45016
+ return;
45017
+ }
45018
+ const sheetId = this.env.model.getters.getActiveSheetId();
45019
+ const range = this.env.model.getters.getRangeFromSheetXC(sheetId, ranges[0]);
45020
+ this.state.range = this.env.model.getters.getRangeString(range, "forceSheetReference", { useBoundedReference: true });
44978
45021
  }
44979
45022
  onSelectionConfirmed() {
44980
45023
  if (this.state.range) {
@@ -48355,9 +48398,7 @@ var HoveredTableStore = class extends SpreadsheetStore {
48355
48398
  //#region src/components/grid_overlay/grid_overlay.ts
48356
48399
  css`
48357
48400
  .o-paint-format-cursor {
48358
- cursor: url("data:image/svg+xml,${encodeURIComponent(`
48359
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="16"><path d="M6.5.4c1.3-.8 2.9-.1 3.8 1.4l2.9 5.1c.2.4.9 1.6-.4 2.3l-1.6.9 1.8 3.1c.2.4.1 1-.2 1.2l-1.6 1c-.3.1-.9 0-1.1-.4l-1.8-3.1-1.6 1c-.6.4-1.7 0-2.2-.8L0 4.3"/><path fill="#fff" d="M9.1 2a1.4 1.1 60 0 0-1.7-.6L5.5 2.5l.9 1.6-1 .6-.9-1.6-.6.4 1.8 3.1-1.3.7-1.8-3.1-1 .6 3.8 6.6 6.8-3.98M3.9 8.8 10.82 5l.795 1.4-6.81 3.96"/></svg>
48360
- `)}"), auto;
48401
+ cursor: url("data:image/svg+xml,${encodeURIComponent(CURSOR_SVG)}"), auto;
48361
48402
  }
48362
48403
  `;
48363
48404
  function useCellHovered(env, gridRef) {
@@ -48533,6 +48574,11 @@ var GridOverlay = class extends Component {
48533
48574
  const y = ev.clientY - this.gridOverlayRect.y;
48534
48575
  return [this.env.model.getters.getColIndex(x), this.env.model.getters.getRowIndex(y)];
48535
48576
  }
48577
+ get isFooterVisible() {
48578
+ const { y } = this.env.model.getters.getMainViewportCoordinates();
48579
+ const { height } = this.env.model.getters.getSheetViewDimension();
48580
+ return !this.env.model.getters.isReadonly() && height - y > 46;
48581
+ }
48536
48582
  };
48537
48583
 
48538
48584
  //#endregion
@@ -56740,6 +56786,16 @@ var FormulaDependencyGraph = class {
56740
56786
  getCellsDependingOn(ranges, ignore) {
56741
56787
  const visited = this.createEmptyPositionSet();
56742
56788
  const queue = Array.from(ranges).reverse();
56789
+ const initialPositionsToRemove = this.createEmptyPositionSet();
56790
+ for (const range of ranges) {
56791
+ const zone = range.zone;
56792
+ const sheetId = range.sheetId;
56793
+ for (let col = zone.left; col <= zone.right; col++) for (let row = zone.top; row <= zone.bottom; row++) initialPositionsToRemove.add({
56794
+ sheetId,
56795
+ col,
56796
+ row
56797
+ });
56798
+ }
56743
56799
  while (queue.length > 0) {
56744
56800
  const range = queue.pop();
56745
56801
  const zone = range.zone;
@@ -56751,9 +56807,13 @@ var FormulaDependencyGraph = class {
56751
56807
  });
56752
56808
  const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
56753
56809
  const nextInQueue = {};
56754
- for (const position of impactedPositions) if (!visited.has(position) && !ignore.has(position)) {
56755
- if (!nextInQueue[position.sheetId]) nextInQueue[position.sheetId] = [];
56756
- nextInQueue[position.sheetId].push(positionToZone(position));
56810
+ for (const position of impactedPositions) {
56811
+ if (ignore.has(position)) continue;
56812
+ initialPositionsToRemove.delete(position);
56813
+ if (!visited.has(position)) {
56814
+ if (!nextInQueue[position.sheetId]) nextInQueue[position.sheetId] = [];
56815
+ nextInQueue[position.sheetId].push(positionToZone(position));
56816
+ }
56757
56817
  }
56758
56818
  for (const sheetId in nextInQueue) {
56759
56819
  const zones = recomputeZones(nextInQueue[sheetId], []);
@@ -56763,15 +56823,7 @@ var FormulaDependencyGraph = class {
56763
56823
  })));
56764
56824
  }
56765
56825
  }
56766
- for (const range of ranges) {
56767
- const zone = range.zone;
56768
- const sheetId = range.sheetId;
56769
- for (let col = zone.left; col <= zone.right; col++) for (let row = zone.top; row <= zone.bottom; row++) visited.delete({
56770
- sheetId,
56771
- col,
56772
- row
56773
- });
56774
- }
56826
+ for (const position of initialPositionsToRemove) visited.delete(position);
56775
56827
  return visited;
56776
56828
  }
56777
56829
  };
@@ -64166,7 +64218,7 @@ var InternalViewport = class {
64166
64218
  let height = lastRowEnd - this.offsetCorrectionY;
64167
64219
  if (this.canScrollVertically) {
64168
64220
  height = Math.max(height, this.viewportHeight);
64169
- if (lastRowEnd + 46 > height && !this.getters.isReadonly()) height += 46;
64221
+ if (lastRowEnd + 46 > height && !this.getters.isReadonly() && this.viewportHeight > 46) height += 46;
64170
64222
  }
64171
64223
  return {
64172
64224
  width,
@@ -66216,6 +66268,9 @@ css`
66216
66268
  position: absolute;
66217
66269
  cursor: pointer;
66218
66270
  }
66271
+ .o-grid.o-dashboard-grid {
66272
+ background: #ffffff;
66273
+ }
66219
66274
  `;
66220
66275
  var SpreadsheetDashboard = class extends Component {
66221
66276
  static template = "o-spreadsheet-SpreadsheetDashboard";
@@ -66741,11 +66796,7 @@ css`
66741
66796
  /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
66742
66797
  .o-composer:empty:not(:focus):not(.active)::before,
66743
66798
  &.o-topbar-composer-readonly .o-composer:empty::before {
66744
- content: url("data:image/svg+xml,${encodeURIComponent(`
66745
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
66746
- <path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
66747
- </svg>
66748
- `)}");
66799
+ content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
66749
66800
  position: relative;
66750
66801
  top: 20%;
66751
66802
  }
@@ -67899,11 +67950,7 @@ css`
67899
67950
  appearance: none;
67900
67951
  -webkit-appearance: none;
67901
67952
  -moz-appearance: none;
67902
- background: transparent url("data:image/svg+xml,${encodeURIComponent(`
67903
- <svg xmlns='http://www.w3.org/2000/svg' width='7' height='4' viewBox='0 0 7 4'>
67904
- <polygon fill='%23374151' points='3.5 4 7 0 0 0'/>
67905
- </svg>
67906
- `)}")
67953
+ background: transparent url("data:image/svg+xml,${encodeURIComponent(CARET_DOWN_SVG)}")
67907
67954
  no-repeat right center;
67908
67955
  text-overflow: ellipsis;
67909
67956
 
@@ -72294,6 +72341,6 @@ const chartHelpers = {
72294
72341
  //#endregion
72295
72342
  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, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
72296
72343
 
72297
- __info__.version = "18.3.60";
72298
- __info__.date = "2026-08-21T15:28:06.523Z";
72299
- __info__.hash = "ab0ffc5";
72344
+ __info__.version = "18.3.62";
72345
+ __info__.date = "2026-09-04T07:18:11.182Z";
72346
+ __info__.hash = "aaaa064";
@@ -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.3.60
6
- * @date 2026-08-21T15:28:06.523Z
7
- * @hash ab0ffc5
5
+ * @version 18.3.62
6
+ * @date 2026-09-04T07:18:11.182Z
7
+ * @hash aaaa064
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -17686,10 +17686,10 @@ stores.inject(MyMetaStore, storeInstance);
17686
17686
  case "bar":
17687
17687
  case "line":
17688
17688
  case "radar":
17689
- options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
17689
+ options.horizontal ? drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: true }) : drawLineOrBarOrRadarChartValues(chart, options, ctx);
17690
17690
  break;
17691
17691
  case "funnel":
17692
- drawHorizontalBarChartValues(chart, options, ctx);
17692
+ drawHorizontalBarChartValues(chart, options, ctx, { offsetFromAxisOrigin: false });
17693
17693
  break;
17694
17694
  }
17695
17695
  ctx.restore();
@@ -17730,7 +17730,7 @@ stores.inject(MyMetaStore, storeInstance);
17730
17730
  }
17731
17731
  }
17732
17732
  }
17733
- function drawHorizontalBarChartValues(chart, options, ctx) {
17733
+ function drawHorizontalBarChartValues(chart, options, ctx, args) {
17734
17734
  const textsPositions = {};
17735
17735
  for (const dataset of chart._metasets) {
17736
17736
  if (isTrendLineAxis(dataset.xAxisID)) return;
@@ -17745,7 +17745,7 @@ stores.inject(MyMetaStore, storeInstance);
17745
17745
  const distanceFromAxisOrigin = Math.abs(point.x - xZeroLine);
17746
17746
  const PADDING = 3;
17747
17747
  let xPosition;
17748
- if (distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
17748
+ if (args.offsetFromAxisOrigin && distanceFromAxisOrigin < textWidth) xPosition = value < 0 ? xZeroLine - textWidth / 2 - PADDING : xZeroLine + textWidth / 2 + PADDING;
17749
17749
  else xPosition = value < 0 ? point.x + point.width / 2 : point.x - point.width / 2;
17750
17750
  if (!textsPositions[yPosition]) textsPositions[yPosition] = [];
17751
17751
  for (const otherPosition of textsPositions[yPosition]) if (Math.abs(otherPosition - xPosition) < textWidth) xPosition = value < 0 ? otherPosition - textWidth - PADDING : otherPosition + textWidth + PADDING;
@@ -17978,7 +17978,8 @@ stores.inject(MyMetaStore, storeInstance);
17978
17978
  data,
17979
17979
  hidden,
17980
17980
  borderColor,
17981
- backgroundColor: borderColor
17981
+ backgroundColor: borderColor,
17982
+ pointBackgroundColor: borderColor
17982
17983
  };
17983
17984
  if (fill) {
17984
17985
  dataset.backgroundColor = setColorAlpha(borderColor, LINE_FILL_TRANSPARENCY);
@@ -31035,12 +31036,48 @@ stores.inject(MyMetaStore, storeInstance);
31035
31036
  } };
31036
31037
 
31037
31038
  //#endregion
31038
- //#region src/components/side_panel/components/checkbox/checkbox.ts
31039
+ //#region src/components/icons/raw_svgs.ts
31040
+ /**
31041
+ * SVG markup used in `css` tagged templates as `data:image/svg+xml` URIs.
31042
+ *
31043
+ * Keep these values in a separate module so Rolldown references them instead
31044
+ * of inlining them into template literals. Inlining produces nested template
31045
+ * literals, which the downstream `rjsmin` minifier cannot parse correctly
31046
+ * because it relies on regular expressions.
31047
+ *
31048
+ * Do not inline these constants.
31049
+ */
31039
31050
  const CHECK_SVG = `
31040
31051
  <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'>
31041
31052
  <path fill='none' stroke='#FFF' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/>
31042
31053
  </svg>
31043
31054
  `;
31055
+ const CIRCLE_SVG = `
31056
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'>
31057
+ <circle r="2" fill="#FFF"/>
31058
+ </svg>
31059
+ `;
31060
+ const FX_SVG = `
31061
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
31062
+ <path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
31063
+ </svg>
31064
+ `;
31065
+ const TRANSPARENT_BACKGROUND_SVG = `
31066
+ <svg xmlns="http://www.w3.org/2000/svg" width="10" height="10">
31067
+ <path fill="#d9d9d9" d="M5 5h5v5H5zH0V0h5"/>
31068
+ </svg>
31069
+ `;
31070
+ const CURSOR_SVG = `
31071
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="16"><path d="M6.5.4c1.3-.8 2.9-.1 3.8 1.4l2.9 5.1c.2.4.9 1.6-.4 2.3l-1.6.9 1.8 3.1c.2.4.1 1-.2 1.2l-1.6 1c-.3.1-.9 0-1.1-.4l-1.8-3.1-1.6 1c-.6.4-1.7 0-2.2-.8L0 4.3"/><path fill="#fff" d="M9.1 2a1.4 1.1 60 0 0-1.7-.6L5.5 2.5l.9 1.6-1 .6-.9-1.6-.6.4 1.8 3.1-1.3.7-1.8-3.1-1 .6 3.8 6.6 6.8-3.98M3.9 8.8 10.82 5l.795 1.4-6.81 3.96"/></svg>
31072
+ `;
31073
+ const CARET_DOWN_SVG = `
31074
+ <svg xmlns='http://www.w3.org/2000/svg' width='7' height='4' viewBox='0 0 7 4'>
31075
+ <polygon fill='%23374151' points='3.5 4 7 0 0 0'/>
31076
+ </svg>
31077
+ `;
31078
+
31079
+ //#endregion
31080
+ //#region src/components/side_panel/components/checkbox/checkbox.ts
31044
31081
  const CHECKBOX_WIDTH = 14;
31045
31082
  css`
31046
31083
  label.o-checkbox {
@@ -37320,14 +37357,16 @@ stores.inject(MyMetaStore, storeInstance);
37320
37357
  border-radius: 8px;
37321
37358
 
37322
37359
  &:checked {
37323
- background: url("data:image/svg+xml,${encodeURIComponent(`
37324
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'>
37325
- <circle r="2" fill="#FFF"/>
37326
- </svg>
37327
- `)}");
37360
+ background: url("data:image/svg+xml,${encodeURIComponent(CIRCLE_SVG)}");
37328
37361
  background-color: ${ACTION_COLOR};
37329
37362
  border-color: ${ACTION_COLOR};
37330
37363
  }
37364
+
37365
+ &:focus {
37366
+ outline: none;
37367
+ box-shadow: 0 0 0 0.25rem rgba(113, 75, 103, 0.25);
37368
+ border-color: ${ACTION_COLOR};
37369
+ }
37331
37370
  }
37332
37371
  }
37333
37372
  `;
@@ -37355,11 +37394,7 @@ stores.inject(MyMetaStore, storeInstance);
37355
37394
  cursor: pointer;
37356
37395
  border: 1px solid ${GRAY_300};
37357
37396
  background-position: 1px 1px;
37358
- background-image: url("data:image/svg+xml,${encodeURIComponent(`
37359
- <svg xmlns="http://www.w3.org/2000/svg" width="10" height="10">
37360
- <path fill="#d9d9d9" d="M5 5h5v5H5zH0V0h5"/>
37361
- </svg>
37362
- `)}");
37397
+ background-image: url("data:image/svg+xml,${encodeURIComponent(TRANSPARENT_BACKGROUND_SVG)}");
37363
37398
  }
37364
37399
  `;
37365
37400
  var RoundColorPicker = class extends _odoo_owl.Component {
@@ -38364,9 +38399,10 @@ stores.inject(MyMetaStore, storeInstance);
38364
38399
  compositionActive = false;
38365
38400
  spreadsheetRect = useSpreadsheetRect();
38366
38401
  lastHoveredTokenIndex = void 0;
38367
- debouncedHover = debounce((tokenIndex, hoveredRect) => {
38402
+ debouncedHover = debounce((tokenIndex, composerContent, hoveredRect) => {
38368
38403
  const selection = this.contentHelper.getCurrentSelection();
38369
- if (selection.start !== selection.end) return;
38404
+ const currentContent = this.props.composerStore.currentContent;
38405
+ if (selection.start !== selection.end || currentContent !== composerContent) return;
38370
38406
  const currentHoveredContext = this.props.composerStore.hoveredTokens;
38371
38407
  this.props.composerStore.hoverToken(tokenIndex);
38372
38408
  if (!deepEquals(currentHoveredContext, this.props.composerStore.hoveredTokens)) this.composerState.hoveredRect = hoveredRect;
@@ -38708,7 +38744,8 @@ stores.inject(MyMetaStore, storeInstance);
38708
38744
  onTokenHover(tokenIndex, hoveredRect) {
38709
38745
  if (this.lastHoveredTokenIndex !== tokenIndex) {
38710
38746
  this.lastHoveredTokenIndex = tokenIndex;
38711
- this.debouncedHover(tokenIndex, hoveredRect);
38747
+ const composerContent = this.props.composerStore.currentContent;
38748
+ this.debouncedHover(tokenIndex, composerContent, hoveredRect);
38712
38749
  }
38713
38750
  }
38714
38751
  /**
@@ -44976,7 +45013,13 @@ stores.inject(MyMetaStore, storeInstance);
44976
45013
  }
44977
45014
  onSelectionChanged(ranges) {
44978
45015
  this.state.rangeHasChanged = true;
44979
- this.state.range = ranges[0];
45016
+ if (ranges.length === 0) {
45017
+ this.state.range = void 0;
45018
+ return;
45019
+ }
45020
+ const sheetId = this.env.model.getters.getActiveSheetId();
45021
+ const range = this.env.model.getters.getRangeFromSheetXC(sheetId, ranges[0]);
45022
+ this.state.range = this.env.model.getters.getRangeString(range, "forceSheetReference", { useBoundedReference: true });
44980
45023
  }
44981
45024
  onSelectionConfirmed() {
44982
45025
  if (this.state.range) {
@@ -48357,9 +48400,7 @@ stores.inject(MyMetaStore, storeInstance);
48357
48400
  //#region src/components/grid_overlay/grid_overlay.ts
48358
48401
  css`
48359
48402
  .o-paint-format-cursor {
48360
- cursor: url("data:image/svg+xml,${encodeURIComponent(`
48361
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="16"><path d="M6.5.4c1.3-.8 2.9-.1 3.8 1.4l2.9 5.1c.2.4.9 1.6-.4 2.3l-1.6.9 1.8 3.1c.2.4.1 1-.2 1.2l-1.6 1c-.3.1-.9 0-1.1-.4l-1.8-3.1-1.6 1c-.6.4-1.7 0-2.2-.8L0 4.3"/><path fill="#fff" d="M9.1 2a1.4 1.1 60 0 0-1.7-.6L5.5 2.5l.9 1.6-1 .6-.9-1.6-.6.4 1.8 3.1-1.3.7-1.8-3.1-1 .6 3.8 6.6 6.8-3.98M3.9 8.8 10.82 5l.795 1.4-6.81 3.96"/></svg>
48362
- `)}"), auto;
48403
+ cursor: url("data:image/svg+xml,${encodeURIComponent(CURSOR_SVG)}"), auto;
48363
48404
  }
48364
48405
  `;
48365
48406
  function useCellHovered(env, gridRef) {
@@ -48535,6 +48576,11 @@ stores.inject(MyMetaStore, storeInstance);
48535
48576
  const y = ev.clientY - this.gridOverlayRect.y;
48536
48577
  return [this.env.model.getters.getColIndex(x), this.env.model.getters.getRowIndex(y)];
48537
48578
  }
48579
+ get isFooterVisible() {
48580
+ const { y } = this.env.model.getters.getMainViewportCoordinates();
48581
+ const { height } = this.env.model.getters.getSheetViewDimension();
48582
+ return !this.env.model.getters.isReadonly() && height - y > 46;
48583
+ }
48538
48584
  };
48539
48585
 
48540
48586
  //#endregion
@@ -56742,6 +56788,16 @@ stores.inject(MyMetaStore, storeInstance);
56742
56788
  getCellsDependingOn(ranges, ignore) {
56743
56789
  const visited = this.createEmptyPositionSet();
56744
56790
  const queue = Array.from(ranges).reverse();
56791
+ const initialPositionsToRemove = this.createEmptyPositionSet();
56792
+ for (const range of ranges) {
56793
+ const zone = range.zone;
56794
+ const sheetId = range.sheetId;
56795
+ for (let col = zone.left; col <= zone.right; col++) for (let row = zone.top; row <= zone.bottom; row++) initialPositionsToRemove.add({
56796
+ sheetId,
56797
+ col,
56798
+ row
56799
+ });
56800
+ }
56745
56801
  while (queue.length > 0) {
56746
56802
  const range = queue.pop();
56747
56803
  const zone = range.zone;
@@ -56753,9 +56809,13 @@ stores.inject(MyMetaStore, storeInstance);
56753
56809
  });
56754
56810
  const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
56755
56811
  const nextInQueue = {};
56756
- for (const position of impactedPositions) if (!visited.has(position) && !ignore.has(position)) {
56757
- if (!nextInQueue[position.sheetId]) nextInQueue[position.sheetId] = [];
56758
- nextInQueue[position.sheetId].push(positionToZone(position));
56812
+ for (const position of impactedPositions) {
56813
+ if (ignore.has(position)) continue;
56814
+ initialPositionsToRemove.delete(position);
56815
+ if (!visited.has(position)) {
56816
+ if (!nextInQueue[position.sheetId]) nextInQueue[position.sheetId] = [];
56817
+ nextInQueue[position.sheetId].push(positionToZone(position));
56818
+ }
56759
56819
  }
56760
56820
  for (const sheetId in nextInQueue) {
56761
56821
  const zones = recomputeZones(nextInQueue[sheetId], []);
@@ -56765,15 +56825,7 @@ stores.inject(MyMetaStore, storeInstance);
56765
56825
  })));
56766
56826
  }
56767
56827
  }
56768
- for (const range of ranges) {
56769
- const zone = range.zone;
56770
- const sheetId = range.sheetId;
56771
- for (let col = zone.left; col <= zone.right; col++) for (let row = zone.top; row <= zone.bottom; row++) visited.delete({
56772
- sheetId,
56773
- col,
56774
- row
56775
- });
56776
- }
56828
+ for (const position of initialPositionsToRemove) visited.delete(position);
56777
56829
  return visited;
56778
56830
  }
56779
56831
  };
@@ -64168,7 +64220,7 @@ stores.inject(MyMetaStore, storeInstance);
64168
64220
  let height = lastRowEnd - this.offsetCorrectionY;
64169
64221
  if (this.canScrollVertically) {
64170
64222
  height = Math.max(height, this.viewportHeight);
64171
- if (lastRowEnd + 46 > height && !this.getters.isReadonly()) height += 46;
64223
+ if (lastRowEnd + 46 > height && !this.getters.isReadonly() && this.viewportHeight > 46) height += 46;
64172
64224
  }
64173
64225
  return {
64174
64226
  width,
@@ -66218,6 +66270,9 @@ stores.inject(MyMetaStore, storeInstance);
66218
66270
  position: absolute;
66219
66271
  cursor: pointer;
66220
66272
  }
66273
+ .o-grid.o-dashboard-grid {
66274
+ background: #ffffff;
66275
+ }
66221
66276
  `;
66222
66277
  var SpreadsheetDashboard = class extends _odoo_owl.Component {
66223
66278
  static template = "o-spreadsheet-SpreadsheetDashboard";
@@ -66743,11 +66798,7 @@ stores.inject(MyMetaStore, storeInstance);
66743
66798
  /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
66744
66799
  .o-composer:empty:not(:focus):not(.active)::before,
66745
66800
  &.o-topbar-composer-readonly .o-composer:empty::before {
66746
- content: url("data:image/svg+xml,${encodeURIComponent(`
66747
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
66748
- <path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
66749
- </svg>
66750
- `)}");
66801
+ content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
66751
66802
  position: relative;
66752
66803
  top: 20%;
66753
66804
  }
@@ -67901,11 +67952,7 @@ stores.inject(MyMetaStore, storeInstance);
67901
67952
  appearance: none;
67902
67953
  -webkit-appearance: none;
67903
67954
  -moz-appearance: none;
67904
- background: transparent url("data:image/svg+xml,${encodeURIComponent(`
67905
- <svg xmlns='http://www.w3.org/2000/svg' width='7' height='4' viewBox='0 0 7 4'>
67906
- <polygon fill='%23374151' points='3.5 4 7 0 0 0'/>
67907
- </svg>
67908
- `)}")
67955
+ background: transparent url("data:image/svg+xml,${encodeURIComponent(CARET_DOWN_SVG)}")
67909
67956
  no-repeat right center;
67910
67957
  text-overflow: ellipsis;
67911
67958
 
@@ -72343,8 +72390,8 @@ exports.stores = stores;
72343
72390
  exports.tokenColors = tokenColors;
72344
72391
  exports.tokenize = tokenize;
72345
72392
 
72346
- __info__.version = "18.3.60";
72347
- __info__.date = "2026-08-21T15:28:06.523Z";
72348
- __info__.hash = "ab0ffc5";
72393
+ __info__.version = "18.3.62";
72394
+ __info__.date = "2026-09-04T07:18:11.182Z";
72395
+ __info__.hash = "aaaa064";
72349
72396
 
72350
72397
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);