@guiexpert/table 1.1.93 → 1.1.96

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.
Files changed (123) hide show
  1. package/README.md +25 -0
  2. package/css/main.css +334 -0
  3. package/css/table-calc.css +7 -0
  4. package/css/table-classes.css +34 -0
  5. package/css/table-color-vars.css +78 -0
  6. package/css/table-fill-batch.css +58 -0
  7. package/css/table-pivot.css +42 -0
  8. package/css/table-row-drag.css +81 -0
  9. package/css/table-row-group.css +25 -0
  10. package/css/table-tree.css +9 -0
  11. package/index.cjs +57 -47
  12. package/index.d.ts +67 -0
  13. package/index.js +11290 -4985
  14. package/lib/table/action/action-id.type.d.ts +1 -1
  15. package/lib/table/aggregation/aggregate-internals.d.ts +30 -0
  16. package/lib/table/aggregation/aggregate-spec.if.d.ts +51 -0
  17. package/lib/table/aggregation/aggregate.d.ts +58 -0
  18. package/lib/table/aggregation/aggregator-name.type.d.ts +39 -0
  19. package/lib/table/aggregation/aggregator.if.d.ts +51 -0
  20. package/lib/table/aggregation/aggregators.d.ts +37 -0
  21. package/lib/table/aggregation/create-value-getter.d.ts +18 -0
  22. package/lib/table/aggregation/selection-aggregates.if.d.ts +35 -0
  23. package/lib/table/aggregation/value-accessor.type.d.ts +13 -0
  24. package/lib/table/aria/aria-texts.d.ts +11 -0
  25. package/lib/table/aria/aria-texts.if.d.ts +87 -0
  26. package/lib/table/batch-edit/batch-edit-options.d.ts +21 -0
  27. package/lib/table/batch-edit/batch-edit-options.if.d.ts +20 -0
  28. package/lib/table/batch-edit/batch-edit-service.d.ts +104 -0
  29. package/lib/table/batch-edit/cell-change.if.d.ts +39 -0
  30. package/lib/table/batch-edit/cell-value-change.if.d.ts +18 -0
  31. package/lib/table/batch-edit/pending-cell-changes.d.ts +104 -0
  32. package/lib/table/calc/column-values.d.ts +55 -0
  33. package/lib/table/calc/show-values-as-internals.d.ts +4 -0
  34. package/lib/table/calc/show-values-as.d.ts +87 -0
  35. package/lib/table/calc/show-values-as.type.d.ts +55 -0
  36. package/lib/table/calc/value-getter-context.if.d.ts +35 -0
  37. package/lib/table/calc/value-getter.type.d.ts +36 -0
  38. package/lib/table/data/common/event/ge-batch-edit-event.d.ts +46 -0
  39. package/lib/table/data/common/event/ge-model-change-event.d.ts +27 -1
  40. package/lib/table/data/common/event/ge-row-drag-event.d.ts +89 -0
  41. package/lib/table/data/common/row-number-column-def.d.ts +107 -0
  42. package/lib/table/data/common/row-number-columns.d.ts +17 -0
  43. package/lib/table/data/common/row-number-options.d.ts +19 -0
  44. package/lib/table/data/common/row-number-options.if.d.ts +44 -0
  45. package/lib/table/data/options/table-options.d.ts +6 -0
  46. package/lib/table/data/options/table-options.if.d.ts +44 -0
  47. package/lib/table/data/tablemodel/areamodel/abstract-area-model.d.ts +66 -0
  48. package/lib/table/data/tablemodel/areamodel/aggregate-footer-options.if.d.ts +73 -0
  49. package/lib/table/data/tablemodel/areamodel/area-model-aggregate-footer.d.ts +150 -0
  50. package/lib/table/data/tablemodel/areamodel/area-model-array-of-arrays.d.ts +24 -0
  51. package/lib/table/data/tablemodel/areamodel/area-model-cell-groups.d.ts +18 -1
  52. package/lib/table/data/tablemodel/areamodel/area-model-object-array.d.ts +70 -0
  53. package/lib/table/data/tablemodel/areamodel/area-model-pivot-footer.d.ts +47 -0
  54. package/lib/table/data/tablemodel/areamodel/area-model-pivot.d.ts +281 -0
  55. package/lib/table/data/tablemodel/areamodel/area-model-row-groups.d.ts +336 -0
  56. package/lib/table/data/tablemodel/areamodel/area-model-tree.d.ts +97 -0
  57. package/lib/table/data/tablemodel/areamodel/area-model.if.d.ts +94 -0
  58. package/lib/table/data/tablemodel/areamodel/derived-values-change.if.d.ts +30 -0
  59. package/lib/table/data/tablemodel/column/column-def.d.ts +31 -1
  60. package/lib/table/data/tablemodel/column/column-def.if.d.ts +86 -0
  61. package/lib/table/event-adapter.d.ts +7 -0
  62. package/lib/table/event-listener.if.d.ts +32 -0
  63. package/lib/table/factory/pivot-factory.d.ts +63 -0
  64. package/lib/table/factory/pivot-table-model-para.if.d.ts +44 -0
  65. package/lib/table/factory/row-group-factory.d.ts +70 -0
  66. package/lib/table/factory/row-group-table-model-para.if.d.ts +66 -0
  67. package/lib/table/factory/table-factory.d.ts +56 -1
  68. package/lib/table/fill/compute-fill-changes.d.ts +67 -0
  69. package/lib/table/fill/fill-direction.type.d.ts +7 -0
  70. package/lib/table/fill/fill-handle-options.d.ts +29 -0
  71. package/lib/table/fill/fill-handle-options.if.d.ts +35 -0
  72. package/lib/table/fill/fill-handle-service.d.ts +55 -0
  73. package/lib/table/fill/fill-series.d.ts +60 -0
  74. package/lib/table/fill/fill-value-context.if.d.ts +36 -0
  75. package/lib/table/formula/compile-formula.d.ts +86 -0
  76. package/lib/table/formula/evaluator.d.ts +19 -0
  77. package/lib/table/formula/formula-ast.if.d.ts +42 -0
  78. package/lib/table/formula/formula-error.d.ts +59 -0
  79. package/lib/table/formula/formula-options.if.d.ts +41 -0
  80. package/lib/table/formula/formula-values.d.ts +13 -0
  81. package/lib/table/formula/functions.d.ts +18 -0
  82. package/lib/table/formula/parser.d.ts +10 -0
  83. package/lib/table/formula/tokenizer.d.ts +22 -0
  84. package/lib/table/instanceof-workaround.d.ts +143 -6
  85. package/lib/table/pivot/area-model-pivot-header.d.ts +9 -0
  86. package/lib/table/pivot/pivot-column-def.d.ts +28 -0
  87. package/lib/table/pivot/pivot-column-info.if.d.ts +25 -0
  88. package/lib/table/pivot/pivot-config.if.d.ts +58 -0
  89. package/lib/table/pivot/pivot-internals.d.ts +13 -0
  90. package/lib/table/pivot/pivot-layout.d.ts +40 -0
  91. package/lib/table/pivot/pivot-result.d.ts +157 -0
  92. package/lib/table/pivot/pivot-table-model.d.ts +86 -0
  93. package/lib/table/pivot/pivot-value.type.d.ts +80 -0
  94. package/lib/table/render-scope.d.ts +142 -4
  95. package/lib/table/renderer/aggregate-cell-renderer.d.ts +27 -0
  96. package/lib/table/renderer/edit/input-cell-renderer.d.ts +1 -1
  97. package/lib/table/renderer/edit/select-cell-renderer.d.ts +1 -1
  98. package/lib/table/renderer/row-number-cell-renderer.d.ts +27 -0
  99. package/lib/table/row-drag/move-rows.d.ts +157 -0
  100. package/lib/table/row-drag/row-drag-options.d.ts +28 -0
  101. package/lib/table/row-drag/row-drag-options.if.d.ts +36 -0
  102. package/lib/table/row-drag/row-drag-service.d.ts +130 -0
  103. package/lib/table/row-drag/row-drop-target.if.d.ts +29 -0
  104. package/lib/table/rowgroup/group-rows-internals.d.ts +14 -0
  105. package/lib/table/rowgroup/group-rows-options.if.d.ts +13 -0
  106. package/lib/table/rowgroup/group-rows.d.ts +48 -0
  107. package/lib/table/rowgroup/row-group-column-def.d.ts +26 -0
  108. package/lib/table/rowgroup/row-group-column-options.if.d.ts +27 -0
  109. package/lib/table/rowgroup/row-group-detail-row.d.ts +8 -0
  110. package/lib/table/rowgroup/row-group-field.type.d.ts +56 -0
  111. package/lib/table/rowgroup/row-group-internals.d.ts +31 -0
  112. package/lib/table/rowgroup/row-group-layout.d.ts +13 -0
  113. package/lib/table/rowgroup/row-group-model-options.if.d.ts +39 -0
  114. package/lib/table/rowgroup/row-group.d.ts +51 -0
  115. package/lib/table/rowgroup/row-group.if.d.ts +48 -0
  116. package/lib/table/selection/selection-aggregator.d.ts +37 -0
  117. package/lib/table/selection/selection-service.d.ts +7 -0
  118. package/lib/table/service/convenience-dom.service.d.ts +5 -0
  119. package/lib/table/service/excel-service.d.ts +6 -0
  120. package/lib/table/service/excel-service.if.d.ts +35 -0
  121. package/lib/table/table-api.d.ts +389 -3
  122. package/lib/table/table-scope.d.ts +140 -0
  123. package/package.json +3 -2
