@odoo/o-spreadsheet 19.1.0-alpha.8 → 19.1.0-alpha.9

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.1.0-alpha.8
6
- * @date 2025-10-23T08:20:05.310Z
7
- * @hash 78717d4
5
+ * @version 19.1.0-alpha.9
6
+ * @date 2025-10-23T11:12:55.400Z
7
+ * @hash bd756dd
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -487,8 +487,17 @@ function isObjectEmptyRecursive(argument) {
487
487
  /**
488
488
  * Returns a function, that, as long as it continues to be invoked, will not
489
489
  * be triggered. The function will be called after it stops being called for
490
- * N milliseconds. If `immediate` is passed, trigger the function on the
491
- * leading edge, instead of the trailing.
490
+ * N milliseconds. If `immediate` is passed, the function is called is called
491
+ * immediately on the first call and the debouncing is triggered starting the second
492
+ * call in the defined time window.
493
+ *
494
+ * Example:
495
+ * debouncedFunction = debounce(() => console.log('Hello!'), 250);
496
+ * debouncedFunction(); debouncedFunction(); // Will log 'Hello!' after 250ms
497
+ *
498
+ * debouncedFunction = debounce(() => console.log('Hello!'), 250, true);
499
+ * debouncedFunction(); debouncedFunction(); // Will log 'Hello!' and relog it after 250ms
500
+ *
492
501
  *
493
502
  * Also decorate the argument function with two methods: stopDebounce and isDebouncePending.
494
503
  *
@@ -496,21 +505,21 @@ function isObjectEmptyRecursive(argument) {
496
505
  */
497
506
  function debounce(func, wait, immediate) {
498
507
  let timeout = undefined;
508
+ let firstCalled = false;
499
509
  const debounced = function () {
500
510
  const context = this;
501
511
  const args = Array.from(arguments);
512
+ if (!firstCalled && immediate) {
513
+ firstCalled = true;
514
+ return func.apply(context, args);
515
+ }
502
516
  function later() {
503
517
  timeout = undefined;
504
- if (!immediate) {
505
- func.apply(context, args);
506
- }
518
+ firstCalled = false;
519
+ func.apply(context, args);
507
520
  }
508
- const callNow = immediate && !timeout;
509
521
  clearTimeout(timeout);
510
522
  timeout = setTimeout(later, wait);
511
- if (callNow) {
512
- func.apply(context, args);
513
- }
514
523
  };
515
524
  debounced.isDebouncePending = () => timeout !== undefined;
516
525
  debounced.stopDebounce = () => {
@@ -73124,39 +73133,38 @@ function useAutofocus({ refName }) {
73124
73133
  }, () => [ref.el]);
73125
73134
  }
73126
73135
 
73127
- class TextInput extends Component {
73128
- static template = "o-spreadsheet-TextInput";
73136
+ class GenericInput extends Component {
73129
73137
  static props = {
73130
- value: String,
73138
+ value: [Number, String],
73131
73139
  onChange: Function,
73132
- class: {
73133
- type: String,
73134
- optional: true,
73135
- },
73136
- id: {
73137
- type: String,
73138
- optional: true,
73139
- },
73140
- placeholder: {
73141
- type: String,
73142
- optional: true,
73143
- },
73144
- autofocus: {
73145
- type: Boolean,
73146
- optional: true,
73147
- },
73140
+ class: { type: String, optional: true },
73141
+ id: { type: String, optional: true },
73142
+ placeholder: { type: String, optional: true },
73143
+ autofocus: { type: Boolean, optional: true },
73148
73144
  alwaysShowBorder: { type: Boolean, optional: true },
73145
+ selectContentOnFocus: { type: Boolean, optional: true },
73149
73146
  };
73150
- inputRef = useRef("input");
73147
+ refName = "input";
73148
+ inputRef;
73151
73149
  setup() {
73150
+ this.inputRef = useRef(this.refName);
73152
73151
  useExternalListener(window, "click", (ev) => {
73153
73152
  if (ev.target !== this.inputRef.el && this.inputRef.el?.value !== this.props.value) {
73154
73153
  this.save();
73155
73154
  }
73156
73155
  }, { capture: true });
73157
73156
  if (this.props.autofocus) {
73158
- useAutofocus({ refName: "input" });
73157
+ useAutofocus({ refName: this.refName });
73159
73158
  }
73159
+ onWillUpdateProps((nextProps) => {
73160
+ if (document.activeElement !== this.inputRef.el && this.inputRef.el) {
73161
+ this.inputRef.el.value = nextProps.value;
73162
+ }
73163
+ });
73164
+ onMounted(() => {
73165
+ if (this.inputRef.el)
73166
+ this.inputRef.el.value = this.props.value.toString();
73167
+ });
73160
73168
  }
73161
73169
  onKeyDown(ev) {
73162
73170
  switch (ev.key) {
@@ -73167,7 +73175,7 @@ class TextInput extends Component {
73167
73175
  break;
73168
73176
  case "Escape":
73169
73177
  if (this.inputRef.el) {
73170
- this.inputRef.el.value = this.props.value;
73178
+ this.inputRef.el.value = this.props.value.toString();
73171
73179
  this.inputRef.el.blur();
73172
73180
  }
73173
73181
  ev.preventDefault();
@@ -73175,12 +73183,14 @@ class TextInput extends Component {
73175
73183
  break;
73176
73184
  }
73177
73185
  }
73178
- save() {
73186
+ save(keepFocus = false) {
73179
73187
  const currentValue = (this.inputRef.el?.value || "").trim();
73180
- if (currentValue !== this.props.value) {
73188
+ if (currentValue !== this.props.value.toString()) {
73181
73189
  this.props.onChange(currentValue);
73182
73190
  }
73183
- this.inputRef.el?.blur();
73191
+ if (!keepFocus) {
73192
+ this.inputRef.el?.blur();
73193
+ }
73184
73194
  }
73185
73195
  onMouseDown(ev) {
73186
73196
  // Stop the event if the input is not focused, we handle everything in onMouseUp
@@ -73193,13 +73203,25 @@ class TextInput extends Component {
73193
73203
  const target = ev.target;
73194
73204
  if (target !== document.activeElement) {
73195
73205
  target.focus();
73196
- target.select();
73206
+ if (this.props.selectContentOnFocus) {
73207
+ target.select();
73208
+ }
73197
73209
  ev.preventDefault();
73198
73210
  ev.stopPropagation();
73199
73211
  }
73200
73212
  }
73213
+ }
73214
+
73215
+ class TextInput extends GenericInput {
73216
+ static template = "o-spreadsheet-TextInput";
73217
+ static components = {};
73218
+ static props = GenericInput.props;
73201
73219
  get inputClass() {
73202
- return [this.props.class, this.props.alwaysShowBorder ? "o-input-border" : undefined]
73220
+ return [
73221
+ this.props.class,
73222
+ "w-100 os-input",
73223
+ this.props.alwaysShowBorder ? "o-input-border" : undefined,
73224
+ ]
73203
73225
  .filter(isDefined$1)
73204
73226
  .join(" ");
73205
73227
  }
@@ -73309,6 +73331,16 @@ class FontSizeEditor extends Component {
73309
73331
  fontSizeListRef = useRef("fontSizeList");
73310
73332
  setup() {
73311
73333
  useExternalListener(window, "click", this.onExternalClick, { capture: true });
73334
+ onWillUpdateProps((nextProps) => {
73335
+ if (this.inputRef.el && document.activeElement !== this.inputRef.el) {
73336
+ this.inputRef.el.value = nextProps.currentFontSize;
73337
+ }
73338
+ });
73339
+ onMounted(() => {
73340
+ if (this.inputRef.el) {
73341
+ this.inputRef.el.value = this.props.currentFontSize.toString();
73342
+ }
73343
+ });
73312
73344
  }
73313
73345
  get popoverProps() {
73314
73346
  const { x, y, width, height } = this.rootEditorRef.el.getBoundingClientRect();
@@ -74202,7 +74234,7 @@ class BadgeSelection extends Component {
74202
74234
 
74203
74235
  class ChartTitle extends Component {
74204
74236
  static template = "o-spreadsheet.ChartTitle";
74205
- static components = { Section, TextStyler };
74237
+ static components = { Section, TextStyler, TextInput };
74206
74238
  static props = {
74207
74239
  title: { type: String, optional: true },
74208
74240
  placeholder: { type: String, optional: true },
@@ -74216,8 +74248,8 @@ class ChartTitle extends Component {
74216
74248
  title: "",
74217
74249
  placeholder: "",
74218
74250
  };
74219
- updateTitle(ev) {
74220
- this.props.updateTitle(ev.target.value);
74251
+ updateTitle(value) {
74252
+ this.props.updateTitle(value);
74221
74253
  }
74222
74254
  }
74223
74255
 
@@ -74361,6 +74393,27 @@ class ChartLegend extends Component {
74361
74393
  }
74362
74394
  }
74363
74395
 
74396
+ class NumberInput extends GenericInput {
74397
+ static template = "o-spreadsheet-NumberInput";
74398
+ static components = {};
74399
+ static props = {
74400
+ ...GenericInput.props,
74401
+ min: { type: Number, optional: true },
74402
+ max: { type: Number, optional: true },
74403
+ };
74404
+ // Very short debounce to prevent up/down arrow on number input to spam the onChange
74405
+ debouncedOnChange = debounce(this.props.onChange.bind(this), 100, true);
74406
+ save() {
74407
+ const currentValue = (this.inputRef.el?.value || "").trim();
74408
+ if (currentValue !== this.props.value.toString()) {
74409
+ this.debouncedOnChange(currentValue);
74410
+ }
74411
+ }
74412
+ get inputClass() {
74413
+ return [this.props.class, "o-input"].join(" ");
74414
+ }
74415
+ }
74416
+
74364
74417
  class SeriesDesignEditor extends Component {
74365
74418
  static template = "o-spreadsheet-SeriesDesignEditor";
74366
74419
  static components = {
@@ -74432,6 +74485,7 @@ class SeriesWithAxisDesignEditor extends Component {
74432
74485
  RadioSelection,
74433
74486
  Section,
74434
74487
  RoundColorPicker,
74488
+ NumberInput,
74435
74489
  };
74436
74490
  static props = {
74437
74491
  chartId: String,
@@ -74523,9 +74577,8 @@ class SeriesWithAxisDesignEditor extends Component {
74523
74577
  get defaultWindowSize() {
74524
74578
  return DEFAULT_WINDOW_SIZE;
74525
74579
  }
74526
- onChangeMovingAverageWindow(index, ev) {
74527
- const element = ev.target;
74528
- let window = parseInt(element.value) || DEFAULT_WINDOW_SIZE;
74580
+ onChangeMovingAverageWindow(index, value) {
74581
+ let window = parseInt(value) || DEFAULT_WINDOW_SIZE;
74529
74582
  if (window <= 1) {
74530
74583
  window = DEFAULT_WINDOW_SIZE;
74531
74584
  }
@@ -75054,10 +75107,8 @@ class LineChartDesignPanel extends GenericZoomableChartDesignPanel {
75054
75107
 
75055
75108
  class PieHoleSize extends Component {
75056
75109
  static template = "o-spreadsheet.PieHoleSize";
75057
- static components = { Section };
75110
+ static components = { Section, NumberInput };
75058
75111
  static props = { onValueChange: Function, value: Number };
75059
- // Very short debounce to prevent up/down arrow on number input to spam the onChange
75060
- debouncedOnChange = debounce(this.onChange.bind(this), 100);
75061
75112
  onChange(value) {
75062
75113
  if (!isNaN(Number(value))) {
75063
75114
  this.props.onValueChange(clip(Number(value), 0, 95));
@@ -79261,7 +79312,14 @@ class TableStylePicker extends Component {
79261
79312
 
79262
79313
  class TablePanel extends Component {
79263
79314
  static template = "o-spreadsheet-TablePanel";
79264
- static components = { TableStylePicker, SelectionInput, ValidationMessages, Checkbox, Section };
79315
+ static components = {
79316
+ TableStylePicker,
79317
+ SelectionInput,
79318
+ ValidationMessages,
79319
+ Checkbox,
79320
+ Section,
79321
+ NumberInput,
79322
+ };
79265
79323
  static props = { onCloseSidePanel: Function, table: Object };
79266
79324
  state;
79267
79325
  setup() {
@@ -79311,13 +79369,9 @@ class TablePanel extends Component {
79311
79369
  this.state.tableZoneErrors = [];
79312
79370
  }
79313
79371
  }
79314
- onChangeNumberOfHeaders(ev) {
79315
- const input = ev.target;
79316
- const numberOfHeaders = parseInt(input.value);
79317
- const result = this.updateNumberOfHeaders(numberOfHeaders);
79318
- if (!result.isSuccessful) {
79319
- input.value = this.props.table.config.numberOfHeaders.toString();
79320
- }
79372
+ onChangeNumberOfHeaders(value) {
79373
+ const numberOfHeaders = parseInt(value);
79374
+ this.updateNumberOfHeaders(numberOfHeaders);
79321
79375
  }
79322
79376
  updateNumberOfHeaders(numberOfHeaders) {
79323
79377
  const hasFilters = numberOfHeaders > 0 && (this.tableConfig.hasFilters || this.state.filtersEnabledIfPossible);
@@ -87802,6 +87856,7 @@ const components = {
87802
87856
  GeoChartRegionSelectSection,
87803
87857
  ChartDashboardMenu,
87804
87858
  FullScreenFigure,
87859
+ NumberInput,
87805
87860
  };
87806
87861
  const hooks = {
87807
87862
  useDragAndDropListItems,
@@ -87851,6 +87906,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
87851
87906
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType$1 as CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DEFAULT_LOCALE, DEFAULT_LOCALES, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, categories, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, createAutocompleteArgumentsProvider, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
87852
87907
 
87853
87908
 
87854
- __info__.version = "19.1.0-alpha.8";
87855
- __info__.date = "2025-10-23T08:20:05.310Z";
87856
- __info__.hash = "78717d4";
87909
+ __info__.version = "19.1.0-alpha.9";
87910
+ __info__.date = "2025-10-23T11:12:55.400Z";
87911
+ __info__.hash = "bd756dd";
@@ -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.1.0-alpha.8
6
- * @date 2025-10-23T08:20:05.310Z
7
- * @hash 78717d4
5
+ * @version 19.1.0-alpha.9
6
+ * @date 2025-10-23T11:12:55.400Z
7
+ * @hash bd756dd
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -488,8 +488,17 @@
488
488
  /**
489
489
  * Returns a function, that, as long as it continues to be invoked, will not
490
490
  * be triggered. The function will be called after it stops being called for
491
- * N milliseconds. If `immediate` is passed, trigger the function on the
492
- * leading edge, instead of the trailing.
491
+ * N milliseconds. If `immediate` is passed, the function is called is called
492
+ * immediately on the first call and the debouncing is triggered starting the second
493
+ * call in the defined time window.
494
+ *
495
+ * Example:
496
+ * debouncedFunction = debounce(() => console.log('Hello!'), 250);
497
+ * debouncedFunction(); debouncedFunction(); // Will log 'Hello!' after 250ms
498
+ *
499
+ * debouncedFunction = debounce(() => console.log('Hello!'), 250, true);
500
+ * debouncedFunction(); debouncedFunction(); // Will log 'Hello!' and relog it after 250ms
501
+ *
493
502
  *
494
503
  * Also decorate the argument function with two methods: stopDebounce and isDebouncePending.
495
504
  *
@@ -497,21 +506,21 @@
497
506
  */
498
507
  function debounce(func, wait, immediate) {
499
508
  let timeout = undefined;
509
+ let firstCalled = false;
500
510
  const debounced = function () {
501
511
  const context = this;
502
512
  const args = Array.from(arguments);
513
+ if (!firstCalled && immediate) {
514
+ firstCalled = true;
515
+ return func.apply(context, args);
516
+ }
503
517
  function later() {
504
518
  timeout = undefined;
505
- if (!immediate) {
506
- func.apply(context, args);
507
- }
519
+ firstCalled = false;
520
+ func.apply(context, args);
508
521
  }
509
- const callNow = immediate && !timeout;
510
522
  clearTimeout(timeout);
511
523
  timeout = setTimeout(later, wait);
512
- if (callNow) {
513
- func.apply(context, args);
514
- }
515
524
  };
516
525
  debounced.isDebouncePending = () => timeout !== undefined;
517
526
  debounced.stopDebounce = () => {
@@ -73125,39 +73134,38 @@ stores.inject(MyMetaStore, storeInstance);
73125
73134
  }, () => [ref.el]);
73126
73135
  }
73127
73136
 
73128
- class TextInput extends owl.Component {
73129
- static template = "o-spreadsheet-TextInput";
73137
+ class GenericInput extends owl.Component {
73130
73138
  static props = {
73131
- value: String,
73139
+ value: [Number, String],
73132
73140
  onChange: Function,
73133
- class: {
73134
- type: String,
73135
- optional: true,
73136
- },
73137
- id: {
73138
- type: String,
73139
- optional: true,
73140
- },
73141
- placeholder: {
73142
- type: String,
73143
- optional: true,
73144
- },
73145
- autofocus: {
73146
- type: Boolean,
73147
- optional: true,
73148
- },
73141
+ class: { type: String, optional: true },
73142
+ id: { type: String, optional: true },
73143
+ placeholder: { type: String, optional: true },
73144
+ autofocus: { type: Boolean, optional: true },
73149
73145
  alwaysShowBorder: { type: Boolean, optional: true },
73146
+ selectContentOnFocus: { type: Boolean, optional: true },
73150
73147
  };
73151
- inputRef = owl.useRef("input");
73148
+ refName = "input";
73149
+ inputRef;
73152
73150
  setup() {
73151
+ this.inputRef = owl.useRef(this.refName);
73153
73152
  owl.useExternalListener(window, "click", (ev) => {
73154
73153
  if (ev.target !== this.inputRef.el && this.inputRef.el?.value !== this.props.value) {
73155
73154
  this.save();
73156
73155
  }
73157
73156
  }, { capture: true });
73158
73157
  if (this.props.autofocus) {
73159
- useAutofocus({ refName: "input" });
73158
+ useAutofocus({ refName: this.refName });
73160
73159
  }
73160
+ owl.onWillUpdateProps((nextProps) => {
73161
+ if (document.activeElement !== this.inputRef.el && this.inputRef.el) {
73162
+ this.inputRef.el.value = nextProps.value;
73163
+ }
73164
+ });
73165
+ owl.onMounted(() => {
73166
+ if (this.inputRef.el)
73167
+ this.inputRef.el.value = this.props.value.toString();
73168
+ });
73161
73169
  }
73162
73170
  onKeyDown(ev) {
73163
73171
  switch (ev.key) {
@@ -73168,7 +73176,7 @@ stores.inject(MyMetaStore, storeInstance);
73168
73176
  break;
73169
73177
  case "Escape":
73170
73178
  if (this.inputRef.el) {
73171
- this.inputRef.el.value = this.props.value;
73179
+ this.inputRef.el.value = this.props.value.toString();
73172
73180
  this.inputRef.el.blur();
73173
73181
  }
73174
73182
  ev.preventDefault();
@@ -73176,12 +73184,14 @@ stores.inject(MyMetaStore, storeInstance);
73176
73184
  break;
73177
73185
  }
73178
73186
  }
73179
- save() {
73187
+ save(keepFocus = false) {
73180
73188
  const currentValue = (this.inputRef.el?.value || "").trim();
73181
- if (currentValue !== this.props.value) {
73189
+ if (currentValue !== this.props.value.toString()) {
73182
73190
  this.props.onChange(currentValue);
73183
73191
  }
73184
- this.inputRef.el?.blur();
73192
+ if (!keepFocus) {
73193
+ this.inputRef.el?.blur();
73194
+ }
73185
73195
  }
73186
73196
  onMouseDown(ev) {
73187
73197
  // Stop the event if the input is not focused, we handle everything in onMouseUp
@@ -73194,13 +73204,25 @@ stores.inject(MyMetaStore, storeInstance);
73194
73204
  const target = ev.target;
73195
73205
  if (target !== document.activeElement) {
73196
73206
  target.focus();
73197
- target.select();
73207
+ if (this.props.selectContentOnFocus) {
73208
+ target.select();
73209
+ }
73198
73210
  ev.preventDefault();
73199
73211
  ev.stopPropagation();
73200
73212
  }
73201
73213
  }
73214
+ }
73215
+
73216
+ class TextInput extends GenericInput {
73217
+ static template = "o-spreadsheet-TextInput";
73218
+ static components = {};
73219
+ static props = GenericInput.props;
73202
73220
  get inputClass() {
73203
- return [this.props.class, this.props.alwaysShowBorder ? "o-input-border" : undefined]
73221
+ return [
73222
+ this.props.class,
73223
+ "w-100 os-input",
73224
+ this.props.alwaysShowBorder ? "o-input-border" : undefined,
73225
+ ]
73204
73226
  .filter(isDefined$1)
73205
73227
  .join(" ");
73206
73228
  }
@@ -73310,6 +73332,16 @@ stores.inject(MyMetaStore, storeInstance);
73310
73332
  fontSizeListRef = owl.useRef("fontSizeList");
73311
73333
  setup() {
73312
73334
  owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
73335
+ owl.onWillUpdateProps((nextProps) => {
73336
+ if (this.inputRef.el && document.activeElement !== this.inputRef.el) {
73337
+ this.inputRef.el.value = nextProps.currentFontSize;
73338
+ }
73339
+ });
73340
+ owl.onMounted(() => {
73341
+ if (this.inputRef.el) {
73342
+ this.inputRef.el.value = this.props.currentFontSize.toString();
73343
+ }
73344
+ });
73313
73345
  }
73314
73346
  get popoverProps() {
73315
73347
  const { x, y, width, height } = this.rootEditorRef.el.getBoundingClientRect();
@@ -74203,7 +74235,7 @@ stores.inject(MyMetaStore, storeInstance);
74203
74235
 
74204
74236
  class ChartTitle extends owl.Component {
74205
74237
  static template = "o-spreadsheet.ChartTitle";
74206
- static components = { Section, TextStyler };
74238
+ static components = { Section, TextStyler, TextInput };
74207
74239
  static props = {
74208
74240
  title: { type: String, optional: true },
74209
74241
  placeholder: { type: String, optional: true },
@@ -74217,8 +74249,8 @@ stores.inject(MyMetaStore, storeInstance);
74217
74249
  title: "",
74218
74250
  placeholder: "",
74219
74251
  };
74220
- updateTitle(ev) {
74221
- this.props.updateTitle(ev.target.value);
74252
+ updateTitle(value) {
74253
+ this.props.updateTitle(value);
74222
74254
  }
74223
74255
  }
74224
74256
 
@@ -74362,6 +74394,27 @@ stores.inject(MyMetaStore, storeInstance);
74362
74394
  }
74363
74395
  }
74364
74396
 
74397
+ class NumberInput extends GenericInput {
74398
+ static template = "o-spreadsheet-NumberInput";
74399
+ static components = {};
74400
+ static props = {
74401
+ ...GenericInput.props,
74402
+ min: { type: Number, optional: true },
74403
+ max: { type: Number, optional: true },
74404
+ };
74405
+ // Very short debounce to prevent up/down arrow on number input to spam the onChange
74406
+ debouncedOnChange = debounce(this.props.onChange.bind(this), 100, true);
74407
+ save() {
74408
+ const currentValue = (this.inputRef.el?.value || "").trim();
74409
+ if (currentValue !== this.props.value.toString()) {
74410
+ this.debouncedOnChange(currentValue);
74411
+ }
74412
+ }
74413
+ get inputClass() {
74414
+ return [this.props.class, "o-input"].join(" ");
74415
+ }
74416
+ }
74417
+
74365
74418
  class SeriesDesignEditor extends owl.Component {
74366
74419
  static template = "o-spreadsheet-SeriesDesignEditor";
74367
74420
  static components = {
@@ -74433,6 +74486,7 @@ stores.inject(MyMetaStore, storeInstance);
74433
74486
  RadioSelection,
74434
74487
  Section,
74435
74488
  RoundColorPicker,
74489
+ NumberInput,
74436
74490
  };
74437
74491
  static props = {
74438
74492
  chartId: String,
@@ -74524,9 +74578,8 @@ stores.inject(MyMetaStore, storeInstance);
74524
74578
  get defaultWindowSize() {
74525
74579
  return DEFAULT_WINDOW_SIZE;
74526
74580
  }
74527
- onChangeMovingAverageWindow(index, ev) {
74528
- const element = ev.target;
74529
- let window = parseInt(element.value) || DEFAULT_WINDOW_SIZE;
74581
+ onChangeMovingAverageWindow(index, value) {
74582
+ let window = parseInt(value) || DEFAULT_WINDOW_SIZE;
74530
74583
  if (window <= 1) {
74531
74584
  window = DEFAULT_WINDOW_SIZE;
74532
74585
  }
@@ -75055,10 +75108,8 @@ stores.inject(MyMetaStore, storeInstance);
75055
75108
 
75056
75109
  class PieHoleSize extends owl.Component {
75057
75110
  static template = "o-spreadsheet.PieHoleSize";
75058
- static components = { Section };
75111
+ static components = { Section, NumberInput };
75059
75112
  static props = { onValueChange: Function, value: Number };
75060
- // Very short debounce to prevent up/down arrow on number input to spam the onChange
75061
- debouncedOnChange = debounce(this.onChange.bind(this), 100);
75062
75113
  onChange(value) {
75063
75114
  if (!isNaN(Number(value))) {
75064
75115
  this.props.onValueChange(clip(Number(value), 0, 95));
@@ -79262,7 +79313,14 @@ stores.inject(MyMetaStore, storeInstance);
79262
79313
 
79263
79314
  class TablePanel extends owl.Component {
79264
79315
  static template = "o-spreadsheet-TablePanel";
79265
- static components = { TableStylePicker, SelectionInput, ValidationMessages, Checkbox, Section };
79316
+ static components = {
79317
+ TableStylePicker,
79318
+ SelectionInput,
79319
+ ValidationMessages,
79320
+ Checkbox,
79321
+ Section,
79322
+ NumberInput,
79323
+ };
79266
79324
  static props = { onCloseSidePanel: Function, table: Object };
79267
79325
  state;
79268
79326
  setup() {
@@ -79312,13 +79370,9 @@ stores.inject(MyMetaStore, storeInstance);
79312
79370
  this.state.tableZoneErrors = [];
79313
79371
  }
79314
79372
  }
79315
- onChangeNumberOfHeaders(ev) {
79316
- const input = ev.target;
79317
- const numberOfHeaders = parseInt(input.value);
79318
- const result = this.updateNumberOfHeaders(numberOfHeaders);
79319
- if (!result.isSuccessful) {
79320
- input.value = this.props.table.config.numberOfHeaders.toString();
79321
- }
79373
+ onChangeNumberOfHeaders(value) {
79374
+ const numberOfHeaders = parseInt(value);
79375
+ this.updateNumberOfHeaders(numberOfHeaders);
79322
79376
  }
79323
79377
  updateNumberOfHeaders(numberOfHeaders) {
79324
79378
  const hasFilters = numberOfHeaders > 0 && (this.tableConfig.hasFilters || this.state.filtersEnabledIfPossible);
@@ -87803,6 +87857,7 @@ stores.inject(MyMetaStore, storeInstance);
87803
87857
  GeoChartRegionSelectSection,
87804
87858
  ChartDashboardMenu,
87805
87859
  FullScreenFigure,
87860
+ NumberInput,
87806
87861
  };
87807
87862
  const hooks = {
87808
87863
  useDragAndDropListItems,
@@ -87906,9 +87961,9 @@ stores.inject(MyMetaStore, storeInstance);
87906
87961
  exports.tokenize = tokenize;
87907
87962
 
87908
87963
 
87909
- __info__.version = "19.1.0-alpha.8";
87910
- __info__.date = "2025-10-23T08:20:05.310Z";
87911
- __info__.hash = "78717d4";
87964
+ __info__.version = "19.1.0-alpha.9";
87965
+ __info__.date = "2025-10-23T11:12:55.400Z";
87966
+ __info__.hash = "bd756dd";
87912
87967
 
87913
87968
 
87914
87969
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);