@proyecto-viviana/solid-stately 0.0.6 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +312 -0
- package/dist/index.d.ts +3363 -6
- package/dist/index.js +6194 -19
- package/dist/index.js.map +1 -1
- package/package.json +52 -48
- package/src/autocomplete/createAutocompleteState.d.ts +46 -0
- package/src/autocomplete/createAutocompleteState.d.ts.map +1 -0
- package/src/autocomplete/createAutocompleteState.ts +90 -0
- package/src/autocomplete/index.d.ts +2 -0
- package/src/autocomplete/index.d.ts.map +1 -0
- package/src/autocomplete/index.ts +5 -0
- package/src/calendar/createCalendarState.d.ts +130 -0
- package/src/calendar/createCalendarState.d.ts.map +1 -0
- package/src/calendar/createCalendarState.ts +461 -0
- package/src/calendar/createDateFieldState.d.ts +110 -0
- package/src/calendar/createDateFieldState.d.ts.map +1 -0
- package/src/calendar/createDateFieldState.ts +562 -0
- package/src/calendar/createRangeCalendarState.d.ts +146 -0
- package/src/calendar/createRangeCalendarState.d.ts.map +1 -0
- package/src/calendar/createRangeCalendarState.ts +535 -0
- package/src/calendar/createTimeFieldState.d.ts +95 -0
- package/src/calendar/createTimeFieldState.d.ts.map +1 -0
- package/src/calendar/createTimeFieldState.ts +483 -0
- package/src/calendar/index.d.ts +7 -0
- package/src/calendar/index.d.ts.map +1 -0
- package/src/calendar/index.ts +81 -0
- package/{dist → src}/checkbox/createCheckboxGroupState.d.ts +1 -0
- package/src/checkbox/createCheckboxGroupState.d.ts.map +1 -0
- package/{dist → src}/checkbox/index.d.ts +1 -0
- package/src/checkbox/index.d.ts.map +1 -0
- package/src/collections/ListCollection.d.ts +37 -0
- package/src/collections/ListCollection.d.ts.map +1 -0
- package/src/collections/ListCollection.ts +146 -0
- package/src/collections/createListState.d.ts +79 -0
- package/src/collections/createListState.d.ts.map +1 -0
- package/src/collections/createListState.ts +264 -0
- package/src/collections/createMenuState.d.ts +50 -0
- package/src/collections/createMenuState.d.ts.map +1 -0
- package/src/collections/createMenuState.ts +106 -0
- package/src/collections/createSelectionState.d.ts +76 -0
- package/src/collections/createSelectionState.d.ts.map +1 -0
- package/src/collections/createSelectionState.ts +336 -0
- package/src/collections/index.d.ts +6 -0
- package/src/collections/index.d.ts.map +1 -0
- package/src/collections/index.ts +46 -0
- package/src/collections/types.d.ts +147 -0
- package/src/collections/types.d.ts.map +1 -0
- package/src/collections/types.ts +169 -0
- package/src/color/Color.d.ts +28 -0
- package/src/color/Color.d.ts.map +1 -0
- package/src/color/Color.ts +951 -0
- package/src/color/createColorAreaState.d.ts +76 -0
- package/src/color/createColorAreaState.d.ts.map +1 -0
- package/src/color/createColorAreaState.ts +293 -0
- package/src/color/createColorFieldState.d.ts +55 -0
- package/src/color/createColorFieldState.d.ts.map +1 -0
- package/src/color/createColorFieldState.ts +292 -0
- package/src/color/createColorSliderState.d.ts +67 -0
- package/src/color/createColorSliderState.d.ts.map +1 -0
- package/src/color/createColorSliderState.ts +241 -0
- package/src/color/createColorWheelState.d.ts +51 -0
- package/src/color/createColorWheelState.d.ts.map +1 -0
- package/src/color/createColorWheelState.ts +211 -0
- package/src/color/index.d.ts +10 -0
- package/src/color/index.d.ts.map +1 -0
- package/src/color/index.ts +47 -0
- package/src/color/types.d.ts +106 -0
- package/src/color/types.d.ts.map +1 -0
- package/src/color/types.ts +127 -0
- package/src/combobox/createComboBoxState.d.ts +125 -0
- package/src/combobox/createComboBoxState.d.ts.map +1 -0
- package/src/combobox/createComboBoxState.ts +703 -0
- package/src/combobox/index.d.ts +5 -0
- package/src/combobox/index.d.ts.map +1 -0
- package/src/combobox/index.ts +13 -0
- package/src/disclosure/createDisclosureState.d.ts +64 -0
- package/src/disclosure/createDisclosureState.d.ts.map +1 -0
- package/src/disclosure/createDisclosureState.ts +193 -0
- package/src/disclosure/index.d.ts +2 -0
- package/src/disclosure/index.d.ts.map +1 -0
- package/src/disclosure/index.ts +9 -0
- package/src/dnd/createDragState.d.ts +59 -0
- package/src/dnd/createDragState.d.ts.map +1 -0
- package/src/dnd/createDragState.ts +153 -0
- package/src/dnd/createDraggableCollectionState.d.ts +57 -0
- package/src/dnd/createDraggableCollectionState.d.ts.map +1 -0
- package/src/dnd/createDraggableCollectionState.ts +165 -0
- package/src/dnd/createDropState.d.ts +61 -0
- package/src/dnd/createDropState.d.ts.map +1 -0
- package/src/dnd/createDropState.ts +212 -0
- package/src/dnd/createDroppableCollectionState.d.ts +78 -0
- package/src/dnd/createDroppableCollectionState.d.ts.map +1 -0
- package/src/dnd/createDroppableCollectionState.ts +357 -0
- package/src/dnd/index.d.ts +11 -0
- package/src/dnd/index.d.ts.map +1 -0
- package/src/dnd/index.ts +76 -0
- package/src/dnd/types.d.ts +264 -0
- package/src/dnd/types.d.ts.map +1 -0
- package/src/dnd/types.ts +317 -0
- package/src/form/createFormValidationState.d.ts +100 -0
- package/src/form/createFormValidationState.d.ts.map +1 -0
- package/src/form/createFormValidationState.ts +389 -0
- package/src/form/index.d.ts +2 -0
- package/src/form/index.d.ts.map +1 -0
- package/src/form/index.ts +15 -0
- package/src/grid/createGridState.d.ts +12 -0
- package/src/grid/createGridState.d.ts.map +1 -0
- package/src/grid/createGridState.ts +327 -0
- package/src/grid/index.d.ts +7 -0
- package/src/grid/index.d.ts.map +1 -0
- package/src/grid/index.ts +13 -0
- package/src/grid/types.d.ts +156 -0
- package/src/grid/types.d.ts.map +1 -0
- package/src/grid/types.ts +179 -0
- package/src/index.d.ts +26 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.ts +350 -1
- package/src/numberfield/createNumberFieldState.d.ts +65 -0
- package/src/numberfield/createNumberFieldState.d.ts.map +1 -0
- package/src/numberfield/createNumberFieldState.ts +383 -0
- package/src/numberfield/index.d.ts +2 -0
- package/src/numberfield/index.d.ts.map +1 -0
- package/src/numberfield/index.ts +5 -0
- package/src/overlays/createOverlayTriggerState.d.ts +32 -0
- package/src/overlays/createOverlayTriggerState.d.ts.map +1 -0
- package/src/overlays/createOverlayTriggerState.ts +67 -0
- package/src/overlays/index.d.ts +2 -0
- package/src/overlays/index.d.ts.map +1 -0
- package/src/overlays/index.ts +5 -0
- package/{dist → src}/radio/createRadioGroupState.d.ts +1 -0
- package/src/radio/createRadioGroupState.d.ts.map +1 -0
- package/{dist → src}/radio/index.d.ts +1 -0
- package/src/radio/index.d.ts.map +1 -0
- package/src/searchfield/createSearchFieldState.d.ts +25 -0
- package/src/searchfield/createSearchFieldState.d.ts.map +1 -0
- package/src/searchfield/createSearchFieldState.ts +62 -0
- package/src/searchfield/index.d.ts +3 -0
- package/src/searchfield/index.d.ts.map +1 -0
- package/src/searchfield/index.ts +5 -0
- package/src/select/createSelectState.d.ts +73 -0
- package/src/select/createSelectState.d.ts.map +1 -0
- package/src/select/createSelectState.ts +181 -0
- package/src/select/index.d.ts +2 -0
- package/src/select/index.d.ts.map +1 -0
- package/src/select/index.ts +5 -0
- package/src/slider/createSliderState.d.ts +72 -0
- package/src/slider/createSliderState.d.ts.map +1 -0
- package/src/slider/createSliderState.ts +211 -0
- package/src/slider/index.d.ts +3 -0
- package/src/slider/index.d.ts.map +1 -0
- package/src/slider/index.ts +6 -0
- package/{dist → src}/ssr/index.d.ts +5 -0
- package/src/ssr/index.d.ts.map +1 -0
- package/src/ssr/index.ts +6 -1
- package/src/table/TableCollection.d.ts +52 -0
- package/src/table/TableCollection.d.ts.map +1 -0
- package/src/table/TableCollection.ts +388 -0
- package/src/table/createTableState.d.ts +12 -0
- package/src/table/createTableState.d.ts.map +1 -0
- package/src/table/createTableState.ts +127 -0
- package/src/table/index.d.ts +8 -0
- package/src/table/index.d.ts.map +1 -0
- package/src/table/index.ts +18 -0
- package/src/table/types.d.ts +139 -0
- package/src/table/types.d.ts.map +1 -0
- package/src/table/types.ts +150 -0
- package/src/tabs/createTabListState.d.ts +68 -0
- package/src/tabs/createTabListState.d.ts.map +1 -0
- package/src/tabs/createTabListState.ts +240 -0
- package/src/tabs/index.d.ts +2 -0
- package/src/tabs/index.d.ts.map +1 -0
- package/src/tabs/index.ts +7 -0
- package/{dist → src}/textfield/createTextFieldState.d.ts +1 -0
- package/src/textfield/createTextFieldState.d.ts.map +1 -0
- package/{dist → src}/textfield/index.d.ts +1 -0
- package/src/textfield/index.d.ts.map +1 -0
- package/src/toast/createToastState.d.ts +118 -0
- package/src/toast/createToastState.d.ts.map +1 -0
- package/src/toast/createToastState.ts +316 -0
- package/src/toast/index.d.ts +2 -0
- package/src/toast/index.d.ts.map +1 -0
- package/src/toast/index.ts +11 -0
- package/{dist → src}/toggle/createToggleState.d.ts +1 -0
- package/src/toggle/createToggleState.d.ts.map +1 -0
- package/{dist → src}/toggle/index.d.ts +1 -0
- package/src/toggle/index.d.ts.map +1 -0
- package/src/tooltip/createTooltipTriggerState.d.ts +39 -0
- package/src/tooltip/createTooltipTriggerState.d.ts.map +1 -0
- package/src/tooltip/createTooltipTriggerState.ts +183 -0
- package/src/tooltip/index.d.ts +2 -0
- package/src/tooltip/index.d.ts.map +1 -0
- package/src/tooltip/index.ts +6 -0
- package/src/tree/TreeCollection.d.ts +40 -0
- package/src/tree/TreeCollection.d.ts.map +1 -0
- package/src/tree/TreeCollection.ts +175 -0
- package/src/tree/createTreeState.d.ts +14 -0
- package/src/tree/createTreeState.d.ts.map +1 -0
- package/src/tree/createTreeState.ts +392 -0
- package/src/tree/index.d.ts +7 -0
- package/src/tree/index.d.ts.map +1 -0
- package/src/tree/index.ts +13 -0
- package/src/tree/types.d.ts +157 -0
- package/src/tree/types.d.ts.map +1 -0
- package/src/tree/types.ts +174 -0
- package/{dist → src}/utils/index.d.ts +1 -0
- package/src/utils/index.d.ts.map +1 -0
- package/{dist → src}/utils/reactivity.d.ts +1 -0
- package/src/utils/reactivity.d.ts.map +1 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TableCollection - A collection class for table data.
|
|
3
|
+
* Based on @react-stately/table/TableCollection.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Key } from '../collections/types';
|
|
7
|
+
import type { GridNode, GridNodeType } from '../grid/types';
|
|
8
|
+
import type {
|
|
9
|
+
TableCollection as ITableCollection,
|
|
10
|
+
TableCollectionOptions,
|
|
11
|
+
ColumnDefinition,
|
|
12
|
+
RowDefinition,
|
|
13
|
+
} from './types';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a table collection from column and row definitions.
|
|
17
|
+
*/
|
|
18
|
+
export class TableCollection<T = unknown> implements ITableCollection<T> {
|
|
19
|
+
private _columns: GridNode<T>[] = [];
|
|
20
|
+
private _rows: GridNode<T>[] = [];
|
|
21
|
+
private _headerRows: GridNode<T>[] = [];
|
|
22
|
+
private _body: GridNode<T>;
|
|
23
|
+
private _head: GridNode<T> | undefined;
|
|
24
|
+
private _keyMap: Map<Key, GridNode<T>> = new Map();
|
|
25
|
+
private _rowHeaderColumnKeys: Set<Key>;
|
|
26
|
+
private _size: number = 0;
|
|
27
|
+
|
|
28
|
+
constructor(options: TableCollectionOptions<T>) {
|
|
29
|
+
const {
|
|
30
|
+
columns,
|
|
31
|
+
rows,
|
|
32
|
+
getKey,
|
|
33
|
+
getTextValue,
|
|
34
|
+
showSelectionCheckboxes = false,
|
|
35
|
+
rowHeaderColumnKeys,
|
|
36
|
+
} = options;
|
|
37
|
+
|
|
38
|
+
// Build columns
|
|
39
|
+
this._columns = this.buildColumns(columns, showSelectionCheckboxes);
|
|
40
|
+
|
|
41
|
+
// Determine row header column keys
|
|
42
|
+
this._rowHeaderColumnKeys = rowHeaderColumnKeys ?? this.getDefaultRowHeaderColumnKeys();
|
|
43
|
+
|
|
44
|
+
// Build header rows
|
|
45
|
+
this._headerRows = this.buildHeaderRows();
|
|
46
|
+
|
|
47
|
+
// Build head node
|
|
48
|
+
if (this._headerRows.length > 0) {
|
|
49
|
+
this._head = {
|
|
50
|
+
type: 'headerrow' as GridNodeType,
|
|
51
|
+
key: 'header',
|
|
52
|
+
index: 0,
|
|
53
|
+
level: 0,
|
|
54
|
+
hasChildNodes: true,
|
|
55
|
+
childNodes: this._headerRows,
|
|
56
|
+
value: null,
|
|
57
|
+
textValue: '',
|
|
58
|
+
};
|
|
59
|
+
this._keyMap.set('header', this._head);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Build body rows
|
|
63
|
+
const bodyRows = this.buildRows(rows, getKey, getTextValue);
|
|
64
|
+
this._size = bodyRows.length;
|
|
65
|
+
|
|
66
|
+
// Build body node
|
|
67
|
+
this._body = {
|
|
68
|
+
type: 'item' as GridNodeType,
|
|
69
|
+
key: 'body',
|
|
70
|
+
index: this._headerRows.length,
|
|
71
|
+
level: 0,
|
|
72
|
+
hasChildNodes: true,
|
|
73
|
+
childNodes: bodyRows,
|
|
74
|
+
value: null,
|
|
75
|
+
textValue: '',
|
|
76
|
+
};
|
|
77
|
+
this._keyMap.set('body', this._body);
|
|
78
|
+
|
|
79
|
+
// Combine all rows
|
|
80
|
+
this._rows = [...this._headerRows, ...bodyRows];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private buildColumns(
|
|
84
|
+
columns: ColumnDefinition<T>[],
|
|
85
|
+
showSelectionCheckboxes: boolean
|
|
86
|
+
): GridNode<T>[] {
|
|
87
|
+
const result: GridNode<T>[] = [];
|
|
88
|
+
let colIndex = 0;
|
|
89
|
+
|
|
90
|
+
// Add selection column if needed
|
|
91
|
+
if (showSelectionCheckboxes) {
|
|
92
|
+
const selectionColumn: GridNode<T> = {
|
|
93
|
+
type: 'column' as GridNodeType,
|
|
94
|
+
key: '__selection__',
|
|
95
|
+
index: colIndex,
|
|
96
|
+
column: 0,
|
|
97
|
+
level: 0,
|
|
98
|
+
hasChildNodes: false,
|
|
99
|
+
childNodes: [],
|
|
100
|
+
value: null,
|
|
101
|
+
textValue: 'Selection',
|
|
102
|
+
};
|
|
103
|
+
result.push(selectionColumn);
|
|
104
|
+
this._keyMap.set(selectionColumn.key, selectionColumn);
|
|
105
|
+
colIndex++;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Build user columns
|
|
109
|
+
for (const col of columns) {
|
|
110
|
+
const node = this.buildColumnNode(col, colIndex);
|
|
111
|
+
result.push(node);
|
|
112
|
+
colIndex++;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private buildColumnNode(col: ColumnDefinition<T>, index: number): GridNode<T> {
|
|
119
|
+
const node: GridNode<T> = {
|
|
120
|
+
type: 'column' as GridNodeType,
|
|
121
|
+
key: col.key,
|
|
122
|
+
index,
|
|
123
|
+
column: index,
|
|
124
|
+
level: 0,
|
|
125
|
+
hasChildNodes: (col.children?.length ?? 0) > 0,
|
|
126
|
+
childNodes: [],
|
|
127
|
+
value: null,
|
|
128
|
+
textValue: col.textValue ?? col.name ?? String(col.key),
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Build child columns if present (for column groups)
|
|
132
|
+
if (col.children && col.children.length > 0) {
|
|
133
|
+
let childIndex = 0;
|
|
134
|
+
for (const child of col.children) {
|
|
135
|
+
const childNode = this.buildColumnNode(child, childIndex);
|
|
136
|
+
childNode.parentKey = col.key;
|
|
137
|
+
childNode.level = 1;
|
|
138
|
+
node.childNodes.push(childNode);
|
|
139
|
+
childIndex++;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
this._keyMap.set(node.key, node);
|
|
144
|
+
return node;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private getDefaultRowHeaderColumnKeys(): Set<Key> {
|
|
148
|
+
// Default to first non-selection column as row header
|
|
149
|
+
for (const col of this._columns) {
|
|
150
|
+
if (col.key !== '__selection__') {
|
|
151
|
+
return new Set([col.key]);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return new Set();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private buildHeaderRows(): GridNode<T>[] {
|
|
158
|
+
if (this._columns.length === 0) {
|
|
159
|
+
return [];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Build a single header row containing all columns
|
|
163
|
+
const headerCells: GridNode<T>[] = this._columns.map((col, index) => ({
|
|
164
|
+
type: 'column' as GridNodeType,
|
|
165
|
+
key: `header-${col.key}`,
|
|
166
|
+
index,
|
|
167
|
+
column: index,
|
|
168
|
+
level: 1,
|
|
169
|
+
hasChildNodes: false,
|
|
170
|
+
childNodes: [],
|
|
171
|
+
value: null,
|
|
172
|
+
textValue: col.textValue,
|
|
173
|
+
parentKey: 'headerrow-0',
|
|
174
|
+
}));
|
|
175
|
+
|
|
176
|
+
const headerRow: GridNode<T> = {
|
|
177
|
+
type: 'headerrow' as GridNodeType,
|
|
178
|
+
key: 'headerrow-0',
|
|
179
|
+
index: 0,
|
|
180
|
+
rowIndex: 0,
|
|
181
|
+
level: 0,
|
|
182
|
+
hasChildNodes: true,
|
|
183
|
+
childNodes: headerCells,
|
|
184
|
+
value: null,
|
|
185
|
+
textValue: '',
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
this._keyMap.set(headerRow.key, headerRow);
|
|
189
|
+
headerCells.forEach((cell) => this._keyMap.set(cell.key, cell));
|
|
190
|
+
|
|
191
|
+
return [headerRow];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private buildRows(
|
|
195
|
+
rows: RowDefinition<T>[] | T[],
|
|
196
|
+
getKey?: (item: T) => Key,
|
|
197
|
+
getTextValue?: (item: T, column: ColumnDefinition<T>) => string
|
|
198
|
+
): GridNode<T>[] {
|
|
199
|
+
const result: GridNode<T>[] = [];
|
|
200
|
+
const rowIndexOffset = this._headerRows.length;
|
|
201
|
+
|
|
202
|
+
for (let i = 0; i < rows.length; i++) {
|
|
203
|
+
const row = rows[i];
|
|
204
|
+
const isRowDef = this.isRowDefinition(row);
|
|
205
|
+
|
|
206
|
+
const key = isRowDef ? row.key : getKey?.(row as T) ?? i;
|
|
207
|
+
const value = isRowDef ? row.value : (row as T);
|
|
208
|
+
const textValue = isRowDef ? row.textValue : undefined;
|
|
209
|
+
|
|
210
|
+
// Build cells for this row
|
|
211
|
+
const cells: GridNode<T>[] = this._columns.map((col, colIndex) => {
|
|
212
|
+
const cellKey = `${key}-${col.key}`;
|
|
213
|
+
const cellTextValue =
|
|
214
|
+
col.key === '__selection__'
|
|
215
|
+
? 'Selection'
|
|
216
|
+
: getTextValue
|
|
217
|
+
? getTextValue(value, { key: col.key } as ColumnDefinition<T>)
|
|
218
|
+
: String((value as Record<string, unknown>)?.[String(col.key)] ?? '');
|
|
219
|
+
|
|
220
|
+
const cell: GridNode<T> = {
|
|
221
|
+
type: this._rowHeaderColumnKeys.has(col.key)
|
|
222
|
+
? ('rowheader' as GridNodeType)
|
|
223
|
+
: ('cell' as GridNodeType),
|
|
224
|
+
key: cellKey,
|
|
225
|
+
index: colIndex,
|
|
226
|
+
column: colIndex,
|
|
227
|
+
level: 1,
|
|
228
|
+
hasChildNodes: false,
|
|
229
|
+
childNodes: [],
|
|
230
|
+
value,
|
|
231
|
+
textValue: cellTextValue,
|
|
232
|
+
parentKey: key,
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
this._keyMap.set(cellKey, cell);
|
|
236
|
+
return cell;
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
const rowNode: GridNode<T> = {
|
|
240
|
+
type: 'item' as GridNodeType,
|
|
241
|
+
key,
|
|
242
|
+
index: i,
|
|
243
|
+
rowIndex: rowIndexOffset + i,
|
|
244
|
+
level: 0,
|
|
245
|
+
hasChildNodes: true,
|
|
246
|
+
childNodes: cells,
|
|
247
|
+
value,
|
|
248
|
+
textValue: textValue ?? cells.map((c) => c.textValue).join(' '),
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
this._keyMap.set(key, rowNode);
|
|
252
|
+
result.push(rowNode);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private isRowDefinition(row: unknown): row is RowDefinition<T> {
|
|
259
|
+
return (
|
|
260
|
+
typeof row === 'object' &&
|
|
261
|
+
row !== null &&
|
|
262
|
+
'key' in row &&
|
|
263
|
+
'value' in row
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Collection interface implementation
|
|
268
|
+
get size(): number {
|
|
269
|
+
return this._size;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
get rows(): GridNode<T>[] {
|
|
273
|
+
return this._rows;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
get columns(): GridNode<T>[] {
|
|
277
|
+
return this._columns;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
get headerRows(): GridNode<T>[] {
|
|
281
|
+
return this._headerRows;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
get head(): GridNode<T> | undefined {
|
|
285
|
+
return this._head;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
get body(): GridNode<T> {
|
|
289
|
+
return this._body;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
get rowCount(): number {
|
|
293
|
+
return this._rows.length;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
get columnCount(): number {
|
|
297
|
+
return this._columns.length;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
get rowHeaderColumnKeys(): Set<Key> {
|
|
301
|
+
return this._rowHeaderColumnKeys;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
getKeys(): Iterable<Key> {
|
|
305
|
+
return this._keyMap.keys();
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
getItem(key: Key): GridNode<T> | null {
|
|
309
|
+
return this._keyMap.get(key) ?? null;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
at(index: number): GridNode<T> | null {
|
|
313
|
+
const bodyRows = this._body.childNodes;
|
|
314
|
+
if (index < 0 || index >= bodyRows.length) {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
return bodyRows[index];
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
getChildren(key: Key): Iterable<GridNode<T>> {
|
|
321
|
+
const node = this._keyMap.get(key);
|
|
322
|
+
return node?.childNodes ?? [];
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
getTextValue(key: Key): string {
|
|
326
|
+
const node = this._keyMap.get(key);
|
|
327
|
+
return node?.textValue ?? '';
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
getCell(rowKey: Key, columnKey: Key): GridNode<T> | null {
|
|
331
|
+
const cellKey = `${rowKey}-${columnKey}`;
|
|
332
|
+
return this._keyMap.get(cellKey) ?? null;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
getFirstKey(): Key | null {
|
|
336
|
+
// Return first body row key
|
|
337
|
+
const bodyRows = this._body.childNodes;
|
|
338
|
+
return bodyRows.length > 0 ? bodyRows[0].key : null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
getLastKey(): Key | null {
|
|
342
|
+
// Return last body row key
|
|
343
|
+
const bodyRows = this._body.childNodes;
|
|
344
|
+
return bodyRows.length > 0 ? bodyRows[bodyRows.length - 1].key : null;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
getKeyBefore(key: Key): Key | null {
|
|
348
|
+
const node = this._keyMap.get(key);
|
|
349
|
+
if (!node) return null;
|
|
350
|
+
|
|
351
|
+
// Find in body rows
|
|
352
|
+
const bodyRows = this._body.childNodes;
|
|
353
|
+
const index = bodyRows.findIndex((r) => r.key === key);
|
|
354
|
+
if (index > 0) {
|
|
355
|
+
return bodyRows[index - 1].key;
|
|
356
|
+
}
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
getKeyAfter(key: Key): Key | null {
|
|
361
|
+
const node = this._keyMap.get(key);
|
|
362
|
+
if (!node) return null;
|
|
363
|
+
|
|
364
|
+
// Find in body rows
|
|
365
|
+
const bodyRows = this._body.childNodes;
|
|
366
|
+
const index = bodyRows.findIndex((r) => r.key === key);
|
|
367
|
+
if (index >= 0 && index < bodyRows.length - 1) {
|
|
368
|
+
return bodyRows[index + 1].key;
|
|
369
|
+
}
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
*[Symbol.iterator](): Iterator<GridNode<T>> {
|
|
374
|
+
// Only iterate body rows, not header rows
|
|
375
|
+
for (const row of this._body.childNodes) {
|
|
376
|
+
yield row;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Creates a table collection from options.
|
|
383
|
+
*/
|
|
384
|
+
export function createTableCollection<T>(
|
|
385
|
+
options: TableCollectionOptions<T>
|
|
386
|
+
): TableCollection<T> {
|
|
387
|
+
return new TableCollection(options);
|
|
388
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table state management for Table components.
|
|
3
|
+
* Based on @react-stately/table/useTableState.
|
|
4
|
+
*/
|
|
5
|
+
import { type Accessor } from 'solid-js';
|
|
6
|
+
import type { TableState, TableStateOptions, TableCollection } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Creates state management for a table component.
|
|
9
|
+
* Extends grid state with sorting and table-specific features.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createTableState<T extends object, C extends TableCollection<T> = TableCollection<T>>(options: Accessor<TableStateOptions<T, C>>): TableState<T, C>;
|
|
12
|
+
//# sourceMappingURL=createTableState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createTableState.d.ts","sourceRoot":"","sources":["createTableState.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,eAAe,EAGhB,MAAM,SAAS,CAAC;AAOjB;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,EACjD,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAkG9D"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table state management for Table components.
|
|
3
|
+
* Based on @react-stately/table/useTableState.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createMemo, type Accessor } from 'solid-js';
|
|
7
|
+
import { createGridState } from '../grid/createGridState';
|
|
8
|
+
import type { Key } from '../collections/types';
|
|
9
|
+
import type {
|
|
10
|
+
TableState,
|
|
11
|
+
TableStateOptions,
|
|
12
|
+
TableCollection,
|
|
13
|
+
SortDescriptor,
|
|
14
|
+
SortDirection,
|
|
15
|
+
} from './types';
|
|
16
|
+
|
|
17
|
+
const OPPOSITE_SORT_DIRECTION: Record<SortDirection, SortDirection> = {
|
|
18
|
+
ascending: 'descending',
|
|
19
|
+
descending: 'ascending',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Creates state management for a table component.
|
|
24
|
+
* Extends grid state with sorting and table-specific features.
|
|
25
|
+
*/
|
|
26
|
+
export function createTableState<
|
|
27
|
+
T extends object,
|
|
28
|
+
C extends TableCollection<T> = TableCollection<T>,
|
|
29
|
+
>(options: Accessor<TableStateOptions<T, C>>): TableState<T, C> {
|
|
30
|
+
const getOptions = () => options();
|
|
31
|
+
|
|
32
|
+
// Create the underlying grid state
|
|
33
|
+
const gridState = createGridState<T, C>(() => ({
|
|
34
|
+
collection: getOptions().collection,
|
|
35
|
+
disabledKeys: getOptions().disabledKeys,
|
|
36
|
+
focusMode: getOptions().focusMode,
|
|
37
|
+
selectionMode: getOptions().selectionMode,
|
|
38
|
+
selectionBehavior: getOptions().selectionBehavior,
|
|
39
|
+
disallowEmptySelection: getOptions().disallowEmptySelection,
|
|
40
|
+
selectedKeys: getOptions().selectedKeys,
|
|
41
|
+
defaultSelectedKeys: getOptions().defaultSelectedKeys,
|
|
42
|
+
onSelectionChange: getOptions().onSelectionChange,
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
// Memoized sort descriptor
|
|
46
|
+
const sortDescriptor = createMemo<SortDescriptor | null>(() => {
|
|
47
|
+
return getOptions().sortDescriptor ?? null;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Show selection checkboxes
|
|
51
|
+
const showSelectionCheckboxes = createMemo(() => {
|
|
52
|
+
return getOptions().showSelectionCheckboxes ?? false;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Sort function
|
|
56
|
+
const sort = (columnKey: Key, direction?: SortDirection) => {
|
|
57
|
+
const opts = getOptions();
|
|
58
|
+
const currentSort = opts.sortDescriptor;
|
|
59
|
+
|
|
60
|
+
// Determine direction
|
|
61
|
+
let newDirection: SortDirection;
|
|
62
|
+
if (direction) {
|
|
63
|
+
newDirection = direction;
|
|
64
|
+
} else if (currentSort?.column === columnKey) {
|
|
65
|
+
// Toggle direction if sorting same column
|
|
66
|
+
newDirection = OPPOSITE_SORT_DIRECTION[currentSort.direction];
|
|
67
|
+
} else {
|
|
68
|
+
// Default to ascending for new column
|
|
69
|
+
newDirection = 'ascending';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
opts.onSortChange?.({
|
|
73
|
+
column: columnKey,
|
|
74
|
+
direction: newDirection,
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
// Forward grid state properties
|
|
80
|
+
get collection() {
|
|
81
|
+
return getOptions().collection;
|
|
82
|
+
},
|
|
83
|
+
get disabledKeys() {
|
|
84
|
+
return gridState.disabledKeys;
|
|
85
|
+
},
|
|
86
|
+
get isKeyboardNavigationDisabled() {
|
|
87
|
+
return gridState.isKeyboardNavigationDisabled;
|
|
88
|
+
},
|
|
89
|
+
get focusedKey() {
|
|
90
|
+
return gridState.focusedKey;
|
|
91
|
+
},
|
|
92
|
+
get childFocusStrategy() {
|
|
93
|
+
return gridState.childFocusStrategy;
|
|
94
|
+
},
|
|
95
|
+
get isFocused() {
|
|
96
|
+
return gridState.isFocused;
|
|
97
|
+
},
|
|
98
|
+
get selectionMode() {
|
|
99
|
+
return gridState.selectionMode;
|
|
100
|
+
},
|
|
101
|
+
get selectedKeys() {
|
|
102
|
+
return gridState.selectedKeys;
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
// Grid state methods
|
|
106
|
+
isSelected: gridState.isSelected,
|
|
107
|
+
isDisabled: gridState.isDisabled,
|
|
108
|
+
setFocusedKey: gridState.setFocusedKey,
|
|
109
|
+
setFocused: gridState.setFocused,
|
|
110
|
+
toggleSelection: gridState.toggleSelection,
|
|
111
|
+
replaceSelection: gridState.replaceSelection,
|
|
112
|
+
extendSelection: gridState.extendSelection,
|
|
113
|
+
selectAll: gridState.selectAll,
|
|
114
|
+
clearSelection: gridState.clearSelection,
|
|
115
|
+
toggleSelectAll: gridState.toggleSelectAll,
|
|
116
|
+
setKeyboardNavigationDisabled: gridState.setKeyboardNavigationDisabled,
|
|
117
|
+
|
|
118
|
+
// Table-specific properties
|
|
119
|
+
get showSelectionCheckboxes() {
|
|
120
|
+
return showSelectionCheckboxes();
|
|
121
|
+
},
|
|
122
|
+
get sortDescriptor() {
|
|
123
|
+
return sortDescriptor();
|
|
124
|
+
},
|
|
125
|
+
sort,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table state management module.
|
|
3
|
+
* Provides state hooks for Table components.
|
|
4
|
+
*/
|
|
5
|
+
export { createTableState } from './createTableState';
|
|
6
|
+
export { TableCollection, createTableCollection } from './TableCollection';
|
|
7
|
+
export type { TableState, TableStateOptions, TableCollection as ITableCollection, SortDescriptor, SortDirection, Sortable, ColumnDefinition, RowDefinition, TableCollectionOptions, } from './types';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,eAAe,IAAI,gBAAgB,EACnC,cAAc,EACd,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,sBAAsB,GACvB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table state management module.
|
|
3
|
+
* Provides state hooks for Table components.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { createTableState } from './createTableState';
|
|
7
|
+
export { TableCollection, createTableCollection } from './TableCollection';
|
|
8
|
+
export type {
|
|
9
|
+
TableState,
|
|
10
|
+
TableStateOptions,
|
|
11
|
+
TableCollection as ITableCollection,
|
|
12
|
+
SortDescriptor,
|
|
13
|
+
SortDirection,
|
|
14
|
+
Sortable,
|
|
15
|
+
ColumnDefinition,
|
|
16
|
+
RowDefinition,
|
|
17
|
+
TableCollectionOptions,
|
|
18
|
+
} from './types';
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table state types for Table components.
|
|
3
|
+
* Based on @react-stately/table and @react-types/table.
|
|
4
|
+
*/
|
|
5
|
+
import type { Key } from '../collections/types';
|
|
6
|
+
import type { GridState, GridCollection, GridNode } from '../grid/types';
|
|
7
|
+
/**
|
|
8
|
+
* Sort direction for table columns.
|
|
9
|
+
*/
|
|
10
|
+
export type SortDirection = 'ascending' | 'descending';
|
|
11
|
+
/**
|
|
12
|
+
* Describes which column to sort by and in what direction.
|
|
13
|
+
*/
|
|
14
|
+
export interface SortDescriptor {
|
|
15
|
+
/** The key of the column to sort by. */
|
|
16
|
+
column: Key;
|
|
17
|
+
/** The direction to sort by. */
|
|
18
|
+
direction: SortDirection;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Interface for sortable components.
|
|
22
|
+
*/
|
|
23
|
+
export interface Sortable {
|
|
24
|
+
/** The current sorted column and direction. */
|
|
25
|
+
sortDescriptor?: SortDescriptor;
|
|
26
|
+
/** Handler that is called when the sorted column or direction changes. */
|
|
27
|
+
onSortChange?: (descriptor: SortDescriptor) => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A collection of table rows and columns.
|
|
31
|
+
* Extends GridCollection with table-specific metadata.
|
|
32
|
+
*/
|
|
33
|
+
export interface TableCollection<T = unknown> extends GridCollection<T> {
|
|
34
|
+
/** A list of header row nodes in the table. */
|
|
35
|
+
readonly headerRows: GridNode<T>[];
|
|
36
|
+
/** A list of column nodes in the table. */
|
|
37
|
+
readonly columns: GridNode<T>[];
|
|
38
|
+
/** A set of column keys that serve as the row header. */
|
|
39
|
+
readonly rowHeaderColumnKeys: Set<Key>;
|
|
40
|
+
/** The node that makes up the header of the table. */
|
|
41
|
+
readonly head?: GridNode<T>;
|
|
42
|
+
/** The node that makes up the body of the table. */
|
|
43
|
+
readonly body: GridNode<T>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* State for a table component.
|
|
47
|
+
* Extends GridState with table-specific functionality.
|
|
48
|
+
*/
|
|
49
|
+
export interface TableState<T, C extends TableCollection<T> = TableCollection<T>> extends Omit<GridState<T, GridCollection<T>>, 'collection'> {
|
|
50
|
+
/** The table collection. */
|
|
51
|
+
readonly collection: C;
|
|
52
|
+
/** Whether the row selection checkboxes should be displayed. */
|
|
53
|
+
readonly showSelectionCheckboxes: boolean;
|
|
54
|
+
/** The current sorted column and direction. */
|
|
55
|
+
readonly sortDescriptor: SortDescriptor | null;
|
|
56
|
+
/** Sort by the given column and direction. */
|
|
57
|
+
sort(columnKey: Key, direction?: SortDirection): void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Options for creating table state.
|
|
61
|
+
*/
|
|
62
|
+
export interface TableStateOptions<T, C extends TableCollection<T> = TableCollection<T>> extends Sortable {
|
|
63
|
+
/** The table collection. */
|
|
64
|
+
collection: C;
|
|
65
|
+
/** Keys of disabled rows. */
|
|
66
|
+
disabledKeys?: Iterable<Key>;
|
|
67
|
+
/** Focus mode: 'row' or 'cell'. */
|
|
68
|
+
focusMode?: 'row' | 'cell';
|
|
69
|
+
/** Selection mode. */
|
|
70
|
+
selectionMode?: 'none' | 'single' | 'multiple';
|
|
71
|
+
/** Selection behavior. */
|
|
72
|
+
selectionBehavior?: 'toggle' | 'replace';
|
|
73
|
+
/** Whether empty selection is disallowed. */
|
|
74
|
+
disallowEmptySelection?: boolean;
|
|
75
|
+
/** Currently selected keys (controlled). */
|
|
76
|
+
selectedKeys?: 'all' | Iterable<Key>;
|
|
77
|
+
/** Default selected keys (uncontrolled). */
|
|
78
|
+
defaultSelectedKeys?: 'all' | Iterable<Key>;
|
|
79
|
+
/** Handler for selection changes. */
|
|
80
|
+
onSelectionChange?: (keys: 'all' | Set<Key>) => void;
|
|
81
|
+
/** Whether the row selection checkboxes should be displayed. */
|
|
82
|
+
showSelectionCheckboxes?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Column definition for building table collections.
|
|
86
|
+
*/
|
|
87
|
+
export interface ColumnDefinition<T = unknown> {
|
|
88
|
+
/** The key for the column. */
|
|
89
|
+
key: Key;
|
|
90
|
+
/** The display name or rendered content. */
|
|
91
|
+
name?: string;
|
|
92
|
+
/** Text value for accessibility. */
|
|
93
|
+
textValue?: string;
|
|
94
|
+
/** Whether this column is a row header. */
|
|
95
|
+
isRowHeader?: boolean;
|
|
96
|
+
/** Whether this column allows sorting. */
|
|
97
|
+
allowsSorting?: boolean;
|
|
98
|
+
/** Child columns (for column groups). */
|
|
99
|
+
children?: ColumnDefinition<T>[];
|
|
100
|
+
/** Width of the column. */
|
|
101
|
+
width?: number | string;
|
|
102
|
+
/** Minimum width of the column. */
|
|
103
|
+
minWidth?: number;
|
|
104
|
+
/** Maximum width of the column. */
|
|
105
|
+
maxWidth?: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Row definition for building table collections.
|
|
109
|
+
*/
|
|
110
|
+
export interface RowDefinition<T = unknown> {
|
|
111
|
+
/** The key for the row. */
|
|
112
|
+
key: Key;
|
|
113
|
+
/** The data value for the row. */
|
|
114
|
+
value: T;
|
|
115
|
+
/** Text value for accessibility/search. */
|
|
116
|
+
textValue?: string;
|
|
117
|
+
/** Whether this row has child rows (for tree tables). */
|
|
118
|
+
hasChildRows?: boolean;
|
|
119
|
+
/** Child rows (for tree tables). */
|
|
120
|
+
childRows?: RowDefinition<T>[];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Options for building a table collection.
|
|
124
|
+
*/
|
|
125
|
+
export interface TableCollectionOptions<T = unknown> {
|
|
126
|
+
/** Column definitions. */
|
|
127
|
+
columns: ColumnDefinition<T>[];
|
|
128
|
+
/** Row definitions or data items. */
|
|
129
|
+
rows: RowDefinition<T>[] | T[];
|
|
130
|
+
/** Function to get the key from a data item. */
|
|
131
|
+
getKey?: (item: T) => Key;
|
|
132
|
+
/** Function to get the text value from a data item. */
|
|
133
|
+
getTextValue?: (item: T, column: ColumnDefinition<T>) => string;
|
|
134
|
+
/** Whether to show selection checkboxes. */
|
|
135
|
+
showSelectionCheckboxes?: boolean;
|
|
136
|
+
/** Set of column keys that serve as row headers. */
|
|
137
|
+
rowHeaderColumnKeys?: Set<Key>;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=types.d.ts.map
|