@@ -0,0 +1,66 @@
1
+ import { ColumnDefIf } from '../data/tablemodel/column/column-def.if.js';
2
+ import { TableOptionsIf } from '../data/options/table-options.if.js';
3
+ import { DefaultRowHeightsIf } from '../data/options/default-row-heights.if.js';
4
+ import { GetT } from '../data/common/get-t.js';
5
+ import { SelectionModelIf } from '../selection/selection-model.if.js';
6
+ import { RowNumberOptionsIf } from '../data/common/row-number-options.if.js';
7
+ import { AggregateSpecMap } from '../aggregation/aggregate-spec.if.js';
8
+ import { AggregateFooterConfig } from '../data/tablemodel/areamodel/aggregate-footer-options.if.js';
9
+ import { RowGroupField } from '../rowgroup/row-group-field.type.js';
10
+ import { RowGroupColumnOptionsIf } from '../rowgroup/row-group-column-options.if.js';
11
+ import { RowGroupExpanded } from '../rowgroup/row-group-model-options.if.js';
12
+
13
+ /**
14
+ * Parameters of {@link RowGroupFactory.createTableModel}.
15
+ *
16
+ * @example
17
+ * const para: RowGroupTableModelParaIf<Sale> = {
18
+ * rows: sales,
19
+ * columnDefs,
20
+ * groupBy: ["region", "produkt"],
21
+ * aggregations: { umsatz: "sum" },
22
+ * expanded: 1 // regions open, products closed
23
+ * };
24
+ * const tableModel = RowGroupFactory.createTableModel(para);
25
+ *
26
+ * @typeParam T - the row type
27
+ * @since 1.1.94
28
+ * @category Row grouping
29
+ */
30
+ export interface RowGroupTableModelParaIf<T = any> {
31
+ /** The flat rows (not changed). */
32
+ rows: T[];
33
+ /** The levels, top first: property paths (`"region"`), functions (`o => o.date.getFullYear()`) or {@link RowGroupFieldIf}. */
34
+ groupBy: RowGroupField<T>[];
35
+ /** The columns. Default: one per key of the first row. The group column is added in front of them. */
36
+ columnDefs?: ColumnDefIf[];
37
+ /** Aggregates in the group rows; the key is the property of the column (`{ umsatz: "sum" }`, see {@link AggregateSpecMap}). */
38
+ aggregations?: AggregateSpecMap<T>;
39
+ /**
40
+ * The total row: `true` = the `aggregations`, `false` = none, or an own configuration ({@link AggregateFooterConfig}).
41
+ * Default: `true` if there are aggregations.
42
+ */
43
+ footerAggregates?: boolean | AggregateFooterConfig<T>;
44
+ /** The group column: header, width, count, own label, fixed. */
45
+ groupColumn?: Partial<RowGroupColumnOptionsIf<T>>;
46
+ /** Hide the columns of the grouped properties. Default true. */
47
+ hideGroupedColumns?: boolean;
48
+ /** Expanded groups: `true` (default), `false`, open levels as a number (`0` = all closed) or a function per group. */
49
+ expanded?: RowGroupExpanded<T>;
50
+ /** The label of the group of empty keys (`null`, `undefined`, `""`). Default `"(empty)"`. */
51
+ emptyLabel?: string;
52
+ /** Options of the table (row heights, selection model, filter …). */
53
+ tableOptions?: TableOptionsIf;
54
+ /** Columns fixed on the left besides the group column (which is fixed by itself). Default 0. */
55
+ fixedLeftColumnCount?: number;
56
+ /** Columns fixed on the right. Default 0. */
57
+ fixedRightColumnCount?: number;
58
+ /** Row numbers in front of all columns (counted per displayed row, group rows included). */
59
+ rowNumbersVisible?: boolean | Partial<RowNumberOptionsIf>;
60
+ /** Set with a {@link CheckboxColumnDef} in `columnDefs` (default: detected). */
61
+ rowCheckboxVisible?: boolean;
62
+ /** Row heights of header, body and footer. Default: `tableOptions.defaultRowHeights`. */
63
+ defaultRowHeights?: DefaultRowHeightsIf;
64
+ /** Selection model factory. Default: `tableOptions.getSelectionModel`. */
65
+ getSelectionModel?: GetT<SelectionModelIf>;
66
+ }
@@ -6,6 +6,8 @@ import { TableOptionsIf } from '../data/options/table-options.if.js';
6
6
  import { TableModelIf } from '../data/tablemodel/table-model.if.js';
