@guiexpert/table 1.1.98 → 1.1.99
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.
- package/README.md +9 -0
- package/css/main.css +296 -0
- package/css/table-clipboard.css +41 -0
- package/css/table-color-vars.css +56 -0
- package/css/table-sheet-editing.css +149 -0
- package/css/table-spreadsheet.css +50 -0
- package/index.cjs +46 -59
- package/index.d.ts +46 -0
- package/index.js +18934 -11624
- package/lib/table/action/action-id.type.d.ts +1 -1
- package/lib/table/action/shortcut.service.d.ts +9 -0
- package/lib/table/aria/aria-texts.d.ts +26 -0
- package/lib/table/aria/aria-texts.if.d.ts +196 -0
- package/lib/table/batch-edit/batch-edit-service.d.ts +22 -0
- package/lib/table/batch-edit/cell-change.if.d.ts +6 -2
- package/lib/table/batch-edit/pending-cell-changes.d.ts +7 -0
- package/lib/table/batch-edit/write-row-value.d.ts +14 -0
- package/lib/table/calc/column-values.d.ts +2 -0
- package/lib/table/clipboard/clipboard-html.d.ts +41 -0
- package/lib/table/clipboard/clipboard-keymap.d.ts +18 -0
- package/lib/table/clipboard/clipboard-options.d.ts +30 -0
- package/lib/table/clipboard/clipboard-options.if.d.ts +67 -0
- package/lib/table/clipboard/clipboard-service.d.ts +122 -0
- package/lib/table/clipboard/input-pipes.d.ts +59 -0
- package/lib/table/clipboard/paste-plan.d.ts +96 -0
- package/lib/table/clipboard/tsv.d.ts +31 -0
- package/lib/table/data/common/event/ge-edit-event.d.ts +46 -0
- package/lib/table/data/common/event/ge-row-drag-event.d.ts +2 -2
- package/lib/table/data/common/event/ge-undo-event.d.ts +29 -0
- package/lib/table/data/options/table-options.d.ts +28 -0
- package/lib/table/data/options/table-options.if.d.ts +99 -1
- package/lib/table/data/tablemodel/areamodel/abstract-area-model.d.ts +11 -2
- package/lib/table/data/tablemodel/areamodel/area-model-array-of-arrays.d.ts +14 -0
- package/lib/table/data/tablemodel/areamodel/area-model-object-array.d.ts +14 -0
- package/lib/table/data/tablemodel/areamodel/area-model.if.d.ts +11 -0
- package/lib/table/data/tablemodel/column/column-def.d.ts +13 -0
- package/lib/table/data/tablemodel/column/column-def.if.d.ts +36 -1
- package/lib/table/data/tablemodel/column/default-editable.d.ts +18 -0
- package/lib/table/event-adapter.d.ts +6 -0
- package/lib/table/event-listener-hub.d.ts +10 -0
- package/lib/table/event-listener.if.d.ts +16 -0
- package/lib/table/factory/pivot-factory.d.ts +1 -1
- package/lib/table/factory/row-group-factory.d.ts +1 -1
- package/lib/table/factory/table-factory.d.ts +14 -0
- package/lib/table/formula/formula-ast.if.d.ts +32 -2
- package/lib/table/formula/formula-error.d.ts +4 -2
- package/lib/table/formula/parser.d.ts +5 -2
- package/lib/table/formula/tokenizer.d.ts +5 -2
- package/lib/table/input-handler.d.ts +8 -0
- package/lib/table/master-detail/master-detail-service.d.ts +9 -0
- package/lib/table/render-scope.d.ts +40 -0
- package/lib/table/row-drag/row-drag-service.d.ts +3 -2
- package/lib/table/selection/selection-service.d.ts +48 -0
- package/lib/table/service/excel-export-options.if.d.ts +6 -0
- package/lib/table/service/excel-service.d.ts +4 -0
- package/lib/table/service/excel-service.if.d.ts +35 -0
- package/lib/table/sheet/cell-address.d.ts +100 -0
- package/lib/table/sheet/cell-formula-options.d.ts +27 -0
- package/lib/table/sheet/cell-formula-options.if.d.ts +27 -0
- package/lib/table/sheet/excel-formula.d.ts +20 -0
- package/lib/table/sheet/format-formula.d.ts +19 -0
- package/lib/table/sheet/sheet-cells.if.d.ts +17 -0
- package/lib/table/sheet/sheet-compiler.d.ts +47 -0
- package/lib/table/sheet/sheet-engine.d.ts +207 -0
- package/lib/table/sheet/sheet-function-info.d.ts +25 -0
- package/lib/table/sheet/sheet-functions.d.ts +27 -0
- package/lib/table/sheet/sheet-values.d.ts +154 -0
- package/lib/table/sheet/shift-formula.d.ts +71 -0
- package/lib/table/sheet/table-sheet.d.ts +214 -0
- package/lib/table/sheet-editing/cell-editor-service.d.ts +105 -0
- package/lib/table/sheet-editing/cell-editor.if.d.ts +110 -0
- package/lib/table/sheet-editing/editing-keymap.d.ts +17 -0
- package/lib/table/sheet-editing/editing-options.d.ts +34 -0
- package/lib/table/sheet-editing/editing-options.if.d.ts +49 -0
- package/lib/table/sheet-editing/editors/date-cell-editor.d.ts +23 -0
- package/lib/table/sheet-editing/editors/number-cell-editor.d.ts +18 -0
- package/lib/table/sheet-editing/editors/select-cell-editor.d.ts +36 -0
- package/lib/table/sheet-editing/editors/text-cell-editor.d.ts +35 -0
- package/lib/table/sheet-editing/formula-assist.d.ts +103 -0
- package/lib/table/sheet-editing/formula-text.d.ts +61 -0
- package/lib/table/sheet-editing/sheet-navigation.d.ts +26 -0
- package/lib/table/spreadsheet/area-model-sheet.d.ts +170 -0
- package/lib/table/spreadsheet/formula-bar.d.ts +53 -0
- package/lib/table/spreadsheet/spreadsheet-factory.d.ts +111 -0
- package/lib/table/spreadsheet/spreadsheet-options.if.d.ts +28 -0
- package/lib/table/spreadsheet/spreadsheet-preset.d.ts +37 -0
- package/lib/table/spreadsheet/structure-edit.d.ts +35 -0
- package/lib/table/table-api.d.ts +511 -2
- package/lib/table/table-scope.d.ts +294 -1
- package/lib/table/undo/cell-changes-undoable.d.ts +34 -0
- package/lib/table/undo/model-rows.d.ts +17 -0
- package/lib/table/undo/pending-changes-undoable.d.ts +35 -0
- package/lib/table/undo/undo-keymap.d.ts +17 -0
- package/lib/table/undo/undo-options.d.ts +26 -0
- package/lib/table/undo/undo-options.if.d.ts +30 -0
- package/lib/table/undo/undo-service.d.ts +103 -0
- package/lib/table/undo/undo-stack.d.ts +62 -0
- package/lib/table/undo/undoable.if.d.ts +36 -0
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ import { BooleanFunction } from '../../common/boolean-function.js';
|
|
|
5
5
|
import { SortState } from '../../common/sort-state.type.js';
|
|
6
6
|
import { GetEditRenderer } from '../../../renderer/edit/edit-cell-renderer.type.js';
|
|
7
7
|
import { editInputPipe } from '../../../renderer/edit/edit-input-pipe.if.js';
|
|
8
|
+
import { ColumnEditorOption } from '../../../sheet-editing/cell-editor.if.js';
|
|
8
9
|
import { ValueGetter, ValueSetter } from '../../../calc/value-getter.type.js';
|
|
9
10
|
import { ShowValuesAsConfig } from '../../../calc/show-values-as.type.js';
|
|
10
11
|
|
|
@@ -131,7 +132,7 @@ export interface ColumnDefIf {
|
|
|
131
132
|
* ColumnDef.create({ property: "total", headerLabel: "Total", sortable: TrueFn,
|
|
132
133
|
* valueGetter: (o: Item) => o.price * o.quantity })
|
|
133
134
|
*
|
|
134
|
-
* @see Training: [
|
|
135
|
+
* @see [Live demo: formulas & calculated columns](https://gui.expert/showcase/formulas/run/) · Training: [Calculated columns, “Show values as” and formulas](https://gui.expert/training/formulas/)
|
|
135
136
|
* @since 1.1.95
|
|
136
137
|
*/
|
|
137
138
|
valueGetter?: ValueGetter;
|
|
@@ -151,6 +152,7 @@ export interface ColumnDefIf {
|
|
|
151
152
|
* @example
|
|
152
153
|
* ColumnDef.create({ property: "total", headerLabel: "Share", showValuesAs: "percentOfColumnTotal" })
|
|
153
154
|
*
|
|
155
|
+
* @see Training: [Show values as](https://gui.expert/training/formulas/#show-values-as)
|
|
154
156
|
* @since 1.1.95
|
|
155
157
|
*/
|
|
156
158
|
showValuesAs?: ShowValuesAsConfig;
|
|
@@ -158,6 +160,7 @@ export interface ColumnDefIf {
|
|
|
158
160
|
* The formula of a formula column (`ColumnDef.create({ formula })` compiles it into the `valueGetter`), e.g.
|
|
159
161
|
* `"[price] * [quantity] * 1.19"`. Informational – change it with {@link TableApi.setColumnFormula}.
|
|
160
162
|
*
|
|
163
|
+
* @see [Live demo: formulas](https://gui.expert/showcase/formulas/run/) · Training: [Formulas your users can type](https://gui.expert/training/formulas/#formulas)
|
|
161
164
|
* @since 1.1.95
|
|
162
165
|
*/
|
|
163
166
|
formula?: string;
|
|
@@ -187,6 +190,38 @@ export interface ColumnDefIf {
|
|
|
187
190
|
* @since 1.1.96
|
|
188
191
|
*/
|
|
189
192
|
validate?: CellValidator;
|
|
193
|
+
/**
|
|
194
|
+
* The editor of this column in Excel-style editing ({@link TableOptionsIf.editing}): `"text"`, `"number"`,
|
|
195
|
+
* `"date"` or a factory for an own {@link CellEditorIf}. Without it the table chooses by the value (numbers →
|
|
196
|
+
* number editor, dates → date editor, otherwise text). A column with an own {@link getEditRenderer} keeps that
|
|
197
|
+
* editor (inside the cell, as before).
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ColumnDef.create({ property: "status", editable: TrueFn, editor: () => SelectCellEditor.create(["open", "paid"]) })
|
|
201
|
+
*
|
|
202
|
+
* @since 1.1.99
|
|
203
|
+
*/
|
|
204
|
+
editor?: ColumnEditorOption;
|
|
205
|
+
/**
|
|
206
|
+
* The value a cleared cell gets (Delete/Backspace in Excel-style editing), e.g. `null` or `0`. Default:
|
|
207
|
+
* {@link EditingOptionsIf.emptyValue} (`""`).
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ColumnDef.create({ property: "quantity", editable: TrueFn, emptyValue: 0 })
|
|
211
|
+
*
|
|
212
|
+
* @since 1.1.99
|
|
213
|
+
*/
|
|
214
|
+
emptyValue?: unknown;
|
|
215
|
+
/**
|
|
216
|
+
* `false`: this column never holds cell formulas ({@link TableOptionsIf.cellFormulas}) – `"=…"` stays text (free
|
|
217
|
+
* text, notes). Default: every data column of a table with `cellFormulas`.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ColumnDef.create({ property: "note", editable: TrueFn, cellFormulas: false })
|
|
221
|
+
*
|
|
222
|
+
* @since 1.1.99
|
|
223
|
+
*/
|
|
224
|
+
cellFormulas?: boolean;
|
|
190
225
|
}
|
|
191
226
|
/**
|
|
192
227
|
* {@link ColumnDefIf.validate}: a message for an invalid value, `undefined` (or `null`, `""`) for a valid one.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ColumnDefIf } from './column-def.if.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `editable` of a column that `ColumnDef.create()` got without `editable`: read only (Excel-style editing with
|
|
5
|
+
* `defaultEditable` may edit it). An own `editable` set later – also `FalseFn` – replaces it.
|
|
6
|
+
*
|
|
7
|
+
* @returns {boolean} false
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULTED_EDITABLE: () => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* True if the column has no own `editable` (`undefined`, or the default of `ColumnDef.create`).
|
|
13
|
+
*
|
|
14
|
+
* @param {ColumnDefIf} def - the column
|
|
15
|
+
* @returns {boolean} true without own `editable`
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare function hasDefaultEditable(def: ColumnDefIf): boolean;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { GeEditEvent } from './data/common/event/ge-edit-event.js';
|
|
2
|
+
import { GeUndoEvent } from './data/common/event/ge-undo-event.js';
|
|
1
3
|
import { GeDetailEvent } from './data/common/event/ge-detail-event.js';
|
|
2
4
|
import { GeModelChangeEvent } from './data/common/event/ge-model-change-event.js';
|
|
3
5
|
import { GeMouseEvent } from './data/common/event/ge-mouse-event.js';
|
|
@@ -43,4 +45,8 @@ export declare class EventAdapter implements EventListenerIf {
|
|
|
43
45
|
onBatchEditChanged(_evt: GeBatchEditEvent): void;
|
|
44
46
|
/** @since 1.1.97 */
|
|
45
47
|
onDetailExpandedChanged(_evt: GeDetailEvent): void;
|
|
48
|
+
/** @since 1.1.99 */
|
|
49
|
+
onEditingChanged(_evt: GeEditEvent): void;
|
|
50
|
+
/** @since 1.1.99 */
|
|
51
|
+
onUndoStackChanged(_evt: GeUndoEvent): void;
|
|
46
52
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EventListenerIf } from './event-listener.if.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The event listener of a table: the listener given to the constructor plus the listeners of
|
|
5
|
+
* {@link TableApi.subscribe}. Without subscribers every call goes to the main listener exactly as before
|
|
6
|
+
* (`listener.onX` is the main listener's member, also `undefined`).
|
|
7
|
+
*
|
|
8
|
+
* Not exported: an internal of {@link TableScope}.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createEventListenerHub(main: EventListenerIf, subscribers: Set<Partial<EventListenerIf>>): EventListenerIf;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { GeEditEvent } from './data/common/event/ge-edit-event.js';
|
|
2
|
+
import { GeUndoEvent } from './data/common/event/ge-undo-event.js';
|
|
1
3
|
import { GeDetailEvent } from './data/common/event/ge-detail-event.js';
|
|
2
4
|
import { GeMouseEvent } from './data/common/event/ge-mouse-event.js';
|
|
3
5
|
import { GeModelChangeEvent } from './data/common/event/ge-model-change-event.js';
|
|
@@ -102,4 +104,18 @@ export interface EventListenerIf extends EventFocusChangedListenerIf, EventSelec
|
|
|
102
104
|
* @since 1.1.97
|
|
103
105
|
*/
|
|
104
106
|
onDetailExpandedChanged?(evt: GeDetailEvent): void;
|
|
107
|
+
/**
|
|
108
|
+
* The cell editor opened, its text changed (Excel-style editing), it committed or it was cancelled. Optional.
|
|
109
|
+
*
|
|
110
|
+
* @param {GeEditEvent} evt - type, cell, mode, editor text
|
|
111
|
+
* @since 1.1.99
|
|
112
|
+
*/
|
|
113
|
+
onEditingChanged?(evt: GeEditEvent): void;
|
|
114
|
+
/**
|
|
115
|
+
* The undo history changed (undo and redo, {@link TableOptionsIf.undo}) – to enable and label own buttons. Optional.
|
|
116
|
+
*
|
|
117
|
+
* @param {GeUndoEvent} evt - can undo/redo, labels, size
|
|
118
|
+
* @since 1.1.99
|
|
119
|
+
*/
|
|
120
|
+
onUndoStackChanged?(evt: GeUndoEvent): void;
|
|
105
121
|
}
|
|
@@ -38,7 +38,7 @@ import { PivotTableModel } from '../pivot/pivot-table-model.js';
|
|
|
38
38
|
* });
|
|
39
39
|
* select.addEventListener("change", () => tableApi.setPivotConfig({ columnFields: [select.value] }));
|
|
40
40
|
*
|
|
41
|
-
* @see Training: [Pivot tables](https://gui.expert/training/pivot-tables/)
|
|
41
|
+
* @see [Live demo: pivot tables](https://gui.expert/showcase/pivot/run/) · Training: [Pivot tables](https://gui.expert/training/pivot-tables/)
|
|
42
42
|
*
|
|
43
43
|
* @since 1.1.94
|
|
44
44
|
* @category Pivot
|
|
@@ -31,7 +31,7 @@ import { RowGroupTableModelParaIf } from './row-group-table-model-para.if.js';
|
|
|
31
31
|
* });
|
|
32
32
|
* select.addEventListener("change", () => tableApi.setRowGroupBy(select.value.split(",")));
|
|
33
33
|
*
|
|
34
|
-
* @see Training: [Row grouping](https://gui.expert/training/row-grouping/)
|
|
34
|
+
* @see [Live demo: row grouping](https://gui.expert/showcase/rowgrouping/run/) · Training: [Row grouping](https://gui.expert/training/row-grouping/)
|
|
35
35
|
*
|
|
36
36
|
* @since 1.1.94
|
|
37
37
|
* @category Row grouping
|
|
@@ -54,6 +54,7 @@ export interface CreateTableModelPara {
|
|
|
54
54
|
* footerAggregates: { quantity: "sum", total: "sum" } // footer: "100,000 rows" | … | 549,812 | 27,481,033.5
|
|
55
55
|
* });
|
|
56
56
|
*
|
|
57
|
+
* @see [Live demo: totals & aggregation](https://gui.expert/showcase/aggregation/run/) · Training: [Totals in one option](https://gui.expert/training/footer-totals/#built-in)
|
|
57
58
|
* @since 1.1.94
|
|
58
59
|
*/
|
|
59
60
|
footerAggregates: AggregateFooterConfig;
|
|
@@ -75,6 +76,7 @@ export interface CreateTableModelPara {
|
|
|
75
76
|
* @example
|
|
76
77
|
* const tableModel = TableFactory.createTableModel({ rows: orders, columnDefs, rowNumbersVisible: true });
|
|
77
78
|
*
|
|
79
|
+
* @see [Live demo: row numbers](https://gui.expert/showcase/rownumbers/run/) · Training: [Row numbers](https://gui.expert/training/fixed-columns/#row-numbers)
|
|
78
80
|
* @since 1.1.93
|
|
79
81
|
*/
|
|
80
82
|
rowNumbersVisible: boolean | Partial<RowNumberOptionsIf>;
|
|
@@ -86,9 +88,21 @@ export interface CreateTableModelPara {
|
|
|
86
88
|
* @example
|
|
87
89
|
* const tableModel = TableFactory.createTableModel({ rows: orders, rowDrag: true });
|
|
88
90
|
*
|
|
91
|
+
* @see [Live demo: row drag](https://gui.expert/showcase/rowdrag/run/) · Training: [Dragging rows into order](https://gui.expert/training/events-and-context-menu/#row-drag)
|
|
89
92
|
* @since 1.1.95
|
|
90
93
|
*/
|
|
91
94
|
rowDrag: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Column letters `A, B, …` as an extra header row above the header labels (like a spreadsheet; for cell formulas,
|
|
97
|
+
* {@link TableOptionsIf.cellFormulas}). A click on a letter selects the column (selection type `"range"`).
|
|
98
|
+
* Row number and checkbox columns get no letter. Only with the default header (labels or `headerData`).
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* const tableModel = TableFactory.createTableModel({ rows, columnDefs, rowNumbersVisible: { mode: "original" }, columnLetters: true });
|
|
102
|
+
*
|
|
103
|
+
* @since 1.1.99
|
|
104
|
+
*/
|
|
105
|
+
columnLetters: boolean;
|
|
92
106
|
/** Row heights of header, body and footer in px. Default: `tableOptions.defaultRowHeights`, otherwise 34 / 34 / 34. */
|
|
93
107
|
defaultRowHeights: DefaultRowHeightsIf;
|
|
94
108
|
/** The columns: property, header label, width, classes, renderers, sorting, editing. See {@link ColumnDef}. */
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* A node of a compiled formula (abstract syntax tree). Read-only; the evaluator walks it – no code is generated
|
|
3
3
|
* (no `eval`, no `new Function`).
|
|
4
4
|
*
|
|
5
|
+
* Cell formulas (since 1.1.99, spreadsheet mode) add cell references (`ref`), ranges (`range`), error literals
|
|
6
|
+
* (`error`, e.g. `#REF!` after deleting rows) and the percent operator (`unary` with `"%"`); the formulas of
|
|
7
|
+
* calculated columns never contain them.
|
|
8
|
+
*
|
|
5
9
|
* @example
|
|
6
10
|
* const ast = compileFormula("[price] * 2").ast;
|
|
7
11
|
* // { kind: "binary", op: "*", left: { kind: "field", name: "price" }, right: { kind: "literal", value: 2 } }
|
|
@@ -11,13 +15,13 @@
|
|
|
11
15
|
*/
|
|
12
16
|
export type FormulaNode = {
|
|
13
17
|
readonly kind: "literal";
|
|
14
|
-
readonly value: number | string | boolean;
|
|
18
|
+
readonly value: number | string | boolean | null;
|
|
15
19
|
} | {
|
|
16
20
|
readonly kind: "field";
|
|
17
21
|
readonly name: string;
|
|
18
22
|
} | {
|
|
19
23
|
readonly kind: "unary";
|
|
20
|
-
readonly op: "-" | "+";
|
|
24
|
+
readonly op: "-" | "+" | "%";
|
|
21
25
|
readonly operand: FormulaNode;
|
|
22
26
|
} | {
|
|
23
27
|
readonly kind: "binary";
|
|
@@ -28,7 +32,33 @@ export type FormulaNode = {
|
|
|
28
32
|
readonly kind: "call";
|
|
29
33
|
readonly name: string;
|
|
30
34
|
readonly args: readonly FormulaNode[];
|
|
35
|
+
} | FormulaRefNode | {
|
|
36
|
+
readonly kind: "range";
|
|
37
|
+
readonly from: FormulaRefNode;
|
|
38
|
+
readonly to: FormulaRefNode;
|
|
39
|
+
} | {
|
|
40
|
+
readonly kind: "error";
|
|
41
|
+
readonly code: string;
|
|
42
|
+
readonly message?: string;
|
|
43
|
+
readonly text?: string;
|
|
31
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* A cell reference of a cell formula: row and column 0-based (`B3` = row 2, column 1), `$` = absolute. In a range a
|
|
47
|
+
* whole column (`A:A`) has `row: -1`, a whole row (`3:3`) has `col: -1`.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* const ref: FormulaRefNode = { kind: "ref", row: 2, col: 1, absRow: true, absCol: false }; // B$3
|
|
51
|
+
*
|
|
52
|
+
* @since 1.1.99
|
|
53
|
+
* @category Spreadsheet
|
|
54
|
+
*/
|
|
55
|
+
export interface FormulaRefNode {
|
|
56
|
+
readonly kind: "ref";
|
|
57
|
+
readonly row: number;
|
|
58
|
+
readonly col: number;
|
|
59
|
+
readonly absRow: boolean;
|
|
60
|
+
readonly absCol: boolean;
|
|
61
|
+
}
|
|
32
62
|
/**
|
|
33
63
|
* The binary operators of a formula: arithmetic (`+ - * / ^`), text concatenation (`&`) and comparisons
|
|
34
64
|
* (`=`/`==`, `<>`/`!=`, `<`, `<=`, `>`, `>=`; normalized to `=` and `<>`).
|
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
* | `#VALUE!` | wrong type, e.g. `"abc" * 2` |
|
|
9
9
|
* | `#DIV/0!` | division by zero |
|
|
10
10
|
* | `#NUM!` | the result is not a finite number (`SQRT(-1)`, overflow) |
|
|
11
|
-
* | `#CIRC!` | circular reference between calculated columns |
|
|
11
|
+
* | `#CIRC!` | circular reference between calculated columns (cell formulas: between cells) |
|
|
12
|
+
* | `#REF!` | cell formulas: a reference to a deleted or non-existing cell (since 1.1.99) |
|
|
13
|
+
* | `#N/A` | cell formulas: a lookup found nothing, `NA()` (since 1.1.99) |
|
|
12
14
|
*
|
|
13
15
|
* @since 1.1.95
|
|
14
16
|
* @category Calculated columns & formulas
|
|
15
17
|
*/
|
|
16
|
-
export type FormulaErrorCode = "#ERROR!" | "#NAME?" | "#VALUE!" | "#DIV/0!" | "#NUM!" | "#CIRC!";
|
|
18
|
+
export type FormulaErrorCode = "#ERROR!" | "#NAME?" | "#VALUE!" | "#DIV/0!" | "#NUM!" | "#CIRC!" | "#REF!" | "#N/A";
|
|
17
19
|
/**
|
|
18
20
|
* An error value of a formula. Formulas never throw: a cell shows the {@link FormulaErrorCode} (`toString()`), the
|
|
19
21
|
* table adds the CSS class `ge-table-cell-error` and shows the message as tooltip. Errors propagate through
|
|
@@ -6,5 +6,8 @@ export declare const MAX_FORMULA_LENGTH = 10000;
|
|
|
6
6
|
export declare const MAX_FORMULA_DEPTH = 64;
|
|
7
7
|
/** The maximum number of binary operators (a long chain is a deep tree, too). */
|
|
8
8
|
export declare const MAX_FORMULA_OPERATORS = 1000;
|
|
9
|
-
/**
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Parses a formula into an AST. Throws a {@link FormulaSyntaxError}. `references`: a cell formula with Excel's syntax
|
|
11
|
+
* (cell references, ranges, `%`, `;`, Excel's precedence of the negation) – since 1.1.99.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseFormula(source: string, references?: boolean): FormulaNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FormulaError } from './formula-error.js';
|
|
2
2
|
|
|
3
3
|
/** The kinds of tokens of a formula. */
|
|
4
|
-
export type FormulaTokenKind = "number" | "string" | "field" | "ident" | "op" | "(" | ")" | "," | "eof";
|
|
4
|
+
export type FormulaTokenKind = "number" | "string" | "field" | "ident" | "op" | "(" | ")" | "," | "error" | "eof";
|
|
5
5
|
/** One token: kind, text (number/string already decoded) and position in the source. */
|
|
6
6
|
export interface FormulaToken {
|
|
7
7
|
readonly kind: FormulaTokenKind;
|
|
@@ -18,5 +18,8 @@ export declare class FormulaSyntaxError extends Error {
|
|
|
18
18
|
/**
|
|
19
19
|
* Splits a formula into tokens. Whitespace is ignored. Throws a {@link FormulaSyntaxError} for an unknown character,
|
|
20
20
|
* an unterminated string or field reference.
|
|
21
|
+
*
|
|
22
|
+
* `references` (cell formulas, since 1.1.99): Excel's rules – texts only in `"…"` with `""` as quotation mark, `$` in
|
|
23
|
+
* identifiers (`$B$3`), `:` and `%`, `;` as argument separator, error literals like `#REF!`.
|
|
21
24
|
*/
|
|
22
|
-
export declare function tokenize(source: string): FormulaToken[];
|
|
25
|
+
export declare function tokenize(source: string, references?: boolean): FormulaToken[];
|
|
@@ -11,6 +11,14 @@ import { TableScope } from './table-scope.js';
|
|
|
11
11
|
export declare class InputHandler {
|
|
12
12
|
protected tableScope: TableScope;
|
|
13
13
|
constructor(tableScope: TableScope);
|
|
14
|
+
/**
|
|
15
|
+
* A restored in-cell editor (its text was put back after a repaint, see {@link RenderScope.setEditorDraft}) fires
|
|
16
|
+
* no "change" for that text – it is committed when the focus leaves it (not when a repaint removes it).
|
|
17
|
+
*/
|
|
18
|
+
private onHostElementFocusOut;
|
|
19
|
+
private commitInCellEditor;
|
|
20
|
+
/** Text typed into the in-cell editor: remembered, so that a repaint (scrolling, live data) keeps it (since 1.1.99). */
|
|
21
|
+
private onHostElementInput;
|
|
14
22
|
/** Escape in the cell editor cancels the editing: the old value stays, nothing is committed. */
|
|
15
23
|
private onHostElementKeyDown;
|
|
16
24
|
/**
|
|
@@ -215,6 +215,15 @@ export declare class MasterDetailService {
|
|
|
215
215
|
/** The mouse wheel over a detail row: scrolls the outer table if nothing in the detail row takes the movement. */
|
|
216
216
|
private onWheel;
|
|
217
217
|
private canScrollInside;
|
|
218
|
+
/**
|
|
219
|
+
* True if Tab on the master row `rowIndex` goes into its open detail row (a focusable element in it) – Excel-style
|
|
220
|
+
* editing then leaves Tab to this service.
|
|
221
|
+
*
|
|
222
|
+
* @param {number} rowIndex - display row index of the focused cell
|
|
223
|
+
* @returns {boolean} true with a tab target
|
|
224
|
+
* @since 1.1.99
|
|
225
|
+
*/
|
|
226
|
+
hasTabTarget(rowIndex: number): boolean;
|
|
218
227
|
/** Tab on a master row with an open detail row: the focus moves to the first focusable element in it. */
|
|
219
228
|
private onHostKeyDown;
|
|
220
229
|
/** The host got the focus back from a detail row (Shift+Tab): its master row gets the focus. */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { RowDragService } from './row-drag/row-drag-service.js';
|
|
2
2
|
import { BatchEditService } from './batch-edit/batch-edit-service.js';
|
|
3
3
|
import { FillHandleService } from './fill/fill-handle-service.js';
|
|
4
|
+
import { CellEditorService } from './sheet-editing/cell-editor-service.js';
|
|
4
5
|
import { TableOverlayChange } from './overlay/table-overlay.js';
|
|
5
6
|
import { EleScope } from './ele-scope.js';
|
|
6
7
|
import { TableModelIf } from './data/tablemodel/table-model.if.js';
|
|
@@ -28,6 +29,7 @@ import { AriaGridInfo } from './aria/aria-grid-info.js';
|
|
|
28
29
|
import { AriaTextsIf } from './aria/aria-texts.if.js';
|
|
29
30
|
import { RowLayout } from './row-layout/row-layout.js';
|
|
30
31
|
import { MasterDetailService } from './master-detail/master-detail-service.js';
|
|
32
|
+
import { TableSheet } from './sheet/table-sheet.js';
|
|
31
33
|
|
|
32
34
|
/** @category Internals */
|
|
33
35
|
export declare class RenderScope extends EleScope {
|
|
@@ -105,12 +107,28 @@ export declare class RenderScope extends EleScope {
|
|
|
105
107
|
* @since 1.1.96
|
|
106
108
|
*/
|
|
107
109
|
fillHandleService?: FillHandleService;
|
|
110
|
+
/**
|
|
111
|
+
* Excel-style editing of this table (the editor above the cell) – created by {@link TableScope} with
|
|
112
|
+
* `tableOptions.editing`.
|
|
113
|
+
* @since 1.1.99
|
|
114
|
+
*/
|
|
115
|
+
cellEditorService?: CellEditorService;
|
|
116
|
+
/**
|
|
117
|
+
* The text of the open in-cell editor (`getEditRenderer`): the cell is rebuilt on every repaint, the text and
|
|
118
|
+
* the caret are put back (before 1.1.99 the typed text was lost when the table scrolled or repainted).
|
|
119
|
+
*/
|
|
120
|
+
private editorDraft?;
|
|
108
121
|
/**
|
|
109
122
|
* Master/detail of this table (detail rows below master rows) – created by {@link TableScope} with
|
|
110
123
|
* `tableOptions.masterDetail`.
|
|
111
124
|
* @since 1.1.97
|
|
112
125
|
*/
|
|
113
126
|
masterDetailService?: MasterDetailService;
|
|
127
|
+
/**
|
|
128
|
+
* Cell formulas of this table – created by {@link TableScope} with `tableOptions.cellFormulas` (flat bodies).
|
|
129
|
+
* @since 1.1.99
|
|
130
|
+
*/
|
|
131
|
+
tableSheet?: TableSheet;
|
|
114
132
|
/** Positions of the body rows (prefix sums of the heights + detail rows), see {@link getBodyRowLayout}. */
|
|
115
133
|
private readonly bodyRowLayout;
|
|
116
134
|
private bodyRowLayoutDirty;
|
|
@@ -221,6 +239,23 @@ export declare class RenderScope extends EleScope {
|
|
|
221
239
|
*/
|
|
222
240
|
getScrollerToContentRatioY(): number;
|
|
223
241
|
isEditing(): boolean;
|
|
242
|
+
/**
|
|
243
|
+
* The cell of the open editor inside a cell (`getEditRenderer`, the way before Excel-style editing).
|
|
244
|
+
*
|
|
245
|
+
* @returns {[number, number] | undefined} display row and model column, `undefined` without such an editor
|
|
246
|
+
* @since 1.1.99
|
|
247
|
+
*/
|
|
248
|
+
getInCellEditorCell(): [number, number] | undefined;
|
|
249
|
+
/**
|
|
250
|
+
* Remembers the text of the open in-cell editor (called on every input, see {@link InputHandler}) so that a
|
|
251
|
+
* repaint keeps it.
|
|
252
|
+
*
|
|
253
|
+
* @param {number} rowIndex - display row index of the edited cell
|
|
254
|
+
* @param {number} columnIndex - model column index
|
|
255
|
+
* @param {HTMLInputElement | HTMLTextAreaElement} input - the editor element
|
|
256
|
+
* @since 1.1.99
|
|
257
|
+
*/
|
|
258
|
+
setEditorDraft(rowIndex: number, columnIndex: number, input: HTMLInputElement | HTMLTextAreaElement): void;
|
|
224
259
|
/**
|
|
225
260
|
* Resets the editor renderer by clearing its values and state.
|
|
226
261
|
*
|
|
@@ -327,6 +362,11 @@ export declare class RenderScope extends EleScope {
|
|
|
327
362
|
* @returns {void}
|
|
328
363
|
*/
|
|
329
364
|
updateCells(events: TableCellUpdateEventIf[], repaintAll?: boolean): void;
|
|
365
|
+
/**
|
|
366
|
+
* Writes a value without the column's `editInputPipe` (values copied inside the table are already converted – a pipe
|
|
367
|
+
* that expects text could break them). All area models apply the pipe in `setValue`, so it is left out for the call.
|
|
368
|
+
*/
|
|
369
|
+
protected setRawValue(rowIndex: number, columnIndex: number, value: unknown): boolean;
|
|
330
370
|
/**
|
|
331
371
|
* After `updateCells()` without a repaint: draws the rendered cells of calculated and „Show values as“ columns of
|
|
332
372
|
* the body again (they depend on the changed cells, e.g. `total = price * quantity` or a share of the total).
|
|
@@ -42,9 +42,10 @@ export declare class RowDragService {
|
|
|
42
42
|
isDragSourceRow(rowIndex: number): boolean;
|
|
43
43
|
/**
|
|
44
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)
|
|
45
|
+
* (a filter hides rows), `"cellFormulas"` (moved rows would change the references of cell formulas, since 1.1.99)
|
|
46
|
+
* – `undefined` if it is possible or the drag is unmanaged.
|
|
46
47
|
*/
|
|
47
|
-
getBlockReason(): "sorted" | "filtered" | undefined;
|
|
48
|
+
getBlockReason(): "sorted" | "filtered" | "cellFormulas" | undefined;
|
|
48
49
|
/**
|
|
49
50
|
* The drag handle of a body cell: none (no `rowDrag`, a group or pivot row, a managed drag the model cannot do),
|
|
50
51
|
* enabled or disabled (managed + sorted/filtered).
|
|
@@ -20,6 +20,10 @@ export declare class SelectionService implements OnActionTriggeredIf {
|
|
|
20
20
|
protected anchorRanges: CellRange[];
|
|
21
21
|
/** The selection before a Ctrl/⌘-drag – each drag frame replaces only the dragged rectangle. */
|
|
22
22
|
protected dragSnapshot?: SelectionSnapshot;
|
|
23
|
+
/** The cell a Shift+click or Shift+arrow range starts at (the last click, or the active cell). @since 1.1.99 */
|
|
24
|
+
protected anchor?: [number, number];
|
|
25
|
+
/** The moving corner of the range of Shift+arrows (Excel); `undefined` = the anchor. @since 1.1.99 */
|
|
26
|
+
protected extent?: [number, number];
|
|
23
27
|
constructor(tableScope: TableScope);
|
|
24
28
|
/**
|
|
25
29
|
* Called on mouse down: a new gesture starts.
|
|
@@ -51,8 +55,52 @@ export declare class SelectionService implements OnActionTriggeredIf {
|
|
|
51
55
|
*/
|
|
52
56
|
onMouseClicked(evt: GeMouseEvent, _previousEvt: GeMouseEvent | undefined): boolean;
|
|
53
57
|
onActionTriggered(actionId: ActionId): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* The cell a Shift+click or Shift+arrow range starts at: the last clicked cell or the active cell set by the
|
|
60
|
+
* keyboard ({@link collapseTo}).
|
|
61
|
+
*
|
|
62
|
+
* @returns {[number, number] | undefined} row and column, `undefined` before the first click/keyboard move
|
|
63
|
+
* @since 1.1.99
|
|
64
|
+
*/
|
|
65
|
+
getAnchor(): [number, number] | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* The moving corner of the range Shift+arrows grow (the anchor if there is none).
|
|
68
|
+
*
|
|
69
|
+
* @returns {[number, number] | undefined} row and column
|
|
70
|
+
* @since 1.1.99
|
|
71
|
+
*/
|
|
72
|
+
getExtent(): [number, number] | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Excel-style editing: the active cell moved (arrow keys, Tab, Enter) – the selection becomes this one cell and it
|
|
75
|
+
* is the new anchor. Selection types other than `"range"`/`"cell"` only get the anchor.
|
|
76
|
+
*
|
|
77
|
+
* @param {number} rowIndex - display row index
|
|
78
|
+
* @param {number} columnIndex - model column index
|
|
79
|
+
* @since 1.1.99
|
|
80
|
+
*/
|
|
81
|
+
collapseTo(rowIndex: number, columnIndex: number): void;
|
|
82
|
+
/**
|
|
83
|
+
* Excel-style editing (Shift+arrows): the last range is spanned from the anchor to `(rowIndex, columnIndex)`;
|
|
84
|
+
* other ranges (Ctrl/⌘-clicks) stay. Only for the selection type `"range"`.
|
|
85
|
+
*
|
|
86
|
+
* @param {number} rowIndex - the new moving corner (display row index)
|
|
87
|
+
* @param {number} columnIndex - model column index
|
|
88
|
+
* @returns {CellRange | undefined} the new range, `undefined` without a range selection
|
|
89
|
+
* @since 1.1.99
|
|
90
|
+
*/
|
|
91
|
+
extendTo(rowIndex: number, columnIndex: number): CellRange | undefined;
|
|
92
|
+
private static rangeBetween;
|
|
54
93
|
/** True if the column is a row number column ({@link RowNumberColumnDef}). */
|
|
55
94
|
private isRowNumberColumn;
|
|
95
|
+
/** True for a cell of a header row with column letters (spreadsheet) – not over row numbers. */
|
|
96
|
+
private isColumnLetterCell;
|
|
97
|
+
/**
|
|
98
|
+
* A click on a column letter (selection type "range"): the whole column – Shift: the columns from the last letter
|
|
99
|
+
* (or the active cell), Ctrl/⌘: added. The active cell goes into the column.
|
|
100
|
+
*/
|
|
101
|
+
private clickColumnLetter;
|
|
102
|
+
/** The column of the last click on a letter (Shift+click spans from it). */
|
|
103
|
+
private letterAnchor?;
|
|
56
104
|
/** A click on the header cell of the row numbers: everything (selection types "row" and "range"). */
|
|
57
105
|
private selectAllByRowNumberHeader;
|
|
58
106
|
/** Selection type "range", click on a row number: the whole row – new, toggled (Ctrl/⌘) or removed (Ctrl/⌘+Alt). */
|
|
@@ -14,4 +14,10 @@ export interface ExcelExportOptionsIf {
|
|
|
14
14
|
* {@link TableApi.downloadExcel} sets it for a right-to-left table ({@link TableOptionsIf.direction}).
|
|
15
15
|
*/
|
|
16
16
|
rightToLeft?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* {@link TableApi.downloadExcel}: cell formulas ({@link TableOptionsIf.cellFormulas}) become Excel formulas with their
|
|
19
|
+
* calculated values (otherwise: values). Only if the export is the sheet itself – no filter hides rows, no sorting,
|
|
20
|
+
* every data column visible; otherwise values and a warning. Since 1.1.99.
|
|
21
|
+
*/
|
|
22
|
+
cellFormulas?: boolean;
|
|
17
23
|
}
|
|
@@ -27,6 +27,8 @@ import { ExcelServiceIf } from './excel-service.if.js';
|
|
|
27
27
|
export declare class ExcelService implements ExcelServiceIf {
|
|
28
28
|
/** Understands cells `{ value, numberFormat }` ({@link ExcelFormattedValueIf}), since 1.1.95. */
|
|
29
29
|
readonly supportsNumberFormats = true;
|
|
30
|
+
/** Understands cells `{ formula, value }` ({@link ExcelFormulaCellIf}), since 1.1.99. */
|
|
31
|
+
readonly supportsFormulas = true;
|
|
30
32
|
/**
|
|
31
33
|
* Downloads a matrix data as an Excel file.
|
|
32
34
|
*
|
|
@@ -52,6 +54,8 @@ export declare class ExcelService implements ExcelServiceIf {
|
|
|
52
54
|
createExcelBlob(matrix: Array<Array<any>>, author?: string, options?: ExcelExportOptionsIf): Promise<Blob>;
|
|
53
55
|
private generateMap;
|
|
54
56
|
private getX1WorksheetsSheet1Xml;
|
|
57
|
+
/** A formula cell: `<f>` plus the cached value with its type (`str`, `b`, `e`; numbers and dates without). */
|
|
58
|
+
private formulaCellXml;
|
|
55
59
|
/** Number format → cell style index (1-based; 0 = default), filled by withNumberFormats() before the sheet is written. */
|
|
56
60
|
private numberFormatStyles;
|
|
57
61
|
/** Adds one cell style per number format used in the matrix (`<numFmts>` + `<cellXfs>`); unchanged without formats. */
|
|
@@ -15,7 +15,42 @@ export interface ExcelServiceIf {
|
|
|
15
15
|
* otherwise a service gets plain numbers (since 1.1.95).
|
|
16
16
|
*/
|
|
17
17
|
readonly supportsNumberFormats?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* True if the service understands cells of the form {@link ExcelFormulaCellIf} (`{ formula, value }`). Only then
|
|
20
|
+
* {@link TableApi.downloadExcel} with `{ cellFormulas: true }` exports cell formulas as formulas (since 1.1.99).
|
|
21
|
+
*/
|
|
22
|
+
readonly supportsFormulas?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A cell of an Excel matrix with a formula (`<f>`) and its calculated value (`<v>`, shown until Excel recalculates).
|
|
26
|
+
* Understood by {@link ExcelService}; {@link TableApi.downloadExcel} writes them for cell formulas with
|
|
27
|
+
* `{ cellFormulas: true }`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* await new ExcelService().downloadExcel([[2, 3, { formula: "A1*B1", value: 6 }]], "sheet.xlsx");
|
|
31
|
+
*
|
|
32
|
+
* @since 1.1.99
|
|
33
|
+
* @category Export & clipboard
|
|
34
|
+
*/
|
|
35
|
+
export interface ExcelFormulaCellIf {
|
|
36
|
+
/** The formula without `=`, with Excel's function names (`"SUM(D2:D4)"`, `"_xlfn.XLOOKUP(…)"`). */
|
|
37
|
+
formula: string;
|
|
38
|
+
/** The calculated value: a number, text, boolean, `Date` or an error value. */
|
|
39
|
+
value: unknown;
|
|
18
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* True for a cell of the form {@link ExcelFormulaCellIf}.
|
|
43
|
+
*
|
|
44
|
+
* @param {unknown} cell - a cell of an Excel matrix
|
|
45
|
+
* @returns {boolean} whether it is a formula cell
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* isExcelFormulaCell({ formula: "A1*2", value: 4 }); // true
|
|
49
|
+
*
|
|
50
|
+
* @since 1.1.99
|
|
51
|
+
* @category Export & clipboard
|
|
52
|
+
*/
|
|
53
|
+
export declare function isExcelFormulaCell(cell: unknown): cell is ExcelFormulaCellIf;
|
|
19
54
|
/**
|
|
20
55
|
* A cell of an Excel matrix with a number format, e.g. a share shown as percentage. Understood by
|
|
21
56
|
* {@link ExcelService} (`supportsNumberFormats`).
|