@guiexpert/table 1.1.98 → 1.1.100

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 (99) hide show
  1. package/README.md +9 -0
  2. package/css/main.css +296 -0
  3. package/css/table-clipboard.css +41 -0
  4. package/css/table-color-vars.css +56 -0
  5. package/css/table-sheet-editing.css +149 -0
  6. package/css/table-spreadsheet.css +50 -0
  7. package/index.cjs +46 -59
  8. package/index.d.ts +46 -0
  9. package/index.js +18934 -11624
  10. package/lib/table/action/action-id.type.d.ts +1 -1
  11. package/lib/table/action/shortcut.service.d.ts +9 -0
  12. package/lib/table/aria/aria-texts.d.ts +26 -0
  13. package/lib/table/aria/aria-texts.if.d.ts +196 -0
  14. package/lib/table/batch-edit/batch-edit-service.d.ts +22 -0
  15. package/lib/table/batch-edit/cell-change.if.d.ts +6 -2
  16. package/lib/table/batch-edit/pending-cell-changes.d.ts +7 -0
  17. package/lib/table/batch-edit/write-row-value.d.ts +14 -0
  18. package/lib/table/calc/column-values.d.ts +2 -0
  19. package/lib/table/clipboard/clipboard-html.d.ts +41 -0
  20. package/lib/table/clipboard/clipboard-keymap.d.ts +18 -0
  21. package/lib/table/clipboard/clipboard-options.d.ts +30 -0
  22. package/lib/table/clipboard/clipboard-options.if.d.ts +67 -0
  23. package/lib/table/clipboard/clipboard-service.d.ts +122 -0
  24. package/lib/table/clipboard/input-pipes.d.ts +59 -0
  25. package/lib/table/clipboard/paste-plan.d.ts +96 -0
  26. package/lib/table/clipboard/tsv.d.ts +31 -0
  27. package/lib/table/data/common/event/ge-edit-event.d.ts +46 -0
  28. package/lib/table/data/common/event/ge-row-drag-event.d.ts +2 -2
  29. package/lib/table/data/common/event/ge-undo-event.d.ts +29 -0
  30. package/lib/table/data/options/table-options.d.ts +28 -0
  31. package/lib/table/data/options/table-options.if.d.ts +99 -1
  32. package/lib/table/data/tablemodel/areamodel/abstract-area-model.d.ts +11 -2
  33. package/lib/table/data/tablemodel/areamodel/area-model-array-of-arrays.d.ts +14 -0
  34. package/lib/table/data/tablemodel/areamodel/area-model-object-array.d.ts +14 -0
  35. package/lib/table/data/tablemodel/areamodel/area-model.if.d.ts +11 -0
  36. package/lib/table/data/tablemodel/column/column-def.d.ts +13 -0
  37. package/lib/table/data/tablemodel/column/column-def.if.d.ts +36 -1
  38. package/lib/table/data/tablemodel/column/default-editable.d.ts +18 -0
  39. package/lib/table/event-adapter.d.ts +6 -0
  40. package/lib/table/event-listener-hub.d.ts +10 -0
  41. package/lib/table/event-listener.if.d.ts +16 -0
  42. package/lib/table/factory/pivot-factory.d.ts +1 -1
  43. package/lib/table/factory/row-group-factory.d.ts +1 -1
  44. package/lib/table/factory/table-factory.d.ts +14 -0
  45. package/lib/table/formula/formula-ast.if.d.ts +32 -2
  46. package/lib/table/formula/formula-error.d.ts +4 -2
  47. package/lib/table/formula/parser.d.ts +5 -2
  48. package/lib/table/formula/tokenizer.d.ts +5 -2
  49. package/lib/table/input-handler.d.ts +8 -0
  50. package/lib/table/master-detail/master-detail-service.d.ts +9 -0
  51. package/lib/table/render-scope.d.ts +40 -0
  52. package/lib/table/row-drag/row-drag-service.d.ts +3 -2
  53. package/lib/table/selection/selection-service.d.ts +48 -0
  54. package/lib/table/service/excel-export-options.if.d.ts +6 -0
  55. package/lib/table/service/excel-service.d.ts +4 -0
  56. package/lib/table/service/excel-service.if.d.ts +35 -0
  57. package/lib/table/sheet/cell-address.d.ts +100 -0
  58. package/lib/table/sheet/cell-formula-options.d.ts +27 -0
  59. package/lib/table/sheet/cell-formula-options.if.d.ts +27 -0
  60. package/lib/table/sheet/excel-formula.d.ts +20 -0
  61. package/lib/table/sheet/format-formula.d.ts +19 -0
  62. package/lib/table/sheet/sheet-cells.if.d.ts +17 -0
  63. package/lib/table/sheet/sheet-compiler.d.ts +47 -0
  64. package/lib/table/sheet/sheet-engine.d.ts +207 -0
  65. package/lib/table/sheet/sheet-function-info.d.ts +25 -0
  66. package/lib/table/sheet/sheet-functions.d.ts +27 -0
  67. package/lib/table/sheet/sheet-values.d.ts +154 -0
  68. package/lib/table/sheet/shift-formula.d.ts +71 -0
  69. package/lib/table/sheet/table-sheet.d.ts +214 -0
  70. package/lib/table/sheet-editing/cell-editor-service.d.ts +105 -0
  71. package/lib/table/sheet-editing/cell-editor.if.d.ts +110 -0
  72. package/lib/table/sheet-editing/editing-keymap.d.ts +17 -0
  73. package/lib/table/sheet-editing/editing-options.d.ts +34 -0
  74. package/lib/table/sheet-editing/editing-options.if.d.ts +49 -0
  75. package/lib/table/sheet-editing/editors/date-cell-editor.d.ts +23 -0
  76. package/lib/table/sheet-editing/editors/number-cell-editor.d.ts +18 -0
  77. package/lib/table/sheet-editing/editors/select-cell-editor.d.ts +36 -0
  78. package/lib/table/sheet-editing/editors/text-cell-editor.d.ts +35 -0
  79. package/lib/table/sheet-editing/formula-assist.d.ts +103 -0
  80. package/lib/table/sheet-editing/formula-text.d.ts +61 -0
  81. package/lib/table/sheet-editing/sheet-navigation.d.ts +26 -0
  82. package/lib/table/spreadsheet/area-model-sheet.d.ts +170 -0
  83. package/lib/table/spreadsheet/formula-bar.d.ts +53 -0
  84. package/lib/table/spreadsheet/spreadsheet-factory.d.ts +111 -0
  85. package/lib/table/spreadsheet/spreadsheet-options.if.d.ts +28 -0
  86. package/lib/table/spreadsheet/spreadsheet-preset.d.ts +37 -0
  87. package/lib/table/spreadsheet/structure-edit.d.ts +35 -0
  88. package/lib/table/table-api.d.ts +511 -2
  89. package/lib/table/table-scope.d.ts +294 -1
  90. package/lib/table/undo/cell-changes-undoable.d.ts +34 -0
  91. package/lib/table/undo/model-rows.d.ts +17 -0
  92. package/lib/table/undo/pending-changes-undoable.d.ts +35 -0
  93. package/lib/table/undo/undo-keymap.d.ts +17 -0
  94. package/lib/table/undo/undo-options.d.ts +26 -0
  95. package/lib/table/undo/undo-options.if.d.ts +30 -0
  96. package/lib/table/undo/undo-service.d.ts +103 -0
  97. package/lib/table/undo/undo-stack.d.ts +62 -0
  98. package/lib/table/undo/undoable.if.d.ts +36 -0
  99. package/package.json +1 -1
