@guiexpert/table 1.1.94 → 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 (72) hide show
  1. package/README.md +12 -0
  2. package/css/main.css +192 -0
  3. package/css/table-calc.css +7 -0
  4. package/css/table-color-vars.css +46 -0
  5. package/css/table-fill-batch.css +58 -0
  6. package/css/table-row-drag.css +81 -0
  7. package/index.cjs +39 -37
  8. package/index.d.ts +28 -0
  9. package/index.js +5501 -1934
  10. package/lib/table/action/action-id.type.d.ts +1 -1
  11. package/lib/table/aria/aria-texts.d.ts +11 -0
  12. package/lib/table/aria/aria-texts.if.d.ts +87 -0
  13. package/lib/table/batch-edit/batch-edit-options.d.ts +21 -0
  14. package/lib/table/batch-edit/batch-edit-options.if.d.ts +20 -0
  15. package/lib/table/batch-edit/batch-edit-service.d.ts +104 -0
  16. package/lib/table/batch-edit/cell-change.if.d.ts +39 -0
  17. package/lib/table/batch-edit/cell-value-change.if.d.ts +18 -0
  18. package/lib/table/batch-edit/pending-cell-changes.d.ts +104 -0
  19. package/lib/table/calc/column-values.d.ts +55 -0
  20. package/lib/table/calc/show-values-as-internals.d.ts +4 -0
  21. package/lib/table/calc/show-values-as.d.ts +87 -0
  22. package/lib/table/calc/show-values-as.type.d.ts +55 -0
  23. package/lib/table/calc/value-getter-context.if.d.ts +35 -0
  24. package/lib/table/calc/value-getter.type.d.ts +36 -0
  25. package/lib/table/data/common/event/ge-batch-edit-event.d.ts +46 -0
  26. package/lib/table/data/common/event/ge-model-change-event.d.ts +27 -1
  27. package/lib/table/data/common/event/ge-row-drag-event.d.ts +89 -0
  28. package/lib/table/data/options/table-options.d.ts +6 -0
  29. package/lib/table/data/options/table-options.if.d.ts +44 -0
  30. package/lib/table/data/tablemodel/areamodel/abstract-area-model.d.ts +66 -0
  31. package/lib/table/data/tablemodel/areamodel/area-model-aggregate-footer.d.ts +5 -0
  32. package/lib/table/data/tablemodel/areamodel/area-model-array-of-arrays.d.ts +24 -0
  33. package/lib/table/data/tablemodel/areamodel/area-model-object-array.d.ts +70 -0
  34. package/lib/table/data/tablemodel/areamodel/area-model-pivot.d.ts +31 -0
  35. package/lib/table/data/tablemodel/areamodel/area-model-row-groups.d.ts +23 -1
  36. package/lib/table/data/tablemodel/areamodel/area-model-tree.d.ts +83 -0
  37. package/lib/table/data/tablemodel/areamodel/area-model.if.d.ts +55 -0
  38. package/lib/table/data/tablemodel/column/column-def.d.ts +31 -1
  39. package/lib/table/data/tablemodel/column/column-def.if.d.ts +86 -0
  40. package/lib/table/event-adapter.d.ts +7 -0
  41. package/lib/table/event-listener.if.d.ts +32 -0
  42. package/lib/table/factory/table-factory.d.ts +11 -0
  43. package/lib/table/fill/compute-fill-changes.d.ts +67 -0
  44. package/lib/table/fill/fill-direction.type.d.ts +7 -0
  45. package/lib/table/fill/fill-handle-options.d.ts +29 -0
  46. package/lib/table/fill/fill-handle-options.if.d.ts +35 -0
  47. package/lib/table/fill/fill-handle-service.d.ts +55 -0
  48. package/lib/table/fill/fill-series.d.ts +60 -0
  49. package/lib/table/fill/fill-value-context.if.d.ts +36 -0
  50. package/lib/table/formula/compile-formula.d.ts +86 -0
  51. package/lib/table/formula/evaluator.d.ts +19 -0
  52. package/lib/table/formula/formula-ast.if.d.ts +42 -0
  53. package/lib/table/formula/formula-error.d.ts +59 -0
  54. package/lib/table/formula/formula-options.if.d.ts +41 -0
  55. package/lib/table/formula/formula-values.d.ts +13 -0
  56. package/lib/table/formula/functions.d.ts +18 -0
  57. package/lib/table/formula/parser.d.ts +10 -0
  58. package/lib/table/formula/tokenizer.d.ts +22 -0
  59. package/lib/table/pivot/pivot-value.type.d.ts +13 -0
  60. package/lib/table/render-scope.d.ts +81 -0
  61. package/lib/table/renderer/edit/input-cell-renderer.d.ts +1 -1
  62. package/lib/table/renderer/edit/select-cell-renderer.d.ts +1 -1
  63. package/lib/table/row-drag/move-rows.d.ts +157 -0
  64. package/lib/table/row-drag/row-drag-options.d.ts +28 -0
  65. package/lib/table/row-drag/row-drag-options.if.d.ts +36 -0
  66. package/lib/table/row-drag/row-drag-service.d.ts +130 -0
  67. package/lib/table/row-drag/row-drop-target.if.d.ts +29 -0
  68. package/lib/table/service/excel-service.d.ts +6 -0
  69. package/lib/table/service/excel-service.if.d.ts +35 -0
  70. package/lib/table/table-api.d.ts +277 -2
  71. package/lib/table/table-scope.d.ts +121 -0
  72. package/package.json +1 -1
