@odoo/o-spreadsheet 16.1.6 → 16.1.7

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.
@@ -111,88 +111,88 @@ const LINK_COLOR = "#01666b";
111
111
  const FILTERS_COLOR = "#188038";
112
112
  const BACKGROUND_HEADER_FILTER_COLOR = "#E6F4EA";
113
113
  const BACKGROUND_HEADER_SELECTED_FILTER_COLOR = "#CEEAD6";
114
- // Color picker
114
+ // Color picker defaults as upper case HEX to match `toHex`helper
115
115
  const COLOR_PICKER_DEFAULTS = [
116
116
  "#000000",
117
117
  "#434343",
118
118
  "#666666",
119
119
  "#999999",
120
- "#b7b7b7",
121
- "#cccccc",
122
- "#d9d9d9",
123
- "#efefef",
124
- "#f3f3f3",
125
- "#ffffff",
120
+ "#B7B7B7",
121
+ "#CCCCCC",
122
+ "#D9D9D9",
123
+ "#EFEFEF",
124
+ "#F3F3F3",
125
+ "#FFFFFF",
126
126
  "#980000",
127
- "#ff0000",
128
- "#ff9900",
129
- "#ffff00",
130
- "#00ff00",
131
- "#00ffff",
132
- "#4a86e8",
133
- "#0000ff",
134
- "#9900ff",
135
- "#ff00ff",
136
- "#e6b8af",
137
- "#f4cccc",
138
- "#fce5cd",
139
- "#fff2cc",
140
- "#d9ead3",
141
- "#d0e0e3",
142
- "#c9daf8",
143
- "#cfe2f3",
144
- "#d9d2e9",
145
- "#ead1dc",
146
- "#dd7e6b",
147
- "#ea9999",
148
- "#f9cb9c",
149
- "#ffe599",
150
- "#b6d7a8",
151
- "#a2c4c9",
152
- "#a4c2f4",
153
- "#9fc5e8",
154
- "#b4a7d6",
155
- "#d5a6bd",
156
- "#cc4125",
157
- "#e06666",
158
- "#f6b26b",
159
- "#ffd966",
160
- "#93c47d",
161
- "#76a5af",
162
- "#6d9eeb",
163
- "#6fa8dc",
164
- "#8e7cc3",
165
- "#c27ba0",
166
- "#a61c00",
167
- "#cc0000",
168
- "#e69138",
169
- "#f1c232",
170
- "#6aa84f",
171
- "#45818e",
172
- "#3c78d8",
173
- "#3d85c6",
174
- "#674ea7",
175
- "#a64d79",
176
- "#85200c",
127
+ "#FF0000",
128
+ "#FF9900",
129
+ "#FFFF00",
130
+ "#00FF00",
131
+ "#00FFFF",
132
+ "#4A86E8",
133
+ "#0000FF",
134
+ "#9900FF",
135
+ "#FF00FF",
136
+ "#E6B8AF",
137
+ "#F4CCCC",
138
+ "#FCE5CD",
139
+ "#FFF2CC",
140
+ "#D9EAD3",
141
+ "#D0E0E3",
142
+ "#C9DAF8",
143
+ "#CFE2F3",
144
+ "#D9D2E9",
145
+ "#EAD1DC",
146
+ "#DD7E6B",
147
+ "#EA9999",
148
+ "#F9CB9C",
149
+ "#FFE599",
150
+ "#B6D7A8",
151
+ "#A2C4C9",
152
+ "#A4C2F4",
153
+ "#9FC5E8",
154
+ "#B4A7D6",
155
+ "#D5A6BD",
156
+ "#CC4125",
157
+ "#E06666",
158
+ "#F6B26B",
159
+ "#FFD966",
160
+ "#93C47D",
161
+ "#76A5AF",
162
+ "#6D9EEB",
163
+ "#6FA8DC",
164
+ "#8E7CC3",
165
+ "#C27BA0",
166
+ "#A61C00",
167
+ "#CC0000",
168
+ "#E69138",
169
+ "#F1C232",
170
+ "#6AA84F",
171
+ "#45818E",
172
+ "#3C78D8",
173
+ "#3D85C6",
174
+ "#674EA7",
175
+ "#A64D79",
176
+ "#85200C",
177
177
  "#990000",
178
- "#b45f06",
179
- "#bf9000",
180
- "#38761d",
181
- "#134f5c",
182
- "#1155cc",
183
- "#0b5394",
184
- "#351c75",
185
- "#741b47",
186
- "#5b0f00",
178
+ "#B45F06",
179
+ "#BF9000",
180
+ "#38761D",
181
+ "#134F5C",
182
+ "#1155CC",
183
+ "#0B5394",
184
+ "#351C75",
185
+ "#741B47",
186
+ "#5B0F00",
187
187
  "#660000",
188
- "#783f04",
189
- "#7f6000",
190
- "#274e13",
191
- "#0c343d",
192
- "#1c4587",
188
+ "#783F04",
189
+ "#7F6000",
190
+ "#274E13",
191
+ "#0C343D",
192
+ "#1C4587",
193
193
  "#073763",
194
- "#20124d",
195
- "#4c1130",
194
+ "#20124D",
195
+ "#4C1130",
196
196
  ];