7
7
  import { TableModel } from '../data/tablemodel/table-model.js';
8
8
  import { SelectionModelIf } from '../selection/selection-model.if.js';
9
+ import { RowNumberOptionsIf } from '../data/common/row-number-options.if.js';
10
+ import { AggregateFooterConfig } from '../data/tablemodel/areamodel/aggregate-footer-options.if.js';
9
11
 
10
12
  /**
11
13
  * Parameters of {@link TableFactory.createTableModel} – pass any subset (`Partial<CreateTableModelPara>`).
@@ -37,14 +39,56 @@ export interface CreateTableModelPara {
37
39
  headerAreaModel: AreaModelIf;
38
40
  /** Model of the body. Default: built from `rows` (objects or tree rows) or `bodyData`. See {@link AreaModel} for own models. */
39
41
  bodyAreaModel: AreaModelIf;
40
- /** Model of the footer. Default: `footerData`, otherwise no footer. Totals that follow the filter: an own {@link AreaModel}. */
42
+ /** Model of the footer. Default: `footerAggregates`, `footerData`, otherwise no footer. */
41
43
  footerAreaModel: AreaModelIf;
44
+ /**
45
+ * A footer with totals that follow filter and sorting ({@link AreaModelAggregateFooter}): `{ total: "sum" }` (one
46
+ * row – the key is the property of the column), `[{ label, aggregates }, …]` (several rows) or full
47
+ * {@link AggregateFooterOptionsIf}. Row height: `defaultRowHeights.footer`. Ignored with an own `footerAreaModel`
48
+ * (warning); `footerData` is ignored with it (warning).
49
+ *
50
+ * @example
51
+ * const tableModel = TableFactory.createTableModel({
52
+ * rows: orders,
53
+ * columnDefs,
54
+ * footerAggregates: { quantity: "sum", total: "sum" } // footer: "100,000 rows" | … | 549,812 | 27,481,033.5
55
+ * });
56
+ *
57
+ * @since 1.1.94
58
+ */
59
+ footerAggregates: AggregateFooterConfig;
42
60
  /** Number of columns fixed on the left (side "west"). Default 0. */
43
61
  fixedLeftColumnCount: number;
44
62
  /** Number of columns fixed on the right (side "east"). Default 0. */
45
63
  fixedRightColumnCount: number;
46
64
  /** Show a checkbox column for every row. Default false. */
47
65
  rowCheckboxVisible: boolean;
