@odoo/o-spreadsheet 19.5.0-alpha.19 → 19.5.0-alpha.20

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.5.0-alpha.19
6
- * @date 2026-09-10T05:38:44.935Z
7
- * @hash 2b1e397
5
+ * @version 19.5.0-alpha.20
6
+ * @date 2026-09-16T08:02:11.430Z
7
+ * @hash 4784627
8
8
  */
9
9
 
10
10
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
@@ -8829,7 +8829,7 @@ function getHueRotateMatrix(degrees) {
8829
8829
  * stored in the theme so that, after the dark-mode CSS filter is applied, the
8830
8830
  * desired color is actually shown.
8831
8831
  *
8832
- * This function computes the exact inverse of the DARK_MODE_FILTER chain.
8832
+ * This function computes an approximate inverse of the DARK_MODE_FILTER chain.
8833
8833
  */
8834
8834
  function adaptForDarkMode(displayedColor) {
8835
8835
  const { r, g, b, a } = colorToRGBA(displayedColor);
@@ -9977,34 +9977,49 @@ const TEXT_HEADER_COLOR = "#666666";
9977
9977
  const BACKGROUND_HEADER_COLOR = "#F8F9FA";
9978
9978
  const BACKGROUND_HEADER_SELECTED_COLOR = "#E8EAED";
9979
9979
  const BACKGROUND_HEADER_ACTIVE_COLOR = "#595959";
9980
+ function adaptColorsForDarkMode(colors) {
9981
+ return Object.fromEntries(Object.entries(colors).map(([key, color]) => [key, adaptForDarkMode(color)]));
9982
+ }
9983
+ const LIGHT_COLORS = {
9984
+ chartBackgroundColor: "#FFFFFF",
9985
+ gridBorderColor: "#CECFCF",
9986
+ gridBorderColorOnDefaultBackground: "#E2E3E3",
9987
+ headerBackgroundColor: BACKGROUND_HEADER_COLOR,
9988
+ headerActiveBackgroundColor: BACKGROUND_HEADER_ACTIVE_COLOR,
9989
+ headerSelectedBackgroundColor: BACKGROUND_HEADER_SELECTED_COLOR,
9990
+ headerTextColor: TEXT_HEADER_COLOR,
9991
+ headerBorderColor: HEADER_BORDER_COLOR,
9992
+ frozenPaneBorderColor: FROZEN_PANE_BORDER_COLOR,
9993
+ frozenPaneHeaderBorderColor: FROZEN_PANE_HEADER_BORDER_COLOR,
9994
+ singleCellSelectionBackgroundColor: "#D2E1FB44",
9995
+ multipleCellsSelectionBackgroundColor: "#ACC7FF44"
9996
+ };
9997
+ /** Every color defined explicitely in the dark theme is expected to be subject to color-inverter mask applied
9998
+ * through the css class `os-theme-dependant`. They are therefore pre-inverted for dark mode.
9999
+ * Note that according to `adaptForDarkMode` documentation, the resulting color will be an approximation of the pre-inverted color.
10000
+ */
10001
+ const DARK_DISPLAYED_COLORS = {
10002
+ chartBackgroundColor: "#25262b",
10003
+ gridBorderColor: "#6B706F",
10004
+ gridBorderColorOnDefaultBackground: "#4F5254",
10005
+ headerBackgroundColor: "#262A36",
10006
+ headerActiveBackgroundColor: "#3A4052",
10007
+ headerSelectedBackgroundColor: "#4E566E",
10008
+ headerTextColor: "#A1A6B3",
10009
+ headerBorderColor: "#7A7F91",
10010
+ frozenPaneBorderColor: "#7A7F91",
10011
+ frozenPaneHeaderBorderColor: "#9FA5BD",
10012
+ singleCellSelectionBackgroundColor: "#696E8044",
10013
+ multipleCellsSelectionBackgroundColor: "#828AA044"
10014
+ };
9980
10015
  const COLOR_THEMES = {
9981
10016
  light: {
9982
10017
  colorThemeName: "light",
9983
- backgroundColor: "#FFFFFF",
9984
- gridBorderColor: "#CECFCF",
9985
- headerBackgroundColor: BACKGROUND_HEADER_COLOR,
9986
- headerActiveBackgroundColor: BACKGROUND_HEADER_ACTIVE_COLOR,
9987
- headerSelectedBackgroundColor: BACKGROUND_HEADER_SELECTED_COLOR,
9988
- headerTextColor: TEXT_HEADER_COLOR,
9989
- headerBorderColor: HEADER_BORDER_COLOR,
9990
- frozenPaneBorderColor: FROZEN_PANE_BORDER_COLOR,
9991
- frozenPaneHeaderBorderColor: FROZEN_PANE_HEADER_BORDER_COLOR,
9992
- singleCellSelectionBackgroundColor: "#F3F7FE",
9993
- multipleCellsSelectionBackgroundColor: "#E9F0FF"
10018
+ ...LIGHT_COLORS
9994
10019
  },
9995
10020
  dark: {
9996
10021
  colorThemeName: "dark",
9997
- backgroundColor: adaptForDarkMode("#1A1C2E"),
9998
- gridBorderColor: adaptForDarkMode("#6B706F"),
9999
- headerBackgroundColor: adaptForDarkMode("#262A36"),
10000
- headerActiveBackgroundColor: adaptForDarkMode("#3A4052"),
10001
- headerSelectedBackgroundColor: adaptForDarkMode("#4E566E"),
10002
- headerTextColor: adaptForDarkMode("#A1A6B3"),
10003
- headerBorderColor: adaptForDarkMode("#7A7F91"),
10004
- frozenPaneBorderColor: adaptForDarkMode("#7A7F91"),
10005
- frozenPaneHeaderBorderColor: adaptForDarkMode("#9FA5BD"),
10006
- singleCellSelectionBackgroundColor: adaptForDarkMode("#696E8044"),
10007
- multipleCellsSelectionBackgroundColor: adaptForDarkMode("#828AA044")
10022
+ ...adaptColorsForDarkMode(DARK_DISPLAYED_COLORS)
10008
10023
  }
10009
10024
  };
10010
10025
 
@@ -10230,7 +10245,7 @@ function isTrendLineAxis(axisID) {
10230
10245
  return axisID === "x1" || axisID === "xMovingAverage";
10231
10246
  }
10232
10247
  function getChartBackgroundColor({ background }, colorThemeName) {
10233
- if (!background) return COLOR_THEMES[colorThemeName].backgroundColor;
10248
+ if (!background) return COLOR_THEMES[colorThemeName].chartBackgroundColor;
10234
10249
  return background;
10235
10250
  }
10236
10251
 
@@ -14203,7 +14218,7 @@ const GAUGE_PADDING_TOP = 10;
14203
14218
  const GAUGE_PADDING_BOTTOM = 20;
14204
14219
  const GAUGE_LABELS_FONT_SIZE = 12;
14205
14220
  const GAUGE_DEFAULT_VALUE_FONT_SIZE = 80;
14206
- const GAUGE_BACKGROUND_COLOR = "#F3F2F1";
14221
+ const GAUGE_BACKGROUND_COLOR = "#F8F8F8";
14207
14222
  const GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN = 6;
14208
14223
  const GAUGE_TITLE_SECTION_HEIGHT = 25;
14209
14224
  function drawGaugeChart(canvas, runtime, zoom = 1, dimensions, options) {
@@ -24538,8 +24553,8 @@ var ClickableCellSortIcon = class extends Component {
24538
24553
  }
24539
24554
  getBackgroundColor(cellStyle) {
24540
24555
  const overlayColor = this.hoveredCellOverlayStore.overlayColors.get(this.props.position);
24541
- if (overlayColor) return blendColors(cellStyle.fillColor || "#FFFFFF", overlayColor);
24542
- return cellStyle.fillColor || "#FFFFFF";
24556
+ if (overlayColor) return cellStyle.fillColor ? blendColors(cellStyle.fillColor, overlayColor) : overlayColor;
24557
+ return cellStyle.fillColor;
24543
24558
  }
24544
24559
  };
24545
24560
 
@@ -28301,8 +28316,11 @@ var GridRenderer = class extends DisposableStore {
28301
28316
  drawGlobalBackground(renderingContext) {
28302
28317
  const { ctx, viewports } = renderingContext;
28303
28318
  const { width, height } = viewports.getSheetViewDimensionWithHeaders();
28304
- ctx.fillStyle = this.getBackgroundColor(renderingContext);
28305
- ctx.fillRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
28319
+ const fillStyle = this.getBackgroundColor(renderingContext);
28320
+ if (fillStyle) {
28321
+ ctx.fillStyle = fillStyle;
28322
+ ctx.fillRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
28323
+ } else ctx.clearRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
28306
28324
  }
28307
28325
  drawBackground(renderingContext, boxes) {
28308
28326
  const { ctx, thinLineWidth } = renderingContext;
@@ -28311,7 +28329,8 @@ var GridRenderer = class extends DisposableStore {
28311
28329
  if (areGridLinesVisible) {
28312
28330
  const theme = this.getters.getSpreadsheetTheme();
28313
28331
  const background = this.getBackgroundColor(renderingContext);
28314
- ctx.strokeStyle = setColorAlpha(blendColors(theme.gridBorderColor + "aa", background + "50"), 1);
28332
+ if (background) ctx.strokeStyle = setColorAlpha(blendColors(theme.gridBorderColor + "aa", toHex(background) + "50"), 1);
28333
+ else ctx.strokeStyle = theme.gridBorderColorOnDefaultBackground;
28315
28334
  ctx.lineWidth = thinLineWidth;
28316
28335
  for (const box of boxes) {
28317
28336
  if (box.style.hideGridLines) continue;
@@ -28321,9 +28340,11 @@ var GridRenderer = class extends DisposableStore {
28321
28340
  }
28322
28341
  drawCellBackground(renderingContext, boxes) {
28323
28342
  const { ctx } = renderingContext;
28343
+ const backgroundColor = this.getBackgroundColor(renderingContext);
28344
+ const background = backgroundColor ? toHex(backgroundColor) : void 0;
28324
28345
  for (const box of boxes) {
28325
28346
  const style = box.style;
28326
- if (style.fillColor && toHex(style.fillColor) !== toHex(this.getBackgroundColor(renderingContext))) {
28347
+ if (style.fillColor && toHex(style.fillColor) !== background) {
28327
28348
  ctx.fillStyle = toHex(style.fillColor);
28328
28349
  ctx.fillRect(box.x - CANVAS_SHIFT, box.y - CANVAS_SHIFT, box.width + CANVAS_SHIFT * 2, box.height + CANVAS_SHIFT * 2);
28329
28350
  }
@@ -28337,7 +28358,8 @@ var GridRenderer = class extends DisposableStore {
28337
28358
  ctx.fillRect(box.x, y, width, height);
28338
28359
  }
28339
28360
  if (box.overlayColor) {
28340
- ctx.fillStyle = blendColors(style.fillColor || this.getBackgroundColor(renderingContext), box.overlayColor);
28361
+ const backdrop = style.fillColor || this.getBackgroundColor(renderingContext);
28362
+ ctx.fillStyle = backdrop ? blendColors(backdrop, box.overlayColor) : box.overlayColor;
28341
28363
  ctx.fillRect(box.x - CANVAS_SHIFT, box.y - CANVAS_SHIFT, box.width + CANVAS_SHIFT * 2, box.height + CANVAS_SHIFT * 2);
28342
28364
  }
28343
28365
  if (box?.chip) {
@@ -28365,6 +28387,7 @@ var GridRenderer = class extends DisposableStore {
28365
28387
  }
28366
28388
  drawOverflowingCellBackground(renderingContext, boxes) {
28367
28389
  const { ctx, thinLineWidth } = renderingContext;
28390
+ const background = this.getBackgroundColor(renderingContext);
28368
28391
  for (const box of boxes) if (box.content && box.isOverflow) {
28369
28392
  const align = box.content.align || "left";
28370
28393
  let x;
@@ -28382,8 +28405,10 @@ var GridRenderer = class extends DisposableStore {
28382
28405
  x = (box.clipRect?.x || box.x + box.width / 2 - box.content.width / 2) + thinLineWidth / 2;
28383
28406
  width = clipWidth - 2 * thinLineWidth;
28384
28407
  }
28385
- ctx.fillStyle = this.getBackgroundColor(renderingContext);
28386
- ctx.fillRect(x, y, width, height);
28408
+ if (background) {
28409
+ ctx.fillStyle = background;
28410
+ ctx.fillRect(x, y, width, height);
28411
+ } else ctx.clearRect(x, y, width, height);
28387
28412
  }
28388
28413
  }
28389
28414
  drawBorders(renderingContext, boxes) {
@@ -28553,7 +28578,7 @@ var GridRenderer = class extends DisposableStore {
28553
28578
  ctx.textBaseline = "middle";
28554
28579
  ctx.lineWidth = thinLineWidth;
28555
28580
  ctx.strokeStyle = theme.headerTextColor;
28556
- ctx.fillStyle = this.getters.getSpreadsheetTheme().backgroundColor;
28581
+ ctx.fillStyle = theme.headerBackgroundColor;
28557
28582
  ctx.fillRect(0, 0, 48, height);
28558
28583
  ctx.fillRect(0, 0, width, 26);
28559
28584
  for (const col of visibleCols) {
@@ -29002,7 +29027,7 @@ var GridRenderer = class extends DisposableStore {
29002
29027
  }
29003
29028
  }
29004
29029
  getBackgroundColor(renderingContext) {
29005
- return this.getters.getSheet(renderingContext.sheetId).backgroundColor || this.getters.getSpreadsheetTheme().backgroundColor;
29030
+ return this.getters.getSheet(renderingContext.sheetId).backgroundColor;
29006
29031
  }
29007
29032
  };
29008
29033
 
@@ -29015,7 +29040,7 @@ function useGridDrawing({ canvasRef, renderingCtx, rendererStore, changeCanvasSi
29015
29040
  function drawGrid() {
29016
29041
  const canvas = canvasRef();
29017
29042
  if (!canvas) return;
29018
- const ctx = canvas.getContext("2d", { alpha: false });
29043
+ const ctx = canvas.getContext("2d", { alpha: true });
29019
29044
  const renderingContext = {
29020
29045
  ctx,
29021
29046
  thinLineWidth: .4,
@@ -29258,7 +29283,7 @@ var StandaloneViewportStore = class extends SpreadsheetStore {
29258
29283
  viewports: this.viewStore.viewports,
29259
29284
  hideGridLines: this.getters.isDashboard(),
29260
29285
  hideFrozenPaneBorder: true,
29261
- dpr: 1,
29286
+ dpr: window.devicePixelRatio || 1,
29262
29287
  selectedZones: [],
29263
29288
  activeCols: /* @__PURE__ */ new Set(),
29264
29289
  activeRows: /* @__PURE__ */ new Set(),
@@ -29820,7 +29845,7 @@ var CarouselFigure = class extends Component {
29820
29845
  }
29821
29846
  get carouselStyle() {
29822
29847
  const cssProperties = {};
29823
- const backgroundColor = this.env.model.getters.getSpreadsheetTheme().backgroundColor;
29848
+ const backgroundColor = this.env.model.getters.getSpreadsheetTheme().chartBackgroundColor;
29824
29849
  if (this.selectedCarouselItem?.type === "chart") {
29825
29850
  const chart = this.env.model.getters.getChartRuntime(this.selectedCarouselItem.chartId);
29826
29851
  if ("background" in chart && chart.background) cssProperties["background-color"] = chart.background;
@@ -42777,7 +42802,7 @@ function analyzeColumn(zone, getters) {
42777
42802
  if (!cells.length) return {
42778
42803
  zone,
42779
42804
  type: "empty",
42780
- hasHeader: false,
42805
+ headerInZone: false,
42781
42806
  rowCount: 0,
42782
42807
  uniqueCount: 0,
42783
42808
  uniqueRatio: 0,
@@ -42785,16 +42810,34 @@ function analyzeColumn(zone, getters) {
42785
42810
  };
42786
42811
  const firstCell = cells[0];
42787
42812
  const rest = cells.slice(1);
42788
- const hasHeader = firstCell.type === "text" && rest.some((c) => c.type !== "text");
42789
- const dataCells = hasHeader ? rest : cells;
42813
+ let title;
42814
+ let dataCells = [];
42815
+ let headerInZone = false;
42816
+ let analyzedZone = zone;
42817
+ const tableHeaderPosition = getColumnTableHeaderPosition(sheetId, zone, getters);
42818
+ if (tableHeaderPosition) {
42819
+ title = getters.getCellText(tableHeaderPosition) || void 0;
42820
+ dataCells = cells.filter((c) => c.position && c.position.row > tableHeaderPosition.row);
42821
+ headerInZone = !!title && tableHeaderPosition.row >= zone.top && tableHeaderPosition.row <= zone.bottom;
42822
+ if (headerInZone) analyzedZone = {
42823
+ top: tableHeaderPosition.row,
42824
+ bottom: zone.bottom,
42825
+ left: zone.left,
42826
+ right: zone.right
42827
+ };
42828
+ } else if (firstCell.type === "text" && rest.some((c) => c.type !== "text")) {
42829
+ title = firstCell.value;
42830
+ dataCells = rest;
42831
+ headerInZone = true;
42832
+ } else dataCells = cells;
42790
42833
  const numericValues = dataCells.filter((c) => c.type === "number").map((c) => c.value);
42791
42834
  const allVals = dataCells.map((c) => String(c.value ?? ""));
42792
42835
  const uniqueCount = new Set(allVals).size;
42793
42836
  return {
42794
- zone,
42837
+ zone: analyzedZone,
42795
42838
  type: computeColumnType(dataCells),
42796
- header: hasHeader ? firstCell.value : void 0,
42797
- hasHeader,
42839
+ title,
42840
+ headerInZone,
42798
42841
  rowCount: dataCells.length,
42799
42842
  uniqueCount,
42800
42843
  uniqueRatio: allVals.length > 0 ? uniqueCount / allVals.length : 0,
@@ -42820,6 +42863,33 @@ function computeColumnType(cells) {
42820
42863
  }
42821
42864
  return "empty";
42822
42865
  }
42866
+ function getColumnTableHeaderPosition(sheetId, zone, getters) {
42867
+ if (zone.left !== zone.right) return;
42868
+ const tables = getters.getTablesOverlappingZones(sheetId, [zone]);
42869
+ if (tables.length !== 1) return;
42870
+ const table = tables[0];
42871
+ const firstCell = {
42872
+ sheetId,
42873
+ col: zone.left,
42874
+ row: zone.top
42875
+ };
42876
+ const lastCell = {
42877
+ sheetId,
42878
+ col: zone.left,
42879
+ row: zone.bottom
42880
+ };
42881
+ if (firstCell.row < table.range.zone.top || lastCell.row > table.range.zone.bottom) {
42882
+ const cells = getters.getEvaluatedCellsInZone(sheetId, zone).filter((c) => c.type !== "empty");
42883
+ for (const cell of cells) if (cell.position && !isInside(cell.position.col, cell.position.row, table.range.zone)) return;
42884
+ }
42885
+ const numberOfHeaders = table.config.numberOfHeaders;
42886
+ if (numberOfHeaders === 0) return;
42887
+ return {
42888
+ sheetId,
42889
+ col: zone.left,
42890
+ row: table.range.zone.top + numberOfHeaders - 1
42891
+ };
42892
+ }
42823
42893
 
42824
42894
  //#endregion
42825
42895
  //#region src/helpers/figures/charts/charts_suggestions_constants.ts
@@ -43064,6 +43134,10 @@ const SINGLE_DATE_COLUMN_SUGGESTIONS = [{
43064
43134
  description: _t("Shows the last date value."),
43065
43135
  isApplicable: ({ rowCount }) => rowCount === 1,
43066
43136
  build: (ctx) => scorecardChart(ctx.title, `=${ctx.lastCellXC}`)
43137
+ }, {
43138
+ description: _t("Shows occurrences for each time slot."),
43139
+ isApplicable: ({ rowCount }) => rowCount > 1,
43140
+ build: (ctx) => calendarChart(ctx.title, ctx.source)
43067
43141
  }];
43068
43142
  /** Pattern D — Single categorical column */
43069
43143
  const SINGLE_CATEGORICAL_COLUMN_SUGGESTIONS = [
@@ -43374,7 +43448,7 @@ const LABEL_VS_MULTIPLE_NUMBERS_SUGGESTIONS = [
43374
43448
  isApplicable: ({ numColsCount }) => numColsCount === 3,
43375
43449
  build: (ctx) => {
43376
43450
  const bubble = ctx.bubble;
43377
- return bubbleChart(ctx.title, bubble.xRange, bubble.yRanges, bubble.sizeRange, bubble.labelRange, bubble.hasTitle);
43451
+ return bubbleChart(ctx.title, bubble.xRange, bubble.yRanges, bubble.sizeRange, bubble.labelRange, bubble.headerInZone);
43378
43452
  }
43379
43453
  }
43380
43454
  ];
@@ -43471,8 +43545,8 @@ function matchesShape(pattern, shape) {
43471
43545
  });
43472
43546
  }
43473
43547
  function isPyramidLike(numCol1, numCol2) {
43474
- const h1 = numCol1.header ?? "";
43475
- const h2 = numCol2.header ?? "";
43548
+ const h1 = numCol1.title ?? "";
43549
+ const h2 = numCol2.title ?? "";
43476
43550
  return PYRAMID_HEADER_KEYWORD_PATTERNS.some((re) => re.test(h1) || re.test(h2));
43477
43551
  }
43478
43552
  /** Returns the first and last cell XC coordinates, and the second-to-last cell XC coordinate if it exists. */
@@ -43493,25 +43567,26 @@ function interestingCellsXc(col) {
43493
43567
  prevCellXC: prevCellPosition ? toXC(prevCellPosition?.col, prevCellPosition?.row) : void 0
43494
43568
  };
43495
43569
  }
43496
- function getCategoryHeader(getters, catCol) {
43497
- let catHeader = catCol.header ?? "";
43498
- if (!catHeader && catCol.rowCount > 0) {
43570
+ function getCategoryHeader(getters, catCol, headerInZone) {
43571
+ if (catCol.title) return catCol.title;
43572
+ if (headerInZone && catCol.rowCount > 0) {
43499
43573
  const { left, top } = catCol.zone;
43500
- catHeader = (getters.getEvaluatedCell({
43574
+ const cellValue = getters.getEvaluatedCell({
43501
43575
  sheetId: getters.getActiveSheetId(),
43502
43576
  col: left,
43503
43577
  row: top
43504
- })?.value || _t("Category")).toString();
43578
+ })?.value;
43579
+ if (cellValue) return cellValue.toString();
43505
43580
  }
43506
- return catHeader;
43581
+ return _t("Category");
43507
43582
  }
43508
43583
  /** Pattern A — Single numeric column */
43509
43584
  function buildSingleNumberContext([col], getters) {
43510
- const title = col.header ?? "";
43585
+ const title = col.title ?? "";
43511
43586
  const { firstCellXC, lastCellXC, prevCellXC } = interestingCellsXc(col);
43512
43587
  return {
43513
43588
  title,
43514
- source: rangeSource([dataset(col.zone, getters)], col.hasHeader),
43589
+ source: rangeSource([dataset(col.zone, getters)], col.headerInZone),
43515
43590
  rowCount: col.rowCount,
43516
43591
  firstCellXC,
43517
43592
  lastCellXC,
@@ -43520,10 +43595,9 @@ function buildSingleNumberContext([col], getters) {
43520
43595
  }
43521
43596
  /** Pattern B — Single percentage column */
43522
43597
  function buildSinglePercentageContext([col], getters) {
43523
- const hasTitle = col.hasHeader;
43524
- const title = col.header ?? "";
43598
+ const title = col.title ?? "";
43525
43599
  const { firstCellXC, lastCellXC, prevCellXC } = interestingCellsXc(col);
43526
- const source = rangeSource([dataset(col.zone, getters)], hasTitle);
43600
+ const source = rangeSource([dataset(col.zone, getters)], col.headerInZone);
43527
43601
  const isAboveOne = (col.maxValue ?? 0) > 1;
43528
43602
  return {
43529
43603
  title,
@@ -43536,22 +43610,24 @@ function buildSinglePercentageContext([col], getters) {
43536
43610
  };
43537
43611
  }
43538
43612
  /** Pattern C — Single date column */
43539
- function buildSingleDateContext([col]) {
43613
+ function buildSingleDateContext([col], getters) {
43540
43614
  const { lastCellXC } = interestingCellsXc(col);
43615
+ const labelRange = getUnboundRange(getters, col.zone);
43616
+ const source = rangeSource([dataset(col.zone, getters)], col.headerInZone, labelRange);
43541
43617
  return {
43542
- title: col.header ?? "",
43618
+ title: col.title ?? "",
43543
43619
  lastCellXC,
43544
- rowCount: col.rowCount
43620
+ rowCount: col.rowCount,
43621
+ source
43545
43622
  };
43546
43623
  }
43547
43624
  /** Pattern D — Single categorical column */
43548
43625
  function buildSingleCategoricalContext([col], getters) {
43549
- const hasTitle = col.hasHeader;
43550
- const title = col.header ?? "";
43626
+ const title = col.title ?? "";
43551
43627
  const range = getUnboundRange(getters, col.zone);
43552
43628
  return {
43553
43629
  title,
43554
- source: rangeSource([dataset(col.zone, getters)], hasTitle, range),
43630
+ source: rangeSource([dataset(col.zone, getters)], col.headerInZone, range),
43555
43631
  range
43556
43632
  };
43557
43633
  }
@@ -43559,7 +43635,7 @@ function buildSingleCategoricalContext([col], getters) {
43559
43635
  function buildSingleLabelContext([col]) {
43560
43636
  const { lastCellXC } = interestingCellsXc(col);
43561
43637
  return {
43562
- title: "",
43638
+ title: col.title ?? "",
43563
43639
  lastCellXC,
43564
43640
  rowCount: col.rowCount
43565
43641
  };
@@ -43567,37 +43643,37 @@ function buildSingleLabelContext([col]) {
43567
43643
  /** Pattern F — Categorical + Number */
43568
43644
  function buildCategoricalVsNumberContext([catCol, numCol], getters) {
43569
43645
  const labelRange = getUnboundRange(getters, catCol.zone);
43570
- const hasTitle = numCol.hasHeader;
43571
- const categoryHeader = hasTitle ? getCategoryHeader(getters, catCol) : _t("Category");
43646
+ const headerInZone = numCol.headerInZone;
43647
+ const categoryHeader = getCategoryHeader(getters, catCol, headerInZone);
43572
43648
  return {
43573
- title: numCol.header ? _t("%(numberHeader)s by %(categoryHeader)s", {
43574
- numberHeader: numCol.header,
43649
+ title: numCol.title ? _t("%(numberHeader)s by %(categoryHeader)s", {
43650
+ numberHeader: numCol.title,
43575
43651
  categoryHeader
43576
43652
  }) : "",
43577
- source: rangeSource([dataset(numCol.zone, getters)], hasTitle, labelRange),
43578
- treemapSource: rangeSource([dataset(catCol.zone, getters)], hasTitle, getUnboundRange(getters, numCol.zone))
43653
+ source: rangeSource([dataset(numCol.zone, getters)], headerInZone, labelRange),
43654
+ treemapSource: rangeSource([dataset(catCol.zone, getters)], headerInZone, getUnboundRange(getters, numCol.zone))
43579
43655
  };
43580
43656
  }
43581
43657
  /** Patterns G & J — Date + Number or Date + Percentage */
43582
43658
  function buildDateVsSeriesContext([dateCol, seriesCol], getters) {
43583
43659
  const isPercentage = seriesCol.type === "percentage";
43584
43660
  const labelRange = getUnboundRange(getters, dateCol.zone);
43585
- const hasTitle = isDatasetTitled(getters, dateCol.zone);
43661
+ const headerInZone = isDatasetTitled(getters, dateCol.zone);
43586
43662
  return {
43587
- title: seriesCol.header ? _t("%(seriesHeader)s over time", { seriesHeader: seriesCol.header }) : "",
43588
- source: rangeSource([dataset(seriesCol.zone, getters)], hasTitle, labelRange),
43663
+ title: seriesCol.title ? _t("%(seriesHeader)s over time", { seriesHeader: seriesCol.title }) : "",
43664
+ source: rangeSource([dataset(seriesCol.zone, getters)], headerInZone, labelRange),
43589
43665
  isPercentage
43590
43666
  };
43591
43667
  }
43592
43668
  /** Pattern H — Number + Number */
43593
43669
  function buildNumberVsNumberContext([col1, col2], getters) {
43594
- const title = col1.header && col2.header ? _t("%(col2Header)s vs %(col1Header)s", {
43595
- col2Header: col2.header,
43596
- col1Header: col1.header
43670
+ const title = col1.title && col2.title ? _t("%(col2Header)s vs %(col1Header)s", {
43671
+ col2Header: col2.title,
43672
+ col1Header: col1.title
43597
43673
  }) : "";
43598
- const hasTitle = col1.hasHeader || col2.hasHeader;
43599
- const source2 = rangeSource([dataset(col2.zone, getters)], col2.hasHeader, getUnboundRange(getters, col1.zone));
43600
- const sourceBoth = rangeSource([dataset(col1.zone, getters, "0"), dataset(col2.zone, getters, "1")], hasTitle);
43674
+ const headerInZone = col1.headerInZone || col2.headerInZone;
43675
+ const source2 = rangeSource([dataset(col2.zone, getters)], col2.headerInZone, getUnboundRange(getters, col1.zone));
43676
+ const sourceBoth = rangeSource([dataset(col1.zone, getters, "0"), dataset(col2.zone, getters, "1")], headerInZone);
43601
43677
  const { lastCellXC } = interestingCellsXc(col2);
43602
43678
  const { lastCellXC: prevCellXC } = interestingCellsXc(col1);
43603
43679
  return {
@@ -43613,26 +43689,25 @@ function buildNumberVsNumberContext([col1, col2], getters) {
43613
43689
  /** Pattern I — Categorical + Percentage */
43614
43690
  function buildCategoricalVsPercentageContext([catCol, pctCol], getters) {
43615
43691
  const labelRange = getUnboundRange(getters, catCol.zone);
43616
- const hasTitle = pctCol.hasHeader;
43617
- const categoryHeader = hasTitle ? getCategoryHeader(getters, catCol) : _t("Category");
43692
+ const headerInZone = pctCol.headerInZone;
43693
+ const categoryHeader = getCategoryHeader(getters, catCol, headerInZone);
43618
43694
  return {
43619
- title: pctCol.header ? _t("%(percentageHeader)s by %(categoryHeader)s", {
43620
- percentageHeader: pctCol.header,
43695
+ title: pctCol.title ? _t("%(percentageHeader)s by %(categoryHeader)s", {
43696
+ percentageHeader: pctCol.title,
43621
43697
  categoryHeader
43622
43698
  }) : "",
43623
- source: rangeSource([dataset(pctCol.zone, getters)], hasTitle, labelRange),
43699
+ source: rangeSource([dataset(pctCol.zone, getters)], headerInZone, labelRange),
43624
43700
  rowCount: catCol.rowCount
43625
43701
  };
43626
43702
  }
43627
43703
  /** Pattern K — Label + Number */
43628
43704
  function buildLabelVsNumberContext([labelCol, numCol], getters) {
43629
43705
  const labelRange = getUnboundRange(getters, labelCol.zone);
43630
- const hasTitle = numCol.hasHeader;
43631
- const title = numCol.header ? _t("%(numberHeader)s by %(labelHeader)s", {
43632
- numberHeader: numCol.header,
43633
- labelHeader: labelCol.header ?? _t("Name")
43706
+ const title = numCol.title ? _t("%(numberHeader)s by %(labelHeader)s", {
43707
+ numberHeader: numCol.title,
43708
+ labelHeader: labelCol.title ?? _t("Name")
43634
43709
  }) : "";
43635
- const source = rangeSource([dataset(numCol.zone, getters)], hasTitle, labelRange);
43710
+ const source = rangeSource([dataset(numCol.zone, getters)], numCol.headerInZone, labelRange);
43636
43711
  const { lastCellXC } = interestingCellsXc(numCol);
43637
43712
  const { lastCellXC: prevCellXC } = interestingCellsXc(labelCol);
43638
43713
  return {
@@ -43646,66 +43721,66 @@ function buildLabelVsNumberContext([labelCol, numCol], getters) {
43646
43721
  /** Pattern M — Categorical + Multiple Numbers */
43647
43722
  function buildCategoricalVsMultipleNumbersContext([catCol, ...numCols], getters) {
43648
43723
  const labelRange = getUnboundRange(getters, catCol.zone);
43649
- const hasTitle = numCols.some((c) => c.hasHeader);
43650
- const categoryHeader = hasTitle ? getCategoryHeader(getters, catCol) : "";
43724
+ const headerInZone = numCols.some((c) => c.headerInZone);
43725
+ const categoryHeader = getCategoryHeader(getters, catCol, headerInZone);
43651
43726
  return {
43652
- title: hasTitle ? _t("Multi-series By %(categoryHeader)s", { categoryHeader }) : "",
43653
- source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), hasTitle, labelRange),
43727
+ title: headerInZone ? _t("Multi-series By %(categoryHeader)s", { categoryHeader }) : "",
43728
+ source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone, labelRange),
43654
43729
  rowCount: catCol.rowCount
43655
43730
  };
43656
43731
  }
43657
43732
  /** Pattern N — Date + Multiple Numbers */
43658
43733
  function buildDateVsMultipleNumbersContext([dateCol, ...numCols], getters) {
43659
43734
  const labelRange = getUnboundRange(getters, dateCol.zone);
43660
- const hasTitle = numCols.some((c) => c.hasHeader) || isDatasetTitled(getters, dateCol.zone);
43735
+ const headerInZone = numCols.some((c) => c.headerInZone) || isDatasetTitled(getters, dateCol.zone);
43661
43736
  return {
43662
- title: numCols.length === 1 && numCols[0].header ? _t("%(header)s over time", { header: numCols[0].header }) : "",
43663
- source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), hasTitle, labelRange)
43737
+ title: numCols.length === 1 && numCols[0].title ? _t("%(header)s over time", { header: numCols[0].title }) : "",
43738
+ source: rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone, labelRange)
43664
43739
  };
43665
43740
  }
43666
43741
  /** Pattern O — Categorical + Categorical + Number */
43667
43742
  function buildMultipleCategoricalsVsNumberContext([cat1, cat2, numCol], getters) {
43668
- const title = numCol.header ? _t("%(numHeader)s by %(cat1Header)s and %(cat2Header)s", {
43669
- numHeader: numCol.header,
43670
- cat1Header: cat1.header ?? _t("Level 1"),
43671
- cat2Header: cat2.header ?? _t("Level 2")
43743
+ const title = numCol.title ? _t("%(numHeader)s by %(cat1Header)s and %(cat2Header)s", {
43744
+ numHeader: numCol.title,
43745
+ cat1Header: cat1.title ?? _t("Level 1"),
43746
+ cat2Header: cat2.title ?? _t("Level 2")
43672
43747
  }) : "";
43673
- const hasTitle = numCol.hasHeader;
43748
+ const headerInZone = numCol.headerInZone;
43674
43749
  return {
43675
43750
  title,
43676
- hierarchySource: rangeSource([dataset(cat1.zone, getters, "0"), dataset(cat2.zone, getters, "1")], hasTitle, getUnboundRange(getters, numCol.zone)),
43677
- barSource: rangeSource([dataset(numCol.zone, getters)], hasTitle, getUnboundRange(getters, cat1.zone))
43751
+ hierarchySource: rangeSource([dataset(cat1.zone, getters, "0"), dataset(cat2.zone, getters, "1")], headerInZone, getUnboundRange(getters, numCol.zone)),
43752
+ barSource: rangeSource([dataset(numCol.zone, getters)], headerInZone, getUnboundRange(getters, cat1.zone))
43678
43753
  };
43679
43754
  }
43680
43755
  /** Pattern P — Categorical + Date + Number */
43681
43756
  function buildCategoricalDateNumberContext([catCol, dateCol, numCol], getters) {
43682
43757
  const dateRange = getUnboundRange(getters, dateCol.zone);
43683
43758
  const catRange = getUnboundRange(getters, catCol.zone);
43684
- const hasTitle = numCol.hasHeader;
43685
- const catHeader = hasTitle ? getCategoryHeader(getters, catCol) : _t("Category");
43759
+ const headerInZone = numCol.headerInZone;
43760
+ const catHeader = getCategoryHeader(getters, catCol, headerInZone);
43686
43761
  return {
43687
- title: numCol.header ? _t("%(numHeader)s by %(catHeader)s over %(dateHeader)s", {
43688
- numHeader: numCol.header,
43762
+ title: numCol.title ? _t("%(numHeader)s by %(catHeader)s over %(dateHeader)s", {
43763
+ numHeader: numCol.title,
43689
43764
  catHeader,
43690
- dateHeader: dateCol.header ?? _t("Time")
43765
+ dateHeader: dateCol.title ?? _t("Time")
43691
43766
  }) : "",
43692
- sourceByDate: rangeSource([dataset(numCol.zone, getters)], hasTitle, dateRange),
43693
- sourceByCat: rangeSource([dataset(numCol.zone, getters)], hasTitle, catRange)
43767
+ sourceByDate: rangeSource([dataset(numCol.zone, getters)], headerInZone, dateRange),
43768
+ sourceByCat: rangeSource([dataset(numCol.zone, getters)], headerInZone, catRange)
43694
43769
  };
43695
43770
  }
43696
43771
  /** Pattern Q — Label + Multiple Numbers */
43697
43772
  function buildLabelVsMultipleNumbersContext([labelCol, ...numCols], getters) {
43698
43773
  const labelRange = getUnboundRange(getters, labelCol.zone);
43699
- const hasTitle = numCols.some((c) => c.hasHeader);
43700
- const title = labelCol.header ? _t("By %(header)s", { header: labelCol.header }) : "";
43701
- const source = rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), hasTitle, labelRange);
43702
- const scatterSource = rangeSource([dataset(numCols[1].zone, getters)], numCols[1].hasHeader, getUnboundRange(getters, numCols[0].zone));
43774
+ const headerInZone = numCols.some((c) => c.headerInZone);
43775
+ const title = labelCol.title ? _t("By %(title)s", { title: labelCol.title }) : "";
43776
+ const source = rangeSource(numCols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone, labelRange);
43777
+ const scatterSource = rangeSource([dataset(numCols[1].zone, getters)], numCols[1].headerInZone, getUnboundRange(getters, numCols[0].zone));
43703
43778
  const bubble = numCols.length === 3 ? {
43704
43779
  xRange: getUnboundRange(getters, numCols[0].zone),
43705
43780
  yRanges: [getUnboundRange(getters, numCols[1].zone)],
43706
43781
  sizeRange: getUnboundRange(getters, numCols[2].zone),
43707
43782
  labelRange,
43708
- hasTitle
43783
+ headerInZone
43709
43784
  } : void 0;
43710
43785
  return {
43711
43786
  title,
@@ -43719,25 +43794,25 @@ function buildLabelVsMultipleNumbersContext([labelCol, ...numCols], getters) {
43719
43794
  /** Pattern R — Categorical + Two Numbers (Population Pyramid or Grouped) */
43720
43795
  function buildCategoricalTwoNumbersContext([catCol, numCol1, numCol2], getters) {
43721
43796
  const catRange = getUnboundRange(getters, catCol.zone);
43722
- const hasTitle = numCol1.hasHeader || numCol2.hasHeader;
43723
- const catHeader = hasTitle ? getCategoryHeader(getters, catCol) : _t("Category");
43724
- const title = numCol1.header && numCol2.header ? _t("%(num1Header)s vs %(num2Header)s by %(catHeader)s", {
43725
- num1Header: numCol1.header,
43726
- num2Header: numCol2.header,
43797
+ const headerInZone = numCol1.headerInZone || numCol2.headerInZone;
43798
+ const catHeader = getCategoryHeader(getters, catCol, headerInZone);
43799
+ const title = numCol1.title && numCol2.title ? _t("%(num1Header)s vs %(num2Header)s by %(catHeader)s", {
43800
+ num1Header: numCol1.title,
43801
+ num2Header: numCol2.title,
43727
43802
  catHeader
43728
43803
  }) : "";
43729
43804
  const isPyramid = isPyramidLike(numCol1, numCol2);
43730
43805
  return {
43731
43806
  title,
43732
- sourceBoth: rangeSource([dataset(numCol1.zone, getters, "0"), dataset(numCol2.zone, getters, "1")], hasTitle, catRange),
43807
+ sourceBoth: rangeSource([dataset(numCol1.zone, getters, "0"), dataset(numCol2.zone, getters, "1")], headerInZone, catRange),
43733
43808
  isPyramid
43734
43809
  };
43735
43810
  }
43736
43811
  /** Pattern S — Many Numbers (3+ numeric columns, no categorical/date) */
43737
43812
  function buildManyNumbersContext(cols, getters) {
43738
- const title = cols.every((c) => c.hasHeader) ? cols.map((c) => c.header).join(" / ") : "";
43739
- const hasTitle = cols.some((c) => c.hasHeader);
43740
- const source = rangeSource(cols.map((c, i) => dataset(c.zone, getters, String(i))), hasTitle);
43813
+ const title = cols.every((c) => c.headerInZone) ? cols.map((c) => c.title).join(" / ") : "";
43814
+ const headerInZone = cols.some((c) => c.headerInZone);
43815
+ const source = rangeSource(cols.map((c, i) => dataset(c.zone, getters, String(i))), headerInZone);
43741
43816
  const { lastCellXC } = interestingCellsXc(cols[2]);
43742
43817
  const { lastCellXC: firstCellXC } = interestingCellsXc(cols[0]);
43743
43818
  const { lastCellXC: secondCellXC } = interestingCellsXc(cols[1]);
@@ -43752,6 +43827,7 @@ function buildManyNumbersContext(cols, getters) {
43752
43827
  };
43753
43828
  }
43754
43829
  const NUMBER_OR_PERCENTAGE = ["number", "percentage"];
43830
+ const CATEGORICAL_OR_BOOLEAN = ["categorical", "boolean"];
43755
43831
  const EXACT_PATTERNS = [
43756
43832
  {
43757
43833
  pattern: { leadingTypes: ["number"] },
@@ -43769,7 +43845,7 @@ const EXACT_PATTERNS = [
43769
43845
  suggestions: SINGLE_DATE_COLUMN_SUGGESTIONS
43770
43846
  },
43771
43847
  {
43772
- pattern: { leadingTypes: ["categorical"] },
43848
+ pattern: { leadingTypes: [CATEGORICAL_OR_BOOLEAN] },
43773
43849
  buildContext: buildSingleCategoricalContext,
43774
43850
  suggestions: SINGLE_CATEGORICAL_COLUMN_SUGGESTIONS
43775
43851
  },
@@ -43779,7 +43855,7 @@ const EXACT_PATTERNS = [
43779
43855
  suggestions: SINGLE_LABEL_COLUMN_SUGGESTIONS
43780
43856
  },
43781
43857
  {
43782
- pattern: { leadingTypes: ["categorical", "number"] },
43858
+ pattern: { leadingTypes: [CATEGORICAL_OR_BOOLEAN, "number"] },
43783
43859
  buildContext: buildCategoricalVsNumberContext,
43784
43860
  suggestions: CATEGORICAL_VS_NUMBER_SUGGESTIONS
43785
43861
  },
@@ -43794,7 +43870,7 @@ const EXACT_PATTERNS = [
43794
43870
  suggestions: NUMBER_VS_NUMBER_SUGGESTIONS
43795
43871
  },
43796
43872
  {
43797
- pattern: { leadingTypes: ["categorical", "percentage"] },
43873
+ pattern: { leadingTypes: [CATEGORICAL_OR_BOOLEAN, "percentage"] },
43798
43874
  buildContext: buildCategoricalVsPercentageContext,
43799
43875
  suggestions: CATEGORICAL_VS_PERCENTAGE_SUGGESTIONS
43800
43876
  },
@@ -43810,8 +43886,8 @@ const EXACT_PATTERNS = [
43810
43886
  },
43811
43887
  {
43812
43888
  pattern: { leadingTypes: [
43813
- "categorical",
43814
- "categorical",
43889
+ CATEGORICAL_OR_BOOLEAN,
43890
+ CATEGORICAL_OR_BOOLEAN,
43815
43891
  "number"
43816
43892
  ] },
43817
43893
  buildContext: buildMultipleCategoricalsVsNumberContext,
@@ -43819,7 +43895,7 @@ const EXACT_PATTERNS = [
43819
43895
  },
43820
43896
  {
43821
43897
  pattern: { leadingTypes: [
43822
- "categorical",
43898
+ CATEGORICAL_OR_BOOLEAN,
43823
43899
  "label",
43824
43900
  "number"
43825
43901
  ] },
@@ -43828,7 +43904,7 @@ const EXACT_PATTERNS = [
43828
43904
  },
43829
43905
  {
43830
43906
  pattern: { leadingTypes: [
43831
- "categorical",
43907
+ CATEGORICAL_OR_BOOLEAN,
43832
43908
  "date",
43833
43909
  NUMBER_OR_PERCENTAGE
43834
43910
  ] },
@@ -43837,7 +43913,7 @@ const EXACT_PATTERNS = [
43837
43913
  },
43838
43914
  {
43839
43915
  pattern: { leadingTypes: [
43840
- "categorical",
43916
+ CATEGORICAL_OR_BOOLEAN,
43841
43917
  NUMBER_OR_PERCENTAGE,
43842
43918
  NUMBER_OR_PERCENTAGE
43843
43919
  ] },
@@ -57232,7 +57308,7 @@ function pivot_presentation_default(PivotClass) {
57232
57308
  return this.strictMeasureValueToNumber(comparedValue);
57233
57309
  }
57234
57310
  getPivotValueCells(measureId) {
57235
- return this.getCollapsedTableStructure().getPivotCells().map((col) => col.filter((cell) => cell.type === "VALUE" && cell.measure === measureId)).filter((col) => col.length > 0);
57311
+ return this.getExpandedTableStructure().getPivotCells().map((col) => col.filter((cell) => cell.type === "VALUE" && cell.measure === measureId)).filter((col) => col.length > 0);
57236
57312
  }
57237
57313
  measureValueToNumber(result) {
57238
57314
  if (typeof result.value === "number") return result.value;
@@ -66112,7 +66188,7 @@ var EvaluationChartPlugin = class extends EvaluationPlugin {
66112
66188
  * Get the background and textColor of a chart based on the color of the first cell of the main range of the chart.
66113
66189
  */
66114
66190
  getStyleOfSingleCellChart(chartBackground, mainRange, colorThemeName) {
66115
- const themeBackground = COLOR_THEMES[colorThemeName].backgroundColor;
66191
+ const themeBackground = COLOR_THEMES[colorThemeName].chartBackgroundColor;
66116
66192
  if (chartBackground) return {
66117
66193
  background: chartBackground,
66118
66194
  fontColor: chartFontColor(chartBackground)
@@ -67166,14 +67242,12 @@ var SubtotalEvaluationPlugin = class extends EvaluationPlugin {
67166
67242
  var UIPlugin = class extends BasePlugin {
67167
67243
  static layers = [];
67168
67244
  getters;
67169
- ui;
67170
67245
  selection;
67171
67246
  dispatch;
67172
67247
  canDispatch;
67173
- constructor({ getters, stateObserver, dispatch, canDispatch, uiActions, selection }) {
67248
+ constructor({ getters, stateObserver, dispatch, canDispatch, selection }) {
67174
67249
  super(stateObserver);
67175
67250
  this.getters = getters;
67176
- this.ui = uiActions;
67177
67251
  this.selection = selection;
67178
67252
  this.dispatch = dispatch;
67179
67253
  this.canDispatch = canDispatch;
@@ -72642,9 +72716,7 @@ var SpreadsheetDashboard = class extends Component {
72642
72716
  return cssPropertiesToCss({ zoom: this.zoomStore.cssZoom });
72643
72717
  }
72644
72718
  get backgroundStyle() {
72645
- const sheet = this.env.model.getters.getActiveSheet();
72646
- const theme = this.env.model.getters.getSpreadsheetTheme();
72647
- return cssPropertiesToCss({ "background-color": sheet.backgroundColor || theme.backgroundColor });
72719
+ return cssPropertiesToCss({ "background-color": this.env.model.getters.getActiveSheet().backgroundColor });
72648
72720
  }
72649
72721
  };
72650
72722
 
@@ -73250,7 +73322,7 @@ var FigureRendererStore = class extends DisposableStore {
73250
73322
  ctx.beginPath();
73251
73323
  ctx.rect(figureRect.x, figureRect.y, figureRect.width, figureRect.height);
73252
73324
  ctx.clip();
73253
- ctx.fillStyle = chartDefinition?.background || this.getters.getSpreadsheetTheme().backgroundColor;
73325
+ ctx.fillStyle = chartDefinition?.background || this.getters.getSpreadsheetTheme().chartBackgroundColor;
73254
73326
  ctx.fillRect(figureRect.x, figureRect.y, figureRect.width, figureRect.height);
73255
73327
  const title = {
73256
73328
  ...DEFAULT_CAROUSEL_TITLE_STYLE,
@@ -75158,14 +75230,10 @@ var Spreadsheet = class extends Component {
75158
75230
  sticky: false
75159
75231
  });
75160
75232
  });
75161
- this.model.on("notify-ui", this, (notification) => this.notificationStore.notifyUser(notification));
75162
- this.model.on("raise-error-ui", this, ({ text }) => this.notificationStore.raiseError(text));
75163
75233
  }
75164
75234
  unbindModelEvents() {
75165
75235
  this.model.off("update", this);
75166
75236
  this.model.off("command-rejected", this);
75167
- this.model.off("notify-ui", this);
75168
- this.model.off("raise-error-ui", this);
75169
75237
  }
75170
75238
  checkViewportSize() {
75171
75239
  const { xRatio, yRatio } = this.viewStore.viewports.getFrozenSheetViewRatio(this.viewStore.displayedSheetId);
@@ -79580,8 +79648,6 @@ var Model = class Model extends EventBus {
79580
79648
  client,
79581
79649
  moveClient: () => {},
79582
79650
  snapshotRequested: false,
79583
- notifyUI: (payload) => this.trigger("notify-ui", payload),
79584
- raiseBlockingErrorUI: (text) => this.trigger("raise-error-ui", { text }),
79585
79651
  customColors: config.customColors || []
79586
79652
  };
79587
79653
  }
@@ -79625,7 +79691,6 @@ var Model = class Model extends EventBus {
79625
79691
  selection: this.selection,
79626
79692
  moveClient: this.session.move.bind(this.session),
79627
79693
  custom: this.config.custom,
79628
- uiActions: this.config,
79629
79694
  session: this.session,
79630
79695
  defaultCurrency: this.config.defaultCurrency,
79631
79696
  customColors: this.config.customColors || [],
@@ -79761,7 +79826,15 @@ var Model = class Model extends EventBus {
79761
79826
  dispatchFromEvaluationPlugin = (type, payload) => {
79762
79827
  const command = createCommand(type, payload);
79763
79828
  if (!isDispatcheableEvaluationCommand(command)) throw new Error(`An evaluation plugin cannot dispatch non-evaluation commands (${type})`);
79829
+ if (this.status !== 0) {
79830
+ this.dispatchToHandlers(this.evaluationHandlers, command);
79831
+ return DispatchResult.Success;
79832
+ }
79833
+ this.status = 3;
79764
79834
  this.dispatchToHandlers(this.evaluationHandlers, command);
79835
+ this.finalize();
79836
+ this.status = 0;
79837
+ this.trigger("update");
79765
79838
  return DispatchResult.Success;
79766
79839
  };
79767
79840
  /**
@@ -82301,7 +82374,7 @@ const BubbleChart = {
82301
82374
  legend: getBubbleChartLegend(definition, chartData),
82302
82375
  tooltip: getBubbleChartTooltip(definition, chartData),
82303
82376
  chartShowValuesPlugin: getChartShowValues(definition, chartData),
82304
- background: { color: definition.background }
82377
+ background: { color: chartData.background }
82305
82378
  }
82306
82379
  }
82307
82380
  } };
@@ -91640,6 +91713,6 @@ exports.stores = stores;
91640
91713
  exports.tokenColors = tokenColors;
91641
91714
  exports.tokenize = tokenize;
91642
91715
 
91643
- __info__.version = "19.5.0-alpha.19";
91644
- __info__.date = "2026-09-10T05:38:44.935Z";
91645
- __info__.hash = "2b1e397";
91716
+ __info__.version = "19.5.0-alpha.20";
91717
+ __info__.date = "2026-09-16T08:02:11.430Z";
91718
+ __info__.hash = "4784627";