197
197
  // Dimensions
198
198
  const MIN_ROW_HEIGHT = 10;
@@ -231,7 +231,7 @@ const DEFAULT_FONT = "'Roboto', arial";
231
231
  const DEFAULT_BORDER_DESC = ["thin", "#000"];
232
232
  const DEFAULT_FILTER_BORDER_DESC = ["thin", FILTERS_COLOR];
233
233
  // DateTimeRegex
234
- const DATETIME_FORMAT = /[ymd:]/;
234
+ const DATETIME_FORMAT = /[ymdhs:]/;
235
235
  // Ranges
236
236
  const INCORRECT_RANGE_STRING = CellErrorType.InvalidReference;
237
237
  // Max Number of history steps kept in memory
@@ -268,11 +268,13 @@ var ComponentsImportance;
268
268
  ComponentsImportance[ComponentsImportance["Highlight"] = 5] = "Highlight";
269
269
  ComponentsImportance[ComponentsImportance["Figure"] = 10] = "Figure";
270
270
  ComponentsImportance[ComponentsImportance["ScrollBar"] = 15] = "ScrollBar";
271
- ComponentsImportance[ComponentsImportance["Dropdown"] = 16] = "Dropdown";
272
- ComponentsImportance[ComponentsImportance["Composer"] = 20] = "Composer";
271
+ ComponentsImportance[ComponentsImportance["GridPopover"] = 19] = "GridPopover";
272
+ ComponentsImportance[ComponentsImportance["GridComposer"] = 20] = "GridComposer";
273
+ ComponentsImportance[ComponentsImportance["Dropdown"] = 21] = "Dropdown";
273
274
  ComponentsImportance[ComponentsImportance["ColorPicker"] = 25] = "ColorPicker";
274
275
  ComponentsImportance[ComponentsImportance["IconPicker"] = 25] = "IconPicker";
275
- ComponentsImportance[ComponentsImportance["Popover"] = 30] = "Popover";
276
+ ComponentsImportance[ComponentsImportance["TopBarComposer"] = 30] = "TopBarComposer";
277
+ ComponentsImportance[ComponentsImportance["Popover"] = 35] = "Popover";
276
278
  ComponentsImportance[ComponentsImportance["ChartAnchor"] = 1000] = "ChartAnchor";
277
279
  })(ComponentsImportance || (ComponentsImportance = {}));
278
280
  const DEFAULT_SHEETVIEW_SIZE = 1000;
@@ -1035,6 +1037,8 @@ function transpose2dArray(matrix) {
1035
1037
  return matrix[0].map((_, i) => matrix.map((row) => row[i]));
1036
1038
  }
1037
1039
 