66
+ /**
67
+ * Row numbers (1, 2, 3 …) in a column in front of all others, fixed on the left: `true` or options
68
+ * ({@link RowNumberOptionsIf}). Puts a {@link RowNumberColumnDef} in front of `columnDefs` and adds 1 to
69
+ * `fixedLeftColumnCount`; `headerData`/`footerData` get an empty cell in front. Default false.
70
+ *
71
+ * The column is a real column: the indices of all other columns are one higher – use properties where you can
72
+ * ({@link TableApi.getColumnIndex}). With `bodyData` or own area models the flag is ignored (with a warning), because
73
+ * their columns would shift – put a `RowNumberColumnDef` into the column definitions of your models yourself.
74
+ *
75
+ * @example
76
+ * const tableModel = TableFactory.createTableModel({ rows: orders, columnDefs, rowNumbersVisible: true });
77
+ *
78
+ * @since 1.1.93
79
+ */
80
+ rowNumbersVisible: boolean | Partial<RowNumberOptionsIf>;
81
+ /**
82
+ * Row drag: `true` puts a drag handle into the first data column (behind row numbers and checkboxes) –
83
+ * sets {@link ColumnDefIf.rowDrag} on that column definition. Options: {@link TableOptionsIf.rowDragOptions}.
84
+ * Default false.
85
+ *
86
+ * @example
87
+ * const tableModel = TableFactory.createTableModel({ rows: orders, rowDrag: true });
88
+ *
89
+ * @since 1.1.95
90
+ */
91
+ rowDrag: boolean;
48
92
  /** Row heights of header, body and footer in px. Default: `tableOptions.defaultRowHeights`, otherwise 34 / 34 / 34. */
49
93
  defaultRowHeights: DefaultRowHeightsIf;
50
94
  /** The columns: property, header label, width, classes, renderers, sorting, editing. See {@link ColumnDef}. */
@@ -120,6 +164,17 @@ export declare class TableFactory {
120
164
  * });
121
165
  */
122
166
  static createTableModel(p: Partial<CreateTableModelPara>): TableModelIf;
