@odoo/o-spreadsheet 19.4.0-alpha.11 → 19.4.0-alpha.13

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 19.4.0-alpha.11
6
- * @date 2026-06-03T11:42:34.595Z
7
- * @hash 6f35bc7
5
+ * @version 19.4.0-alpha.13
6
+ * @date 2026-06-06T09:34:53.140Z
7
+ * @hash af3c199
8
8
  */
9
9
 
10
10
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
@@ -4323,6 +4323,7 @@ const DEFAULT_LOCALE_DIGIT_GROUPING = "[3,0]";
4323
4323
  //#endregion
4324
4324
  //#region src/helpers/format/format_tokenizer.ts
4325
4325
  function tokenizeFormat(str) {
4326
+ str = str.replace(/\s/g, " ");
4326
4327
  const chars = new TokenizingChars(str);
4327
4328
  const result = [];
4328
4329
  let currentFormatPart = [];
@@ -10557,7 +10558,7 @@ function getFunnelChartScales(definition, args) {
10557
10558
  };
10558
10559
  }
10559
10560
  function getGeoChartProjection(projection) {
10560
- if (projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
10561
+ if (globalThis.ChartGeo && projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
10561
10562
  return projection;
10562
10563
  }
10563
10564
  function getChartAxisTitleRuntime(design) {
@@ -10570,7 +10571,7 @@ function getChartAxisTitleRuntime(design) {
10570
10571
  font: {
10571
10572
  style: italic ? "italic" : "normal",
10572
10573
  weight: bold ? "bold" : "normal",
10573
- size: design.title.fontSize ?? 12
10574
+ size: fontSizeInPixels(design.title.fontSize ?? 12)
10574
10575
  },
10575
10576
  align: align === "left" ? "start" : align === "right" ? "end" : "center"
10576
10577
  };
@@ -11192,7 +11193,7 @@ function getTextStyle(design, defaultDesign) {
11192
11193
  font: {
11193
11194
  weight: design?.bold ?? defaultDesign?.bold ? "bold" : "normal",
11194
11195
  style: design?.italic ?? defaultDesign?.italic ? "italic" : "normal",
11195
- size: design?.fontSize ?? defaultDesign?.fontSize
11196
+ size: fontSizeInPixels(design?.fontSize ?? defaultDesign.fontSize)
11196
11197
  }
11197
11198
  };
11198
11199
  }
@@ -12128,35 +12129,35 @@ var ScorecardChartConfigBuilder = class {
12128
12129
  if (this.runtime.progressBar) baselineValueFontSize /= 1.5;
12129
12130
  return {
12130
12131
  title: {
12131
- font: getDefaultContextFont(this.runtime.title.fontSize ?? 14, this.runtime.title.bold, this.runtime.title.italic),
12132
+ font: getDefaultContextFont(fontSizeInPixels(this.runtime.title.fontSize ?? 14), this.runtime.title.bold, this.runtime.title.italic),
12132
12133
  color: this.runtime.title.color ?? this.secondaryFontColor
12133
12134
  },
12134
12135
  keyValue: {
12135
12136
  color: this.runtime.keyValueStyle?.textColor || this.runtime.fontColor,
12136
- font: getDefaultContextFont(keyValueFontSize, this.runtime.keyValueStyle?.bold, this.runtime.keyValueStyle?.italic),
12137
+ font: getDefaultContextFont(fontSizeInPixels(keyValueFontSize), this.runtime.keyValueStyle?.bold, this.runtime.keyValueStyle?.italic),
12137
12138
  strikethrough: this.runtime.keyValueStyle?.strikethrough,
12138
12139
  underline: this.runtime.keyValueStyle?.underline
12139
12140
  },
12140
12141
  keyDescr: {
12141
12142
  color: this.runtime.keyValueDescrStyle?.textColor || this.runtime.fontColor,
12142
- font: getDefaultContextFont(keyValueDescrFontSize, this.runtime.keyValueDescrStyle?.bold, this.runtime.keyValueDescrStyle?.italic),
12143
+ font: getDefaultContextFont(fontSizeInPixels(keyValueDescrFontSize), this.runtime.keyValueDescrStyle?.bold, this.runtime.keyValueDescrStyle?.italic),
12143
12144
  strikethrough: this.runtime.keyValueDescrStyle?.strikethrough,
12144
12145
  underline: this.runtime.keyValueDescrStyle?.underline
12145
12146
  },
12146
12147
  baselineValue: {
12147
- font: getDefaultContextFont(baselineValueFontSize, this.runtime.baselineStyle?.bold, this.runtime.baselineStyle?.italic),
12148
+ font: getDefaultContextFont(fontSizeInPixels(baselineValueFontSize), this.runtime.baselineStyle?.bold, this.runtime.baselineStyle?.italic),
12148
12149
  strikethrough: this.runtime.baselineStyle?.strikethrough,
12149
12150
  underline: this.runtime.baselineStyle?.underline,
12150
12151
  color: this.runtime.baselineColor || this.runtime.baselineStyle?.textColor || this.secondaryFontColor
12151
12152
  },
12152
12153
  baselineDescr: {
12153
- font: getDefaultContextFont(baselineDescrFontSize, this.runtime.baselineDescrStyle?.bold, this.runtime.baselineDescrStyle?.italic),
12154
+ font: getDefaultContextFont(fontSizeInPixels(baselineDescrFontSize), this.runtime.baselineDescrStyle?.bold, this.runtime.baselineDescrStyle?.italic),
12154
12155
  strikethrough: this.runtime.baselineDescrStyle?.strikethrough,
12155
12156
  underline: this.runtime.baselineDescrStyle?.underline,
12156
12157
  color: this.runtime.baselineDescrStyle?.textColor ?? this.secondaryFontColor
12157
12158
  },
12158
12159
  baselineArrow: this.baselineArrow === "neutral" || this.runtime.progressBar ? void 0 : {
12159
- size: this.keyValue ? .8 * baselineValueFontSize : 0,
12160
+ size: this.keyValue ? .8 * fontSizeInPixels(baselineValueFontSize) : 0,
12160
12161
  color: this.runtime.baselineColor || this.runtime.baselineStyle?.textColor || this.secondaryFontColor
12161
12162
  }
12162
12163
  };
@@ -12366,7 +12367,7 @@ function drawInflectionValues(ctx, config) {
12366
12367
  function drawTitle(ctx, config) {
12367
12368
  ctx.save();
12368
12369
  const title = config.title;
12369
- ctx.font = getDefaultContextFont(title.fontSize, title.bold, title.italic);
12370
+ ctx.font = getDefaultContextFont(fontSizeInPixels(title.fontSize), title.bold, title.italic);
12370
12371
  ctx.textBaseline = "middle";
12371
12372
  ctx.fillStyle = title.color;
12372
12373
  ctx.fillText(title.label, title.textPosition.x, title.textPosition.y);
@@ -12400,8 +12401,8 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
12400
12401
  const inflectionValues = getInflectionValues(runtime, gaugeRect, textColor, ctx);
12401
12402
  let x = 0, titleWidth = 0, titleHeight = 0;
12402
12403
  if (runtime.title.text) ({width: titleWidth, height: titleHeight} = computeTextDimension(ctx, runtime.title.text, {
12403
- fontSize: 16,
12404
- ...runtime.title
12404
+ ...runtime.title,
12405
+ fontSize: fontSizeInPixels(runtime.title.fontSize ?? 16)
12405
12406
  }, "px"));
12406
12407
  switch (runtime.title.align) {
12407
12408
  case "right":
@@ -13924,10 +13925,10 @@ var GaugeChartComponent = class extends Component {
13924
13925
  let animation = null;
13925
13926
  let lastRuntime = void 0;
13926
13927
  useLayoutEffect(() => {
13927
- if (this.env.isDashboard() && lastRuntime === void 0 && this.animationStore?.animationPlayed[this.animationChartId] !== "gauge") {
13928
+ if (this.env.model.getters.isDashboard() && lastRuntime === void 0 && this.animationStore?.animationPlayed[this.animationChartId] !== "gauge") {
13928
13929
  animation = this.drawGaugeWithAnimation();
13929
13930
  this.animationStore?.disableAnimationForChart(this.animationChartId, "gauge");
13930
- } else if (this.env.isDashboard() && lastRuntime !== void 0 && !deepEquals(this.runtime, lastRuntime)) {
13931
+ } else if (this.env.model.getters.isDashboard() && lastRuntime !== void 0 && !deepEquals(this.runtime, lastRuntime)) {
13931
13932
  animation = this.drawGaugeWithAnimation();
13932
13933
  this.animationStore?.disableAnimationForChart(this.animationChartId, "gauge");
13933
13934
  } else {
@@ -15218,10 +15219,12 @@ var CarouselFigure = class extends Component {
15218
15219
  return this.carousel.title?.text ?? "";
15219
15220
  }
15220
15221
  get titleStyle() {
15221
- return cssPropertiesToCss(cellTextStyleToCss(chartStyleToCellStyle({
15222
+ const style = {
15222
15223
  ...DEFAULT_CAROUSEL_TITLE_STYLE,
15223
15224
  ...this.carousel.title
15224
- })));
15225
+ };
15226
+ style.fontSize = fontSizeInPixels(style.fontSize ?? 16);
15227
+ return cssPropertiesToCss(cellTextStyleToCss(chartStyleToCellStyle(style)));
15225
15228
  }
15226
15229
  updateTabsVisibility() {
15227
15230
  const tabsContainerEl = this.carouselTabsRef();
@@ -15384,7 +15387,7 @@ var FigureComponent = class extends Component {
15384
15387
  return figureRegistry;
15385
15388
  }
15386
15389
  getBorderWidth() {
15387
- if (this.env.isDashboard()) return 0;
15390
+ if (this.env.model.getters.isDashboard()) return 0;
15388
15391
  return this.isSelected ? ACTIVE_BORDER_WIDTH : this.borderWidth;
15389
15392
  }
15390
15393
  getBorderStyle(position) {
@@ -15526,7 +15529,7 @@ var FigureComponent = class extends Component {
15526
15529
  };
15527
15530
  }
15528
15531
  onContextMenu(ev) {
15529
- if (this.env.isDashboard()) return;
15532
+ if (this.env.model.getters.isDashboard()) return;
15530
15533
  const zoomedMouseEvent = withZoom(this.env, ev);
15531
15534
  this.openContextMenu({
15532
15535
  x: zoomedMouseEvent.clientX,
@@ -15552,7 +15555,7 @@ var FigureComponent = class extends Component {
15552
15555
  if (el) for (const property in properties) el.style.setProperty(property, properties[property] || null);
15553
15556
  }
15554
15557
  get isFigureResizable() {
15555
- return this.isSelected && !this.env.isMobile() && !this.env.isDashboard() && !this.env.model.getters.isCurrentSheetLocked();
15558
+ return this.isSelected && !this.env.isMobile() && !this.env.model.getters.isDashboard() && !this.env.model.getters.isCurrentSheetLocked();
15556
15559
  }
15557
15560
  };
15558
15561
 
@@ -24802,6 +24805,18 @@ var ColorPicker = class extends Component {
24802
24805
  isSameColor(color1, color2) {
24803
24806
  return isSameColor(color1, color2);
24804
24807
  }
24808
+ get canUseEyeDropper() {
24809
+ return !!globalThis.EyeDropper && !this.env.model.getters.isDarkMode();
24810
+ }
24811
+ async activateEyedropper() {
24812
+ if (!globalThis.EyeDropper) return;
24813
+ try {
24814
+ const result = await new globalThis.EyeDropper().open();
24815
+ if (result && result.sRGBHex) this.props.onColorPicked(toHex(result.sRGBHex));
24816
+ } catch (error) {
24817
+ if (error.name !== "AbortError") throw error;
24818
+ }
24819
+ }
24805
24820
  };
24806
24821
 
24807
24822
  //#endregion
@@ -28481,7 +28496,7 @@ function getSunburstShowValues(definition, args) {
28481
28496
  showLabels: definition.showLabels ?? SunburstChartDefaults.showLabels,
28482
28497
  showValues: definition.showValues ?? SunburstChartDefaults.showValues,
28483
28498
  style: {
28484
- fontSize: definition.valuesDesign?.fontSize ?? SunburstChartDefaults.valuesDesign.fontSize,
28499
+ fontSize: fontSizeInPixels(definition.valuesDesign?.fontSize ?? SunburstChartDefaults.valuesDesign.fontSize),
28485
28500
  align: definition.valuesDesign?.align ?? SunburstChartDefaults.valuesDesign.align,
28486
28501
  bold: definition.valuesDesign?.bold ?? SunburstChartDefaults.valuesDesign.bold,
28487
28502
  italic: definition.valuesDesign?.italic ?? SunburstChartDefaults.valuesDesign.italic,
@@ -28536,7 +28551,7 @@ function getChartTitle({ title, legendPosition, background }, getters) {
28536
28551
  color: title?.color ?? fontColor,
28537
28552
  align: title.align === "center" ? "center" : title.align === "right" ? "end" : "start",
28538
28553
  font: {
28539
- size: title.fontSize ?? 16,
28554
+ size: fontSizeInPixels(title.fontSize ?? 16),
28540
28555
  weight: title.bold ? "bold" : "normal",
28541
28556
  style: title.italic ? "italic" : "normal"
28542
28557
  },
@@ -38785,7 +38800,8 @@ var PivotDimensionOrder = class extends Component {
38785
38800
  static template = "o-spreadsheet-PivotDimensionOrder";
38786
38801
  props = (0, _odoo_owl.props)({
38787
38802
  dimension: types$6.PivotDimension(),
38788
- onUpdated: types$6.function([types$6.PivotDimension(), types$6.instanceOf(InputEvent)])
38803
+ onUpdated: types$6.function([types$6.PivotDimension(), types$6.instanceOf(InputEvent)]),
38804
+ "isMeasureSorted?": types$6.boolean()
38789
38805
  });
38790
38806
  static components = { Select };
38791
38807
  get orderSelectOptions() {
@@ -38796,12 +38812,20 @@ var PivotDimensionOrder = class extends Component {
38796
38812
  value: "desc",
38797
38813
  label: _t("Descending")
38798
38814
  }];
38815
+ if (this.props.isMeasureSorted) options.unshift({
38816
+ value: "measures",
38817
+ label: _t("Sorted by measure")
38818
+ });
38799
38819
  if (this.props.dimension.type === "date") return options;
38800
38820
  return [{
38801
38821
  value: "",
38802
38822
  label: _t("Unsorted")
38803
38823
  }, ...options];
38804
38824
  }
38825
+ get selectedValue() {
38826
+ if (this.props.isMeasureSorted) return "measures";
38827
+ return this.props.dimension.order || "";
38828
+ }
38805
38829
  };
38806
38830
 
38807
38831
  //#endregion
@@ -39172,7 +39196,8 @@ var PivotLayoutConfigurator = class extends Component {
39172
39196
  return this.env.model.getters.getPivotCoreDefinition(this.props.pivotId).customFields?.[dimension.nameWithGranularity];
39173
39197
  }
39174
39198
  updateOrder(updateDimension, order) {
39175
- const { rows, columns } = this.props.definition;
39199
+ const { rows, columns, sortedColumn } = this.props.definition;
39200
+ const isRow = rows.some((row) => row.nameWithGranularity === updateDimension.nameWithGranularity);
39176
39201
  this.props.onDimensionsUpdated({
39177
39202
  rows: rows.map((row) => {
39178
39203
  if (row.nameWithGranularity === updateDimension.nameWithGranularity) return {
@@ -39187,7 +39212,8 @@ var PivotLayoutConfigurator = class extends Component {
39187
39212
  order: order || void 0
39188
39213
  };
39189
39214
  return col;
39190
- })
39215
+ }),
39216
+ sortedColumn: isRow ? void 0 : sortedColumn
39191
39217
  });
39192
39218
  }
39193
39219
  updateGranularity(dimension, granularity) {
@@ -39213,6 +39239,9 @@ var PivotLayoutConfigurator = class extends Component {
39213
39239
  const possibleValues = this.env.model.getters.getPivot(this.props.pivotId).getPossibleFieldValues(dimension);
39214
39240
  return possibleValues.length > 100 ? _t("This dimension contains a lot of values (%s), and might slow down the pivot table.", possibleValues.length) : void 0;
39215
39241
  }
39242
+ get hasSortedColumn() {
39243
+ return !!this.props.definition.sortedColumn;
39244
+ }
39216
39245
  };
39217
39246
 
39218
39247
  //#endregion
@@ -59011,9 +59040,11 @@ var PivotUIPlugin = class extends CoreViewPlugin {
59011
59040
  this.refreshPivot(cmd.id);
59012
59041
  break;
59013
59042
  case "ADD_PIVOT":
59043
+ this.unusedPivotsInFormulas?.push(cmd.pivotId);
59014
59044
  this.setupPivot(cmd.pivotId);
59015
59045
  break;
59016
59046
  case "DUPLICATE_PIVOT":
59047
+ this.unusedPivotsInFormulas?.push(cmd.newPivotId);
59017
59048
  this.setupPivot(cmd.newPivotId);
59018
59049
  break;
59019
59050
  case "UPDATE_PIVOT":
@@ -59205,8 +59236,8 @@ var PivotUIPlugin = class extends CoreViewPlugin {
59205
59236
  }
59206
59237
  }
59207
59238
  for (const pivotId of this.getters.getPivotIds()) {
59208
- const pivot = this.getters.getPivot(pivotId);
59209
- for (const measure of pivot.definition.measures) if (measure.computedBy) {
59239
+ const pivot = this.getters.getPivotCoreDefinition(pivotId);
59240
+ for (const measure of pivot.measures) if (measure.computedBy) {
59210
59241
  const { sheetId } = measure.computedBy;
59211
59242
  const formula = this.getters.getMeasureCompiledFormula(pivotId, measure);
59212
59243
  const relatedPivotIds = this.getPivotIdsFromFormula(sheetId, formula);
@@ -62548,6 +62579,7 @@ var GeoFeaturePlugin = class extends UIPlugin {
62548
62579
  convertToGeoJson(json) {
62549
62580
  if (!json) return null;
62550
62581
  if (json.type === "Topology") {
62582
+ if (!globalThis.ChartGeo) return null;
62551
62583
  const features = globalThis.ChartGeo.topojson.feature(json, Object.values(json.objects)[0]);
62552
62584
  return features.type === "FeatureCollection" ? features.features : [features];
62553
62585
  } else if (json.type === "FeatureCollection") return json.features;
@@ -70968,7 +71000,7 @@ var Spreadsheet = class extends Component {
70968
71000
  properties["color-scheme"] = this.props.model.getters.isDarkMode() ? "dark" : "light";
70969
71001
  if (this.state.printModeEnabled) properties["display"] = `block`;
70970
71002
  else {
70971
- if (this.env.isDashboard()) properties["grid-template-rows"] = `auto`;
71003
+ if (this.env.model.getters.isDashboard()) properties["grid-template-rows"] = `auto`;
70972
71004
  else properties["grid-template-rows"] = `min-content auto min-content`;
70973
71005
  properties["grid-template-columns"] = `auto ${this.sidePanel.mainPanel ? `${this.sidePanel.totalPanelSize || 350}px` : "auto"}`;
70974
71006
  }
@@ -70996,7 +71028,6 @@ var Spreadsheet = class extends Component {
70996
71028
  imageProvider: fileStore ? new ImageProvider(fileStore) : void 0,
70997
71029
  loadCurrencies: this.model.config.external.loadCurrencies,
70998
71030
  loadLocales: this.model.config.external.loadLocales,
70999
- isDashboard: () => this.model.getters.isDashboard(),
71000
71031
  openSidePanel: this.sidePanel.open.bind(this.sidePanel),
71001
71032
  replaceSidePanel: this.sidePanel.replace.bind(this.sidePanel),
71002
71033
  toggleSidePanel: this.sidePanel.toggle.bind(this.sidePanel),
@@ -86245,7 +86276,8 @@ const registries = {
86245
86276
  pivotToFunctionValueRegistry,
86246
86277
  migrationStepRegistry,
86247
86278
  chartJsExtensionRegistry,
86248
- onIterationEndEvaluationRegistry
86279
+ onIterationEndEvaluationRegistry,
86280
+ specificRangeTransformRegistry
86249
86281
  };
86250
86282
  const helpers = {
86251
86283
  arg,
@@ -86545,6 +86577,6 @@ exports.stores = stores;
86545
86577
  exports.tokenColors = tokenColors;
86546
86578
  exports.tokenize = tokenize;
86547
86579
 
86548
- __info__.version = "19.4.0-alpha.11";
86549
- __info__.date = "2026-06-03T11:42:34.595Z";
86550
- __info__.hash = "6f35bc7";
86580
+ __info__.version = "19.4.0-alpha.13";
86581
+ __info__.date = "2026-06-06T09:34:53.140Z";
86582
+ __info__.hash = "af3c199";
@@ -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 19.4.0-alpha.11
6
- * @date 2026-06-03T11:42:36.487Z
7
- * @hash 6f35bc7
5
+ * @version 19.4.0-alpha.13
6
+ * @date 2026-06-06T09:34:54.989Z
7
+ * @hash af3c199
8
8
  */
9
9
  :root {
10
10
  --os-gray-100: light-dark(#f9fafb, #1b1d26);
@@ -2251,6 +2251,7 @@
2251
2251
  /* Originates from src/components/headers_overlay/headers_overlay.css */
2252
2252
  .o-spreadsheet {
2253
2253
  .o-col-resizer {
2254
+ z-index: calc(var(--os-components-importance-grid) + 1);
2254
2255
  position: absolute;
2255
2256
  top: 0;
2256
2257
  left: var(--os-header-width);
@@ -2293,12 +2294,12 @@
2293
2294
  background-color: var(--os-selection-border-color);
2294
2295
  }
2295
2296
  .o-unhide:hover {
2296
- z-index: calc(var(--os-components-importance-grid) + 1);
2297
2297
  background-color: var(--os-gray-400);
2298
2298
  }
2299
2299
  }
2300
2300
 
2301
2301
  .o-row-resizer {
2302
+ z-index: calc(var(--os-components-importance-grid) + 1);
2302
2303
  position: absolute;
2303
2304
  top: var(--os-header-height);
2304
2305
  left: 0;
@@ -2340,7 +2341,6 @@
2340
2341
  background-color: var(--os-selection-border-color);
2341
2342
  }
2342
2343
  .o-unhide:hover {
2343
- z-index: calc(var(--os-components-importance-grid) + 1);
2344
2344
  background-color: var(--os-gray-400);
2345
2345
  }
2346
2346
  }
@@ -3173,9 +3173,12 @@
3173
3173
  }
3174
3174
  }
3175
3175
  }
3176
+
3177
+ --color-picker-item-size: calc(var(--os-item-edge-length) + (2 * var(--os-item-border-width)));
3178
+
3176
3179
  .o-color-picker-line-item {
3177
- width: calc(var(--os-item-edge-length) + (2 * var(--os-item-border-width)));
3178
- height: calc(var(--os-item-edge-length) + (2 * var(--os-item-border-width)));
3180
+ width: var(--color-picker-item-size);
3181
+ height: var(--color-picker-item-size);
3179
3182
  margin: 0px;
3180
3183
  border-radius: 50px;
3181
3184
  border: var(--os-item-border-width) solid light-dark(var(--os-gray-600), #c0c0c0);
@@ -3187,6 +3190,18 @@
3187
3190
  cursor: pointer;
3188
3191
  }
3189
3192
  }
3193
+ .eyedropper {
3194
+ width: var(--color-picker-item-size);
3195
+ height: var(--color-picker-item-size);
3196
+ &:hover {
3197
+ background-color: var(--os-hovered-menu-item-color);
3198
+ color: var(--os-button-active-text-color);
3199
+ cursor: pointer;
3200
+ }
3201
+ .fa {
3202
+ font-size: 13px;
3203
+ }
3204
+ }
3190
3205
  .o-buttons {
3191
3206
  padding: var(--os-picker-padding);
3192
3207
  display: flex;