@@ -0,0 +1,157 @@
1
+ import { RowDropTargetIf } from './row-drop-target.if.js';
2
+ import { TreeRowIf } from '../data/common/tree-row-if.js';
3
+
4
+ /**
5
+ * Sorted, unique row indices inside `0 … rowCount - 1` (the order of the dragged rows is their display order).
6
+ *
7
+ * @param {number[]} rowIndices - any indices, e.g. from a selection
8
+ * @param {number} rowCount - number of rows
9
+ * @returns {number[]} a new, ascending array
10
+ *
11
+ * @example
12
+ * normalizeRowIndices([5, 2, 2, 99, -1], 10); // [2, 5]
13
+ *
14
+ * @category Row drag
15
+ * @since 1.1.95
16
+ */
17
+ export declare function normalizeRowIndices(rowIndices: readonly number[], rowCount: number): number[];
18
+ /**
19
+ * The index in front of which the rows are inserted (before the move): `"after"` row 7 = in front of row 8.
20
+ * `"inside"` counts like `"after"` (flat lists have no children).
21
+ *
22
+ * @param {RowDropTargetIf} target - the drop target
23
+ * @returns {number} the insert position, 0 … rowCount
24
+ *
25
+ * @example
26
+ * getInsertBeforeIndex({ rowIndex: 7, position: "after" }); // 8
27
+ *
28
+ * @category Row drag
29
+ * @since 1.1.95
30
+ */
31
+ export declare function getInsertBeforeIndex(target: RowDropTargetIf): number;
32
+ /**
33
+ * The index of the first moved row after a move in a flat list: the insert position minus the moved rows in front
34
+ * of it. A target inside the moved rows (or right next to them) returns their current index – nothing changes.
35
+ *
36
+ * @param {number[]} rowIndices - ascending, unique row indices ({@link normalizeRowIndices})
37
+ * @param {RowDropTargetIf} target - the drop target
38
+ * @returns {number} the new index of the first moved row, -1 without rows
39
+ *
40
+ * @example
41
+ * // D1: row 3 (index 2) dropped between row 7 and 8 → it is row 7 (index 6) afterwards
42
+ * calcMoveToIndex([2], { rowIndex: 6, position: "after" }); // 6
43
+ *
44
+ * @category Row drag
45
+ * @since 1.1.95
46
+ */
47
+ export declare function calcMoveToIndex(rowIndices: readonly number[], target: RowDropTargetIf): number;
48
+ /**
49
+ * Moves items of an array **in place** (like `Array.prototype.sort`): the items at `indices` keep their order and are
50
+ * inserted in front of `insertBefore` (an index of the array before the move, `array.length` = at the end).
51
+ *
52
+ * @param {T[]} array - the array to change
53
+ * @param {number[]} indices - ascending, unique indices ({@link normalizeRowIndices})
54
+ * @param {number} insertBefore - 0 … array.length
55
+ * @returns {number} the new index of the first moved item (-1 if nothing was given)
56
+ *
57
+ * @example
58
+ * const list = ["a", "b", "c", "d", "e"];
59
+ * moveArrayItems(list, [1, 3], 5); // 3
60
+ * list; // ["a", "c", "e", "b", "d"]
61
+ *
62
+ * @category Row drag
63
+ * @since 1.1.95
64
+ */
65
+ export declare function moveArrayItems<T>(array: T[], indices: readonly number[], insertBefore: number): number;
66
+ /**
67
+ * The dragged tree rows without the ones that travel with an ancestor (a child of a dragged node moves with it).
68
+ *
69
+ * @param {TreeRowIf<S>[]} rows - dragged rows in display order
70
+ * @returns {TreeRowIf<S>[]} the topmost dragged rows, same order
71
+ *
72
+ * @category Row drag
73
+ * @since 1.1.95
74
+ */
75
+ export declare function getTopmostTreeRows<S>(rows: readonly TreeRowIf<S>[]): TreeRowIf<S>[];
76
+ /**
77
+ * True if the tree rows can be dropped at the target row: the target is none of the dragged rows and no descendant
78
+ * of them (a node cannot become its own child – no cycle).
79
+ *
80
+ * @param {TreeRowIf<S>[]} rows - dragged rows
81
+ * @param {TreeRowIf<S>} targetRow - the row under the drop marker
82
+ * @returns {boolean} false for a cycle
83
+ *
84
+ * @example
85
+ * const treeModel = tableModel.getBodyModel() as AreaModelTree<OrderNode>;
86
+ * const node = treeModel.rows[0];
87
+ * canMoveTreeRows([node], node.children?.[0]); // false – into its own child
88
+ *
89
+ * @category Row drag
90
+ * @since 1.1.95
91
+ */
92
+ export declare function canMoveTreeRows<S>(rows: readonly TreeRowIf<S>[], targetRow: TreeRowIf<S> | undefined): boolean;
93
+ /**
94
+ * Moves tree rows **in place**: in front of / behind `targetRow` (siblings, same parent) or `"inside"` it (last
95
+ * children; the target is expanded). Children travel with their parent; `parent` and `deep` are updated.
96
+ *
97
+ * @param {TreeRowIf<S>[]} roots - the top-level rows (e.g. `AreaModelTree.rows`)
98
+ * @param {TreeRowIf<S>[]} rows - dragged rows in display order
99
+ * @param {TreeRowIf<S>} targetRow - the row under the drop marker
100
+ * @param {"before" | "after" | "inside"} position - where to drop
101
+ * @returns {boolean} false if nothing was moved (cycle, no rows)
102
+ *
103
+ * @example
104
+ * const treeModel = tableModel.getBodyModel() as AreaModelTree<OrderNode>;
105
+ * moveTreeRows(treeModel.rows, [treeModel.rows[2]], treeModel.rows[0], "inside"); // 3rd root → child of the 1st
106
+ * treeModel.recalcVisibleTreeRows();
107
+ *
108
+ * @category Row drag
109
+ * @since 1.1.95
110
+ */
111
+ export declare function moveTreeRows<S>(roots: TreeRowIf<S>[], rows: readonly TreeRowIf<S>[], targetRow: TreeRowIf<S>, position: RowDropTargetIf["position"]): boolean;
112
+ /**
113
+ * Flat area models: true if the dragged rows can be moved – all rows are displayed (no filter hides one), the target
114
+ * row exists and is not `"inside"`.
115
+ *
116
+ * @param {number} displayedCount - displayed rows (`getRowCount()`)
117
+ * @param {number} allCount - all rows (`getUnfilteredRowCount()`)
118
+ * @param {number[]} rowIndices - display indices of the dragged rows
119
+ * @param {RowDropTargetIf} target - the drop target
120
+ * @returns {boolean} true if a move is possible
121
+ *
122
+ * @category Row drag
123
+ * @since 1.1.95
124
+ */
125
+ export declare function canMoveFlatRows(displayedCount: number, allCount: number, rowIndices: readonly number[], target: RowDropTargetIf): boolean;
126
+ /**
127
+ * Flat area models: moves the rows in the displayed array and writes the new order back to the array of all rows –
128
+ * both in place. Used by `AreaModelObjectArray` and `AreaModelArrayOfArrays`.
129
+ *
130
+ * @param {T[]} displayed - displayed rows (display order)
131
+ * @param {T[]} all - all rows (same rows – no filter hides one)
132
+ * @param {number[]} rowIndices - display indices of the dragged rows
133
+ * @param {RowDropTargetIf} target - the drop target
134
+ * @returns {boolean} true if moved
135
+ *
136
+ * @category Row drag
137
+ * @since 1.1.95
138
+ */
139
+ export declare function moveFlatRows<T>(displayed: T[], all: T[], rowIndices: readonly number[], target: RowDropTargetIf): boolean;
140
+ /**
141
+ * The row at a content position (y in px from the top of all body rows): constant row heights are computed directly,
142
+ * variable ones by a binary search over the row tops. Positions above / below the rows give the first / last row.
143
+ *
144
+ * @param {number} contentY - y in content pixels
145
+ * @param {number} rowCount - number of rows (> 0)
146
+ * @param {(rowIndex: number) => number} getYPosByRowIndex - top of a row in content pixels (`AreaModelIf.getYPosByRowIndex`)
147
+ * @param {number} [constantRowHeight] - the height of every row, if they are all equal (`AreaModelIf.getConstantRowHeight`)
148
+ * @returns {number} the row index, 0 … rowCount - 1
149
+ *
150
+ * @example
151
+ * const body = tableModel.getBodyModel();
152
+ * const rowIndex = findRowIndexAtY(1234, body.getRowCount(), i => body.getYPosByRowIndex(i), body.getConstantRowHeight?.());
153
+ *
154
+ * @category Row drag
155
+ * @since 1.1.95
156
+ */
157
+ export declare function findRowIndexAtY(contentY: number, rowCount: number, getYPosByRowIndex: (rowIndex: number) => number, constantRowHeight?: number): number;
@@ -0,0 +1,28 @@
1
+ import { RowDragOptionsIf } from './row-drag-options.if.js';
2
+
3
+ /**
4
+ * The defaults of {@link RowDragOptionsIf}.
5
+ *
6
+ * @example
7
+ * const options = RowDragOptions.create({ managed: false });
8
+ * options.autoScrollZoneInPx; // 40
9
+ *
10
+ * @category Row drag
11
+ * @since 1.1.95
12
+ */
13
+ export declare class RowDragOptions implements RowDragOptionsIf {
14
+ managed: boolean;
15
+ multiRow: boolean;
16
+ treeDropInside: boolean;
17
+ dragThresholdInPx: number;
18
+ autoScrollZoneInPx: number;
19
+ autoScrollMaxSpeedInPx: number;
20
+ ghostText?: (rows: any[]) => string;
21
+ /**
22
+ * The defaults, overridden by the given values (`undefined` keeps the default).
23
+ *
24
+ * @param {Partial<RowDragOptionsIf>} [options] - e.g. `tableOptions.rowDragOptions`
25
+ * @returns {RowDragOptionsIf} complete options
26
+ */
27
+ static create(options?: Partial<RowDragOptionsIf>): RowDragOptionsIf;
28
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Options of row dragging ({@link TableOptionsIf.rowDragOptions}). Rows get a drag handle in every column with
3
+ * {@link ColumnDefIf.rowDrag} (or `TableFactory.createTableModel({ rows, rowDrag: true })`).
4
+ *
5
+ * @example
6
+ * const tableOptions: TableOptionsIf = {
7
+ * ...new TableOptions(),
8
+ * rowDragOptions: { managed: false, autoScrollMaxSpeedInPx: 40 } // events only – the app moves the rows
9
+ * };
10
+ *
11
+ * @category Row drag
12
+ * @since 1.1.95
13
+ */
14
+ export interface RowDragOptionsIf {
15
+ /**
16
+ * `true` (default): the table moves the rows itself (`AreaModelIf.moveRows`) – only while the table is neither
17
+ * sorted (a column with sort state asc/desc) nor filtered. `false`: the table only reports the drag
18
+ * (`onRowDragStart/Move/End`), the app moves the rows (e.g. after the server confirmed), always allowed.
19
+ */
20
+ managed: boolean;
21
+ /** `true` (default): grabbing a selected row drags all rows with a selection (their order stays). */
22
+ multiRow: boolean;
23
+ /** `true` (default): tree – dropping on the middle of a row makes the rows its children. */
24
+ treeDropInside: boolean;
25
+ /** Distance in px the pointer has to move before a drag starts (default 4) – below it is a click on the handle. */
26
+ dragThresholdInPx: number;
27
+ /** Height in px of the zone at the top and bottom edge of the body that scrolls automatically (default 40). */
28
+ autoScrollZoneInPx: number;
29
+ /** Maximum auto-scroll speed in px per animation frame (default 24). */
30
+ autoScrollMaxSpeedInPx: number;
31
+ /**
32
+ * Text of the drag ghost. Default: the text of the handle cell of the first row, "(+2)" for two more rows.
33
+ * The text is shown as text (never as HTML).
34
+ */
35
+ ghostText?: (rows: any[]) => string;
36
+ }
@@ -0,0 +1,130 @@
1
+ import { TableScope } from '../table-scope.js';
2
+ import { AreaModelIf } from '../data/tablemodel/areamodel/area-model.if.js';
3
+ import { ColumnDefIf } from '../data/tablemodel/column/column-def.if.js';
4
+ import { RowDropTargetIf } from './row-drop-target.if.js';
5
+ import { RowDragOptionsIf } from './row-drag-options.if.js';
6
+
7
+ /**
8
+ * Whether a body cell shows a drag handle: `"none"`, `"enabled"`, or `"disabled"` (managed drag while the table is
9
+ * sorted or filtered).
10
+ *
11
+ * @category Row drag
12
+ * @since 1.1.95
13
+ */
14
+ export type RowDragHandleState = "none" | "enabled" | "disabled";
15
+ /**
16
+ * Row drag of one table (`tableScope.rowDragService`): drag handles ({@link ColumnDefIf.rowDrag}), pointer drag with
17
+ * ghost, drop marker and auto-scroll, the keyboard alternative (`MOVE_ROW_UP` / `MOVE_ROW_DOWN`) and the managed move.
18
+ * Use {@link TableApi.moveRows}, {@link TableApi.isRowDragging} and {@link TableApi.cancelRowDrag} instead.
19
+ *
20
+ * Pointer Events (mouse, touch, pen) – only on the drag handle; its `pointerdown` is prevented, so the mouse handler
21
+ * of the table (range selection, column drag) never sees it.
22
+ *
23
+ * @category Internals
24
+ * @since 1.1.95
25
+ */
26
+ export declare class RowDragService {
27
+ private readonly tableScope;
28
+ private pending?;
29
+ private session?;
30
+ private sessionAbortController?;
31
+ private ghost?;
32
+ private indicator?;
33
+ private autoScrollFrame;
34
+ private suppressClick;
35
+ private warnedUnsupported;
36
+ constructor(tableScope: TableScope);
37
+ /** The options of this table ({@link TableOptionsIf.rowDragOptions} + defaults). */
38
+ get options(): RowDragOptionsIf;
39
+ /** true while rows are dragged with the pointer. */
40
+ isDragging(): boolean;
41
+ /** true if the row is one of the dragged rows (it is painted dimmed). */
42
+ isDragSourceRow(rowIndex: number): boolean;
43
+ /**
44
+ * Why a managed drag is not possible right now: `"sorted"` (a column has the sort state asc/desc), `"filtered"`
45
+ * (a filter hides rows) – `undefined` if it is possible or the drag is unmanaged.
46
+ */
47
+ getBlockReason(): "sorted" | "filtered" | undefined;
48
+ /**
49
+ * The drag handle of a body cell: none (no `rowDrag`, a group or pivot row, a managed drag the model cannot do),
50
+ * enabled or disabled (managed + sorted/filtered).
51
+ */
52
+ getHandleState(rowIndex: number, columnDef: ColumnDefIf | undefined, areaModel: AreaModelIf): RowDragHandleState;
53
+ /**
54
+ * Adds the drag handle to a rendered body cell (called by the render pass for columns with `rowDrag`).
55
+ *
56
+ * @param {HTMLDivElement} cell - the cell div
57
+ * @param {RowDragHandleState} state - from {@link getHandleState}
58
+ */
59
+ decorateCell(cell: HTMLDivElement, state: RowDragHandleState): void;
60
+ private onPointerDown;
61
+ private listenToDocument;
62
+ private onPointerMove;
63
+ private onPointerUp;
64
+ private onPointerCancel;
65
+ private onKeyDown;
66
+ private onClickCapture;
67
+ /** Starts the drag after the threshold – false if the listener vetoed it. */
68
+ private startPointerDrag;
69
+ /** Computes the drop target from the pointer position, reports a change, moves ghost and marker, auto-scrolls. */
70
+ private updateTarget;
71
+ private autoScrollStep;
72
+ /**
73
+ * Speed in px per frame (negative = up): a quadratic ramp inside the zone at the top/bottom edge of the body, full
74
+ * speed above (header) and below (footer) the body.
75
+ */
76
+ private calcAutoScrollSpeed;
77
+ /** The row under the pointer and the position (before/after/inside) – computed, not read from the DOM. */
78
+ private computeTarget;
79
+ private isValidTarget;
80
+ private drop;
81
+ /**
82
+ * Cancels a running drag (Escape, `pointercancel`, {@link TableApi.cancelRowDrag}, destroy): `onRowDragEnd` with the
83
+ * type `"cancel"`, nothing is moved.
84
+ */
85
+ cancel(originalEvent?: PointerEvent | KeyboardEvent): void;
86
+ /** Ends the pointer session: listeners, ghost, marker, auto-scroll. */
87
+ private stopListening;
88
+ /** Releases everything (TableScope.destroy). A running drag is cancelled. */
89
+ destroy(): void;
90
+ private createDragElements;
91
+ private getGhostText;
92
+ private renderDragElements;
93
+ /** The rows' width (fixed columns + center columns), at most the visible width – the marker ends with the rows. */
94
+ private getMarkerWidth;
95
+ /**
96
+ * Moves rows in the model (managed), repaints, keeps focus and selection on the moved rows and announces the new
97
+ * position.
98
+ *
99
+ * @param {number[]} rowIndices - display indices
100
+ * @param {RowDropTargetIf} target - drop target
101
+ * @param {boolean} reselect - select the moved rows again (multi-row drag)
102
+ * @returns {number} the new display index of the first moved row, -1 if nothing moved
103
+ */
104
+ moveRows(rowIndices: number[], target: RowDropTargetIf, reselect?: boolean): number;
105
+ private findDisplayIndices;
106
+ /**
107
+ * `MOVE_ROW_UP` / `MOVE_ROW_DOWN`: moves the focused row (or the selected rows, if it is one of them) one position.
108
+ * Trees: among the siblings.
109
+ *
110
+ * @param {-1 | 1} direction - up or down
111
+ * @returns {boolean} true if the key was used (a row with a drag handle has the focus)
112
+ */
113
+ moveByKeyboard(direction: -1 | 1): boolean;
114
+ private getFlatKeyboardTarget;
115
+ private getTreeKeyboardTarget;
116
+ /** The dragged rows for a grabbed row: all rows with a selection if it is one of them (multiRow), else this one. */
117
+ getDragRowIndices(rowIndex: number): number[];
118
+ private getRows;
119
+ /** Index of the first column whose drag handle is shown for the row, -1 if none. */
120
+ private getHandleColumnIndex;
121
+ /** The state of the handle of a row that has one (see {@link getHandleColumnIndex}). */
122
+ private getHandleStateOfRow;
123
+ /** true if a column has the sort state asc or desc (the header shows the arrow). */
124
+ private isSorted;
125
+ private isManaged;
126
+ private canModelMove;
127
+ private createEvent;
128
+ private announceNotPossible;
129
+ private texts;
130
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Where dragged rows are dropped, relative to the row under the drop marker:
3
+ * `"before"` / `"after"` that row, or `"inside"` it (it becomes the last child – trees only).
4
+ *
5
+ * @example
6
+ * const target: RowDropTargetIf = { rowIndex: 7, position: "before" }; // between row 7 and row 8 (1-based)
7
+ *
8
+ * @category Row drag
9
+ * @since 1.1.95
10
+ */
11
+ export type RowDropPosition = "before" | "after" | "inside";
12
+ /**
13
+ * The drop target of a row drag ({@link GeRowDragEvent.target}, {@link TableApi.moveRows}).
14
+ *
15
+ * `rowIndex` is the display index (body row index) of the target row **before** the rows are moved.
16
+ *
17
+ * @example
18
+ * // move the rows 2 and 3 behind the last row
19
+ * tableApi.moveRows([2, 3], { rowIndex: tableApi.getDisplayedRowCount() - 1, position: "after" });
20
+ *
21
+ * @category Row drag
22
+ * @since 1.1.95
23
+ */
24
+ export interface RowDropTargetIf {
25
+ /** Display index of the row next to (or under) the drop marker – before the move. */
26
+ rowIndex: number;
27
+ /** Before or after that row, or inside it (tree: becomes its last child). */
28
+ position: RowDropPosition;
29
+ }
@@ -24,6 +24,8 @@ import { ExcelServiceIf } from './excel-service.if.js';
24
24
  * @category Export & clipboard
25
25
  */
26
26
  export declare class ExcelService implements ExcelServiceIf {
27
+ /** Understands cells `{ value, numberFormat }` ({@link ExcelFormattedValueIf}), since 1.1.95. */
28
+ readonly supportsNumberFormats = true;
27
29
  /**
28
30
  * Downloads a matrix data as an Excel file.
29
31
  *
@@ -44,6 +46,10 @@ export declare class ExcelService implements ExcelServiceIf {
44
46
  createExcelBlob(matrix: Array<Array<any>>, author?: string): Promise<Blob>;
45
47
  private generateMap;
46
48
  private getX1WorksheetsSheet1Xml;
49
+ /** Number format → cell style index (1-based; 0 = default), filled by withNumberFormats() before the sheet is written. */
50
+ private numberFormatStyles;
51
+ /** Adds one cell style per number format used in the matrix (`<numFmts>` + `<cellXfs>`); unchanged without formats. */
52
+ private withNumberFormats;
47
53
  private escapeXml;
48
54
  private getCellAddress;
49
55
  /**
@@ -7,4 +7,39 @@
7
7
  export interface ExcelServiceIf {
8
8
  /** Creates the file from `matrix` (rows of values) and hands it to the browser as download. */
9
9
  downloadExcel(matrix: Array<Array<any>>, filename: string, author?: string): void | Promise<void>;
10
+ /**
11
+ * True if the service understands cells of the form {@link ExcelFormattedValueIf} (`{ value, numberFormat }`).
12
+ * Only then {@link TableApi.downloadExcel} exports percentages of „Show values as“ columns with the format `0.0%`;
13
+ * otherwise a service gets plain numbers (since 1.1.95).
14
+ */
15
+ readonly supportsNumberFormats?: boolean;
10
16
  }
17
+ /**
18
+ * A cell of an Excel matrix with a number format, e.g. a share shown as percentage. Understood by
19
+ * {@link ExcelService} (`supportsNumberFormats`).
20
+ *
21
+ * @example
22
+ * await new ExcelService().downloadExcel([["Share"], [{ value: 0.667, numberFormat: "0.0%" }]], "shares.xlsx");
23
+ *
24
+ * @since 1.1.95
25
+ * @category Export & clipboard
26
+ */
27
+ export interface ExcelFormattedValueIf {
28
+ /** The number. */
29
+ value: number;
30
+ /** An Excel number format code, e.g. `"0.0%"`, `"#,##0.00"`. */
31
+ numberFormat: string;
32
+ }
33
+ /**
34
+ * True for a cell of the form {@link ExcelFormattedValueIf}.
35
+ *
36
+ * @param {unknown} cell - a cell of an Excel matrix
37
+ * @returns {boolean} whether it is a number with format
38
+ *
39
+ * @example
40
+ * isExcelFormattedValue({ value: 0.5, numberFormat: "0%" }); // true
41
+ *
42
+ * @since 1.1.95
43
+ * @category Export & clipboard
44
+ */
45
+ export declare function isExcelFormattedValue(cell: unknown): cell is ExcelFormattedValueIf;