167
+ /**
168
+ * `footerAggregates`: returns the configuration if the factory builds an aggregate footer (after the body model),
169
+ * `undefined` if there is none or an own `footerAreaModel` wins.
170
+ */
171
+ private static checkFooterAggregates;
172
+ /**
173
+ * `rowNumbersVisible`: puts a RowNumberColumnDef in front of the column definitions (and an empty cell in front of
174
+ * `headerData`/`footerData`) and fixes it on the left. Only where the factory builds the models from the column
175
+ * definitions – with `bodyData` or own area models every column would shift by one.
176
+ */
177
+ private static addRowNumberColumn;
123
178
  /**
124
179
  * Constructs a table model (an instance of `TableModelIf`) by using provided parameters.
125
180
  *
@@ -0,0 +1,67 @@
1
+ import { CellRange } from '../data/common/cell-range.js';
2
+ import { CellValueChangeIf } from '../batch-edit/cell-value-change.if.js';
3
+ import { FillDirection } from './fill-direction.type.js';
4
+ import { FillValueContextIf } from './fill-value-context.if.js';
5
+ import { FillMode } from './fill-series.js';
6
+
7
+ /**
8
+ * Input of {@link computeFillChanges}.
9
+ *
10
+ * @category Fill handle & batch edit
11
+ * @since 1.1.96
12
+ */
13
+ export interface FillRequestIf {
14
+ /** The selected source range (body display indices, `r1 <= r2`, `c1 <= c2`). */
15
+ source: CellRange;
16
+ /** Where the range is extended to. */
17
+ direction: FillDirection;
18
+ /** The number of rows (down/up) or columns (right/left) to fill. */
19
+ count: number;
20
+ /** Series or copy, see {@link FillMode}. */
21
+ mode?: FillMode;
22
+ /** The shown value of a cell (batch edit: the pending value). */
23
+ getValue: (rowIndex: number, columnIndex: number) => unknown;
24
+ /** `false` skips a target cell (not editable, hidden column …); the series keeps counting. */
25
+ isFillable?: (rowIndex: number, columnIndex: number) => boolean;
26
+ /** Own fill function, see {@link FillHandleOptionsIf.fillValue}. */
27
+ fillValue?: (ctx: FillValueContextIf) => unknown;
28
+ /** Row object and property of a cell – for `fillValue`. */
29
+ getCellInfo?: (rowIndex: number, columnIndex: number) => {
30
+ row: unknown;
31
+ property: string;
32
+ };
33
+ }
34
+ /**
35
+ * The cells a fill covers: the source range extended by `count` rows or columns in `direction`.
36
+ *
37
+ * @param {CellRange} source - the selected range
38
+ * @param {FillDirection} direction - the direction of the fill
39
+ * @param {number} count - rows or columns added
40
+ * @returns {CellRange} source and filled cells together
41
+ *
42
+ * @example
43
+ * getFillRange(new CellRange(2, 1, 3, 1), "down", 3); // rows 2…6 of column 1
44
+ *
45
+ * @category Fill handle & batch edit
46
+ * @since 1.1.96
47
+ */
48
+ export declare function getFillRange(source: CellRange, direction: FillDirection, count: number): CellRange;
49
+ /**
50
+ * The values a fill writes: per line of the source range (each column when filling down/up, each row when filling
51
+ * right/left) the continuation of its values ({@link computeFillValues}) – DOM-free, the table applies the result with
52
+ * {@link TableApi.applyCellChanges}.
53
+ *
54
+ * @param {FillRequestIf} request - source range, direction, count, value access
55
+ * @returns {CellValueChangeIf[]} one change per fillable target cell (column = model index)
56
+ *
57
+ * @example
58
+ * const values = [[1], [2]]; // a 2 × 1 source range
59
+ * computeFillChanges({
60
+ * source: new CellRange(0, 0, 1, 0), direction: "down", count: 2,
61
+ * getValue: (r, c) => values[r]?.[c],
62
+ * }); // [{ rowIndex: 2, column: 0, value: 3 }, { rowIndex: 3, column: 0, value: 4 }]
63
+ *
64
+ * @category Fill handle & batch edit
65
+ * @since 1.1.96
66
+ */
67
+ export declare function computeFillChanges(request: FillRequestIf): CellValueChangeIf[];
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The direction of a fill: the fill handle was dragged down, up, right or left of the selected range.
3
+ *
4
+ * @category Fill handle & batch edit
5
+ * @since 1.1.96
6
+ */
7
+ export type FillDirection = "down" | "up" | "right" | "left";
@@ -0,0 +1,29 @@
1
+ import { FillHandleOptionsIf } from './fill-handle-options.if.js';
2
+ import { FillValueContextIf } from './fill-value-context.if.js';
3
+
4
+ /**
5
+ * The defaults of {@link FillHandleOptionsIf}.
6
+ *
7
+ * @example
8
+ * const options = FillHandleOptions.create(true);
9
+ * options?.direction; // "both"
10
+ *
11
+ * @category Fill handle & batch edit
12
+ * @since 1.1.96
13
+ */
14
+ export declare class FillHandleOptions implements FillHandleOptionsIf {
15
+ direction: "vertical" | "horizontal" | "both";
16
+ fillValue?: (ctx: FillValueContextIf) => unknown;
17
+ maxCells: number;
18
+ dragThresholdInPx: number;
19
+ autoScrollZoneInPx: number;
20
+ autoScrollMaxSpeedInPx: number;
21
+ /**
22
+ * The options of {@link TableOptionsIf.fillHandle}: `undefined`/`false` = no fill handle, `true` = the defaults, an
23
+ * object = the defaults overridden by its values (`undefined` keeps the default).
24
+ *
25
+ * @param {boolean | Partial<FillHandleOptionsIf>} [option] - `tableOptions.fillHandle`
26
+ * @returns {FillHandleOptionsIf | undefined} complete options, `undefined` if the fill handle is off
27
+ */
28
+ static create(option?: boolean | Partial<FillHandleOptionsIf>): FillHandleOptionsIf | undefined;
29
+ }
@@ -0,0 +1,35 @@
1
+ import { FillValueContextIf } from './fill-value-context.if.js';
2
+
3
+ /**
4
+ * Options of the fill handle ({@link TableOptionsIf.fillHandle}): the small square at the bottom right corner of the
5
+ * selected range. Dragging it fills the neighbouring cells – copies values or continues series (1, 2, 3 …; dates;
6
+ * `Item 1` → `Item 2`). Needs a {@link SelectionModel} of the type `"range"`.
7
+ *
8
+ * @example
9
+ * const selectionModel = new SelectionModel("range", "multi"); // one model – not a new one per call
10
+ * const tableOptions: TableOptionsIf = {
11
+ * ...new TableOptions(),
12
+ * getSelectionModel: () => selectionModel,
13
+ * fillHandle: { direction: "vertical" },
14
+ * };
15
+ *
16
+ * @category Fill handle & batch edit
17
+ * @since 1.1.96
18
+ */
19
+ export interface FillHandleOptionsIf {
20
+ /** Allowed directions: `"vertical"` (down/up), `"horizontal"` (right/left) or `"both"` (default). */
21
+ direction: "vertical" | "horizontal" | "both";
22
+ /**
23
+ * Own fill function, called for every filled cell. Return the value – or `undefined` for the default
24
+ * (`ctx.defaultValue`).
25
+ */
26
+ fillValue?: (ctx: FillValueContextIf) => unknown;
27
+ /** At most this many cells are filled at once (default 100,000); a bigger fill is refused and announced. */
28
+ maxCells: number;
29
+ /** Distance in px the pointer has to move before a fill starts (default 3). */
30
+ dragThresholdInPx: number;
31
+ /** Width in px of the zone at the edges of the body that scrolls automatically (default 40). */
32
+ autoScrollZoneInPx: number;
33
+ /** Maximum auto-scroll speed in px per animation frame (default 24). */
34
+ autoScrollMaxSpeedInPx: number;
35
+ }
@@ -0,0 +1,55 @@
1
+ import { TableScope } from '../table-scope.js';
2
+
3
+ /**
4
+ * The fill handle of one table (`tableScope.fillHandleService`): the square at the bottom right corner of the selected
5
+ * range, the pointer drag with preview and auto-scroll, Escape. The values come from {@link TableScope.fillRange}.
6
+ * Use {@link TableApi.fillRange}, {@link TableApi.isFilling} and {@link TableApi.cancelFill} instead.
7
+ *
8
+ * Pointer Events (mouse, touch, pen) only on the handle; its `pointerdown` is prevented, so the mouse handler of the
9
+ * table (range selection, column drag) never sees it.
10
+ *
11
+ * @category Internals
12
+ * @since 1.1.96
13
+ */
14
+ export declare class FillHandleService {
15
+ private readonly tableScope;
16
+ private handle?;
17
+ private preview?;
18
+ private pending?;
19
+ private session?;
20
+ private sessionAbortController?;
21
+ private autoScrollFrame;
22
+ private suppressClick;
23
+ private shortcutsSet;
24
+ constructor(tableScope: TableScope);
25
+ /** true while the handle is dragged. */
26
+ isFilling(): boolean;
27
+ /**
28
+ * Places the handle at the bottom right corner of the last selected range (called after every render pass) – or
29
+ * hides it: no fill handle option, no range, the corner scrolled out, an open editor, a blocking overlay.
30
+ */
31
+ update(): void;
32
+ /** The handle's position (the corner of the range) in host coordinates – `undefined` if it is not visible. */
33
+ private getCornerOf;
34
+ private ensureHandle;
35
+ private removeHandle;
36
+ /** Keyboard alternative on the grid: Ctrl/⌘+D, Ctrl/⌘+R (only directions the options allow). */
37
+ private updateHostShortcuts;
38
+ private isHandle;
39
+ private onPointerDown;
40
+ private listenToDocument;
41
+ private onPointerMove;
42
+ private onPointerUp;
43
+ private suppressNextClick;
44
+ private onClickCapture;
45
+ /** Target cell under the pointer → direction and count; preview; auto-scroll. */
46
+ private updateTarget;
47
+ private renderPreview;
48
+ private updateAutoScroll;
49
+ private autoScrollStep;
50
+ /** Cancels a running fill (Escape, `pointercancel`, {@link TableApi.cancelFill}): nothing is changed. */
51
+ cancel(): void;
52
+ private stopListening;
53
+ /** Releases everything (TableScope.destroy). */
54
+ destroy(): void;
55
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * How {@link computeFillValues} continues the source values:
3
+ * - `"auto"`: the default rules – one number is copied, several numbers continue as a linear series, dates and texts
4
+ * with a trailing number count up, everything else repeats;
5
+ * - `"alternate"`: the other choice for numbers, dates and texts with a number (⌥/Alt or Ctrl while dragging the fill
6
+ * handle): one number counts up by 1, a series is copied;
7
+ * - `"copy"`: always repeat the source values (Ctrl/⌘+D, Ctrl/⌘+R).
8
+ *
9
+ * @category Fill handle & batch edit
10
+ * @since 1.1.96
11
+ */
12
+ export type FillMode = "auto" | "alternate" | "copy";
13
+ /**
14
+ * Computes the values of a fill (fill handle, Ctrl/⌘+D): `count` values that continue `sourceValues` – forward
15
+ * (down/right) or backward (up/left: the value directly in front of the source first).
16
+ *
17
+ * | source | `"auto"` | `"alternate"` |
18
+ * |---|---|---|
19
+ * | one number `5` | 5, 5, 5 | 6, 7, 8 |
20
+ * | numbers `1, 2` | 3, 4, 5 (linear; uneven steps: best-fit line) | 1, 2, 1 |
21
+ * | date `2026-10-14` (`Date` or ISO text) | +1 day each; several dates a month apart: +1 month (month ends stay month ends) | copied |
22
+ * | text with a trailing number `Item 9` | `Item 10`, `Item 11` (leading zeros stay) | copied |
23
+ * | anything else | repeated: `A, B` → `A, B, A, B` | repeated |
24
+ *
25
+ * The type stays: a date text stays a text in the same format, a `Date` stays a `Date`, a number written as text
26
+ * stays a text. Decimal noise is rounded (0.1, 0.2 → 0.3, not 0.30000000000000004).
27
+ *
28
+ * @param {unknown[]} sourceValues - the values of one line (column or row) of the source range, in display order
29
+ * @param {number} count - the number of values to compute
30
+ * @param {boolean} [backward=false] - fill up/left: the values in front of the source, nearest first
31
+ * @param {FillMode} [mode="auto"] - see {@link FillMode}
32
+ * @returns {unknown[]} `count` values, nearest to the source first
33
+ *
34
+ * @example
35
+ * computeFillValues([1, 2], 3); // [3, 4, 5]
36
+ * computeFillValues([5], 3); // [5, 5, 5]
37
+ * computeFillValues([5], 3, false, "alternate"); // [6, 7, 8]
38
+ * computeFillValues(["2026-10-14"], 2); // ["2026-10-15", "2026-10-16"]
39
+ * computeFillValues(["Item 9"], 2); // ["Item 10", "Item 11"]
40
+ * computeFillValues([1, 2], 2, true); // [0, -1] (filled upwards)
41
+ *
42
+ * @category Fill handle & batch edit
43
+ * @since 1.1.96
44
+ */
45
+ export declare function computeFillValues(sourceValues: unknown[], count: number, backward?: boolean, mode?: FillMode): unknown[];
46
+ /**
47
+ * `true` if {@link computeFillValues} continues the values as a series, `false` if it repeats them.
48
+ *
49
+ * @param {unknown[]} sourceValues - the values of one line of the source range
50
+ * @param {FillMode} [mode="auto"] - see {@link FillMode}
51
+ * @returns {boolean} whether the fill is a series
52
+ *
53
+ * @example
54
+ * isFillSeries([5]); // false – one number is copied
55
+ * isFillSeries([1, 2]); // true
56
+ *
57
+ * @category Fill handle & batch edit
58
+ * @since 1.1.96
59
+ */
60
+ export declare function isFillSeries(sourceValues: unknown[], mode?: FillMode): boolean;
@@ -0,0 +1,36 @@
1
+ import { FillDirection } from './fill-direction.type.js';
2
+
3
+ /**
4
+ * What an own fill function ({@link FillHandleOptionsIf.fillValue}) gets for each filled cell.
5
+ *
6
+ * @example
7
+ * const weekdays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
8
+ * const fillValue = (ctx: FillValueContextIf) => {
9
+ * const last = ctx.sourceValues[ctx.sourceValues.length - 1];
10
+ * const i = weekdays.indexOf(String(last));
11
+ * return i < 0 || ctx.copy ? undefined : weekdays[(((i + ctx.step) % 7) + 7) % 7]; // undefined = default
12
+ * };
13
+ *
14
+ * @category Fill handle & batch edit
15
+ * @since 1.1.96
16
+ */
17
+ export interface FillValueContextIf {
18
+ /** The values of the source line (the column when filling down/up, the row when filling right/left), as shown. */
19
+ sourceValues: unknown[];
20
+ /** 1, 2, 3 … after the source (down/right), −1, −2 … in front of it (up/left). */
21
+ step: number;
22
+ /** The direction of the fill. */
23
+ direction: FillDirection;
24
+ /** Display index of the filled cell's row. */
25
+ rowIndex: number;
26
+ /** Model index of the filled cell's column. */
27
+ columnIndex: number;
28
+ /** The property of the column (`""` without a column definition). */
29
+ property: string;
30
+ /** The row object of the filled cell (`undefined` for own area models without row objects). */
31
+ row: unknown;
32
+ /** The value the table would use (series or copy). */
33
+ defaultValue: unknown;
34
+ /** `true` if the values are copied (⌥/Alt on a series, Ctrl/⌘+D, Ctrl/⌘+R). */
35
+ copy: boolean;
36
+ }
@@ -0,0 +1,86 @@
1
+ import { FormulaNode } from './formula-ast.if.js';
2
+ import { FormulaError } from './formula-error.js';
3
+ import { FormulaOptionsIf, FormulaValue } from './formula-options.if.js';
4
+ import { ValueGetterContextIf } from '../calc/value-getter-context.if.js';
5
+ import { ValueGetter } from '../calc/value-getter.type.js';
6
+
7
+ /**
8
+ * The names of the built-in formula functions (upper case), e.g. for the help text of an own formula input.
9
+ *
10
+ * @example
11
+ * hint.textContent = `Functions: ${FORMULA_FUNCTION_NAMES.join(", ")}`;
12
+ *
13
+ * @since 1.1.95
14
+ * @category Calculated columns & formulas
15
+ */
16
+ export declare const FORMULA_FUNCTION_NAMES: readonly string[];
17
+ /**
18
+ * A formula compiled once ({@link compileFormula}): the AST, the referenced fields and `evaluate()` for a row.
19
+ * A formula with a syntax error or an unknown function has `error` set; `evaluate()` then always returns it.
20
+ *
21
+ * @example
22
+ * const f = compileFormula("[price] * [quantity] * 1.19");
23
+ * f.fields; // ["price", "quantity"]
24
+ * f.evaluate({ price: 1299, quantity: 2 }); // 3091.62
25
+ *
26
+ * @since 1.1.95
27
+ * @category Calculated columns & formulas
28
+ */
29
+ export interface CompiledFormula {
30
+ /** The formula text as given. */
31
+ readonly source: string;
32
+ /** The syntax tree; `undefined` if the formula has an error. */
33
+ readonly ast?: FormulaNode;
34
+ /** The error of the formula itself (`#ERROR!`, `#NAME?` for an unknown function); `undefined` if it is valid. */
35
+ readonly error?: FormulaError;
36
+ /** The referenced fields (`[price]` → `"price"`), each once, in order of appearance. */
37
+ readonly fields: readonly string[];
38
+ /** True if the formula uses a column aggregate (`SUM([total])` …). */
39
+ readonly usesAggregates: boolean;
40
+ /**
41
+ * Evaluates the formula for a row. Never throws: errors are returned as {@link FormulaError}.
42
+ * Without a context, column aggregates (`SUM([x])`) return `#VALUE!`.
43
+ */
44
+ evaluate(row: unknown, context?: ValueGetterContextIf): FormulaValue;
45
+ }
46
+ /**
47
+ * Compiles a formula once – no `eval`, no `new Function` (works with a strict Content-Security-Policy, user input
48
+ * cannot run code). The result evaluates rows; never throws.
49
+ *
50
+ * Syntax (details: instructions.md „Formulas“):
51
+ * - fields in brackets: `[price]`, `[address.city]`, `[Unit price]` – own properties of the row or calculated columns
52
+ * - numbers `12`, `1.5`, `1e3`, texts `"a"` / `'a'`, `TRUE`, `FALSE`
53
+ * - operators: `+ - * / ^` (power), `&` (text), `= <> < <= > >=`; `-2^2 = -4`
54
+ * - functions: `ROUND(x, 2)`, `IF(c, a, b)`, `IFERROR`, `AND`, `OR`, `NOT`, `ABS`, `MOD`, `SQRT`, `POWER`, `FLOOR`,
55
+ * `CEILING`, `CONCAT`, `LEN`, `UPPER`, `LOWER`, `TRIM`, `ISBLANK`; `SUM AVG MIN MAX COUNT` – with one field the
56
+ * aggregate of the column (`[total] / SUM([total])`), otherwise of the arguments
57
+ *
58
+ * @param {string} source - the formula, e.g. `"[price] * [quantity] * 1.19"` (a leading `=` is ignored)
59
+ * @param {FormulaOptionsIf} [options] - own functions
60
+ * @returns {CompiledFormula} the compiled formula
61
+ *
62
+ * @example
63
+ * const gross = compileFormula("ROUND([price] * [quantity] * 1.19, 2)");
64
+ * gross.evaluate({ price: 25, quantity: 10 }); // 297.5
65
+ * compileFormula("[price] / 0").evaluate({ price: 1 }); // FormulaError #DIV/0!
66
+ * compileFormula("[price] *").error?.code; // "#ERROR!"
67
+ *
68
+ * @since 1.1.95
69
+ * @category Calculated columns & formulas
70
+ */
71
+ export declare function compileFormula(source: string, options?: FormulaOptionsIf): CompiledFormula;
72
+ /**
73
+ * The {@link ValueGetter} of a formula – what `ColumnDef.create({ formula })` sets as `valueGetter`.
74
+ *
75
+ * @param {CompiledFormula | string} formula - a compiled formula or its text
76
+ * @param {FormulaOptionsIf} [options] - own functions (only with a text)
77
+ * @returns {ValueGetter} the getter
78
+ *
79
+ * @example
80
+ * const column = ColumnDef.create({ property: "gross", headerLabel: "Gross" });
81
+ * column.valueGetter = createFormulaValueGetter("[net] * 1.19");
82
+ *
83
+ * @since 1.1.95
84
+ * @category Calculated columns & formulas
85
+ */
86
+ export declare function createFormulaValueGetter(formula: CompiledFormula | string, options?: FormulaOptionsIf): ValueGetter;
@@ -0,0 +1,19 @@
1
+ import { FormulaNode } from './formula-ast.if.js';
2
+ import { FormulaFunction, FormulaValue } from './formula-options.if.js';
3
+ import { ValueGetterContextIf } from '../calc/value-getter-context.if.js';
4
+
5
+ type Evaluate = (row: unknown, context: ValueGetterContextIf | undefined) => FormulaValue;
6
+ /** Reads a field: own properties only (no prototype chain), path segments separated by ".". */
7
+ export declare function readField(row: unknown, name: string, context?: ValueGetterContextIf, path?: string[]): FormulaValue;
8
+ /** Compiles an AST into closures. Never throws at evaluation time (see {@link FormulaEvaluator.evaluate}). */
9
+ export declare class FormulaEvaluator {
10
+ private readonly functions;
11
+ constructor(functions: Map<string, FormulaFunction>);
12
+ /** The evaluation function of a (checked) AST. */
13
+ compile(node: FormulaNode): Evaluate;
14
+ /** Evaluates an AST once (compiles it each time – for single use). */
15
+ evaluate(node: FormulaNode, row: unknown, context?: ValueGetterContextIf): FormulaValue;
16
+ private node;
17
+ private call;
18
+ }
19
+ export {};
@@ -0,0 +1,42 @@
1
+ /**
2
+ * A node of a compiled formula (abstract syntax tree). Read-only; the evaluator walks it – no code is generated
3
+ * (no `eval`, no `new Function`).
4
+ *
5
+ * @example
6
+ * const ast = compileFormula("[price] * 2").ast;
7
+ * // { kind: "binary", op: "*", left: { kind: "field", name: "price" }, right: { kind: "literal", value: 2 } }
8
+ *
9
+ * @since 1.1.95
10
+ * @category Calculated columns & formulas
11
+ */
12
+ export type FormulaNode = {
13
+ readonly kind: "literal";
14
+ readonly value: number | string | boolean;
15
+ } | {
16
+ readonly kind: "field";
17
+ readonly name: string;
18
+ } | {
19
+ readonly kind: "unary";
20
+ readonly op: "-" | "+";
21
+ readonly operand: FormulaNode;
22
+ } | {
23
+ readonly kind: "binary";
24
+ readonly op: FormulaBinaryOperator;
25
+ readonly left: FormulaNode;
26
+ readonly right: FormulaNode;
27
+ } | {
28
+ readonly kind: "call";
29
+ readonly name: string;
30
+ readonly args: readonly FormulaNode[];
31
+ };
32
+ /**
33
+ * The binary operators of a formula: arithmetic (`+ - * / ^`), text concatenation (`&`) and comparisons
34
+ * (`=`/`==`, `<>`/`!=`, `<`, `<=`, `>`, `>=`; normalized to `=` and `<>`).
35
+ *
36
+ * @example
37
+ * const op: FormulaBinaryOperator = "&"; // "Total: " & [total]
38
+ *
39
+ * @since 1.1.95
40
+ * @category Calculated columns & formulas
41
+ */
42
+ export type FormulaBinaryOperator = "+" | "-" | "*" | "/" | "^" | "&" | "=" | "<>" | "<" | "<=" | ">" | ">=";
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The error codes of a formula – like in a spreadsheet:
3
+ *
4
+ * | Code | Meaning |
5
+ * |---|---|
6
+ * | `#ERROR!` | syntax error (the whole column shows it) |
7
+ * | `#NAME?` | unknown field or function |
8
+ * | `#VALUE!` | wrong type, e.g. `"abc" * 2` |
9
+ * | `#DIV/0!` | division by zero |
10
+ * | `#NUM!` | the result is not a finite number (`SQRT(-1)`, overflow) |
11
+ * | `#CIRC!` | circular reference between calculated columns |
12
+ *
13
+ * @since 1.1.95
14
+ * @category Calculated columns & formulas
15
+ */
16
+ export type FormulaErrorCode = "#ERROR!" | "#NAME?" | "#VALUE!" | "#DIV/0!" | "#NUM!" | "#CIRC!";
17
+ /**
18
+ * An error value of a formula. Formulas never throw: a cell shows the {@link FormulaErrorCode} (`toString()`), the
19
+ * table adds the CSS class `ge-table-cell-error` and shows the message as tooltip. Errors propagate through
20
+ * operators and functions (`[a] / 0 + 1` → `#DIV/0!`), `IFERROR(x, fallback)` catches them, aggregators skip them.
21
+ *
22
+ * @example
23
+ * const result = compileFormula("[price] / [quantity]").evaluate({ price: 10, quantity: 0 });
24
+ * if (isFormulaError(result)) {
25
+ * console.log(result.code, result.message); // "#DIV/0!" "Division by zero"
26
+ * }
27
+ *
28
+ * @since 1.1.95
29
+ * @category Calculated columns & formulas
30
+ */
31
+ export declare class FormulaError {
32
+ readonly code: FormulaErrorCode;
33
+ readonly message: string;
34
+ readonly position?: number | undefined;
35
+ /** Marker (works across copies of the core): {@link isFormulaError}. */
36
+ readonly type = "FormulaError";
37
+ /**
38
+ * @param {FormulaErrorCode} code - the code shown in the cell
39
+ * @param {string} message - a short English explanation (tooltip); never contains HTML
40
+ * @param {number} [position] - for syntax errors: the position in the formula text (0-based)
41
+ */
42
+ constructor(code: FormulaErrorCode, message: string, position?: number | undefined);
43
+ /** The code, e.g. `"#DIV/0!"` – what a cell shows. */
44
+ toString(): string;
45
+ }
46
+ /**
47
+ * True for an error value of a formula ({@link FormulaError}) – also for one created by another copy of the core.
48
+ *
49
+ * @param {unknown} value - any value
50
+ * @returns {boolean} whether it is a formula error
51
+ *
52
+ * @example
53
+ * const value = tableApi.getRowValue(row, "margin");
54
+ * if (!isFormulaError(value)) console.log(value);
55
+ *
56
+ * @since 1.1.95
57
+ * @category Calculated columns & formulas
58
+ */
59
+ export declare function isFormulaError(value: unknown): value is FormulaError;