@@ -0,0 +1,59 @@
1
+ import { editInputPipe } from '../renderer/edit/edit-input-pipe.if.js';
2
+
3
+ /**
4
+ * An `editInputPipe` for numbers in the format of a locale, for the editor and for pasting: `"1.234,56"` (de-DE) and
5
+ * `"1,234.56"` (en-US) → `1234.56`, `"12 %"` → `0.12`, `"€ 9,90"` → `9.9`, `"(5)"` → `-5`. Empty text stays `""`,
6
+ * text that is no number stays as it is (a `validate` of the column can refuse it); numbers pass unchanged.
7
+ *
8
+ * @param {string} [locale] - BCP 47 tag, default: the browser's locale
9
+ * @returns {editInputPipe} the pipe
10
+ *
11
+ * @example
12
+ * ColumnDef.create({ property: "price", editable: TrueFn, editInputPipe: createNumberInputPipe("de-DE") });
13
+ *
14
+ * @category Spreadsheet
15
+ * @since 1.1.99
16
+ */
17
+ export declare function createNumberInputPipe(locale?: string): editInputPipe;
18
+ /**
19
+ * An `editInputPipe` for dates: ISO text (`"2026-10-16"`, with time `"2026-10-16T08:30"`) or the short date of the
20
+ * locale (`"16.10.2026"` in de-DE, `"10/16/2026"` in en-US) → `Date` (local time). Empty text stays `""`, other text as
21
+ * it is; a `Date` passes unchanged.
22
+ *
23
+ * @param {string} [locale] - BCP 47 tag for the order of day and month, default: the browser's locale
24
+ * @returns {editInputPipe} the pipe
25
+ *
26
+ * @example
27
+ * ColumnDef.create({ property: "due", editable: TrueFn, editInputPipe: createDateInputPipe("de-DE") });
28
+ *
29
+ * @category Spreadsheet
30
+ * @since 1.1.99
31
+ */
32
+ export declare function createDateInputPipe(locale?: string): editInputPipe;
33
+ /**
34
+ * An `editInputPipe` for `true`/`false`: `"TRUE"`, `"yes"`, `"1"`, `"x"` (also German `WAHR`, `ja`) → `true`; `"FALSE"`,
35
+ * `"no"`, `"0"` (`FALSCH`, `nein`) → `false`, ignoring case; empty text stays `""`, other text as it is.
36
+ *
37
+ * @example
38
+ * ColumnDef.create({ property: "paid", editable: TrueFn, editInputPipe: booleanInputPipe });
39
+ *
40
+ * @category Spreadsheet
41
+ * @since 1.1.99
42
+ */
43
+ export declare const booleanInputPipe: editInputPipe;
44
+ /**
45
+ * An `editInputPipe` that recognizes values like Excel: a number in the format of the locale (also `%` and currency
46
+ * signs), a date (ISO or the short date of the locale), `TRUE`/`FALSE` (ignoring case) – otherwise text. Text that
47
+ * starts with `=` or `'=` (formulas, see the spreadsheet mode) stays unchanged; so does a leading `'` (Excel: "keep
48
+ * this as text") minus the quote.
49
+ *
50
+ * @param {string} [locale] - BCP 47 tag, default: the browser's locale
51
+ * @returns {editInputPipe} the pipe
52
+ *
53
+ * @example
54
+ * ColumnDef.create({ property: "b", editable: TrueFn, editInputPipe: sheetInputPipe("en-US") });
55
+ *
56
+ * @category Spreadsheet
57
+ * @since 1.1.99
58
+ */
59
+ export declare function sheetInputPipe(locale?: string): editInputPipe;
@@ -0,0 +1,96 @@
1
+ import { CellRange } from '../data/common/cell-range.js';
2
+
3
+ /**
4
+ * Input of {@link computePastePlan}: what is pasted and where. All rows are **displayed** rows (display order after
5
+ * sorting and filtering), columns are model indices; `shownColumns` lists the visible columns in display order –
6
+ * hidden columns are skipped and not counted (like the fill handle).
7
+ *
8
+ * @category Spreadsheet
9
+ * @since 1.1.99
10
+ */
11
+ export interface PasteRequestIf<V = unknown> {
12
+ /** The pasted cells (rows of values, at least one row and one column). */
13
+ matrix: ReadonlyArray<ReadonlyArray<V>>;
14
+ /** First row of the target (display index). */
15
+ anchorRow: number;
16
+ /** First column of the target (model index, must be in `shownColumns`). */
17
+ anchorColumn: number;
18
+ /** The visible columns (model indices) in display order. */
19
+ shownColumns: ReadonlyArray<number>;
20
+ /** Number of displayed body rows. */
21
+ rowCount: number;
22
+ /**
23
+ * The selected target in rows × shown columns (from the anchor), if a range is selected: an integer multiple of
24
+ * the matrix tiles it (Excel), a single value fills it.
25
+ */
26
+ selection?: {
27
+ rows: number;
28
+ columns: number;
29
+ };
30
+ /** True if rows may be added below the last row (`pasteAddsRows`). */
31
+ canAddRows?: boolean;
32
+ /** `false` skips a target cell (not editable, calculated, group row); it still counts for the layout. */
33
+ isWritable?: (rowIndex: number, columnIndex: number) => boolean;
34
+ }
35
+ /**
36
+ * Result of {@link computePastePlan}.
37
+ *
38
+ * @category Spreadsheet
39
+ * @since 1.1.99
40
+ */
41
+ export interface PastePlanIf<V = unknown> {
42
+ /** The cells to write: display row (may be ≥ `rowCount` for added rows), model column, value. */
43
+ cells: {
44
+ rowIndex: number;
45
+ columnIndex: number;
46
+ value: V;
47
+ }[];
48
+ /** The covered target (display rows, model columns from the first to the last shown column). */
49
+ range: CellRange;
50
+ /** Target cells left out because they are not writable. */
51
+ skipped: number;
52
+ /** Cells cut off at the last column (or the last row without `canAddRows`). */
53
+ clipped: number;
54
+ /** Rows to add below the last row before writing (`canAddRows`). */
55
+ addRows: number;
56
+ }
57
+ /**
58
+ * Where pasted cells go, like Excel: from the anchor, once – or tiled over a selected range that is an integer
59
+ * multiple of the matrix, a single value into every cell of the selected range; cut off at the last column (and at
60
+ * the last row unless rows may be added); cells that are not writable are skipped. DOM-free.
61
+ *
62
+ * @param {PasteRequestIf<V>} req - matrix, target and table size
63
+ * @returns {PastePlanIf<V>} the cells to write
64
+ *
65
+ * @example
66
+ * const plan = computePastePlan({ matrix: [["x"]], anchorRow: 1, anchorColumn: 2, shownColumns: [0, 1, 2, 3],
67
+ * rowCount: 10, selection: { rows: 3, columns: 1 } });
68
+ * plan.cells.length; // 3 – rows 1…3 of column 2
69
+ *
70
+ * @category Spreadsheet
71
+ * @since 1.1.99
72
+ */
73
+ export declare function computePastePlan<V>(req: PasteRequestIf<V>): PastePlanIf<V>;
74
+ /**
75
+ * The size a paste covers before cutting off: the matrix – or the selected range if the matrix is a single value or
76
+ * fits into it an integer number of times (tiling, Excel).
77
+ *
78
+ * @param {number} matrixRows - rows of the pasted cells
79
+ * @param {number} matrixColumns - columns of the pasted cells
80
+ * @param {{ rows: number, columns: number }} [selection] - the selected range (rows × shown columns)
81
+ * @returns {{ rows: number, columns: number }} the covered size
82
+ *
83
+ * @example
84
+ * getPasteSize(2, 1, { rows: 6, columns: 1 }); // { rows: 6, columns: 1 } – three times
85
+ * getPasteSize(2, 1, { rows: 5, columns: 1 }); // { rows: 2, columns: 1 } – once
86
+ *
87
+ * @category Spreadsheet
88
+ * @since 1.1.99
89
+ */
90
+ export declare function getPasteSize(matrixRows: number, matrixColumns: number, selection?: {
91
+ rows: number;
92
+ columns: number;
93
+ }): {
94
+ rows: number;
95
+ columns: number;
96
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Text of a cell matrix as tab-separated values (TSV) the way Excel and Google Sheets read it: cells separated by a
3
+ * tab, rows by a line break; a cell with a tab, a line break or a quotation mark is put in quotation marks
4
+ * (`"…"`), a quotation mark inside is doubled. DOM-free.
5
+ *
6
+ * @param {ReadonlyArray<ReadonlyArray<string>>} matrix - rows of cell texts
7
+ * @returns {string} the TSV text (a line break at the end only if the last row is empty)
8
+ *
9
+ * @example
10
+ * toTsv([["a", "b"], ["1", 'say "hi"']]); // 'a\tb\n1\t"say ""hi"""'
11
+ *
12
+ * @category Spreadsheet
13
+ * @since 1.1.99
14
+ */
15
+ export declare function toTsv(matrix: ReadonlyArray<ReadonlyArray<string>>): string;
16
+ /**
17
+ * Cell matrix of a TSV text from the clipboard (Excel, Google Sheets, LibreOffice, a text editor): line breaks
18
+ * `\r\n`, `\n` or `\r`; a cell that starts with a quotation mark is quoted (`""` inside = one quotation mark, line
19
+ * breaks and tabs inside belong to the cell); one line break at the end is ignored; a byte order mark is removed;
20
+ * shorter rows are filled with `""`. DOM-free.
21
+ *
22
+ * @param {string} text - the clipboard text
23
+ * @returns {string[][]} rows of cell texts, all of the same length; `[]` for `""`
24
+ *
25
+ * @example
26
+ * parseTsv('a\t"x\ny"\r\n1\t2\r\n'); // [["a", "x\ny"], ["1", "2"]]
27
+ *
28
+ * @category Spreadsheet
29
+ * @since 1.1.99
30
+ */
31
+ export declare function parseTsv(text: string): string[][];
@@ -0,0 +1,46 @@
1
+ import { CellEditMode } from '../../../sheet-editing/cell-editor.if.js';
2
+
3
+ /**
4
+ * What happened to the cell editor: `"start"` (opened), `"input"` (its text changed – Excel-style editing only),
5
+ * `"commit"` (closed with the input written or – batch edit – marked), `"cancel"` (closed without writing).
6
+ *
7
+ * @category Spreadsheet
8
+ * @since 1.1.99
9
+ */
10
+ export type GeEditEventType = "start" | "input" | "commit" | "cancel";
11
+ /**
12
+ * Reported by {@link EventListenerIf.onEditingChanged}: the cell editor opened, its text changed, it committed or
13
+ * it was cancelled – e.g. to show the input in an own formula bar or to disable buttons while editing.
14
+ *
15
+ * @example
16
+ * const listener = new EventAdapter();
17
+ * listener.onEditingChanged = (evt: GeEditEvent) => {
18
+ * hint.textContent = evt.type === "start" ? `Editing row ${evt.rowIndex + 1}` : "";
19
+ * };
20
+ *
21
+ * @category Spreadsheet
22
+ * @since 1.1.99
23
+ */
24
+ export declare class GeEditEvent {
25
+ /** What happened. */
26
+ readonly type: GeEditEventType;
27
+ /** Display row index of the edited body cell. */
28
+ readonly rowIndex: number;
29
+ /** Model column index. */
30
+ readonly columnIndex: number;
31
+ /** "enter" (opened by typing) or "edit" (F2, Enter, double click). */
32
+ readonly mode: CellEditMode;
33
+ /** The text of the editor (`"input"` and `"commit"`). */
34
+ readonly input?: string | undefined;
35
+ constructor(
36
+ /** What happened. */
37
+ type: GeEditEventType,
38
+ /** Display row index of the edited body cell. */
39
+ rowIndex: number,
40
+ /** Model column index. */
41
+ columnIndex: number,
42
+ /** "enter" (opened by typing) or "edit" (F2, Enter, double click). */
43
+ mode: CellEditMode,
44
+ /** The text of the editor (`"input"` and `"commit"`). */
45
+ input?: string | undefined);
46
+ }
@@ -56,7 +56,7 @@ export declare class GeRowDragEvent<T = any> {
56
56
  /** true if the table moves the rows itself ({@link RowDragOptionsIf.managed}). */
57
57
  readonly managed: boolean;
58
58
  /** The browser event behind this event (pointer or keyboard). */
59
- readonly originalEvent?: PointerEvent | KeyboardEvent | undefined;
59
+ readonly originalEvent?: KeyboardEvent | PointerEvent | undefined;
60
60
  /** true if the moved rows changed in the table (managed mode, `"end"`, not prevented). */
61
61
  moved: boolean;
62
62
  private prevented;
@@ -81,7 +81,7 @@ export declare class GeRowDragEvent<T = any> {
81
81
  /** true if the table moves the rows itself ({@link RowDragOptionsIf.managed}). */
82
82
  managed: boolean,
83
83
  /** The browser event behind this event (pointer or keyboard). */
84
- originalEvent?: PointerEvent | KeyboardEvent | undefined);
84
+ originalEvent?: KeyboardEvent | PointerEvent | undefined);
85
85
  /** true after {@link preventDefault}. */
86
86
  get defaultPrevented(): boolean;
87
87
  /** Veto: no drag (`"start"`), invalid target (`"move"`); no effect in `"end"` and `"cancel"`. */
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The undo history changed ({@link EventListenerIf.onUndoStackChanged}, wrapper event `undoStackChanged`): enough to
3
+ * enable and label own buttons ("Undo Paste").
4
+ *
5
+ * @example
6
+ * const listener = new EventAdapter();
7
+ * listener.onUndoStackChanged = (evt: GeUndoEvent) => {
8
+ * undoButton.disabled = !evt.canUndo;
9
+ * undoButton.title = evt.undoLabel ? `Undo ${evt.undoLabel}` : "Undo";
10
+ * };
11
+ *
12
+ * @category Events
13
+ * @since 1.1.99
14
+ */
15
+ export declare class GeUndoEvent {
16
+ readonly canUndo: boolean;
17
+ readonly canRedo: boolean;
18
+ readonly undoLabel: string | undefined;
19
+ readonly redoLabel: string | undefined;
20
+ readonly size: number;
21
+ /**
22
+ * @param {boolean} canUndo - a step can be undone
23
+ * @param {boolean} canRedo - a step can be redone
24
+ * @param {string | undefined} undoLabel - the label of the step undo takes (`"Edit"`, `"Paste"` …)
25
+ * @param {string | undefined} redoLabel - the label of the step redo takes
26
+ * @param {number} size - steps on the undo stack
27
+ */
28
+ constructor(canUndo: boolean, canRedo: boolean, undoLabel: string | undefined, redoLabel: string | undefined, size: number);
29
+ }
@@ -16,8 +16,26 @@ import { AriaTextsIf } from '../../aria/aria-texts.if.js';
16
16
  import { OverlayOptionsIf } from './overlay-options.if.js';
17
17
  import { RowDragOptionsIf } from '../../row-drag/row-drag-options.if.js';
18
18
  import { FillHandleOptionsIf } from '../../fill/fill-handle-options.if.js';
19
+ import { EditingOptionsIf } from '../../sheet-editing/editing-options.if.js';
20
+ import { ClipboardOptionsIf } from '../../clipboard/clipboard-options.if.js';
21
+ import { UndoOptionsIf } from '../../undo/undo-options.if.js';
22
+ import { CellFormulaOptionsIf } from '../../sheet/cell-formula-options.if.js';
23
+ import { SpreadsheetOptionsIf } from '../../spreadsheet/spreadsheet-options.if.js';
19
24
  import { BatchEditOptionsIf } from '../../batch-edit/batch-edit-options.if.js';
20
25
 
26
+ /**
27
+ * The default editor of {@link TableOptions.getEditRenderer}: a text input in the cell ({@link InputCellRenderer}).
28
+ * With Excel-style editing ({@link TableOptionsIf.editing}) the table recognises this default and uses its own
29
+ * editor above the cell instead – an own `getEditRenderer` is kept.
30
+ *
31
+ * @example
32
+ * const tableOptions: TableOptionsIf = { ...new TableOptions() };
33
+ * tableOptions.getEditRenderer === DEFAULT_GET_EDIT_RENDERER; // true
34
+ *
35
+ * @category Spreadsheet
36
+ * @since 1.1.99
37
+ */
38
+ export declare const DEFAULT_GET_EDIT_RENDERER: GetEditRenderer;
21
39
  /**
22
40
  * All default options of a table – see {@link TableOptionsIf} for the meaning of each field.
23
41
  *
@@ -89,6 +107,16 @@ export declare class TableOptions implements TableOptionsIf {
89
107
  fillHandle?: boolean | Partial<FillHandleOptionsIf>;
90
108
  masterDetail?: Partial<MasterDetailOptionsIf>;
91
109
  batchEdit?: boolean | Partial<BatchEditOptionsIf>;
110
+ /** Excel-style editing ({@link TableOptionsIf.editing}). Not set = off. @since 1.1.99 */
111
+ editing?: boolean | Partial<EditingOptionsIf>;
112
+ /** Copy, cut and paste ({@link TableOptionsIf.clipboard}). Not set = off. @since 1.1.99 */
113
+ clipboard?: boolean | Partial<ClipboardOptionsIf>;
114
+ /** Undo and redo ({@link TableOptionsIf.undo}). Not set = off. @since 1.1.99 */
115
+ undo?: boolean | Partial<UndoOptionsIf>;
116
+ /** Cell formulas ({@link TableOptionsIf.cellFormulas}). Not set = off. @since 1.1.99 */
117
+ cellFormulas?: boolean | Partial<CellFormulaOptionsIf>;
118
+ /** Preset like a spreadsheet ({@link TableOptionsIf.spreadsheet}). Not set = off. @since 1.1.99 */
119
+ spreadsheet?: boolean | Partial<SpreadsheetOptionsIf>;
92
120
  /**
93
121
  * Writing direction (`"ltr"` | `"rtl"` | `"auto"`). Not set = `"ltr"`; a nested table (master/detail) without its
94
122
  * own value takes the direction of the outer table. @since 1.1.98
@@ -1,6 +1,11 @@
1
1
  import { MasterDetailOptionsIf } from '../../master-detail/master-detail-options.if.js';
2
2
  import { RowDragOptionsIf } from '../../row-drag/row-drag-options.if.js';
3
3
  import { FillHandleOptionsIf } from '../../fill/fill-handle-options.if.js';
4
+ import { ClipboardOptionsIf } from '../../clipboard/clipboard-options.if.js';
5
+ import { UndoOptionsIf } from '../../undo/undo-options.if.js';
6
+ import { CellFormulaOptionsIf } from '../../sheet/cell-formula-options.if.js';
7
+ import { SpreadsheetOptionsIf } from '../../spreadsheet/spreadsheet-options.if.js';
8
+ import { EditingOptionsIf } from '../../sheet-editing/editing-options.if.js';
4
9
  import { BatchEditOptionsIf } from '../../batch-edit/batch-edit-options.if.js';
5
10
  import { DefaultRowHeightsIf } from './default-row-heights.if.js';
6
11
  import { TreeOptionsIf } from './tree-options.if.js';
@@ -267,7 +272,7 @@ export interface TableOptionsIf {
267
272
  * const tableOptions: TableOptionsIf = { ...new TableOptions(), ariaLabel: "Orders" };
268
273
  *
269
274
  * @since 1.1.91
270
- * @see Training: [Accessible tables: keyboard and screen readers](https://gui.expert/training/accessibility/)
275
+ * @see [Live demo: accessible order table](https://gui.expert/showcase/accessibility/run/) · Training: [Accessible tables: keyboard and screen readers](https://gui.expert/training/accessibility/)
271
276
  */
272
277
  ariaLabel?: string;
273
278
  /**
@@ -320,6 +325,7 @@ export interface TableOptionsIf {
320
325
  * };
321
326
  *
322
327
  * @since 1.1.92
328
+ * @see [Live demo: loading & empty states](https://gui.expert/showcase/overlays/run/) · Training: [Loading and empty tables](https://gui.expert/training/live-data/#overlays)
323
329
  */
324
330
  overlayOptions?: Partial<OverlayOptionsIf>;
325
331
  /**
@@ -333,6 +339,7 @@ export interface TableOptionsIf {
333
339
  * };
334
340
  *
335
341
  * @since 1.1.95
342
+ * @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)
336
343
  */
337
344
  rowDragOptions?: Partial<RowDragOptionsIf>;
338
345
  /**
@@ -350,8 +357,95 @@ export interface TableOptionsIf {
350
357
  * };
351
358
  *
352
359
  * @since 1.1.96
360
+ * @see [Live demo: fill handle & batch edit](https://gui.expert/showcase/batchedit/run/) · Training: [Fill handle and batch edit](https://gui.expert/training/inline-editing/#fill-batch)
353
361
  */
354
362
  fillHandle?: boolean | Partial<FillHandleOptionsIf>;
363
+ /**
364
+ * Excel-style editing: typing on a focused cell opens the editor (the text is replaced), Enter edits, Enter/Tab
365
+ * commit and move on, Shift+arrows extend the selection, Ctrl/⌘+arrows jump to the edge of the data, Delete
366
+ * clears the selected cells, Ctrl/⌘+Enter writes into all selected cells. The editor lives above the cell and
367
+ * survives scrolling. `true` = defaults ({@link EditingOptions}); without the option the table behaves as before
368
+ * (F2/double click edit, Enter activates, Tab leaves the table).
369
+ *
370
+ * @example
371
+ * const selectionModel = new SelectionModel("range", "multi");
372
+ * const tableOptions: TableOptionsIf = {
373
+ * ...new TableOptions(),
374
+ * getSelectionModel: () => selectionModel,
375
+ * editing: { defaultEditable: true }, // every data column can be edited
376
+ * };
377
+ *
378
+ * @since 1.1.99
379
+ */
380
+ editing?: boolean | Partial<EditingOptionsIf>;
381
+ /**
382
+ * Copy, cut and paste like Excel and Google Sheets: Ctrl/⌘+C puts tab-separated text (with Excel's quoting) and an
383
+ * HTML table into the clipboard, Ctrl/⌘+X marks the range (dashed frame) and moves it on paste, Ctrl/⌘+V pastes
384
+ * from the anchor – tiled over a selected range, cut off at the last column, skipping read-only cells; **one**
385
+ * `onModelChanged` with `source: "paste"` (or `"cut"`). `true` = defaults ({@link ClipboardOptions}); without the
386
+ * option Ctrl/⌘+C copies as before and Ctrl/⌘+X/V do nothing.
387
+ *
388
+ * @example
389
+ * const tableOptions: TableOptionsIf = {
390
+ * ...new TableOptions(),
391
+ * getSelectionModel: () => new SelectionModel("range", "multi"),
392
+ * editing: true,
393
+ * clipboard: true,
394
+ * };
395
+ *
396
+ * @since 1.1.99
397
+ */
398
+ clipboard?: boolean | Partial<ClipboardOptionsIf>;
399
+ /**
400
+ * Undo and redo: Ctrl/⌘+Z undoes the last change – an edit, a fill, a paste, a cut, Delete – as **one** step,
401
+ * Ctrl+Y or Ctrl/⌘+Shift+Z redoes it (source `"undo"`/`"redo"` in `onModelChanged`). Cells are found by their row
402
+ * object (sorting and filtering in between don't matter). `true` = defaults ({@link UndoOptions}); without the option
403
+ * Ctrl/⌘+Z does nothing (as before). In a batch edit the marked values are undone; commit and cancel empty the
404
+ * history.
405
+ *
406
+ * @example
407
+ * const tableOptions: TableOptionsIf = {
408
+ * ...new TableOptions(),
409
+ * editing: true,
410
+ * clipboard: true,
411
+ * undo: true,
412
+ * };
413
+ *
414
+ * @since 1.1.99
415
+ */
416
+ undo?: boolean | Partial<UndoOptionsIf>;
417
+ /**
418
+ * Cell formulas like in Excel: a text with a leading `=` in the data (`row.total = "=B2*C2"`) is calculated –
419
+ * references `A1`, `$B$3`, `B2:D10`, `A:A`, ≈ 70 functions, dependencies are recalculated after every write.
420
+ * Row 1 is the first row of `getAllRows()` (sorting and filtering keep the references), column A the first data
421
+ * column (row numbers and checkboxes don't count). The data keep the formula text; sorting, filters, totals, copy
422
+ * and the Excel export use the results. `'=…` is the text `=…`. `true` = every data column with the defaults of
423
+ * {@link CellFormulaOptions}; `{ columns: ["total"] }` = only these properties. Flat bodies only (objects or
424
+ * arrays; a tree, row grouping, pivot table or master/detail: a warning, no formulas). Not set: `"=1+1"` is text.
425
+ *
426
+ * @example
427
+ * const tableOptions: TableOptionsIf = {
428
+ * ...new TableOptions(),
429
+ * editing: { defaultEditable: true },
430
+ * cellFormulas: true,
431
+ * };
432
+ *
433
+ * @since 1.1.99
434
+ */
435
+ cellFormulas?: boolean | Partial<CellFormulaOptionsIf>;
436
+ /**
437
+ * Preset „like a spreadsheet“ for existing models: switches on `editing` (with `defaultEditable`), `clipboard`,
438
+ * `undo`, `cellFormulas` and `fillHandle` – unless the options set them themselves – and a range selection.
439
+ * An object switches single parts off (`false`) or configures them ({@link SpreadsheetOptionsIf}). For a new, empty
440
+ * sheet use {@link SpreadsheetFactory}; column letters above existing headers: `TableFactory.createTableModel({ …,
441
+ * columnLetters: true })`.
442
+ *
443
+ * @example
444
+ * const tableOptions: TableOptionsIf = { ...new TableOptions(), spreadsheet: true };
445
+ *
446
+ * @since 1.1.99
447
+ */
448
+ spreadsheet?: boolean | Partial<SpreadsheetOptionsIf>;
355
449
  /**
356
450
  * Batch edit always on: edited and filled values are collected (marked `ge-table-cell-pending`) and written with
357
451
  * {@link TableApi.commitBatchEdit} or discarded with {@link TableApi.cancelBatchEdit}. Without it, start a batch
@@ -361,6 +455,7 @@ export interface TableOptionsIf {
361
455
  * const tableOptions: TableOptionsIf = { ...new TableOptions(), batchEdit: true };
362
456
  *
363
457
  * @since 1.1.96
458
+ * @see [Live demo: fill handle & batch edit](https://gui.expert/showcase/batchedit/run/) · Training: [Fill handle and batch edit](https://gui.expert/training/inline-editing/#fill-batch)
364
459
  */
365
460
  batchEdit?: boolean | Partial<BatchEditOptionsIf>;
366
461
  /**
@@ -378,6 +473,7 @@ export interface TableOptionsIf {
378
473
  * };
379
474
  *
380
475
  * @since 1.1.97
476
+ * @see [Live demo: master/detail](https://gui.expert/showcase/masterdetail/run/) · Training: [Master/detail](https://gui.expert/training/master-detail/)
381
477
  */
382
478
  masterDetail?: Partial<MasterDetailOptionsIf>;
383
479
  /**
@@ -394,6 +490,7 @@ export interface TableOptionsIf {
394
490
  * const tableOptions: TableOptionsIf = { ...new TableOptions(), direction: "rtl" };
395
491
  *
396
492
  * @since 1.1.98
493
+ * @see [Live demo: right-to-left](https://gui.expert/showcase/rtl/run/) · Training: [Right-to-left](https://gui.expert/training/theming-dark-mode/#rtl)
397
494
  */
398
495
  direction?: TableDirection;
399
496
  /**
@@ -406,6 +503,7 @@ export interface TableOptionsIf {
406
503
  * const tableOptions: TableOptionsIf = { ...new TableOptions(), initialState: saved ?? undefined };
407
504
  *
408
505
  * @since 1.1.92
506
+ * @see [Live demo: persisted layout](https://gui.expert/showcase/state/run/) · Training: [Remember the state](https://gui.expert/training/persist-state/)
409
507
  */
410
508
  initialState?: Partial<TableStateIf>;
411
509
  /**
@@ -8,6 +8,7 @@ import { FilterFunction } from '../../common/filter-function.js';
8
8
  import { SortItem } from '../../common/sort-item.js';
9
9
  import { HasDefaultRowHeightIf } from './has-default-row-height-if.js';
10
10
  import { ColumnValues } from '../../../calc/column-values.js';
11
+ import { SheetCellsIf } from '../../../sheet/sheet-cells.if.js';
11
12
 
12
13
  /** @category Area models */
13
14
  export declare abstract class AbstractAreaModel<T> implements AreaModelIf, HasDefaultRowHeightIf {
@@ -19,15 +20,17 @@ export declare abstract class AbstractAreaModel<T> implements AreaModelIf, HasDe
19
20
  private calcTextRenderer?;
20
21
  protected cellRenderers: (CellRendererIf | undefined)[];
21
22
  protected yPositions: number[];
23
+ /** Cell formulas of the table (since 1.1.99, set by the table for a flat body). @internal */
24
+ sheetCells?: SheetCellsIf;
22
25
  constructor(areaIdent: AreaIdent, columnDefs?: ColumnDefIf[], defaultRowHeight?: number);
23
26
  abstract getRowCount(): number;
24
27
  abstract getValueAt(rowIndex: number, columnIndex: number): any;
25
28
  getTextValueAt(rowIndex: number, columnIndex: number): string;
26
- getTooltipAt(_rowIndex: number, _columnIndex: number): any;
29
+ getTooltipAt(rowIndex: number, columnIndex: number): any;
27
30
  abstract getRowHeight(rowIndex: number): number;
28
31
  getCellRenderer(_rowIndex: number, columnIndex: number): CellRendererIf | undefined;
29
32
  getColspanAt(_rowIndex: number, _columnIndex: number): number;
30
- getCustomClassesAt(_rowIndex: number, _columnIndex: number): string[];
33
+ getCustomClassesAt(rowIndex: number, columnIndex: number): string[];
31
34
  getCustomStyleAt(_rowIndex: number, _columnIndex: number): {
32
35
  [key: string]: string;
33
36
  } | undefined;
@@ -44,6 +47,12 @@ export declare abstract class AbstractAreaModel<T> implements AreaModelIf, HasDe
44
47
  isFilterable(): boolean;
45
48
  doSort(_sortItems: SortItem[]): boolean;
46
49
  sort(_compareFn?: (a: any, b: any) => number): void;
50
+ /**
51
+ * Columns without an own `editable` are editable (Excel-style editing, `EditingOptionsIf.defaultEditable`; set by
52
+ * the table). Row number, checkbox and group columns stay read only.
53
+ * @since 1.1.99
54
+ */
55
+ defaultEditable: boolean;
47
56
  isEditable(_rowIndex: number, columnIndex: number): boolean;
48
57
  setValue(rowIndex: number, columnIndex: number, value: any): boolean;
49
58
  isSelectable(_rowIndex: number, _columnIndex: number): boolean;
@@ -50,6 +50,20 @@ export declare class AreaModelArrayOfArrays<T> extends AbstractAreaModel<T[][]>
50
50
  */
51
51
  moveRows(rowIndices: number[], target: RowDropTargetIf): boolean;
52
52
  getValueAt(rowIndex: number, columnIndex: number): any;
53
+ /**
54
+ * The input of a cell – the formula text of a cell formula (`"=B2*C2"`), otherwise the value (since 1.1.99,
55
+ * {@link TableOptionsIf.cellFormulas}).
56
+ *
57
+ * @param {number} rowIndex - display index
58
+ * @param {number} columnIndex - column
59
+ * @returns {unknown} the input
60
+ *
61
+ * @example
62
+ * new AreaModelArrayOfArrays("body", [[2, "=A1*2"]], 30).getInputValueAt(0, 1); // "=A1*2"
63
+ *
64
+ * @since 1.1.99
65
+ */
66
+ getInputValueAt(rowIndex: number, columnIndex: number): unknown;
53
67
  setValue(rowIndex: number, columnIndex: number, value: any): boolean;
54
68
  getRowByIndex(rowIndex: number): any;
55
69
  getRowHeight(_rowIndex: number): number;
@@ -577,6 +577,20 @@ export declare class AreaModelObjectArray<T> extends AbstractAreaModel<T> implem
577
577
  * console.log(email); // 'john@example.com'
578
578
  */
579
579
  getValueByT(t: T, property: string): any;
580
+ /**
581
+ * The input of a cell – what was typed: the formula text of a cell formula (`"=B2*C2"`), otherwise the value
582
+ * (since 1.1.99, {@link TableOptionsIf.cellFormulas}).
583
+ *
584
+ * @param {number} rowIndex - display index
585
+ * @param {number} columnIndex - model column
586
+ * @returns {unknown} the input
587
+ *
588
+ * @example
589
+ * bodyAreaModel.getInputValueAt(0, 3); // "=B2*C2" (getValueAt: 2598)
590
+ *
591
+ * @since 1.1.99
592
+ */
593
+ getInputValueAt(rowIndex: number, columnIndex: number): unknown;
580
594
  /**
581
595
  * Changes the order of columns by moving a column from one position to another.
582
596
  * This method updates both the properties array and calls the parent class implementation.
@@ -364,6 +364,17 @@ export interface AreaModelIf {
364
364
  * @since 1.1.95
365
365
  */
366
366
  isCalculatedProperty?(property: string): boolean;
367
+ /**
368
+ * Optional: the input of a cell – what was typed, e.g. the formula text of a cell formula (`"=B2*C2"`), while
369
+ * {@link getValueAt} gives its result ({@link TableOptionsIf.cellFormulas}). Editor, copy inside the table and undo
370
+ * use it. Without it the input is the value. Implemented by the object-array and array models.
371
+ *
372
+ * @example
373
+ * tableModel.getBodyModel().getInputValueAt?.(0, 3); // "=B2*C2"
374
+ *
375
+ * @since 1.1.99
376
+ */
377
+ getInputValueAt?(rowIndex: number, columnIndex: number): unknown;
367
378
  /**
368
379
  * Optional: the value of a column for a row object – computed for a calculated column, otherwise the property
369
380
  * path ({@link TableApi.getRowValue}). Implemented by the object-array, tree, row-group and pivot models.
@@ -7,6 +7,7 @@ import { BooleanFunction } from '../../common/boolean-function.js';
7
7
  import { SortState } from '../../common/sort-state.type.js';
8
8
  import { GetEditRenderer } from '../../../renderer/edit/edit-cell-renderer.type.js';
9
9
  import { editInputPipe } from '../../../renderer/edit/edit-input-pipe.if.js';
10
+ import { ColumnEditorOption } from '../../../sheet-editing/cell-editor.if.js';
10
11
  import { ValueGetter, ValueSetter } from '../../../calc/value-getter.type.js';
11
12
  import { ShowValuesAsConfig } from '../../../calc/show-values-as.type.js';
12
13
  import { FormulaOptionsIf } from '../../../formula/formula-options.if.js';
@@ -66,6 +67,12 @@ export declare class ColumnDef implements ColumnDefIf {
66
67
  rowDrag?: RowDragColumnOption;
67
68
  /** Checks edited values, see {@link ColumnDefIf.validate} (since 1.1.96). */
68
69
  validate?: CellValidator;
70
+ /** The editor of Excel-style editing, see {@link ColumnDefIf.editor} (since 1.1.99). */
71
+ editor?: ColumnEditorOption;
72
+ /** The value of a cleared cell, see {@link ColumnDefIf.emptyValue} (since 1.1.99). */
73
+ emptyValue?: unknown;
74
+ /** `false`: no cell formulas in this column, see {@link ColumnDefIf.cellFormulas} (since 1.1.99). */
75
+ cellFormulas?: boolean;
69
76
  constructor(property: string, headerLabel: string, width?: SizeIf, classes?: AreaObjectMapType<string[]>, rendererMap?: AreaObjectMapType<CellRendererIf>, minWidth?: SizeIf, maxWidth?: SizeIf, sortable?: BooleanFunction | undefined, sortComparator?: ValueRowSortComparator | undefined, sortState?: SortState | undefined, sortStatesOrder?: SortState[] | undefined, sortIconVisible?: BooleanFunction | undefined, editable?: BooleanFunction | undefined, getEditRenderer?: GetEditRenderer | undefined, editInputPipe?: editInputPipe | undefined, isVisible?: BooleanFunction);
70
77
  static bodyRenderer(bodyRenderer: CellRendererIf): AreaObjectMap<CellRendererIf>;
71
78
  /**
@@ -139,5 +146,11 @@ export declare class ColumnDef implements ColumnDefIf {
139
146
  rowDrag?: RowDragColumnOption;
140
147
  /** Checks edited values: a message for an invalid value (since 1.1.96). */
141
148
  validate?: CellValidator;
149
+ /** The editor of Excel-style editing: `"text"`, `"number"`, `"date"` or a factory (since 1.1.99). */
150
+ editor?: ColumnEditorOption;
151
+ /** The value of a cleared cell (Delete) – default `EditingOptionsIf.emptyValue` (since 1.1.99). */
152
+ emptyValue?: unknown;
153
+ /** `false`: `"=…"` stays text in this column of a table with cell formulas (since 1.1.99). */
154
+ cellFormulas?: boolean;
142
155
  }): ColumnDefIf;
143
156
  }