@rozie-ui/data-table-lit 0.7.1 → 0.7.3
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/CHANGELOG.md +429 -0
- package/README.md +11 -11
- package/dist/index.cjs +97 -17
- package/dist/index.d.cts +174 -77
- package/dist/index.d.mts +174 -77
- package/dist/index.mjs +114 -34
- package/package.json +4 -3
- package/src/Column.ts +8 -6
- package/src/DataTable.ts +275 -206
- package/src/FilterNumberRange.ts +10 -1
- package/src/index.ts +2 -0
package/src/DataTable.ts
CHANGED
|
@@ -46,63 +46,167 @@ import { columnSpecsEquivalent } from './helpers/columnDefUtils';
|
|
|
46
46
|
|
|
47
47
|
// The registry API handed to <Column> children (whole-object-replace — T-48-PP guard).
|
|
48
48
|
|
|
49
|
+
import type { Column as TableColumn, ColumnDef, ColumnFiltersState, ColumnOrderState, ColumnPinningState, ColumnSizingState, ExpandedState, GroupingState, PaginationState, RowSelectionState, SortingState, VisibilityState } from '@tanstack/table-core';
|
|
50
|
+
|
|
51
|
+
/** A cell position as integers over the visible (display-order) model. */
|
|
52
|
+
export interface DataTableCellPosition {
|
|
53
|
+
rowIndex: number;
|
|
54
|
+
colIndex: number;
|
|
55
|
+
}
|
|
56
|
+
/** The active (roving-focus) cell. A header cell reports `rowIndex: null` and `isHeader: true`. */
|
|
57
|
+
export interface DataTableActiveCell {
|
|
58
|
+
rowIndex: number | null;
|
|
59
|
+
colIndex: number;
|
|
60
|
+
isHeader: boolean;
|
|
61
|
+
}
|
|
62
|
+
/** The rectangular cell-range selection. Both corners are `null` when there is no range. */
|
|
63
|
+
export interface DataTableRange {
|
|
64
|
+
anchor: DataTableCellPosition | null;
|
|
65
|
+
focus: DataTableCellPosition | null;
|
|
66
|
+
}
|
|
67
|
+
/** One data column offered to the `#groupBar` slot. */
|
|
68
|
+
export interface DataTableGroupableColumn {
|
|
69
|
+
id: string;
|
|
70
|
+
label: string;
|
|
71
|
+
}
|
|
72
|
+
/** One changed cell inside a row edit commit. */
|
|
73
|
+
export interface DataTableCellChange {
|
|
74
|
+
columnId: string;
|
|
75
|
+
oldValue: any;
|
|
76
|
+
newValue: any;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The `activecell-change` payload. `isHeader` is set when the move landed on or left a header cell. */
|
|
80
|
+
export interface DataTableActiveCellChangePayload {
|
|
81
|
+
rowIndex: number | null;
|
|
82
|
+
colIndex: number;
|
|
83
|
+
isHeader?: boolean;
|
|
84
|
+
}
|
|
85
|
+
/** The `cell-edit-commit` payload: one committed cell. */
|
|
86
|
+
export interface DataTableCellEditCommitPayload {
|
|
87
|
+
rowId: string;
|
|
88
|
+
columnId: string;
|
|
89
|
+
oldValue: any;
|
|
90
|
+
newValue: any;
|
|
91
|
+
}
|
|
92
|
+
/** The `row-edit-commit` payload: the row and every cell the save changed. */
|
|
93
|
+
export interface DataTableRowEditCommitPayload {
|
|
94
|
+
rowId: string;
|
|
95
|
+
changes: DataTableCellChange[];
|
|
96
|
+
}
|
|
97
|
+
/** The `filter-change` payload: `globalFilter` for the search box, `columnFilters` for a per-column filter. Exactly one key is set. */
|
|
98
|
+
export interface DataTableFilterChangePayload {
|
|
99
|
+
globalFilter?: string;
|
|
100
|
+
columnFilters?: ColumnFiltersState;
|
|
101
|
+
}
|
|
102
|
+
/** The `history-change` payload: undo/redo availability. */
|
|
103
|
+
export interface DataTableHistoryChangePayload {
|
|
104
|
+
canUndo: boolean;
|
|
105
|
+
canRedo: boolean;
|
|
106
|
+
}
|
|
107
|
+
/** The `range-change` payload: the new range corners (both `null` when the range cleared). */
|
|
108
|
+
export type DataTableRangeChangePayload = DataTableRange;
|
|
109
|
+
/** The `row-activate` payload. `row` is the original data object and `index` its position in the rendered model. */
|
|
110
|
+
export interface DataTableRowActivatePayload {
|
|
111
|
+
row: any;
|
|
112
|
+
index: number;
|
|
113
|
+
trigger: 'keyboard' | 'click';
|
|
114
|
+
}
|
|
115
|
+
/** The `visible-range-change` payload: the rendered row window, `end` exclusive. */
|
|
116
|
+
export interface DataTableVisibleRangeChangePayload {
|
|
117
|
+
start: number;
|
|
118
|
+
end: number;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface RozieDataTableEventMap extends Omit<HTMLElementEventMap, 'activecell-change' | 'cell-edit-commit' | 'expand-change' | 'filter-change' | 'group-change' | 'history-change' | 'page-change' | 'pin-change' | 'range-change' | 'reorder-change' | 'resize-change' | 'row-activate' | 'row-edit-commit' | 'selection-change' | 'sort-change' | 'visibility-change' | 'visible-range-change' | 'data-change' | 'sorting-change' | 'global-filter-change' | 'column-filters-change' | 'pagination-change' | 'expanded-change' | 'grouping-change' | 'row-selection-change' | 'column-visibility-change' | 'column-sizing-change' | 'column-order-change' | 'column-pinning-change'> {
|
|
122
|
+
'activecell-change': CustomEvent<DataTableActiveCellChangePayload>;
|
|
123
|
+
'cell-edit-commit': CustomEvent<DataTableCellEditCommitPayload>;
|
|
124
|
+
'expand-change': CustomEvent<ExpandedState>;
|
|
125
|
+
'filter-change': CustomEvent<DataTableFilterChangePayload>;
|
|
126
|
+
'group-change': CustomEvent<GroupingState>;
|
|
127
|
+
'history-change': CustomEvent<DataTableHistoryChangePayload>;
|
|
128
|
+
'page-change': CustomEvent<PaginationState>;
|
|
129
|
+
'pin-change': CustomEvent<ColumnPinningState>;
|
|
130
|
+
'range-change': CustomEvent<DataTableRangeChangePayload>;
|
|
131
|
+
'reorder-change': CustomEvent<ColumnOrderState>;
|
|
132
|
+
'resize-change': CustomEvent<ColumnSizingState>;
|
|
133
|
+
'row-activate': CustomEvent<DataTableRowActivatePayload>;
|
|
134
|
+
'row-edit-commit': CustomEvent<DataTableRowEditCommitPayload>;
|
|
135
|
+
'selection-change': CustomEvent<RowSelectionState>;
|
|
136
|
+
'sort-change': CustomEvent<SortingState>;
|
|
137
|
+
'visibility-change': CustomEvent<VisibilityState>;
|
|
138
|
+
'visible-range-change': CustomEvent<DataTableVisibleRangeChangePayload>;
|
|
139
|
+
'data-change': CustomEvent<any[]>;
|
|
140
|
+
'sorting-change': CustomEvent<any[]>;
|
|
141
|
+
'global-filter-change': CustomEvent<string>;
|
|
142
|
+
'column-filters-change': CustomEvent<any[]>;
|
|
143
|
+
'pagination-change': CustomEvent<any>;
|
|
144
|
+
'expanded-change': CustomEvent<any | boolean>;
|
|
145
|
+
'grouping-change': CustomEvent<any[]>;
|
|
146
|
+
'row-selection-change': CustomEvent<any>;
|
|
147
|
+
'column-visibility-change': CustomEvent<any>;
|
|
148
|
+
'column-sizing-change': CustomEvent<any>;
|
|
149
|
+
'column-order-change': CustomEvent<any[]>;
|
|
150
|
+
'column-pinning-change': CustomEvent<any>;
|
|
151
|
+
}
|
|
152
|
+
|
|
49
153
|
const __rozieCtx_data_table_columns = createContext(Symbol.for("rozie:data-table:columns"));
|
|
50
154
|
|
|
51
155
|
interface RozieGroupBarSlotCtx {
|
|
52
|
-
grouping:
|
|
53
|
-
groupableColumns:
|
|
54
|
-
applyGrouping:
|
|
55
|
-
clearGrouping:
|
|
156
|
+
grouping: string[];
|
|
157
|
+
groupableColumns: DataTableGroupableColumn[];
|
|
158
|
+
applyGrouping: (cols: string[]) => void;
|
|
159
|
+
clearGrouping: () => void;
|
|
56
160
|
}
|
|
57
161
|
|
|
58
162
|
interface RozieSelectAllSlotCtx {
|
|
59
|
-
checked:
|
|
60
|
-
indeterminate:
|
|
61
|
-
toggle: any;
|
|
163
|
+
checked: boolean;
|
|
164
|
+
indeterminate: boolean;
|
|
165
|
+
toggle: (event: any) => void;
|
|
62
166
|
}
|
|
63
167
|
|
|
64
168
|
interface RozieDynamicColHeaderSlotCtx {
|
|
65
|
-
columnId:
|
|
66
|
-
column: any
|
|
67
|
-
label:
|
|
169
|
+
columnId: string;
|
|
170
|
+
column: TableColumn<any, unknown>;
|
|
171
|
+
label: string;
|
|
68
172
|
}
|
|
69
173
|
|
|
70
174
|
interface RozieDynamicFilterSlotCtx {
|
|
71
|
-
columnId:
|
|
175
|
+
columnId: string;
|
|
72
176
|
value: any;
|
|
73
|
-
uniqueValues: any;
|
|
74
|
-
minMax:
|
|
75
|
-
columnLabel:
|
|
76
|
-
setFilter: any;
|
|
177
|
+
uniqueValues: any[];
|
|
178
|
+
minMax: [number, number] | null;
|
|
179
|
+
columnLabel: string;
|
|
180
|
+
setFilter: (columnId: string, value: any) => void;
|
|
77
181
|
}
|
|
78
182
|
|
|
79
183
|
interface RoziePlaceholderSlotCtx {
|
|
80
|
-
index:
|
|
81
|
-
columnId:
|
|
184
|
+
index: number;
|
|
185
|
+
columnId: string;
|
|
82
186
|
}
|
|
83
187
|
|
|
84
188
|
interface RozieSelectCellSlotCtx {
|
|
85
189
|
row: any;
|
|
86
|
-
checked:
|
|
87
|
-
toggle: any;
|
|
190
|
+
checked: boolean;
|
|
191
|
+
toggle: (event: any) => void;
|
|
88
192
|
}
|
|
89
193
|
|
|
90
194
|
interface RozieDynamicCellSlotCtx {
|
|
91
|
-
columnId:
|
|
92
|
-
column: any
|
|
195
|
+
columnId: string;
|
|
196
|
+
column: TableColumn<any, unknown>;
|
|
93
197
|
row: any;
|
|
94
198
|
value: any;
|
|
95
199
|
}
|
|
96
200
|
|
|
97
201
|
interface RozieDynamicEditorSlotCtx {
|
|
98
|
-
columnId:
|
|
99
|
-
column: any
|
|
202
|
+
columnId: string;
|
|
203
|
+
column: TableColumn<any, unknown>;
|
|
100
204
|
row: any;
|
|
101
205
|
value: any;
|
|
102
|
-
commit: any;
|
|
103
|
-
cancel:
|
|
104
|
-
columnLabel:
|
|
105
|
-
autofocus:
|
|
206
|
+
commit: (value: any) => void;
|
|
207
|
+
cancel: () => void;
|
|
208
|
+
columnLabel: string;
|
|
209
|
+
autofocus: boolean;
|
|
106
210
|
}
|
|
107
211
|
|
|
108
212
|
interface RozieDetailSlotCtx {
|
|
@@ -110,36 +214,36 @@ interface RozieDetailSlotCtx {
|
|
|
110
214
|
}
|
|
111
215
|
|
|
112
216
|
interface RozieColHeaderSlotCtx {
|
|
113
|
-
columnId:
|
|
114
|
-
column: any
|
|
115
|
-
label:
|
|
217
|
+
columnId: string;
|
|
218
|
+
column: TableColumn<any, unknown>;
|
|
219
|
+
label: string;
|
|
116
220
|
}
|
|
117
221
|
|
|
118
222
|
interface RozieFilterSlotCtx {
|
|
119
|
-
columnId:
|
|
223
|
+
columnId: string;
|
|
120
224
|
value: any;
|
|
121
|
-
uniqueValues: any;
|
|
122
|
-
minMax:
|
|
123
|
-
columnLabel:
|
|
124
|
-
setFilter: any;
|
|
225
|
+
uniqueValues: any[];
|
|
226
|
+
minMax: [number, number] | null;
|
|
227
|
+
columnLabel: string;
|
|
228
|
+
setFilter: (columnId: string, value: any) => void;
|
|
125
229
|
}
|
|
126
230
|
|
|
127
231
|
interface RozieCellSlotCtx {
|
|
128
|
-
columnId:
|
|
129
|
-
column: any
|
|
232
|
+
columnId: string;
|
|
233
|
+
column: TableColumn<any, unknown>;
|
|
130
234
|
row: any;
|
|
131
235
|
value: any;
|
|
132
236
|
}
|
|
133
237
|
|
|
134
238
|
interface RozieEditorSlotCtx {
|
|
135
|
-
columnId:
|
|
136
|
-
column: any
|
|
239
|
+
columnId: string;
|
|
240
|
+
column: TableColumn<any, unknown>;
|
|
137
241
|
row: any;
|
|
138
242
|
value: any;
|
|
139
|
-
commit: any;
|
|
140
|
-
cancel:
|
|
141
|
-
columnLabel:
|
|
142
|
-
autofocus:
|
|
243
|
+
commit: (value: any) => void;
|
|
244
|
+
cancel: () => void;
|
|
245
|
+
columnLabel: string;
|
|
246
|
+
autofocus: boolean;
|
|
143
247
|
}
|
|
144
248
|
|
|
145
249
|
@customElement('rozie-data-table')
|
|
@@ -768,8 +872,10 @@ export default class DataTable extends SignalWatcher(LitElement) {
|
|
|
768
872
|
private _liveAnnounce = signal('');
|
|
769
873
|
@query('[data-rozie-ref="__rozieRoot"]') private _ref__rozieRoot!: HTMLElement;
|
|
770
874
|
private __rozieWatchInitial_0 = true;
|
|
875
|
+
private __rozieWatchPrev_1: unknown;
|
|
771
876
|
private __rozieWatchInitial_1 = true;
|
|
772
877
|
private __rozieWatchInitial_2 = true;
|
|
878
|
+
private __rozieFirstUpdateDone = false;
|
|
773
879
|
private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { context: __rozieCtx_data_table_columns, initialValue: ((__rozieCtxHost) => ({
|
|
774
880
|
registerColumn: (id: any, spec: any) => {
|
|
775
881
|
if (id == null) return;
|
|
@@ -806,20 +912,20 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
806
912
|
@queryAssignedElements({ flatten: true }) private _slotDefaultElements!: Element[];
|
|
807
913
|
@state() private _hasSlotGroupBar = false;
|
|
808
914
|
@queryAssignedElements({ slot: 'groupBar', flatten: true }) private _slotGroupBarElements!: Element[];
|
|
809
|
-
@property({ attribute: false }) groupBar?: (scope: { grouping:
|
|
915
|
+
@property({ attribute: false }) groupBar?: (scope: { grouping: string[]; groupableColumns: DataTableGroupableColumn[]; applyGrouping: (cols: string[]) => void; clearGrouping: () => void }) => unknown;
|
|
810
916
|
@state() private _hasSlotSelectAll = false;
|
|
811
917
|
@queryAssignedElements({ slot: 'selectAll', flatten: true }) private _slotSelectAllElements!: Element[];
|
|
812
|
-
@property({ attribute: false }) selectAll?: (scope: { checked:
|
|
918
|
+
@property({ attribute: false }) selectAll?: (scope: { checked: boolean; indeterminate: boolean; toggle: (event: any) => void }) => unknown;
|
|
813
919
|
@state() private _hasSlotDynamicColHeader = false;
|
|
814
920
|
@queryAssignedElements({ flatten: true }) private _slotDynamicColHeaderElements!: Element[];
|
|
815
921
|
@state() private _hasSlotDynamicFilter = false;
|
|
816
922
|
@queryAssignedElements({ flatten: true }) private _slotDynamicFilterElements!: Element[];
|
|
817
923
|
@state() private _hasSlotPlaceholder = false;
|
|
818
924
|
@queryAssignedElements({ slot: 'placeholder', flatten: true }) private _slotPlaceholderElements!: Element[];
|
|
819
|
-
@property({ attribute: false }) placeholder?: (scope: { index:
|
|
925
|
+
@property({ attribute: false }) placeholder?: (scope: { index: number; columnId: string }) => unknown;
|
|
820
926
|
@state() private _hasSlotSelectCell = false;
|
|
821
927
|
@queryAssignedElements({ slot: 'selectCell', flatten: true }) private _slotSelectCellElements!: Element[];
|
|
822
|
-
@property({ attribute: false }) selectCell?: (scope: { row: any; checked:
|
|
928
|
+
@property({ attribute: false }) selectCell?: (scope: { row: any; checked: boolean; toggle: (event: any) => void }) => unknown;
|
|
823
929
|
@state() private _hasSlotDynamicCell = false;
|
|
824
930
|
@queryAssignedElements({ flatten: true }) private _slotDynamicCellElements!: Element[];
|
|
825
931
|
@state() private _hasSlotDynamicEditor = false;
|
|
@@ -829,16 +935,16 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
829
935
|
@property({ attribute: false }) detail?: (scope: { row: any }) => unknown;
|
|
830
936
|
@state() private _hasSlotColHeader = false;
|
|
831
937
|
@queryAssignedElements({ slot: 'colHeader', flatten: true }) private _slotColHeaderElements!: Element[];
|
|
832
|
-
@property({ attribute: false }) colHeader?: (scope: { columnId:
|
|
938
|
+
@property({ attribute: false }) colHeader?: (scope: { columnId: string; column: TableColumn<any, unknown>; label: string }) => unknown;
|
|
833
939
|
@state() private _hasSlotFilter = false;
|
|
834
940
|
@queryAssignedElements({ slot: 'filter', flatten: true }) private _slotFilterElements!: Element[];
|
|
835
|
-
@property({ attribute: false }) filter?: (scope: { columnId:
|
|
941
|
+
@property({ attribute: false }) filter?: (scope: { columnId: string; value: any; uniqueValues: any[]; minMax: [number, number] | null; columnLabel: string; setFilter: (columnId: string, value: any) => void }) => unknown;
|
|
836
942
|
@state() private _hasSlotCell = false;
|
|
837
943
|
@queryAssignedElements({ slot: 'cell', flatten: true }) private _slotCellElements!: Element[];
|
|
838
|
-
@property({ attribute: false }) cell?: (scope: { columnId:
|
|
944
|
+
@property({ attribute: false }) cell?: (scope: { columnId: string; column: TableColumn<any, unknown>; row: any; value: any }) => unknown;
|
|
839
945
|
@state() private _hasSlotEditor = false;
|
|
840
946
|
@queryAssignedElements({ slot: 'editor', flatten: true }) private _slotEditorElements!: Element[];
|
|
841
|
-
@property({ attribute: false }) editor?: (scope: { columnId:
|
|
947
|
+
@property({ attribute: false }) editor?: (scope: { columnId: string; column: TableColumn<any, unknown>; row: any; value: any; commit: (value: any) => void; cancel: () => void; columnLabel: string; autofocus: boolean }) => unknown;
|
|
842
948
|
// Phase 79 Plan 08 (R4) contract for 79-09: the record intake for
|
|
843
949
|
// record-routed slot fills. 79-09's consumer-side emitSlotFiller
|
|
844
950
|
// accumulates an object literal onto the SAME `.rozieSlots=${{ ... }}`
|
|
@@ -848,7 +954,7 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
848
954
|
// named function-prop / <slot> fallback (AC-9). Attribute
|
|
849
955
|
// deserialization is disabled — this is a function-valued record,
|
|
850
956
|
// never reflected to/from an HTML attribute.
|
|
851
|
-
@property({ attribute: false }) rozieSlots?: { [key: `colHeader-${string}`]: (scope: { columnId:
|
|
957
|
+
@property({ attribute: false }) rozieSlots?: { [key: `colHeader-${string}`]: (scope: { columnId: string; column: TableColumn<any, unknown>; label: string }) => unknown; [key: `filter-${string}`]: (scope: { columnId: string; value: any; uniqueValues: any[]; minMax: [number, number] | null; columnLabel: string; setFilter: (columnId: string, value: any) => void }) => unknown; [key: `cell-${string}`]: (scope: { columnId: string; column: TableColumn<any, unknown>; row: any; value: any }) => unknown; [key: `editor-${string}`]: (scope: { columnId: string; column: TableColumn<any, unknown>; row: any; value: any; commit: (value: any) => void; cancel: () => void; columnLabel: string; autofocus: boolean }) => unknown; } & Record<string, (scope: any) => unknown>;
|
|
852
958
|
|
|
853
959
|
private _disconnectCleanups: Array<() => void> = [];
|
|
854
960
|
// Re-parenting guard: set true once the deferred teardown has actually
|
|
@@ -1048,7 +1154,7 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1048
1154
|
// columnDefs()/tableColumns() build the UNION of both, and reFeed re-passes columns.
|
|
1049
1155
|
// (Consumers memoize the array as with $props.data/$props.sorting; the uncontrolled
|
|
1050
1156
|
// <Column>-children path leaves $props.columns undefined — a stable no-op getter.)
|
|
1051
|
-
this.columns, this._colReg.value])(); untracked(() => { if (this.__rozieWatchInitial_1) { this.__rozieWatchInitial_1 = false; return; } (() => {
|
|
1157
|
+
this.columns, this._colReg.value])(); untracked(() => { this.__rozieWatchPrev_1 = __watchVal; if (this.__rozieWatchInitial_1) { this.__rozieWatchInitial_1 = false; return; } (() => {
|
|
1052
1158
|
// Seed BEFORE the re-feed so the pinning this call may write is part of the state object
|
|
1053
1159
|
// table-core receives on this same tick (rather than landing a frame late and re-ordering
|
|
1054
1160
|
// getVisibleCells() a render after the columns appear). One-shot and self-latching — see
|
|
@@ -1104,15 +1210,8 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1104
1210
|
// re-ordering a render later. Covers the `:columns` config-array form, which is available
|
|
1105
1211
|
// now; `<Column>` children register during mount and are covered by the re-feed watch's own
|
|
1106
1212
|
// call. One-shot and self-latching — see seedColumnPinning() in stateAssembly.rzts.
|
|
1107
|
-
// Apply any per-column `pinned` declaration as the INITIAL pinning state BEFORE createTable
|
|
1108
|
-
// reads currentState() below, so the first row model table-core builds is already correctly
|
|
1109
|
-
// ordered (getVisibleCells() returns [left-pinned, center, right-pinned]) rather than
|
|
1110
|
-
// re-ordering a render later. Covers the `:columns` config-array form, which is available
|
|
1111
|
-
// now; `<Column>` children register during mount and are covered by the re-feed watch's own
|
|
1112
|
-
// call. One-shot and self-latching — see seedColumnPinning() in stateAssembly.rzts.
|
|
1113
1213
|
this.seedColumnPinning();
|
|
1114
1214
|
// Build the table instance HERE so the closures below capture the live `table`.
|
|
1115
|
-
// Build the table instance HERE so the closures below capture the live `table`.
|
|
1116
1215
|
this.table = createTable({
|
|
1117
1216
|
// Plain value (NOT a `get data()` getter): an object-literal getter rebinds
|
|
1118
1217
|
// `this` to the options object, and the Angular/Lit emitters resolve $props via
|
|
@@ -1295,14 +1394,9 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1295
1394
|
if (typeof queueMicrotask !== 'undefined') queueMicrotask(this.syncIndeterminate);else Promise.resolve().then(this.syncIndeterminate);
|
|
1296
1395
|
};
|
|
1297
1396
|
|
|
1298
|
-
// initial pull
|
|
1299
1397
|
// initial pull
|
|
1300
1398
|
this.refreshRowModel();
|
|
1301
1399
|
|
|
1302
|
-
// ── Grid mode: capture the table root ──────────────────────────────────────────────
|
|
1303
|
-
// $el is the component root; the <table class="rozie-data-table"> is the grid root the
|
|
1304
|
-
// cell selectors hang off (the exact idiom proven ×6 by plan 01's probe). Captured here
|
|
1305
|
-
// (post-mount) so it is non-null and ROZ123-clean.
|
|
1306
1400
|
// ── Grid mode: capture the table root ──────────────────────────────────────────────
|
|
1307
1401
|
// $el is the component root; the <table class="rozie-data-table"> is the grid root the
|
|
1308
1402
|
// cell selectors hang off (the exact idiom proven ×6 by plan 01's probe). Captured here
|
|
@@ -1311,9 +1405,6 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1311
1405
|
// B-02: the click-away detector. `composedPath()` rather than `ev.target` because on Lit the
|
|
1312
1406
|
// grid lives in a shadow root and a document-level listener sees the retargeted HOST element,
|
|
1313
1407
|
// which is never `gridRoot.contains(...)` — every in-grid click would read as "outside".
|
|
1314
|
-
// B-02: the click-away detector. `composedPath()` rather than `ev.target` because on Lit the
|
|
1315
|
-
// grid lives in a shadow root and a document-level listener sees the retargeted HOST element,
|
|
1316
|
-
// which is never `gridRoot.contains(...)` — every in-grid click would read as "outside".
|
|
1317
1408
|
if (typeof document !== 'undefined') {
|
|
1318
1409
|
this.docPointerDown = (ev: any) => {
|
|
1319
1410
|
if (!this.gridRoot) {
|
|
@@ -1332,20 +1423,6 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1332
1423
|
// cell IS the first Tab-in target (matching the Wave-0 probe's "no auto-focus on
|
|
1333
1424
|
// mount"); the consumer drives focus by Tabbing/clicking in, never the component.
|
|
1334
1425
|
|
|
1335
|
-
// ── Windowing: capture the scroll element + construct the row virtualizer (req-1/2 — the
|
|
1336
|
-
// row virtual-core instance ONLY when rows are windowed; the scroll-element capture whenever
|
|
1337
|
-
// EITHER axis is windowed, since both axes observe the SAME .rdt-scroll element — D-03). Built
|
|
1338
|
-
// HERE (post-mount) so getScrollElement resolves the rendered .rdt-scroll div and
|
|
1339
|
-
// getPrePaginationRowModel reads the live table. ENTIRELY inside the isWindowed()/rowsWindowed()
|
|
1340
|
-
// guards: when both axes are off, NO virtual-core runtime code executes (byte-identical-off).
|
|
1341
|
-
// _didMount() registers the scroll-element ResizeObserver and returns the teardown stored for
|
|
1342
|
-
// $onUnmount.
|
|
1343
|
-
// WR-04: NO on-mount auto-focus of the entry cell. Auto-focusing here stole focus on
|
|
1344
|
-
// page load AND was non-deterministic on React/Solid (the entry cell may not be
|
|
1345
|
-
// committed to the DOM yet at the $onMount microtask). The roving tabindex="0" entry
|
|
1346
|
-
// cell IS the first Tab-in target (matching the Wave-0 probe's "no auto-focus on
|
|
1347
|
-
// mount"); the consumer drives focus by Tabbing/clicking in, never the component.
|
|
1348
|
-
|
|
1349
1426
|
// ── Windowing: capture the scroll element + construct the row virtualizer (req-1/2 — the
|
|
1350
1427
|
// row virtual-core instance ONLY when rows are windowed; the scroll-element capture whenever
|
|
1351
1428
|
// EITHER axis is windowed, since both axes observe the SAME .rdt-scroll element — D-03). Built
|
|
@@ -1364,9 +1441,6 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1364
1441
|
// Phase 87 87-04: construct the SECOND, horizontal Virtualizer instance when the COLUMN
|
|
1365
1442
|
// axis is windowed — entirely inside its own colsWindowed() guard, byte-identical-off for
|
|
1366
1443
|
// 'rows'/true/false.
|
|
1367
|
-
// Phase 87 87-04: construct the SECOND, horizontal Virtualizer instance when the COLUMN
|
|
1368
|
-
// axis is windowed — entirely inside its own colsWindowed() guard, byte-identical-off for
|
|
1369
|
-
// 'rows'/true/false.
|
|
1370
1444
|
if (this.colsWindowed()) {
|
|
1371
1445
|
this.colVirtualizer = new Virtualizer(this.columnVirtualizerOptions());
|
|
1372
1446
|
this.colVirtualizerCleanup = this.colVirtualizer._didMount();
|
|
@@ -1389,24 +1463,6 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1389
1463
|
// idiom lowers to a functional React setState update and is safe regardless of ordering, the
|
|
1390
1464
|
// same reasoning virtualizerOptions()'s onChange documents), but collapsing to one bump avoids
|
|
1391
1465
|
// manufacturing the false-positive warning at all rather than accepting it.
|
|
1392
|
-
// FINE-GRAINED FIRST-WINDOW KICK (Solid/Svelte), either axis: the windowed <For>/{#each}
|
|
1393
|
-
// accessor was first evaluated at initial render — while `virtualizer`/`colVirtualizer` were
|
|
1394
|
-
// still null — and (because windowedRows()/windowedColIndices() read $data.windowVer up top)
|
|
1395
|
-
// subscribed to windowVer then returned []/the full set. Both `let`s are non-reactive, so
|
|
1396
|
-
// their assignment above does NOT notify the accessor; we must bump the SIGNAL it subscribed
|
|
1397
|
-
// to. _didMount() computes the first window synchronously but its onChange only fires on
|
|
1398
|
-
// SUBSEQUENT scroll/resize, so without this explicit bump the first window would never paint
|
|
1399
|
-
// on the fine-grained targets. Idempotent + harmless on the coarse targets (they re-render
|
|
1400
|
-
// wholesale anyway). ONE bump here (not one per axis, Rule 1 — see the ROZ138 note below)
|
|
1401
|
-
// covers both: windowedRows()/windowedColIndices() each simply re-derive against their own
|
|
1402
|
-
// now-non-null virtualizer instance off the SAME counter (87-02 checkpoint decision (b): no
|
|
1403
|
-
// separate $data.colWindowVer). Gated on isWindowed() (either axis) rather than two separate
|
|
1404
|
-
// per-axis bumps: a second `$data.windowVer = $data.windowVer + 1` write later in this SAME
|
|
1405
|
-
// $onMount body would dominate-flag ROZ138 (React stale-read) on its own right-hand-side read
|
|
1406
|
-
// of the counter it had just written a few lines above — a false positive (this increment
|
|
1407
|
-
// idiom lowers to a functional React setState update and is safe regardless of ordering, the
|
|
1408
|
-
// same reasoning virtualizerOptions()'s onChange documents), but collapsing to one bump avoids
|
|
1409
|
-
// manufacturing the false-positive warning at all rather than accepting it.
|
|
1410
1466
|
if (this.isWindowed()) {
|
|
1411
1467
|
this._windowVer.value = this._windowVer.value + 1;
|
|
1412
1468
|
}
|
|
@@ -1416,12 +1472,6 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1416
1472
|
// row-specific measurement + warns stay further guarded by rowsWindowed() (byte-identical to
|
|
1417
1473
|
// before this restructure); the column-axis warn (Phase 87 D-07(a)) is guarded by
|
|
1418
1474
|
// colsWindowed() so it can fire ONLY on the 'columns'/'both' path, never on 'rows'/true/false.
|
|
1419
|
-
// After the first window commits (next frame), refine heights + fire the dev-mode warns ONCE.
|
|
1420
|
-
// Entirely inside the isWindowed() guard so the off (neither axis windowed) emitted path adds
|
|
1421
|
-
// NO code and these warns can never fire there (req-1 byte-identical-off preserved). The
|
|
1422
|
-
// row-specific measurement + warns stay further guarded by rowsWindowed() (byte-identical to
|
|
1423
|
-
// before this restructure); the column-axis warn (Phase 87 D-07(a)) is guarded by
|
|
1424
|
-
// colsWindowed() so it can fire ONLY on the 'columns'/'both' path, never on 'rows'/true/false.
|
|
1425
1475
|
if (this.isWindowed()) {
|
|
1426
1476
|
const afterFirstFrame = () => {
|
|
1427
1477
|
if (this.rowsWindowed()) {
|
|
@@ -1488,9 +1538,6 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1488
1538
|
if (typeof requestAnimationFrame === 'function') requestAnimationFrame(() => requestAnimationFrame(afterFirstFrame));else setTimeout(afterFirstFrame, 0);
|
|
1489
1539
|
}
|
|
1490
1540
|
|
|
1491
|
-
// #14: seed the sort/filter announce baseline from the initial (post-mount) state so the LAZY
|
|
1492
|
-
// watch's first fire — a real user sort/filter — compares against the true starting values and
|
|
1493
|
-
// is classified correctly (a null sentinel would misread the first filter change as a sort change).
|
|
1494
1541
|
// #14: seed the sort/filter announce baseline from the initial (post-mount) state so the LAZY
|
|
1495
1542
|
// watch's first fire — a real user sort/filter — compares against the true starting values and
|
|
1496
1543
|
// is classified correctly (a null sentinel would misread the first filter change as a sort change).
|
|
@@ -1500,41 +1547,55 @@ private __rozieCtxProvider_data_table_columns = new ContextProvider(this, { cont
|
|
|
1500
1547
|
}
|
|
1501
1548
|
|
|
1502
1549
|
updated(changedProperties: Map<string, unknown>): void {
|
|
1503
|
-
this.
|
|
1504
|
-
//
|
|
1505
|
-
//
|
|
1506
|
-
|
|
1507
|
-
// the
|
|
1508
|
-
//
|
|
1509
|
-
//
|
|
1510
|
-
//
|
|
1511
|
-
// the
|
|
1512
|
-
|
|
1513
|
-
//
|
|
1514
|
-
//
|
|
1515
|
-
//
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1550
|
+
if (this.__rozieFirstUpdateDone && (changedProperties.has('rowCount') || changedProperties.has('pageCount') || changedProperties.has('expandable') || changedProperties.has('groupable') || changedProperties.has('selectionMode') || changedProperties.has('columns'))) { const __watchVal = untracked(() => [this.sorting, this.globalFilter, this.columnFilters, this.pagination, // Server-side page-count sources (#2): re-feed when the consumer's rowCount/pageCount
|
|
1551
|
+
// changes at runtime (e.g. a server response updates the total) so getPageCount() and the
|
|
1552
|
+
// Next button availability track the new total.
|
|
1553
|
+
this.rowCount, this.pageCount, this.rowSelection, this.expanded, this.expandable, this.grouping, this.groupable, this.columnVisibility, this.columnSizing, this.columnOrder, this.columnPinning, this.selectionMode, (this.data || []).length, // Phase 51 req-4: key on the data REFERENCE (both sinks) so a committed edit re-feeds
|
|
1554
|
+
// even when the fresh array is the SAME length (a single-cell edit replaces one row
|
|
1555
|
+
// object → new array ref, identical length → the .length key alone would miss it). The
|
|
1556
|
+
// controlled path observes $props.data; the uncontrolled path observes $data.dataDefault.
|
|
1557
|
+
// writeData is echo-guarded (programmatic) and reFeed writes neither sink, so no loop.
|
|
1558
|
+
this.data, this._dataDefault.value, // Column CONFIG prop (the `:columns` array form) — the sibling column source to
|
|
1559
|
+
// $data.colReg (the `<Column>` children). Watch it so a runtime `:columns` swap re-feeds:
|
|
1560
|
+
// columnDefs()/tableColumns() build the UNION of both, and reFeed re-passes columns.
|
|
1561
|
+
// (Consumers memoize the array as with $props.data/$props.sorting; the uncontrolled
|
|
1562
|
+
// <Column>-children path leaves $props.columns undefined — a stable no-op getter.)
|
|
1563
|
+
this.columns, this._colReg.value]); if (!Object.is(__watchVal, this.__rozieWatchPrev_1)) { this.__rozieWatchPrev_1 = __watchVal; untracked(() => (() => {
|
|
1564
|
+
// Seed BEFORE the re-feed so the pinning this call may write is part of the state object
|
|
1565
|
+
// table-core receives on this same tick (rather than landing a frame late and re-ordering
|
|
1566
|
+
// getVisibleCells() a render after the columns appear). One-shot and self-latching — see
|
|
1567
|
+
// seedColumnPinning() in stateAssembly.rzts. This is the `<Column>`-children entry point:
|
|
1568
|
+
// those register during mount, so the $onMount call below can find zero columns.
|
|
1569
|
+
this.seedColumnPinning();
|
|
1570
|
+
this.reFeed();
|
|
1571
|
+
this.maybeClearHistoryOnExternalSwap();
|
|
1572
|
+
})()); } }
|
|
1573
|
+
this.__rozieFirstUpdateDone = true;
|
|
1574
|
+
|
|
1575
|
+
(() => {
|
|
1576
|
+
this.maybeClearHistoryOnExternalSwap();
|
|
1577
|
+
// visible-range-change backstop (quick 260925-dtl part 2): a re-render from new data can move
|
|
1578
|
+
// the rendered window WITHOUT a window-version bump (measured on React: filling placeholders
|
|
1579
|
+
// shifted the window by two rows and nothing was reported). Deduped, so a render that leaves
|
|
1580
|
+
// the window where it was emits nothing.
|
|
1581
|
+
this.emitVisibleRangeIfChanged();
|
|
1582
|
+
// A-02: the post-render hook is the one place that observes EVERY column-width change on all
|
|
1583
|
+
// six targets — an interactive resize writes `columnSizing` through table-core under
|
|
1584
|
+
// `columnResizeMode: 'onChange'` and never reaches the coarse re-feed watch (which keys on
|
|
1585
|
+
// `$props.columnSizing`, undefined on the uncontrolled path). Self-guarded on the width
|
|
1586
|
+
// signature, so a tick that changed no width costs one loop over the leaf columns.
|
|
1587
|
+
this.remeasureColumnSizes();
|
|
1588
|
+
if (!this.table) return;
|
|
1589
|
+
// Phase 51 req-4: track currentData() (the bound prop OR the uncontrolled
|
|
1590
|
+
// $data.dataDefault) so a committed edit re-feeds on Lit whether or not the two-way
|
|
1591
|
+
// `data` model is bound. Compare by reference AND length so a same-length single-cell edit (fresh array,
|
|
1592
|
+
// identical length) still re-feeds.
|
|
1593
|
+
const d = this.currentData() || [];
|
|
1594
|
+
if (d === this.lastData && d.length === this.lastDataLen) return;
|
|
1595
|
+
this.lastData = d;
|
|
1596
|
+
this.lastDataLen = d.length;
|
|
1597
|
+
this.reFeed();
|
|
1598
|
+
})();
|
|
1538
1599
|
}
|
|
1539
1600
|
|
|
1540
1601
|
disconnectedCallback(): void {
|
|
@@ -2458,7 +2519,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2458
2519
|
this.programmatic++;
|
|
2459
2520
|
this._sortingDefault.value = next; // fresh array only (never in-place)
|
|
2460
2521
|
this._sortingControllable.write(next); // two-way emit if bound (no-op-diff if not)
|
|
2461
|
-
this.dispatchEvent(new CustomEvent("sort-change", {
|
|
2522
|
+
this.dispatchEvent(new CustomEvent<SortingState>("sort-change", {
|
|
2462
2523
|
detail: next,
|
|
2463
2524
|
bubbles: true,
|
|
2464
2525
|
composed: true
|
|
@@ -2488,7 +2549,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2488
2549
|
// → duplicate-identifier TS2300 (the model-prop==emit-name collision class). Every
|
|
2489
2550
|
// sibling slice avoids this by stemming the event off a DISTINCT name (sorting→
|
|
2490
2551
|
// sort-change, rowSelection→selection-change); `expanded`→`expand-change` follows suit.
|
|
2491
|
-
this.dispatchEvent(new CustomEvent("expand-change", {
|
|
2552
|
+
this.dispatchEvent(new CustomEvent<ExpandedState>("expand-change", {
|
|
2492
2553
|
detail: next,
|
|
2493
2554
|
bubbles: true,
|
|
2494
2555
|
composed: true
|
|
@@ -2512,7 +2573,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2512
2573
|
this.programmatic++;
|
|
2513
2574
|
this._groupingDefault.value = next; // fresh ordered array only (never in-place push)
|
|
2514
2575
|
this._groupingControllable.write(next); // two-way emit if bound (no-op-diff if not)
|
|
2515
|
-
this.dispatchEvent(new CustomEvent("group-change", {
|
|
2576
|
+
this.dispatchEvent(new CustomEvent<GroupingState>("group-change", {
|
|
2516
2577
|
detail: next,
|
|
2517
2578
|
bubbles: true,
|
|
2518
2579
|
composed: true
|
|
@@ -2528,7 +2589,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2528
2589
|
this.programmatic++;
|
|
2529
2590
|
this._globalFilterDefault.value = next;
|
|
2530
2591
|
this._globalFilterControllable.write(next);
|
|
2531
|
-
this.dispatchEvent(new CustomEvent("filter-change", {
|
|
2592
|
+
this.dispatchEvent(new CustomEvent<DataTableFilterChangePayload>("filter-change", {
|
|
2532
2593
|
detail: {
|
|
2533
2594
|
globalFilter: next
|
|
2534
2595
|
},
|
|
@@ -2547,7 +2608,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2547
2608
|
this.programmatic++;
|
|
2548
2609
|
this._columnFiltersDefault.value = next;
|
|
2549
2610
|
this._columnFiltersControllable.write(next);
|
|
2550
|
-
this.dispatchEvent(new CustomEvent("filter-change", {
|
|
2611
|
+
this.dispatchEvent(new CustomEvent<DataTableFilterChangePayload>("filter-change", {
|
|
2551
2612
|
detail: {
|
|
2552
2613
|
columnFilters: next
|
|
2553
2614
|
},
|
|
@@ -2564,7 +2625,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2564
2625
|
this.programmatic++;
|
|
2565
2626
|
this._paginationDefault.value = next;
|
|
2566
2627
|
this._paginationControllable.write(next);
|
|
2567
|
-
this.dispatchEvent(new CustomEvent("page-change", {
|
|
2628
|
+
this.dispatchEvent(new CustomEvent<PaginationState>("page-change", {
|
|
2568
2629
|
detail: next,
|
|
2569
2630
|
bubbles: true,
|
|
2570
2631
|
composed: true
|
|
@@ -2580,7 +2641,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2580
2641
|
this.programmatic++;
|
|
2581
2642
|
this._rowSelectionDefault.value = next;
|
|
2582
2643
|
this._rowSelectionControllable.write(next);
|
|
2583
|
-
this.dispatchEvent(new CustomEvent("selection-change", {
|
|
2644
|
+
this.dispatchEvent(new CustomEvent<RowSelectionState>("selection-change", {
|
|
2584
2645
|
detail: next,
|
|
2585
2646
|
bubbles: true,
|
|
2586
2647
|
composed: true
|
|
@@ -2596,7 +2657,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2596
2657
|
this.programmatic++;
|
|
2597
2658
|
this._columnVisibilityDefault.value = next;
|
|
2598
2659
|
this._columnVisibilityControllable.write(next);
|
|
2599
|
-
this.dispatchEvent(new CustomEvent("visibility-change", {
|
|
2660
|
+
this.dispatchEvent(new CustomEvent<VisibilityState>("visibility-change", {
|
|
2600
2661
|
detail: next,
|
|
2601
2662
|
bubbles: true,
|
|
2602
2663
|
composed: true
|
|
@@ -2612,7 +2673,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2612
2673
|
this.programmatic++;
|
|
2613
2674
|
this._columnSizingDefault.value = next;
|
|
2614
2675
|
this._columnSizingControllable.write(next);
|
|
2615
|
-
this.dispatchEvent(new CustomEvent("resize-change", {
|
|
2676
|
+
this.dispatchEvent(new CustomEvent<ColumnSizingState>("resize-change", {
|
|
2616
2677
|
detail: next,
|
|
2617
2678
|
bubbles: true,
|
|
2618
2679
|
composed: true
|
|
@@ -2628,7 +2689,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2628
2689
|
this.programmatic++;
|
|
2629
2690
|
this._columnOrderDefault.value = next;
|
|
2630
2691
|
this._columnOrderControllable.write(next);
|
|
2631
|
-
this.dispatchEvent(new CustomEvent("reorder-change", {
|
|
2692
|
+
this.dispatchEvent(new CustomEvent<ColumnOrderState>("reorder-change", {
|
|
2632
2693
|
detail: next,
|
|
2633
2694
|
bubbles: true,
|
|
2634
2695
|
composed: true
|
|
@@ -2655,7 +2716,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2655
2716
|
this.programmatic++;
|
|
2656
2717
|
this._columnPinningDefault.value = clean;
|
|
2657
2718
|
this._columnPinningControllable.write(clean);
|
|
2658
|
-
this.dispatchEvent(new CustomEvent("pin-change", {
|
|
2719
|
+
this.dispatchEvent(new CustomEvent<ColumnPinningState>("pin-change", {
|
|
2659
2720
|
detail: clean,
|
|
2660
2721
|
bubbles: true,
|
|
2661
2722
|
composed: true
|
|
@@ -2767,13 +2828,13 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2767
2828
|
this.redoStack = [];
|
|
2768
2829
|
};
|
|
2769
2830
|
|
|
2770
|
-
canUndo = () => this.undoStack.length > 0;
|
|
2831
|
+
canUndo: () => boolean = () => this.undoStack.length > 0;
|
|
2771
2832
|
|
|
2772
|
-
canRedo = () => this.redoStack.length > 0;
|
|
2833
|
+
canRedo: () => boolean = () => this.redoStack.length > 0;
|
|
2773
2834
|
|
|
2774
2835
|
// Both stacks empty — the external-swap latch (DataTable.rozie reFeed) and the
|
|
2775
2836
|
// clearHistory() $expose verb share this single implementation.
|
|
2776
|
-
clearHistory = () => {
|
|
2837
|
+
clearHistory: () => void = () => {
|
|
2777
2838
|
this.undoStack = [];
|
|
2778
2839
|
this.redoStack = [];
|
|
2779
2840
|
};
|
|
@@ -2783,7 +2844,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2783
2844
|
// per call per the design — NOT edge-gated there; only the writeData-triggered recording path
|
|
2784
2845
|
// below is edge-gated, since a routine sequence of edits would otherwise spam the event).
|
|
2785
2846
|
emitHistoryChange = () => {
|
|
2786
|
-
this.dispatchEvent(new CustomEvent("history-change", {
|
|
2847
|
+
this.dispatchEvent(new CustomEvent<DataTableHistoryChangePayload>("history-change", {
|
|
2787
2848
|
detail: {
|
|
2788
2849
|
canUndo: this.canUndo(),
|
|
2789
2850
|
canRedo: this.canRedo()
|
|
@@ -2809,7 +2870,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2809
2870
|
// re-capture this replay (which would corrupt the stack). Replaying through writeData
|
|
2810
2871
|
// (rather than writing $data/$model directly) is deliberate: the two-way $model.data
|
|
2811
2872
|
// writeback, the re-feed $watch, and the echo guard all keep working with zero new code.
|
|
2812
|
-
undo = () => {
|
|
2873
|
+
undo: () => void = () => {
|
|
2813
2874
|
if (!this.canUndo()) return;
|
|
2814
2875
|
const prev = this.undoStack.pop();
|
|
2815
2876
|
this.redoStack.push(this.currentData());
|
|
@@ -2821,7 +2882,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
2821
2882
|
|
|
2822
2883
|
// redo(): symmetric — pop the redo stack, push the CURRENT data back onto the undo stack,
|
|
2823
2884
|
// replay through the same guarded writeData seam.
|
|
2824
|
-
redo = () => {
|
|
2885
|
+
redo: () => void = () => {
|
|
2825
2886
|
if (!this.canRedo()) return;
|
|
2826
2887
|
const next = this.redoStack.pop();
|
|
2827
2888
|
this.undoStack.push(this.currentData());
|
|
@@ -3410,7 +3471,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
3410
3471
|
if (start === this.lastRangeStart && end === this.lastRangeEnd) return;
|
|
3411
3472
|
this.lastRangeStart = start;
|
|
3412
3473
|
this.lastRangeEnd = end;
|
|
3413
|
-
this.dispatchEvent(new CustomEvent("visible-range-change", {
|
|
3474
|
+
this.dispatchEvent(new CustomEvent<DataTableVisibleRangeChangePayload>("visible-range-change", {
|
|
3414
3475
|
detail: {
|
|
3415
3476
|
start,
|
|
3416
3477
|
end
|
|
@@ -3447,7 +3508,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
3447
3508
|
// into the internal `.rdt-scroll` class selector. Returns null when nothing is windowed:
|
|
3448
3509
|
// gridScrollEl is only ever assigned inside the isWindowed() guard, so no extra gate is
|
|
3449
3510
|
// needed here beyond that natural null.
|
|
3450
|
-
getScrollElement = (): any => this.gridScrollEl;
|
|
3511
|
+
getScrollElement: () => HTMLElement | null = (): any => this.gridScrollEl;
|
|
3451
3512
|
|
|
3452
3513
|
// ══ Generic vertical windowing math (Phase 64, D-04) — the target-agnostic virtual-core bridge ══
|
|
3453
3514
|
// Lifted verbatim from the DataTable virtualization.rzts (the Phase 53/63 B13 baseline). This partial
|
|
@@ -5024,39 +5085,39 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
5024
5085
|
// is dropped on ALL SIX targets, only the by-reference key survives → a
|
|
5025
5086
|
// runtime ReferenceError at `defineExpose`/`useImperativeHandle`). Sorting verbs +
|
|
5026
5087
|
// a fresh column-def readout, selection, pagination, and column-management verbs.
|
|
5027
|
-
sortColumn = (colId: any, desc: any) => {
|
|
5088
|
+
sortColumn: (colId: string, desc?: boolean) => void = (colId: any, desc: any) => {
|
|
5028
5089
|
if (this.table) this.table.getColumn(colId) && this.table.getColumn(colId).toggleSorting(desc, false);
|
|
5029
5090
|
};
|
|
5030
5091
|
|
|
5031
|
-
clearSorting = () => {
|
|
5092
|
+
clearSorting: () => void = () => {
|
|
5032
5093
|
if (this.table) this.table.resetSorting(true);
|
|
5033
5094
|
};
|
|
5034
5095
|
|
|
5035
|
-
getColumnDefs = () => this.columnDefs();
|
|
5096
|
+
getColumnDefs: () => ColumnDef<any, any>[] = () => this.columnDefs();
|
|
5036
5097
|
|
|
5037
5098
|
// selection verbs (req-7) — drive table-core so the onRowSelectionChange funnel
|
|
5038
5099
|
// emits the fresh state + selection-change.
|
|
5039
|
-
toggleAllRows = (value: any) => {
|
|
5100
|
+
toggleAllRows: (value?: boolean) => void = (value: any) => {
|
|
5040
5101
|
if (this.table) this.table.toggleAllRowsSelected(value);
|
|
5041
5102
|
};
|
|
5042
5103
|
|
|
5043
|
-
clearSelection = () => {
|
|
5104
|
+
clearSelection: () => void = () => {
|
|
5044
5105
|
if (this.table) this.table.resetRowSelection(true);
|
|
5045
5106
|
};
|
|
5046
5107
|
|
|
5047
|
-
getSelectedRows = () => this.table ? this.table.getSelectedRowModel().rows.map((r: any) => r.original) : [];
|
|
5108
|
+
getSelectedRows: () => any[] = () => this.table ? this.table.getSelectedRowModel().rows.map((r: any) => r.original) : [];
|
|
5048
5109
|
|
|
5049
5110
|
// pagination verbs.
|
|
5050
|
-
setPage = (idx: any) => {
|
|
5111
|
+
setPage: (idx: number) => void = (idx: any) => {
|
|
5051
5112
|
if (this.table) this.table.setPageIndex(idx);
|
|
5052
5113
|
};
|
|
5053
5114
|
|
|
5054
|
-
setRowsPerPage = (size: any) => {
|
|
5115
|
+
setRowsPerPage: (size: number) => void = (size: any) => {
|
|
5055
5116
|
if (this.table) this.table.setPageSize(size);
|
|
5056
5117
|
};
|
|
5057
5118
|
|
|
5058
5119
|
// column-management verbs (req-8/9/10/11) — drive table-core so the funnels fire.
|
|
5059
|
-
toggleColumnVisibility = (colId: any) => {
|
|
5120
|
+
toggleColumnVisibility: (colId: string) => void = (colId: any) => {
|
|
5060
5121
|
if (this.table) {
|
|
5061
5122
|
const c = this.table.getColumn(colId);
|
|
5062
5123
|
if (c && c.toggleVisibility) c.toggleVisibility();
|
|
@@ -5070,17 +5131,17 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
5070
5131
|
// off-limits). So the public verb is `applyColumnOrder` (semantically: apply a
|
|
5071
5132
|
// new column order). The other set* verbs (setPage/setRowsPerPage) do NOT match
|
|
5072
5133
|
// any model prop's setter, so they are collision-free.
|
|
5073
|
-
applyColumnOrder = (order: any) => {
|
|
5134
|
+
applyColumnOrder: (order: string[]) => void = (order: any) => {
|
|
5074
5135
|
if (this.table) this.table.setColumnOrder(order);
|
|
5075
5136
|
};
|
|
5076
5137
|
|
|
5077
|
-
resetColumnSizing = () => {
|
|
5138
|
+
resetColumnSizing: () => void = () => {
|
|
5078
5139
|
if (this.table) this.table.resetColumnSizing(true);
|
|
5079
5140
|
};
|
|
5080
5141
|
|
|
5081
5142
|
// pinColumn: the verb that drives column.pin; distinct from the template handler
|
|
5082
5143
|
// onPinColumn (no shadow — the deferred-items finding #4 collision check).
|
|
5083
|
-
pinColumn = (colId: any, side: any) => {
|
|
5144
|
+
pinColumn: (colId: string, side: 'left' | 'right' | false) => void = (colId: any, side: any) => {
|
|
5084
5145
|
if (this.table) {
|
|
5085
5146
|
const c = this.table.getColumn(colId);
|
|
5086
5147
|
if (c && c.pin) c.pin(side);
|
|
@@ -5094,7 +5155,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
5094
5155
|
// there is no page (windowing replaces pagination) → the windowed model IS the full model, so it
|
|
5095
5156
|
// returns the absolute index unchanged. Collision-safe: no *-change event, prop, React auto-setter,
|
|
5096
5157
|
// or inherited Lit DOM method named getRowIndexRelativeToPage (ROZ121/124/137 clear).
|
|
5097
|
-
getRowIndexRelativeToPage = (absRow: any) => {
|
|
5158
|
+
getRowIndexRelativeToPage: (absRow?: number) => number = (absRow: any) => {
|
|
5098
5159
|
const abs = absRow == null ? this.toAbsRow(this._activeRow.value) : Math.trunc(Number(absRow)) || 0;
|
|
5099
5160
|
if (this.rowsWindowed()) return abs;
|
|
5100
5161
|
return abs - this.pageRowOffset();
|
|
@@ -5106,7 +5167,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
5106
5167
|
// active cell, so it cuts the current selection even when the call arrives off a control that
|
|
5107
5168
|
// moved DOM focus off the grid. Collision-safe: no `cut` event / model prop / React auto-setter /
|
|
5108
5169
|
// inherited Lit DOM method named `cut` (ROZ121/124/137 clear) — `cut` is not on HTMLElement.
|
|
5109
|
-
cut = () => this.cutRange();
|
|
5170
|
+
cut: () => void = () => this.cutRange();
|
|
5110
5171
|
|
|
5111
5172
|
// 260709-8ct (grid-wide undo/redo): NO pass-through wrapper lands here for
|
|
5112
5173
|
// undo/redo/canUndo/canRedo/clearHistory. Unlike `cut` above (which delegates to a
|
|
@@ -5174,9 +5235,6 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
5174
5235
|
// page-relative active row → absolute (display-order) index.
|
|
5175
5236
|
toAbsRow = (localRow: any) => localRow + this.pageRowOffset();
|
|
5176
5237
|
|
|
5177
|
-
// A body row's ABSOLUTE display-order index = its page-relative index + the page offset. Drives
|
|
5178
|
-
// aria-rowindex on the non-virtual paginated body (B27); the virtual path uses wr.vi.index
|
|
5179
|
-
// directly (already absolute). Reactive via rowIndexOf's tick().
|
|
5180
5238
|
// Total filtered+sorted PRE-pagination row count — the clamp bound for an absolute focusCell.
|
|
5181
5239
|
// In virtual mode $data.rows IS the full pre-pagination model (bodyRowCount suffices); in the
|
|
5182
5240
|
// non-virtual paginated body $data.rows is only the page slice, so read the live model.
|
|
@@ -6117,7 +6175,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
6117
6175
|
// SAME language): a header cell has no body-row index, so emit rowIndex:null + isHeader:true
|
|
6118
6176
|
// rather than a bogus toAbsRow(nextRow) — which would compute a real body-row absolute index
|
|
6119
6177
|
// for a HEADER move, misleading a consumer into thinking that body row is the active cell.
|
|
6120
|
-
this.dispatchEvent(new CustomEvent("activecell-change", {
|
|
6178
|
+
this.dispatchEvent(new CustomEvent<DataTableActiveCellChangePayload>("activecell-change", {
|
|
6121
6179
|
detail: nextIsHeader ? {
|
|
6122
6180
|
rowIndex: null,
|
|
6123
6181
|
colIndex: nextCol,
|
|
@@ -6327,7 +6385,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
6327
6385
|
activateRowAt = (index: any, trigger: any) => {
|
|
6328
6386
|
const row = (this._rows.value || [])[index];
|
|
6329
6387
|
if (!row || this.rowIsGrouped(row) || this.rowIsLazyPlaceholder(row)) return;
|
|
6330
|
-
this.dispatchEvent(new CustomEvent("row-activate", {
|
|
6388
|
+
this.dispatchEvent(new CustomEvent<DataTableRowActivatePayload>("row-activate", {
|
|
6331
6389
|
detail: {
|
|
6332
6390
|
row: row.original,
|
|
6333
6391
|
index,
|
|
@@ -6734,7 +6792,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
6734
6792
|
// { rowIndex, colIndex } pair (or null when no range). T-49-02: positions only, no row
|
|
6735
6793
|
// data, no DOM node. Used by the getSelectedRange $expose verb AND every range-change emit
|
|
6736
6794
|
// (the single payload source) AND copyRange/fillRange (the rectangle they operate over).
|
|
6737
|
-
getSelectedRange = () => {
|
|
6795
|
+
getSelectedRange: () => DataTableRange = () => {
|
|
6738
6796
|
// B8: clamp the corners to the CURRENT bounds ON READ so the verb (and the range-change emit
|
|
6739
6797
|
// payload) never reports a corner past a shrunken model — React-stale-safe (the eager
|
|
6740
6798
|
// refreshRowModel clamp is async-defeated on React; this read-time clamp is the guarantee).
|
|
@@ -6799,7 +6857,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
6799
6857
|
|
|
6800
6858
|
emitRangeChange = (anchor: any, focus: any) => {
|
|
6801
6859
|
this._rangeAnnounce.value = this.rangeSummary(anchor, focus);
|
|
6802
|
-
this.dispatchEvent(new CustomEvent("range-change", {
|
|
6860
|
+
this.dispatchEvent(new CustomEvent<DataTableRangeChangePayload>("range-change", {
|
|
6803
6861
|
detail: {
|
|
6804
6862
|
anchor,
|
|
6805
6863
|
focus
|
|
@@ -7242,7 +7300,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
7242
7300
|
// is the first-party code that actually escapes.
|
|
7243
7301
|
for (let i = 0; i < committed.length; i++) {
|
|
7244
7302
|
try {
|
|
7245
|
-
this.dispatchEvent(new CustomEvent("cell-edit-commit", {
|
|
7303
|
+
this.dispatchEvent(new CustomEvent<DataTableCellEditCommitPayload>("cell-edit-commit", {
|
|
7246
7304
|
detail: committed[i],
|
|
7247
7305
|
bubbles: true,
|
|
7248
7306
|
composed: true
|
|
@@ -8241,7 +8299,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
8241
8299
|
const next = replaceRowValue(this.currentData(), srcIndex, field, newValue);
|
|
8242
8300
|
this.writeData(next);
|
|
8243
8301
|
// Exactly one emit per commit, from this single call site (writeData does NOT emit).
|
|
8244
|
-
this.dispatchEvent(new CustomEvent("cell-edit-commit", {
|
|
8302
|
+
this.dispatchEvent(new CustomEvent<DataTableCellEditCommitPayload>("cell-edit-commit", {
|
|
8245
8303
|
detail: {
|
|
8246
8304
|
rowId,
|
|
8247
8305
|
columnId: colId,
|
|
@@ -8326,7 +8384,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
8326
8384
|
this.writeData(replaceRowValue(this.currentData(), srcIndex, field, newValue));
|
|
8327
8385
|
// Exactly one emit per toggle, from this single call site (writeData does NOT emit) —
|
|
8328
8386
|
// mirrors commitEdit's D-07 single-emit discipline.
|
|
8329
|
-
this.dispatchEvent(new CustomEvent("cell-edit-commit", {
|
|
8387
|
+
this.dispatchEvent(new CustomEvent<DataTableCellEditCommitPayload>("cell-edit-commit", {
|
|
8330
8388
|
detail: {
|
|
8331
8389
|
rowId,
|
|
8332
8390
|
columnId: colId,
|
|
@@ -8562,7 +8620,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
8562
8620
|
const next = replaceRowValues(this.currentData(), srcIndex, fieldValues);
|
|
8563
8621
|
this.writeData(next);
|
|
8564
8622
|
// EXACTLY ONE emit per row commit, from THIS single call site (React multi-emit dedup, D-07).
|
|
8565
|
-
this.dispatchEvent(new CustomEvent("row-edit-commit", {
|
|
8623
|
+
this.dispatchEvent(new CustomEvent<DataTableRowEditCommitPayload>("row-edit-commit", {
|
|
8566
8624
|
detail: {
|
|
8567
8625
|
rowId,
|
|
8568
8626
|
changes
|
|
@@ -9107,7 +9165,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9107
9165
|
// editCell(rowIndex, colIndex) — programmatic edit-entry ($expose, req-3). Coerces +
|
|
9108
9166
|
// clamps indices, moves the active cell, and opens the editor (no-op on a non-editable
|
|
9109
9167
|
// cell). Collision-clean (RESEARCH name-check): not a verb/event/prop/ROZ137 member.
|
|
9110
|
-
editCell = (rowIndex: any, colIndex: any) => {
|
|
9168
|
+
editCell: (rowIndex: number, colIndex: number) => void = (rowIndex: any, colIndex: any) => {
|
|
9111
9169
|
const lastRow = this.bodyRowCount() - 1;
|
|
9112
9170
|
const maxRow = lastRow < 0 ? 0 : lastRow;
|
|
9113
9171
|
const maxCol = this.visibleColCount() - 1;
|
|
@@ -9126,7 +9184,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9126
9184
|
// edit (editRow()/Shift+F2) drives editingRowIndex and leaves editingRow at -1, so the
|
|
9127
9185
|
// single-cell commitEdit guard (editingRow >= 0) is false during a row edit — route to
|
|
9128
9186
|
// commitRow() first so a programmatic commit of a row editor is not a silent no-op.
|
|
9129
|
-
commitEditing = () => {
|
|
9187
|
+
commitEditing: () => void = () => {
|
|
9130
9188
|
if (this.inRowEdit()) {
|
|
9131
9189
|
this.commitRow();
|
|
9132
9190
|
return;
|
|
@@ -9140,7 +9198,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9140
9198
|
// name-check): `editRow` is not in the 15 existing verbs, not a prop, not a *-change/commit
|
|
9141
9199
|
// event, not a Lit ROZ137-reserved host member. Moves the active cell to the row first so the
|
|
9142
9200
|
// commit/cancel focus-return lands in the right row.
|
|
9143
|
-
editRow = (rowIndex: any) => {
|
|
9201
|
+
editRow: (rowIndex: number) => void = (rowIndex: any) => {
|
|
9144
9202
|
const lastRow = this.bodyRowCount() - 1;
|
|
9145
9203
|
const maxRow = lastRow < 0 ? 0 : lastRow;
|
|
9146
9204
|
const r = clamp(Math.trunc(Number(rowIndex)) || 0, 0, maxRow);
|
|
@@ -9203,7 +9261,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9203
9261
|
// data-* selector is built (T-49-01/T-63-06-01: never interpolate a raw consumer string; clamp
|
|
9204
9262
|
// the abs index into getPrePaginationRowModel bounds). The activecell-change payload + getActiveCell
|
|
9205
9263
|
// speak the SAME absolute language (toAbsRow).
|
|
9206
|
-
focusCell = (rowIndex: any, colIndex: any) => {
|
|
9264
|
+
focusCell: (rowIndex: number, colIndex: number) => void = (rowIndex: any, colIndex: any) => {
|
|
9207
9265
|
// B16: isGrid()-gate the verb. In 'table' mode there is no roving active cell, so focusCell
|
|
9208
9266
|
// is a NO-OP (never an activecell-change emit) — the keyboard path (onGridKeyDown) is already
|
|
9209
9267
|
// isGrid-gated; the exposed verb must mirror that so a consumer's focusCell on a table-mode
|
|
@@ -9267,7 +9325,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9267
9325
|
}
|
|
9268
9326
|
}
|
|
9269
9327
|
if (absRow !== prevAbs || c !== prevCol || prevIsHeader) {
|
|
9270
|
-
this.dispatchEvent(new CustomEvent("activecell-change", {
|
|
9328
|
+
this.dispatchEvent(new CustomEvent<DataTableActiveCellChangePayload>("activecell-change", {
|
|
9271
9329
|
detail: {
|
|
9272
9330
|
rowIndex: absRow,
|
|
9273
9331
|
colIndex: c
|
|
@@ -9287,7 +9345,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9287
9345
|
// is unchanged for the body case).
|
|
9288
9346
|
// C1: a body cell returns the ABSOLUTE display-order rowIndex (toAbsRow) — matching focusCell's
|
|
9289
9347
|
// addressing + the activecell-change payload — in BOTH paginated and virtual modes.
|
|
9290
|
-
getActiveCell = () => this._activeIsHeader.value ? {
|
|
9348
|
+
getActiveCell: () => DataTableActiveCell = () => this._activeIsHeader.value ? {
|
|
9291
9349
|
rowIndex: null,
|
|
9292
9350
|
colIndex: this._activeColIndex.value,
|
|
9293
9351
|
isHeader: true
|
|
@@ -9301,7 +9359,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9301
9359
|
// exit interaction mode; the next Tab-in re-enters at the entry cell (D-01). Does NOT emit
|
|
9302
9360
|
// (no move to a new addressable cell — a reset, not a navigation). B16: isGrid()-gated — a
|
|
9303
9361
|
// table-mode instance has no roving active cell, so the verb is a no-op there.
|
|
9304
|
-
clearActiveCell = () => {
|
|
9362
|
+
clearActiveCell: () => void = () => {
|
|
9305
9363
|
if (!this.isGrid()) return;
|
|
9306
9364
|
this._activeIsHeader.value = false;
|
|
9307
9365
|
this._activeInControl.value = false;
|
|
@@ -9318,7 +9376,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9318
9376
|
// toggleRowExpanded(rowId) — toggle ONE row's expanded state, addressed by the consumer's
|
|
9319
9377
|
// row id (the data `id` field) OR the table-core row id. Scans the core flat-row set (all
|
|
9320
9378
|
// rows regardless of current expansion) so a collapsed parent is still resolvable.
|
|
9321
|
-
toggleRowExpanded = (rowId: any) => {
|
|
9379
|
+
toggleRowExpanded: (rowId: string | number) => void = (rowId: any) => {
|
|
9322
9380
|
if (!this.table) return;
|
|
9323
9381
|
const target = String(rowId);
|
|
9324
9382
|
const flat = this.table.getCoreRowModel().flatRows;
|
|
@@ -9332,14 +9390,14 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9332
9390
|
|
|
9333
9391
|
// expandAll() — open every expandable row (table-core sets ExpandedState to the `true`
|
|
9334
9392
|
// literal under the hood → Pitfall 2: writeExpanded passes it through verbatim).
|
|
9335
|
-
expandAll = () => {
|
|
9393
|
+
expandAll: () => void = () => {
|
|
9336
9394
|
if (!this.table) return;
|
|
9337
9395
|
this.table.toggleAllRowsExpanded(true);
|
|
9338
9396
|
};
|
|
9339
9397
|
|
|
9340
9398
|
// collapseAll() — reset to a blank expanded state ({}). resetExpanded(true) forces the
|
|
9341
9399
|
// blank reset (NOT the initialState) and fires onExpandedChange → one expanded-change.
|
|
9342
|
-
collapseAll = () => {
|
|
9400
|
+
collapseAll: () => void = () => {
|
|
9343
9401
|
if (!this.table) return;
|
|
9344
9402
|
this.table.resetExpanded(true);
|
|
9345
9403
|
};
|
|
@@ -9347,7 +9405,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9347
9405
|
// getExpandedRows() — return the original row data for every currently-expanded row
|
|
9348
9406
|
// (read-verb twin of expanded-change). Integers/data only — scans the core flat rows and
|
|
9349
9407
|
// filters by getIsExpanded(). Empty when nothing is expanded.
|
|
9350
|
-
getExpandedRows = () => {
|
|
9408
|
+
getExpandedRows: () => any[] = () => {
|
|
9351
9409
|
if (!this.table) return [];
|
|
9352
9410
|
const out = [];
|
|
9353
9411
|
const flat = this.table.getCoreRowModel().flatRows;
|
|
@@ -9362,11 +9420,11 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9362
9420
|
// setColumnOrder→applyColumnOrder) + clearGrouping. Both drive @tanstack/table-core's
|
|
9363
9421
|
// table.setGrouping so the onGroupingChange → writeGrouping funnel fires one group-change with
|
|
9364
9422
|
// the fresh ordered key list. Also handed to the headless #groupBar slot as apply/clear helpers.
|
|
9365
|
-
applyGrouping = (cols: any) => {
|
|
9423
|
+
applyGrouping: (cols: string[]) => void = (cols: any) => {
|
|
9366
9424
|
if (this.table) this.table.setGrouping(cols);
|
|
9367
9425
|
};
|
|
9368
9426
|
|
|
9369
|
-
clearGrouping = () => {
|
|
9427
|
+
clearGrouping: () => void = () => {
|
|
9370
9428
|
if (this.table) this.table.setGrouping([]);
|
|
9371
9429
|
};
|
|
9372
9430
|
|
|
@@ -9384,7 +9442,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9384
9442
|
// column/table. NAMED to match the $expose verb exactly (the ExposedMethod.name shorthand
|
|
9385
9443
|
// contract: an exposed verb lowers to `{ getFacetedUniqueValues }`, which must resolve to THIS
|
|
9386
9444
|
// helper — the table-core factory was aliased to makeFacetedUniqueValues to free this name).
|
|
9387
|
-
getFacetedUniqueValues = (colId: any) => {
|
|
9445
|
+
getFacetedUniqueValues: (colId: string) => any[] = (colId: any) => {
|
|
9388
9446
|
if (this.tick() < 0 || !this.table) return [];
|
|
9389
9447
|
const col = this.table.getColumn(colId);
|
|
9390
9448
|
if (!col || !col.getFacetedUniqueValues) return [];
|
|
@@ -9394,7 +9452,7 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9394
9452
|
|
|
9395
9453
|
// getFacetedMinMaxValues: the column's [min, max] numeric range, or null when unavailable.
|
|
9396
9454
|
// Named to match the $expose verb (same shorthand contract as getFacetedUniqueValues above).
|
|
9397
|
-
getFacetedMinMaxValues = (colId: any) => {
|
|
9455
|
+
getFacetedMinMaxValues: (colId: string) => [number, number] | null = (colId: any) => {
|
|
9398
9456
|
if (this.tick() < 0 || !this.table) return null;
|
|
9399
9457
|
const col = this.table.getColumn(colId);
|
|
9400
9458
|
if (!col || !col.getFacetedMinMaxValues) return null;
|
|
@@ -9425,4 +9483,15 @@ ${this.groupable ? html`<div class="rdt-group-bar-host" data-rozie-s-d5dcab4c>
|
|
|
9425
9483
|
set columnOrder(v: any[]) { this._columnOrderControllable.notifyPropertyWrite(v); }
|
|
9426
9484
|
get columnPinning(): any { return this._columnPinningControllable.read(); }
|
|
9427
9485
|
set columnPinning(v: any) { this._columnPinningControllable.notifyPropertyWrite(v); }
|
|
9486
|
+
|
|
9487
|
+
addEventListener<K extends keyof RozieDataTableEventMap>(type: K, listener: (this: DataTable, ev: RozieDataTableEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
9488
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
9489
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void {
|
|
9490
|
+
super.addEventListener(type, listener, options);
|
|
9491
|
+
}
|
|
9492
|
+
removeEventListener<K extends keyof RozieDataTableEventMap>(type: K, listener: (this: DataTable, ev: RozieDataTableEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
9493
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
9494
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void {
|
|
9495
|
+
super.removeEventListener(type, listener, options);
|
|
9496
|
+
}
|
|
9428
9497
|
}
|