1040
+ const RBA_REGEX = /rgba?\(|\s+|\)/gi;
1041
+ const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/g;
1038
1042
  const colors$1 = [
1039
1043
  "#eb6d00",
1040
1044
  "#0074d9",
@@ -1060,7 +1064,10 @@ function colorNumberString(color) {
1060
1064
  }
1061
1065
  /**
1062
1066
  * Converts any CSS color value to a standardized hex6 value.
1063
- * Accepts: hex3, hex6, hex8 and rgb (rgba is not supported)
1067
+ * Accepts: hex3, hex6, hex8, rgb[1] and rgba[1].
1068
+ *
1069
+ * [1] under the form rgb(r, g, b, a?) or rgba(r, g, b, a?)
1070
+ * with r,g,b ∈ [0, 255] and a ∈ [0, 1]
1064
1071
  *
1065
1072
  * toHex("#ABC")
1066
1073
  * >> "#AABBCC"
@@ -1071,27 +1078,31 @@ function colorNumberString(color) {
1071
1078
  * toHex("rgb(30, 80, 16)")
1072
1079
  * >> "#1E5010"
1073
1080
  *
1081
+ * * toHex("rgb(30, 80, 16, 0.5)")
1082
+ * >> "#1E501080"
1083
+ *
1074
1084
  */
1075
1085
  function toHex(color) {
1076
- if (color.includes("rgba")) {
1077
- throw new Error(`rgba() conversion currently not supported: ${color}`);
1086
+ let hexColor = color;
1087
+ if (color.startsWith("rgb")) {
1088
+ hexColor = rgbaStringToHex(color);
1078
1089
  }
1079
- if (color.includes("rgb")) {
1080
- return rgbToHex6(color);
1081
- }
1082
- color = color.replace("#", "").toUpperCase();
1083
- if (color.length === 3 || color.length === 4) {
1084
- color = color.split("").reduce((acc, h) => acc + h + h, "");
1090
+ else {
1091
+ hexColor = color.replace("#", "").toUpperCase();
1092
+ if (hexColor.length === 3 || hexColor.length === 4) {
1093
+ hexColor = hexColor.split("").reduce((acc, h) => acc + h + h, "");
1094
+ }
1095
+ hexColor = `#${hexColor}`;
1085
1096
  }
1086
- if (color.replace(/[a-f0-9]/gi, "") !== "") {
1087
- throw new Error("invalid color");
1097
+ if (!hexColor.match(HEX_MATCH)) {
1098
+ throw new Error(`invalid color input: ${color}`);
1088
1099
  }
1089
- return "#" + color;
1100
+ return hexColor;
1090
1101
  }
1091
1102
  function isColorValid(color) {
1092
1103
  try {
1093
- const { r, g, b, a } = colorToRGBA(color);
1094
- return (isColorValueValid(r) && isColorValueValid(g) && isColorValueValid(b) && isColorValueValid(a));
1104
+ toHex(color);
1105
+ return true;
1095
1106
  }
1096
1107
  catch (error) {
1097
1108
  return false;
@@ -1124,15 +1135,29 @@ function relativeLuminance(color) {
1124
1135
  /**
1125
1136
  * Convert a CSS rgb color string to a standardized hex6 color value.
1126
1137
  *
1127
- * rgbToHex6("rgb(30, 80, 16)")
1138
+ * rgbaStringToHex("rgb(30, 80, 16)")
1128
1139
  * >> "#1E5010"
1140
+ *
1141
+ * rgbaStringToHex("rgba(30, 80, 16, 0.5)")
1142
+ * >> "#1E501080"
1143
+ *
1144
+ * DOES NOT SUPPORT NON INTEGER RGB VALUES
1129
1145
  */
1130
- function rgbToHex6(color) {
1131
- return ("#" +
1132
- concat(color
1133
- .slice(4, -1)
1134
- .split(",")
1135
- .map((valueString) => parseInt(valueString, 10).toString(16).padStart(2, "0"))).toUpperCase());
1146
+ function rgbaStringToHex(color) {
1147
+ const stringVals = color.replace(RBA_REGEX, "").split(",");
1148
+ let alphaHex = 255;
1149
+ if (stringVals.length !== 3 && stringVals.length !== 4) {
1150
+ throw new Error("invalid color");
1151
+ }
1152
+ else if (stringVals.length === 4) {
1153
+ const alpha = parseFloat(stringVals.pop() || "1");
1154
+ alphaHex = Math.round((alpha || 1) * 255);
1155
+ }
1156
+ const vals = stringVals.map((val) => parseInt(val, 10));
1157
+ if (alphaHex !== 255) {
1158
+ vals.push(alphaHex);
1159
+ }
1160
+ return "#" + concat(vals.map((value) => value.toString(16).padStart(2, "0"))).toUpperCase();
1136
1161
  }
1137
1162
  /**
1138
1163
  * RGBA to HEX representation (#RRGGBBAA).
@@ -1154,7 +1179,7 @@ function rgbaToHex(rgba) {
1154
1179
  a = "0" + a;
1155
1180
  if (a === "ff")
1156
1181
  a = "";
1157
- return "#" + r + g + b + a;
1182
+ return ("#" + r + g + b + a).toUpperCase();
1158
1183
  }
1159
1184
  /**
1160
1185
  * Color string to RGBA representation
@@ -1275,6 +1300,9 @@ function rgbaToHSLA(rgba) {
1275
1300
  s = +(s * 100).toFixed(1);
1276
1301
  l = +(l * 100).toFixed(1);
1277
1302
  return { a: rgba.a, h, s, l };
1303
+ }
1304
+ function isSameColor(color1, color2) {
1305
+ return isColorValid(color1) && isColorValid(color2) && toHex(color1) === toHex(color2);
1278
1306
  }
1279
1307
 
1280
1308
  /** Reference of a cell (eg. A1, $B$5) */
@@ -1426,7 +1454,7 @@ function scrollDelay(value) {
1426
1454
  * formula, commas are used to separate arguments
1427
1455
  * - it does not support % symbol, in formulas % is an operator
1428
1456
  */
1429
- const formulaNumberRegexp = /^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+/;
1457
+ const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
1430
1458
  const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
1431
1459
  const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
1432
1460
  const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
@@ -3021,6 +3049,7 @@ const CHART_PADDING_RATIO = 0.02;
3021
3049
  const LINE_HEIGHT = 1.2;
3022
3050
  css /* scss */ `
3023
3051
  div.o-scorecard {
3052
+ font-family: ${DEFAULT_FONT};
3024
3053
  user-select: none;
3025
3054
  background-color: white;
3026
3055
  display: flex;
@@ -5645,6 +5674,11 @@ class Popover extends Component {
5645
5674
  this.currentPosition = newPosition;
5646
5675
  });
5647
5676
  }
5677
+ get popoverStyle() {
5678
+ return cssPropertiesToCss({
5679
+ "z-index": `${this.props.zIndex}`,
5680
+ });
5681
+ }
5648
5682
  }
5649
5683
  Popover.template = "o-spreadsheet-Popover";
5650
5684
  Popover.defaultProps = {
@@ -5653,6 +5687,7 @@ Popover.defaultProps = {
5653
5687
  onMouseWheel: () => { },
5654
5688
  onPopoverMoved: () => { },
5655
5689
  onPopoverHidden: () => { },
5690
+ zIndex: ComponentsImportance.Popover,
5656
5691
  };
5657
5692
  Popover.props = {
5658
5693
  anchorRect: Object,
@@ -5664,6 +5699,7 @@ Popover.props = {
5664
5699
  onMouseWheel: { type: Function, optional: true },
5665
5700
  onPopoverHidden: { type: Function, optional: true },
5666
5701
  onPopoverMoved: { type: Function, optional: true },
5702
+ zIndex: { type: Number, optional: true },
5667
5703
  slots: Object,
5668
5704
  };
5669
5705
  class PopoverPositionContext {
@@ -17034,10 +17070,10 @@ css /* scss */ `
17034
17070
  padding: 0;
17035
17071
  margin: 0;
17036
17072
  border: 0;
17037
- z-index: ${ComponentsImportance.Composer};
17038
17073
  flex-grow: 1;
17039
17074
  max-height: inherit;
17040
17075
  .o-composer {
17076
+ font-family: ${DEFAULT_FONT};
17041
17077
  caret-color: black;
17042
17078
  padding-left: 3px;
17043
17079
  padding-right: 3px;
@@ -17072,6 +17108,10 @@ css /* scss */ `
17072
17108
  .o-topbar-toolbar .o-composer-container:focus-within {
17073
17109
  border: 1px solid ${SELECTION_BORDER_COLOR};
17074
17110
  }
17111
+
17112
+ .o-topbar-toolbar .o-composer-container {
17113
+ z-index: ${ComponentsImportance.TopBarComposer};
17114
+ }
17075
17115
  `;
17076
17116
  class Composer extends Component {
17077
17117
  constructor() {
@@ -17520,7 +17560,7 @@ const SCROLLBAR_HIGHT = 15;
17520
17560
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
17521
17561
  css /* scss */ `
17522
17562
  div.o-grid-composer {
17523
- z-index: ${ComponentsImportance.Composer};
17563
+ z-index: ${ComponentsImportance.GridComposer};
17524
17564
  box-sizing: border-box;
17525
17565
  position: absolute;
17526
17566
  border: ${COMPOSER_BORDER_WIDTH}px solid ${SELECTION_BORDER_COLOR};
@@ -20056,6 +20096,9 @@ class ColorPicker extends Component {
20056
20096
  const { display, background, left, top } = this.state.style;
20057
20097
  return `display:${display};${display === "block" ? `background-color:${background};left:${left};top:${top};` : ""}`;
20058
20098
  }
20099
+ isSameColor(color1, color2) {
20100
+ return isSameColor(color1, color2);
20101
+ }
20059
20102
  }
20060
20103
  ColorPicker.template = "o-spreadsheet-ColorPicker";
20061
20104
  ColorPicker.defaultProps = {
@@ -20200,6 +20243,12 @@ class GaugeChartDesignPanel extends Component {
20200
20243
  const cancelledReasons = [...(((_a = this.state.sectionRuleDispatchResult) === null || _a === void 0 ? void 0 : _a.reasons) || [])];
20201
20244
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
20202
20245
  }
20246
+ onClick(ev) {
20247
+ this.state.openedMenu = undefined;
20248
+ }
20249
+ setup() {
20250
+ useExternalListener(window, "click", this.onClick);
20251
+ }
20203
20252
  updateBackgroundColor(color) {
20204
20253
  this.state.openedMenu = undefined;
20205
20254
  this.props.updateChart({
@@ -20383,6 +20432,12 @@ class ScorecardChartDesignPanel extends Component {
20383
20432
  openedColorPicker: undefined,
20384
20433
  });
20385
20434
  }
20435
+ onClick(ev) {
20436
+ this.state.openedColorPicker = undefined;
20437
+ }
20438
+ setup() {
20439
+ useExternalListener(window, "click", this.onClick);
20440
+ }
20386
20441
  updateTitle(ev) {
20387
20442
  this.props.updateChart({
20388
20443
  title: ev.target.value,
@@ -22345,6 +22400,10 @@ GridOverlay.props = {
22345
22400
  };
22346
22401
 
22347
22402
  class GridPopover extends Component {
22403
+ constructor() {
22404
+ super(...arguments);
22405
+ this.zIndex = ComponentsImportance.GridPopover;
22406
+ }
22348
22407
  get cellPopover() {
22349
22408
  const popover = this.env.model.getters.getCellPopover(this.props.hoveredCell);
22350
22409
  if (!popover.isOpen) {
@@ -24562,6 +24621,70 @@ function fixXlsxUnicode(str) {
24562
24621
  });
24563
24622
  }
24564
24623
 
24624
+ const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
24625
+ /**
24626
+ * Convert excel format to o_spreadsheet format
24627
+ *
24628
+ * Excel format are defined in openXML §18.8.31
24629
+ */
24630
+ function convertXlsxFormat(numFmtId, formats, warningManager) {
24631
+ var _a, _b, _c;
24632
+ if (numFmtId === 0) {
24633
+ return undefined;
24634
+ }
24635
+ // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
24636
+ let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
24637
+ if (format) {
24638
+ try {
24639
+ let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
24640
+ convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
24641
+ convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
24642
+ // Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
24643
+ const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
24644
+ const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
24645
+ if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
24646
+ throw new Error("Multiple escaped blocks in format");
24647
+ }
24648
+ convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
24649
+ convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore width of next char for align purposes. Not supported ATM
24650
+ convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
24651
+ convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
24652
+ convertedFormat = convertedFormat.replace(/\\./g, (match) => match[1]); // unescape other characters
24653
+ if (isXlsxDateFormat(convertedFormat)) {
24654
+ convertedFormat = convertDateFormat$1(convertedFormat);
24655
+ }
24656
+ if (isFormatSupported(convertedFormat)) {
24657
+ return convertedFormat;
24658
+ }
24659
+ }
24660
+ catch (e) { }
24661
+ }
24662
+ warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
24663
+ return undefined;
24664
+ }
24665
+ function isFormatSupported(format) {
24666
+ try {
24667
+ formatValue(0, format);
24668
+ return true;
24669
+ }
24670
+ catch (e) {
24671
+ return false;
24672
+ }
24673
+ }
24674
+ function isXlsxDateFormat(format) {
24675
+ return format.match(XLSX_DATE_FORMAT_REGEX) !== null;
24676
+ }
24677
+ function convertDateFormat$1(format) {
24678
+ // Some of these aren't defined neither in the OpenXML spec not the Xlsx extension of OpenXML,
24679
+ // but can still occur and are supported by Excel/Google sheets
24680
+ format = format.toLowerCase();
24681
+ format = format.replace(/mmmmm/g, "mmm");
24682
+ format = format.replace(/am\/pm|a\/m/g, "a");
24683
+ format = format.replace(/hhhh/g, "hh");
24684
+ format = format.replace(/\bh\b/g, "hh");
24685
+ return format;
24686
+ }
24687
+
24565
24688
  function convertBorders(data, warningManager) {
24566
24689
  const borderArray = data.borders.map((border) => {
24567
24690
  addBorderWarnings(border, warningManager);
@@ -24626,41 +24749,6 @@ function convertFormats(data, warningManager) {
24626
24749
  }
24627
24750
  return arrayToObject(formats, 1);
24628
24751
  }
24629
- /**
24630
- * Convert excel format to o_spreadsheet format
24631
- *
24632
- * Excel format are defined in openXML §18.8.31
24633
- */
24634
- function convertXlsxFormat(numFmtId, formats, warningManager) {
24635
- var _a, _b, _c;
24636
- if (numFmtId === 0) {
24637
- return undefined;
24638
- }
24639
- // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
24640
- let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
24641
- if (format) {
24642
- try {
24643
- let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
24644
- convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
24645
- convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
24646
- // Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
24647
- const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
24648
- const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
24649
- if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
24650
- throw new Error("Multiple escaped blocks in format");
24651
- }
24652
- convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
24653
- convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore with of next char for align purposes. Not supported ATM
24654
- convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
24655
- convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
24656
- formatValue(0, convertedFormat);
24657
- return convertedFormat;
24658
- }
24659
- catch (e) { }
24660
- }
24661
- warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
24662
- return undefined;
24663
- }
24664
24752
  /**
24665
24753
  * We currently only support only a set of font sizes, we cannot define new font sizes.
24666
24754
  * This function adapts an arbitrary font size to the closest supported font size.
@@ -31827,9 +31915,7 @@ class CustomColorsPlugin extends UIPlugin {
31827
31915
  // remove duplicates first to check validity on a reduced
31828
31916
  // set of colors, then normalize to HEX and remove duplicates
31829
31917
  // again
31830
- [...new Set([...usedColors, ...this.customColors])]
31831
- .filter(isColorValid)
31832
- .map((c) => toHex(c).toLowerCase())),
31918
+ [...new Set([...usedColors, ...this.customColors])].filter(isColorValid).map(toHex)),
31833
31919
  ]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
31834
31920
  }
31835
31921
  getColorsFromCells(cells) {
@@ -31890,7 +31976,7 @@ class CustomColorsPlugin extends UIPlugin {
31890
31976
  return [...chartsColors];
31891
31977
  }
31892
31978
  tryToAddColor(color) {
31893
- const formattedColor = toHex(color).toLowerCase();
31979
+ const formattedColor = toHex(color);
31894
31980
  if (color && !COLOR_PICKER_DEFAULTS.includes(formattedColor)) {
31895
31981
  this.customColors.add(formattedColor);
31896
31982
  }
@@ -32895,8 +32981,8 @@ class InternalViewport {
32895
32981
  this.getters = getters;
32896
32982
  this.sheetId = sheetId;
32897
32983
  this.boundaries = boundaries;
32898
- this.width = sizeInGrid.width;
32899
- this.height = sizeInGrid.height;
32984
+ this.viewportWidth = sizeInGrid.width;
32985
+ this.viewportHeight = sizeInGrid.height;
32900
32986
  this.offsetScrollbarX = offsets.x;
32901
32987
  this.offsetScrollbarY = offsets.y;
32902
32988
  this.canScrollVertically = options.canScrollVertically;
@@ -32907,6 +32993,10 @@ class InternalViewport {
32907
32993
  this.adjustViewportOffsetY();
32908
32994
  }
32909
32995
  // PUBLIC
32996
+ /** Returns the maximum size (in Pixels) of the viewport relative to its allocated client size
32997
+ * When the viewport grid size is smaller than its client width (resp. height), it will return
32998
+ * the client width (resp. height).
32999
+ */
32910
33000
  getMaxSize() {
32911
33001
  const lastCol = this.getters.findLastVisibleColRowIndex(this.sheetId, "COL", {
32912
33002
  first: this.boundaries.left,
@@ -32918,20 +33008,24 @@ class InternalViewport {
32918
33008
  });
32919
33009
  const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
32920
33010
  const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
32921
- const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.width, 0);
33011
+ const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
32922
33012
  const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
32923
- const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.height, 0);
33013
+ const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
32924
33014
  const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
32925
- const width = lastColEnd -
32926
- this.offsetCorrectionX +
32927
- (this.canScrollHorizontally
32928
- ? Math.max(DEFAULT_CELL_WIDTH, Math.min(leftColSize, this.width - lastColSize))
32929
- : 0);
32930
- const height = lastRowEnd -
32931
- this.offsetCorrectionY +
32932
- (this.canScrollVertically
32933
- ? Math.max(DEFAULT_CELL_HEIGHT + 5, Math.min(topRowSize, this.height - lastRowSize))
32934
- : 0);
33015
+ let width = lastColEnd - this.offsetCorrectionX;
33016
+ if (this.canScrollHorizontally) {
33017
+ width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
33018
+ Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
33019
+ );
33020
+ width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
33021
+ }
33022
+ let height = lastRowEnd - this.offsetCorrectionY;
33023
+ if (this.canScrollVertically) {
33024
+ height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
33025
+ Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
33026
+ );
33027
+ height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
33028
+ }
32935
33029
  return { width, height };
32936
33030
  }
32937
33031
  /**
@@ -32940,7 +33034,7 @@ class InternalViewport {
32940
33034
  * It returns -1 if no column is found.
32941
33035
  */
32942
33036
  getColIndex(x, absolute = false) {
32943
- if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.width) {
33037
+ if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
32944
33038
  return -1;
32945
33039
  }
32946
33040
  return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left, absolute);
@@ -32951,7 +33045,7 @@ class InternalViewport {
32951
33045
  * It returns -1 if no row is found.
32952
33046
  */
32953
33047
  getRowIndex(y, absolute = false) {
32954
- if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.height) {
33048
+ if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
32955
33049
  return -1;
32956
33050
  }
32957
33051
  return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top, absolute);
@@ -32978,7 +33072,7 @@ class InternalViewport {
32978
33072
  adjustPositionX(col) {
32979
33073
  const sheetId = this.sheetId;
32980
33074
  const { start, end } = this.getters.getColDimensions(sheetId, col);
32981
- while (end > this.offsetX + this.offsetCorrectionX + this.width &&
33075
+ while (end > this.offsetX + this.offsetCorrectionX + this.viewportWidth &&
32982
33076
  this.offsetX + this.offsetCorrectionX < start) {
32983
33077
  this.offsetX = this.getters.getColDimensions(sheetId, this.left).end - this.offsetCorrectionX;
32984
33078
  this.offsetScrollbarX = this.offsetX;
@@ -33000,7 +33094,7 @@ class InternalViewport {
33000
33094
  adjustPositionY(row) {
33001
33095
  const sheetId = this.sheetId;
33002
33096
  while (this.getters.getRowDimensions(sheetId, row).end >
33003
- this.offsetY + this.height + this.offsetCorrectionY &&
33097
+ this.offsetY + this.viewportHeight + this.offsetCorrectionY &&
33004
33098
  this.offsetY + this.offsetCorrectionY < this.getters.getRowDimensions(sheetId, row).start) {
33005
33099
  this.offsetY = this.getters.getRowDimensions(sheetId, this.top).end - this.offsetCorrectionY;
33006
33100
  this.offsetScrollbarY = this.offsetY;
@@ -33038,8 +33132,8 @@ class InternalViewport {
33038
33132
  const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
33039
33133
  this.offsetCorrectionX;
33040
33134
  const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
33041
- const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.width);
33042
- const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.height);
33135
+ const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
33136
+ const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
33043
33137
  return {
33044
33138
  x,
33045
33139
  y,
@@ -33102,12 +33196,12 @@ class InternalViewport {
33102
33196
  adjustViewportOffsetX() {
33103
33197
  if (this.canScrollHorizontally) {
33104
33198
  const { width: viewportWidth } = this.getMaxSize();
33105
- if (this.width + this.offsetScrollbarX > viewportWidth) {
33106
- this.offsetScrollbarX = Math.max(0, viewportWidth - this.width);
33199
+ if (this.viewportWidth + this.offsetScrollbarX > viewportWidth) {
33200
+ this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
33107
33201
  }
33108
33202
  }
33109
33203
  this.left = this.getColIndex(this.offsetScrollbarX, true);
33110
- this.right = this.getColIndex(this.offsetScrollbarX + this.width, true);
33204
+ this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth, true);
33111
33205
  if (this.right === -1) {
33112
33206
  this.right = this.boundaries.right;
33113
33207
  }
@@ -33119,12 +33213,12 @@ class InternalViewport {
33119
33213
  adjustViewportOffsetY() {
33120
33214
  if (this.canScrollVertically) {
33121
33215
  const { height: paneHeight } = this.getMaxSize();
33122
- if (this.height + this.offsetScrollbarY > paneHeight) {
33123
- this.offsetScrollbarY = Math.max(0, paneHeight - this.height);
33216
+ if (this.viewportHeight + this.offsetScrollbarY > paneHeight) {
33217
+ this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
33124
33218
  }
33125
33219
  }
33126
33220
  this.top = this.getRowIndex(this.offsetScrollbarY, true);
33127
- this.bottom = this.getRowIndex(this.offsetScrollbarY + this.width, true);
33221
+ this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportWidth, true);
33128
33222
  if (this.bottom === -1) {
33129
33223
  this.bottom = this.boundaries.bottom;
33130
33224
  }
@@ -33135,7 +33229,7 @@ class InternalViewport {
33135
33229
  adjustViewportZoneX() {
33136
33230
  const sheetId = this.sheetId;
33137
33231
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
33138
- this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.width, this.left));
33232
+ this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
33139
33233
  if (this.right === -1) {
33140
33234
  this.right = this.getters.getNumberCols(sheetId) - 1;
33141
33235
  }
@@ -33148,7 +33242,7 @@ class InternalViewport {
33148
33242
  adjustViewportZoneY() {
33149
33243
  const sheetId = this.sheetId;
33150
33244
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
33151
- this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.height, this.top));
33245
+ this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
33152
33246
  if (this.bottom === -1) {
33153
33247
  this.bottom = this.getters.getNumberRows(sheetId) - 1;
33154
33248
  }
@@ -33410,8 +33504,7 @@ class SheetViewPlugin extends UIPlugin {
33410
33504
  return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
33411
33505
  }
33412
33506
  /**
33413
- * Return the main viewport maximum size. That is the zone dimension
33414
- * with some bottom and right padding.
33507
+ * Return the main viewport maximum size relative to the client size.
33415
33508
  */
33416
33509
  getMainViewportRect() {
33417
33510
  const sheetId = this.getters.getActiveSheetId();
@@ -33427,8 +33520,8 @@ class SheetViewPlugin extends UIPlugin {
33427
33520
  const { width, height } = this.getMainViewportRect();
33428
33521
  const viewport = this.getMainInternalViewport(sheetId);
33429
33522
  return {
33430
- maxOffsetX: Math.max(0, width - viewport.width + 1),
33431
- maxOffsetY: Math.max(0, height - viewport.height + 1),
33523
+ maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
33524
+ maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
33432
33525
  };
33433
33526
  }
33434
33527
  getColRowOffsetInViewport(dimension, referenceIndex, index) {
@@ -40132,9 +40225,6 @@ css /* scss */ `
40132
40225
  color: #333;
40133
40226
  }
40134
40227
 
40135
- * {
40136
- font-family: "Roboto", "RobotoDraft", Helvetica, Arial, sans-serif;
40137
- }
40138
40228
  &,
40139
40229
  *,
40140
40230
  *:before,
@@ -43902,6 +43992,6 @@ function addFunction(functionName, functionDescription) {
43902
43992
  export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
43903
43993
 
43904
43994
 
43905
- __info__.version = '16.1.6';
43906
- __info__.date = '2023-03-23T11:36:48.524Z';
43907
- __info__.hash = '3bad828';
43995
+ __info__.version = '16.1.7';
43996
+ __info__.date = '2023-04-13T08:29:52.140Z';
43997
+ __info__.hash = '3141a6d';