@proyecto-viviana/solid-stately 0.2.7 → 0.4.0
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 +30 -283
- package/dist/autocomplete/createAutocompleteState.d.ts +2 -2
- package/dist/autocomplete/index.d.ts +1 -1
- package/dist/calendar/IncompleteDate.d.ts +61 -0
- package/dist/calendar/createCalendarState.d.ts +41 -16
- package/dist/calendar/createDateFieldState.d.ts +39 -9
- package/dist/calendar/createDatePickerState.d.ts +60 -0
- package/dist/calendar/createRangeCalendarState.d.ts +37 -10
- package/dist/calendar/createTimeFieldState.d.ts +34 -7
- package/dist/calendar/index.d.ts +7 -6
- package/dist/checkbox/createCheckboxGroupState.d.ts +6 -6
- package/dist/checkbox/index.d.ts +1 -1
- package/dist/collections/ListCollection.d.ts +1 -1
- package/dist/collections/createListState.d.ts +11 -8
- package/dist/collections/createMenuState.d.ts +7 -7
- package/dist/collections/createSelectionState.d.ts +22 -10
- package/dist/collections/getChildNodes.d.ts +11 -0
- package/dist/collections/index.d.ts +6 -5
- package/dist/collections/types.d.ts +12 -12
- package/dist/color/Color.d.ts +1 -1
- package/dist/color/createColorAreaState.d.ts +4 -2
- package/dist/color/createColorFieldState.d.ts +38 -12
- package/dist/color/createColorSliderState.d.ts +9 -2
- package/dist/color/createColorWheelState.d.ts +13 -2
- package/dist/color/getColorChannels.d.ts +1 -1
- package/dist/color/index.d.ts +6 -6
- package/dist/color/types.d.ts +4 -4
- package/dist/combobox/createComboBoxState.d.ts +34 -13
- package/dist/combobox/index.d.ts +1 -1
- package/dist/data/createAsyncList.d.ts +4 -4
- package/dist/data/createListData.d.ts +2 -2
- package/dist/data/createTreeData.d.ts +6 -2
- package/dist/data/index.d.ts +3 -3
- package/dist/datepicker/index.d.ts +2 -4
- package/dist/disclosure/createDisclosureState.d.ts +2 -2
- package/dist/disclosure/index.d.ts +1 -1
- package/dist/dnd/createDragState.d.ts +2 -2
- package/dist/dnd/createDraggableCollectionState.d.ts +2 -2
- package/dist/dnd/createDropState.d.ts +2 -2
- package/dist/dnd/createDroppableCollectionState.d.ts +3 -3
- package/dist/dnd/index.d.ts +5 -5
- package/dist/dnd/types.d.ts +19 -17
- package/dist/form/createFormValidationState.d.ts +3 -3
- package/dist/form/index.d.ts +1 -1
- package/dist/grid/createGridState.d.ts +2 -2
- package/dist/grid/index.d.ts +2 -2
- package/dist/grid/types.d.ts +27 -11
- package/dist/index.d.ts +31 -30
- package/dist/index.js +9077 -7246
- package/dist/index.js.map +1 -1
- package/dist/menu/index.d.ts +2 -2
- package/dist/numberfield/createNumberFieldState.d.ts +2 -2
- package/dist/numberfield/index.d.ts +1 -1
- package/dist/overlays/createOverlayTriggerState.d.ts +2 -2
- package/dist/overlays/index.d.ts +1 -1
- package/dist/radio/createRadioGroupState.d.ts +7 -7
- package/dist/radio/index.d.ts +1 -1
- package/dist/searchfield/createSearchFieldState.d.ts +2 -2
- package/dist/searchfield/index.d.ts +2 -2
- package/dist/select/createSelectState.d.ts +14 -8
- package/dist/select/index.d.ts +1 -1
- package/dist/selection/Selection.d.ts +16 -0
- package/dist/selection/SelectionManager.d.ts +110 -0
- package/dist/selection/createMultipleSelectionState.d.ts +59 -0
- package/dist/selection/index.d.ts +6 -5
- package/dist/slider/createSliderState.d.ts +3 -3
- package/dist/slider/index.d.ts +2 -2
- package/dist/steplist/createStepListState.d.ts +48 -0
- package/dist/steplist/index.d.ts +1 -0
- package/dist/table/TableCollection.d.ts +33 -3
- package/dist/table/createTableColumnResizeState.d.ts +54 -0
- package/dist/table/createTableState.d.ts +2 -2
- package/dist/table/createTreeGridState.d.ts +15 -0
- package/dist/table/index.d.ts +6 -3
- package/dist/table/types.d.ts +68 -10
- package/dist/tabs/createTabListState.d.ts +5 -5
- package/dist/tabs/index.d.ts +1 -1
- package/dist/textfield/createTextFieldState.d.ts +2 -2
- package/dist/textfield/index.d.ts +1 -1
- package/dist/toast/createToastState.d.ts +24 -2
- package/dist/toast/index.d.ts +1 -1
- package/dist/toggle/createToggleGroupState.d.ts +4 -4
- package/dist/toggle/createToggleState.d.ts +2 -2
- package/dist/toggle/index.d.ts +2 -2
- package/dist/tooltip/createTooltipTriggerState.d.ts +2 -2
- package/dist/tooltip/index.d.ts +1 -1
- package/dist/tree/TreeCollection.d.ts +2 -2
- package/dist/tree/createTreeState.d.ts +2 -2
- package/dist/tree/index.d.ts +3 -3
- package/dist/tree/types.d.ts +27 -13
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/reactivity.d.ts +1 -1
- package/package.json +29 -30
- package/src/autocomplete/createAutocompleteState.d.ts +19 -17
- package/src/autocomplete/createAutocompleteState.ts +24 -30
- package/src/autocomplete/index.d.ts +6 -2
- package/src/autocomplete/index.ts +1 -1
- package/src/calendar/IncompleteDate.ts +430 -0
- package/src/calendar/createCalendarState.d.ts +139 -117
- package/src/calendar/createCalendarState.ts +308 -94
- package/src/calendar/createDateFieldState.d.ts +130 -95
- package/src/calendar/createDateFieldState.ts +447 -334
- package/src/calendar/createDatePickerState.ts +347 -0
- package/src/calendar/createRangeCalendarState.d.ts +154 -129
- package/src/calendar/createRangeCalendarState.ts +411 -85
- package/src/calendar/createTimeFieldState.d.ts +81 -79
- package/src/calendar/createTimeFieldState.ts +187 -108
- package/src/calendar/index.d.ts +80 -7
- package/src/calendar/index.ts +23 -12
- package/src/checkbox/createCheckboxGroupState.d.ts +57 -55
- package/src/checkbox/createCheckboxGroupState.ts +20 -29
- package/src/checkbox/index.d.ts +6 -2
- package/src/checkbox/index.ts +1 -1
- package/src/collections/ListCollection.d.ts +25 -22
- package/src/collections/ListCollection.ts +6 -6
- package/src/collections/createListState.d.ts +73 -58
- package/src/collections/createListState.ts +67 -35
- package/src/collections/createMenuState.d.ts +36 -31
- package/src/collections/createMenuState.ts +21 -12
- package/src/collections/createSelectionState.d.ts +78 -65
- package/src/collections/createSelectionState.ts +66 -52
- package/src/collections/getChildNodes.ts +98 -0
- package/src/collections/index.d.ts +38 -6
- package/src/collections/index.ts +14 -10
- package/src/collections/types.d.ts +101 -101
- package/src/collections/types.ts +12 -12
- package/src/color/Color.d.ts +20 -5
- package/src/color/Color.ts +357 -254
- package/src/color/createColorAreaState.d.ts +67 -65
- package/src/color/createColorAreaState.ts +21 -13
- package/src/color/createColorFieldState.d.ts +46 -44
- package/src/color/createColorFieldState.ts +285 -149
- package/src/color/createColorSliderState.d.ts +58 -56
- package/src/color/createColorSliderState.ts +45 -14
- package/src/color/createColorWheelState.d.ts +42 -40
- package/src/color/createColorWheelState.ts +101 -64
- package/src/color/getColorChannels.ts +7 -5
- package/src/color/index.d.ts +36 -7
- package/src/color/index.ts +6 -9
- package/src/color/types.d.ts +68 -63
- package/src/color/types.ts +11 -19
- package/src/combobox/createComboBoxState.d.ts +107 -105
- package/src/combobox/createComboBoxState.ts +184 -89
- package/src/combobox/index.d.ts +10 -2
- package/src/combobox/index.ts +1 -1
- package/src/data/createAsyncList.ts +89 -63
- package/src/data/createListData.ts +67 -67
- package/src/data/createTreeData.ts +304 -91
- package/src/data/index.ts +3 -3
- package/src/datepicker/index.ts +6 -10
- package/src/disclosure/createDisclosureState.d.ts +47 -43
- package/src/disclosure/createDisclosureState.ts +7 -21
- package/src/disclosure/index.d.ts +10 -2
- package/src/disclosure/index.ts +1 -1
- package/src/dnd/createDragState.d.ts +51 -42
- package/src/dnd/createDragState.ts +12 -14
- package/src/dnd/createDraggableCollectionState.d.ts +52 -41
- package/src/dnd/createDraggableCollectionState.ts +14 -21
- package/src/dnd/createDropState.d.ts +64 -45
- package/src/dnd/createDropState.ts +22 -32
- package/src/dnd/createDroppableCollectionState.d.ts +88 -59
- package/src/dnd/createDroppableCollectionState.ts +40 -43
- package/src/dnd/index.d.ts +55 -6
- package/src/dnd/index.ts +6 -18
- package/src/dnd/types.d.ts +170 -157
- package/src/dnd/types.ts +24 -22
- package/src/form/createFormValidationState.d.ts +47 -45
- package/src/form/createFormValidationState.ts +30 -63
- package/src/form/index.d.ts +16 -2
- package/src/form/index.ts +1 -1
- package/src/grid/createGridState.d.ts +7 -4
- package/src/grid/createGridState.ts +78 -51
- package/src/grid/index.d.ts +3 -3
- package/src/grid/index.ts +2 -8
- package/src/grid/types.d.ts +136 -129
- package/src/grid/types.ts +34 -18
- package/src/index.d.ts +311 -26
- package/src/index.ts +59 -89
- package/src/menu/index.ts +2 -4
- package/src/numberfield/createNumberFieldState.d.ts +56 -54
- package/src/numberfield/createNumberFieldState.ts +26 -31
- package/src/numberfield/index.d.ts +6 -2
- package/src/numberfield/index.ts +1 -1
- package/src/overlays/createOverlayTriggerState.d.ts +22 -20
- package/src/overlays/createOverlayTriggerState.ts +3 -4
- package/src/overlays/index.d.ts +6 -2
- package/src/overlays/index.ts +1 -1
- package/src/radio/createRadioGroupState.d.ts +54 -52
- package/src/radio/createRadioGroupState.ts +27 -29
- package/src/radio/index.d.ts +7 -2
- package/src/radio/index.ts +1 -1
- package/src/searchfield/createSearchFieldState.d.ts +16 -14
- package/src/searchfield/createSearchFieldState.ts +5 -11
- package/src/searchfield/index.d.ts +3 -3
- package/src/searchfield/index.ts +2 -5
- package/src/select/createSelectState.d.ts +63 -61
- package/src/select/createSelectState.ts +42 -29
- package/src/select/index.d.ts +2 -2
- package/src/select/index.ts +1 -5
- package/src/selection/Selection.ts +28 -0
- package/src/selection/SelectionManager.ts +526 -0
- package/src/selection/createMultipleSelectionState.ts +247 -0
- package/src/selection/index.ts +12 -7
- package/src/slider/createSliderState.d.ts +60 -60
- package/src/slider/createSliderState.ts +55 -33
- package/src/slider/index.d.ts +3 -3
- package/src/slider/index.ts +2 -6
- package/src/ssr/index.d.ts +1 -1
- package/src/ssr/index.ts +2 -2
- package/src/steplist/createStepListState.ts +191 -0
- package/src/steplist/index.ts +5 -0
- package/src/table/TableCollection.d.ts +42 -40
- package/src/table/TableCollection.ts +266 -99
- package/src/table/createTableColumnResizeState.ts +242 -0
- package/src/table/createTableState.d.ts +7 -4
- package/src/table/createTableState.ts +30 -7
- package/src/table/createTreeGridState.ts +146 -0
- package/src/table/index.d.ts +14 -4
- package/src/table/index.ts +13 -3
- package/src/table/types.d.ts +98 -92
- package/src/table/types.ts +83 -13
- package/src/tabs/createTabListState.d.ts +59 -57
- package/src/tabs/createTabListState.ts +34 -39
- package/src/tabs/index.d.ts +8 -2
- package/src/tabs/index.ts +1 -1
- package/src/textfield/createTextFieldState.d.ts +16 -14
- package/src/textfield/createTextFieldState.ts +7 -18
- package/src/textfield/index.d.ts +6 -2
- package/src/textfield/index.ts +1 -1
- package/src/toast/createToastState.d.ts +92 -86
- package/src/toast/createToastState.ts +90 -52
- package/src/toast/index.d.ts +12 -2
- package/src/toast/index.ts +2 -1
- package/src/toggle/createToggleGroupState.ts +11 -21
- package/src/toggle/createToggleState.d.ts +19 -19
- package/src/toggle/createToggleState.ts +2 -16
- package/src/toggle/index.d.ts +2 -2
- package/src/toggle/index.ts +2 -6
- package/src/tooltip/createTooltipTriggerState.d.ts +17 -17
- package/src/tooltip/createTooltipTriggerState.ts +12 -11
- package/src/tooltip/index.d.ts +7 -2
- package/src/tooltip/index.ts +1 -1
- package/src/tree/TreeCollection.d.ts +26 -23
- package/src/tree/TreeCollection.ts +29 -22
- package/src/tree/createTreeState.d.ts +7 -4
- package/src/tree/createTreeState.ts +70 -41
- package/src/tree/index.d.ts +10 -4
- package/src/tree/index.ts +3 -3
- package/src/tree/types.d.ts +131 -126
- package/src/tree/types.ts +30 -13
- package/src/utils/index.d.ts +2 -2
- package/src/utils/index.ts +1 -1
- package/src/utils/reactivity.d.ts +2 -2
- package/src/utils/reactivity.ts +3 -3
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* convenience methods to update the data over time.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { createSignal } from
|
|
8
|
+
import { createSignal } from "solid-js";
|
|
9
9
|
|
|
10
10
|
export type Key = string | number;
|
|
11
|
-
export type Selection =
|
|
11
|
+
export type Selection = "all" | Set<Key>;
|
|
12
12
|
|
|
13
13
|
export interface TreeNode<T> {
|
|
14
14
|
/** A unique key for the tree node. */
|
|
@@ -25,7 +25,7 @@ export interface TreeOptions<T> {
|
|
|
25
25
|
/** Initial items in the tree. */
|
|
26
26
|
initialItems?: T[];
|
|
27
27
|
/** The keys for the initially selected items. */
|
|
28
|
-
initialSelectedKeys?:
|
|
28
|
+
initialSelectedKeys?: "all" | Iterable<Key>;
|
|
29
29
|
/** A function that returns a unique key for an item object. */
|
|
30
30
|
getKey?: (item: T) => Key;
|
|
31
31
|
/** A function that returns the children of an item object. */
|
|
@@ -57,6 +57,10 @@ export interface TreeData<T> {
|
|
|
57
57
|
removeSelectedItems(): void;
|
|
58
58
|
/** Moves an item to a new parent. */
|
|
59
59
|
move(key: Key, toParentKey: Key | null, index: number): void;
|
|
60
|
+
/** Moves items before a given key. */
|
|
61
|
+
moveBefore(key: Key, keys: Iterable<Key>): void;
|
|
62
|
+
/** Moves items after a given key. */
|
|
63
|
+
moveAfter(key: Key, keys: Iterable<Key>): void;
|
|
60
64
|
/** Updates an item in the tree. */
|
|
61
65
|
update(key: Key, newValue: T): void;
|
|
62
66
|
}
|
|
@@ -71,11 +75,20 @@ interface TreeDataState<T> {
|
|
|
71
75
|
* convenience methods to update the data over time.
|
|
72
76
|
*/
|
|
73
77
|
export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
78
|
+
const defaultGetKey = (item: T): Key => {
|
|
79
|
+
const candidate = item as { id?: Key; key?: Key };
|
|
80
|
+
return candidate.id ?? candidate.key ?? String(item);
|
|
81
|
+
};
|
|
82
|
+
const defaultGetChildren = (item: T): T[] => {
|
|
83
|
+
const candidate = item as { children?: T[] };
|
|
84
|
+
return candidate.children ?? [];
|
|
85
|
+
};
|
|
86
|
+
|
|
74
87
|
const {
|
|
75
88
|
initialItems = [],
|
|
76
89
|
initialSelectedKeys,
|
|
77
|
-
getKey =
|
|
78
|
-
getChildren =
|
|
90
|
+
getKey = defaultGetKey,
|
|
91
|
+
getChildren = defaultGetChildren,
|
|
79
92
|
} = options;
|
|
80
93
|
|
|
81
94
|
// Build initial tree
|
|
@@ -83,7 +96,7 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
83
96
|
|
|
84
97
|
const [treeState, setTreeState] = createSignal<TreeDataState<T>>(initialTree);
|
|
85
98
|
const [selectedKeys, setSelectedKeys] = createSignal<Selection>(
|
|
86
|
-
initialSelectedKeys ===
|
|
99
|
+
initialSelectedKeys === "all" ? "all" : new Set(initialSelectedKeys || []),
|
|
87
100
|
);
|
|
88
101
|
|
|
89
102
|
function updateTree(
|
|
@@ -103,12 +116,17 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
103
116
|
// Delete node
|
|
104
117
|
deleteNode(node, newMap);
|
|
105
118
|
if (node.parentKey != null) {
|
|
106
|
-
return updateTree(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
119
|
+
return updateTree(
|
|
120
|
+
items,
|
|
121
|
+
node.parentKey,
|
|
122
|
+
(parent) => ({
|
|
123
|
+
...parent,
|
|
124
|
+
children: parent.children!.filter((c) => c.key !== key),
|
|
125
|
+
}),
|
|
126
|
+
newMap,
|
|
127
|
+
);
|
|
110
128
|
}
|
|
111
|
-
return { items: items.filter(i => i.key !== key), nodeMap: newMap };
|
|
129
|
+
return { items: items.filter((i) => i.key !== key), nodeMap: newMap };
|
|
112
130
|
}
|
|
113
131
|
|
|
114
132
|
newMap.set(key!, updated);
|
|
@@ -119,21 +137,30 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
119
137
|
}
|
|
120
138
|
|
|
121
139
|
if (node.parentKey != null) {
|
|
122
|
-
return updateTree(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
140
|
+
return updateTree(
|
|
141
|
+
items,
|
|
142
|
+
node.parentKey,
|
|
143
|
+
(parent) => ({
|
|
144
|
+
...parent,
|
|
145
|
+
children: parent.children!.map((c) => (c.key === key ? updated : c)),
|
|
146
|
+
}),
|
|
147
|
+
newMap,
|
|
148
|
+
);
|
|
126
149
|
}
|
|
127
150
|
|
|
128
|
-
return { items: items.map(i => i.key === key ? updated : i), nodeMap: newMap };
|
|
151
|
+
return { items: items.map((i) => (i.key === key ? updated : i)), nodeMap: newMap };
|
|
129
152
|
}
|
|
130
153
|
|
|
131
154
|
return { items, nodeMap: newMap };
|
|
132
155
|
}
|
|
133
156
|
|
|
134
157
|
return {
|
|
135
|
-
get items() {
|
|
136
|
-
|
|
158
|
+
get items() {
|
|
159
|
+
return treeState().items;
|
|
160
|
+
},
|
|
161
|
+
get selectedKeys() {
|
|
162
|
+
return selectedKeys();
|
|
163
|
+
},
|
|
137
164
|
|
|
138
165
|
setSelectedKeys(keys: Selection) {
|
|
139
166
|
setSelectedKeys(keys);
|
|
@@ -144,10 +171,10 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
144
171
|
},
|
|
145
172
|
|
|
146
173
|
insert(parentKey: Key | null, index: number, ...values: T[]) {
|
|
147
|
-
setTreeState(state => {
|
|
174
|
+
setTreeState((state) => {
|
|
148
175
|
const { items, nodeMap } = state;
|
|
149
176
|
const newMap = new Map(nodeMap);
|
|
150
|
-
const newNodes = values.map(v => {
|
|
177
|
+
const newNodes = values.map((v) => {
|
|
151
178
|
const tree = buildTree([v], newMap, parentKey, getKey, getChildren);
|
|
152
179
|
return tree.items[0];
|
|
153
180
|
});
|
|
@@ -159,30 +186,35 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
159
186
|
};
|
|
160
187
|
}
|
|
161
188
|
|
|
162
|
-
return updateTree(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
...
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
189
|
+
return updateTree(
|
|
190
|
+
items,
|
|
191
|
+
parentKey,
|
|
192
|
+
(parent) => ({
|
|
193
|
+
...parent,
|
|
194
|
+
children: [
|
|
195
|
+
...(parent.children || []).slice(0, index),
|
|
196
|
+
...newNodes,
|
|
197
|
+
...(parent.children || []).slice(index),
|
|
198
|
+
],
|
|
199
|
+
}),
|
|
200
|
+
newMap,
|
|
201
|
+
);
|
|
170
202
|
});
|
|
171
203
|
},
|
|
172
204
|
|
|
173
205
|
insertBefore(key: Key, ...values: T[]) {
|
|
174
|
-
setTreeState(state => {
|
|
206
|
+
setTreeState((state) => {
|
|
175
207
|
const { items, nodeMap } = state;
|
|
176
208
|
const node = nodeMap.get(key);
|
|
177
209
|
if (!node) return state;
|
|
178
210
|
|
|
179
211
|
const parent = node.parentKey != null ? nodeMap.get(node.parentKey) : null;
|
|
180
212
|
const siblings = parent?.children ?? items;
|
|
181
|
-
const index = siblings.findIndex(n => n.key === key);
|
|
213
|
+
const index = siblings.findIndex((n) => n.key === key);
|
|
182
214
|
if (index === -1) return state;
|
|
183
215
|
|
|
184
216
|
const newMap = new Map(nodeMap);
|
|
185
|
-
const newNodes = values.map(v => {
|
|
217
|
+
const newNodes = values.map((v) => {
|
|
186
218
|
const tree = buildTree([v], newMap, node.parentKey, getKey, getChildren);
|
|
187
219
|
return tree.items[0];
|
|
188
220
|
});
|
|
@@ -194,30 +226,31 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
194
226
|
};
|
|
195
227
|
}
|
|
196
228
|
|
|
197
|
-
return updateTree(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
...
|
|
202
|
-
...p.children!.slice(index),
|
|
203
|
-
|
|
204
|
-
|
|
229
|
+
return updateTree(
|
|
230
|
+
items,
|
|
231
|
+
node.parentKey,
|
|
232
|
+
(p) => ({
|
|
233
|
+
...p,
|
|
234
|
+
children: [...p.children!.slice(0, index), ...newNodes, ...p.children!.slice(index)],
|
|
235
|
+
}),
|
|
236
|
+
newMap,
|
|
237
|
+
);
|
|
205
238
|
});
|
|
206
239
|
},
|
|
207
240
|
|
|
208
241
|
insertAfter(key: Key, ...values: T[]) {
|
|
209
|
-
setTreeState(state => {
|
|
242
|
+
setTreeState((state) => {
|
|
210
243
|
const { items, nodeMap } = state;
|
|
211
244
|
const node = nodeMap.get(key);
|
|
212
245
|
if (!node) return state;
|
|
213
246
|
|
|
214
247
|
const parent = node.parentKey != null ? nodeMap.get(node.parentKey) : null;
|
|
215
248
|
const siblings = parent?.children ?? items;
|
|
216
|
-
const index = siblings.findIndex(n => n.key === key);
|
|
249
|
+
const index = siblings.findIndex((n) => n.key === key);
|
|
217
250
|
if (index === -1) return state;
|
|
218
251
|
|
|
219
252
|
const newMap = new Map(nodeMap);
|
|
220
|
-
const newNodes = values.map(v => {
|
|
253
|
+
const newNodes = values.map((v) => {
|
|
221
254
|
const tree = buildTree([v], newMap, node.parentKey, getKey, getChildren);
|
|
222
255
|
return tree.items[0];
|
|
223
256
|
});
|
|
@@ -229,22 +262,27 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
229
262
|
};
|
|
230
263
|
}
|
|
231
264
|
|
|
232
|
-
return updateTree(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
...
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
265
|
+
return updateTree(
|
|
266
|
+
items,
|
|
267
|
+
node.parentKey,
|
|
268
|
+
(p) => ({
|
|
269
|
+
...p,
|
|
270
|
+
children: [
|
|
271
|
+
...p.children!.slice(0, index + 1),
|
|
272
|
+
...newNodes,
|
|
273
|
+
...p.children!.slice(index + 1),
|
|
274
|
+
],
|
|
275
|
+
}),
|
|
276
|
+
newMap,
|
|
277
|
+
);
|
|
240
278
|
});
|
|
241
279
|
},
|
|
242
280
|
|
|
243
281
|
append(parentKey: Key | null, ...values: T[]) {
|
|
244
|
-
setTreeState(state => {
|
|
282
|
+
setTreeState((state) => {
|
|
245
283
|
const { items, nodeMap } = state;
|
|
246
284
|
const newMap = new Map(nodeMap);
|
|
247
|
-
const newNodes = values.map(v => {
|
|
285
|
+
const newNodes = values.map((v) => {
|
|
248
286
|
const tree = buildTree([v], newMap, parentKey, getKey, getChildren);
|
|
249
287
|
return tree.items[0];
|
|
250
288
|
});
|
|
@@ -253,18 +291,23 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
253
291
|
return { items: [...items, ...newNodes], nodeMap: newMap };
|
|
254
292
|
}
|
|
255
293
|
|
|
256
|
-
return updateTree(
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
294
|
+
return updateTree(
|
|
295
|
+
items,
|
|
296
|
+
parentKey,
|
|
297
|
+
(parent) => ({
|
|
298
|
+
...parent,
|
|
299
|
+
children: [...(parent.children || []), ...newNodes],
|
|
300
|
+
}),
|
|
301
|
+
newMap,
|
|
302
|
+
);
|
|
260
303
|
});
|
|
261
304
|
},
|
|
262
305
|
|
|
263
306
|
prepend(parentKey: Key | null, ...values: T[]) {
|
|
264
|
-
setTreeState(state => {
|
|
307
|
+
setTreeState((state) => {
|
|
265
308
|
const { items, nodeMap } = state;
|
|
266
309
|
const newMap = new Map(nodeMap);
|
|
267
|
-
const newNodes = values.map(v => {
|
|
310
|
+
const newNodes = values.map((v) => {
|
|
268
311
|
const tree = buildTree([v], newMap, parentKey, getKey, getChildren);
|
|
269
312
|
return tree.items[0];
|
|
270
313
|
});
|
|
@@ -273,15 +316,20 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
273
316
|
return { items: [...newNodes, ...items], nodeMap: newMap };
|
|
274
317
|
}
|
|
275
318
|
|
|
276
|
-
return updateTree(
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
319
|
+
return updateTree(
|
|
320
|
+
items,
|
|
321
|
+
parentKey,
|
|
322
|
+
(parent) => ({
|
|
323
|
+
...parent,
|
|
324
|
+
children: [...newNodes, ...(parent.children || [])],
|
|
325
|
+
}),
|
|
326
|
+
newMap,
|
|
327
|
+
);
|
|
280
328
|
});
|
|
281
329
|
},
|
|
282
330
|
|
|
283
331
|
remove(...keys: Key[]) {
|
|
284
|
-
setTreeState(state => {
|
|
332
|
+
setTreeState((state) => {
|
|
285
333
|
let { items, nodeMap } = state;
|
|
286
334
|
let newMap = new Map(nodeMap);
|
|
287
335
|
let newItems = items;
|
|
@@ -295,8 +343,8 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
295
343
|
return { items: newItems, nodeMap: newMap };
|
|
296
344
|
});
|
|
297
345
|
|
|
298
|
-
setSelectedKeys(sel => {
|
|
299
|
-
if (sel ===
|
|
346
|
+
setSelectedKeys((sel) => {
|
|
347
|
+
if (sel === "all") return sel;
|
|
300
348
|
const newSel = new Set(sel);
|
|
301
349
|
for (const key of keys) {
|
|
302
350
|
newSel.delete(key);
|
|
@@ -307,14 +355,14 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
307
355
|
|
|
308
356
|
removeSelectedItems() {
|
|
309
357
|
const sel = selectedKeys();
|
|
310
|
-
if (sel ===
|
|
358
|
+
if (sel === "all") {
|
|
311
359
|
setTreeState({ items: [], nodeMap: new Map() });
|
|
312
360
|
setSelectedKeys(new Set<Key>());
|
|
313
361
|
return;
|
|
314
362
|
}
|
|
315
363
|
|
|
316
364
|
const keysToRemove = [...sel];
|
|
317
|
-
setTreeState(state => {
|
|
365
|
+
setTreeState((state) => {
|
|
318
366
|
let { items, nodeMap } = state;
|
|
319
367
|
let newMap = new Map(nodeMap);
|
|
320
368
|
let newItems = items;
|
|
@@ -329,11 +377,20 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
329
377
|
},
|
|
330
378
|
|
|
331
379
|
move(key: Key, toParentKey: Key | null, index: number) {
|
|
332
|
-
setTreeState(state => {
|
|
380
|
+
setTreeState((state) => {
|
|
333
381
|
const { items, nodeMap } = state;
|
|
334
382
|
const node = nodeMap.get(key);
|
|
335
383
|
if (!node) return state;
|
|
336
384
|
|
|
385
|
+
// Cyclical move validation: prevent moving a node into its own subtree
|
|
386
|
+
if (toParentKey != null) {
|
|
387
|
+
let parent: TreeNode<T> | undefined = nodeMap.get(toParentKey);
|
|
388
|
+
while (parent) {
|
|
389
|
+
if (parent.key === key) return state;
|
|
390
|
+
parent = parent.parentKey != null ? nodeMap.get(parent.parentKey) : undefined;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
337
394
|
// Remove the node
|
|
338
395
|
let newMap = new Map(nodeMap);
|
|
339
396
|
const removeResult = updateTree(items, key, () => null, newMap);
|
|
@@ -351,33 +408,76 @@ export function createTreeData<T>(options: TreeOptions<T>): TreeData<T> {
|
|
|
351
408
|
};
|
|
352
409
|
}
|
|
353
410
|
|
|
354
|
-
return updateTree(
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
411
|
+
return updateTree(
|
|
412
|
+
newItems,
|
|
413
|
+
toParentKey,
|
|
414
|
+
(parent) => ({
|
|
415
|
+
...parent,
|
|
416
|
+
children: [
|
|
417
|
+
...(parent.children || []).slice(0, index),
|
|
418
|
+
movedNode,
|
|
419
|
+
...(parent.children || []).slice(index),
|
|
420
|
+
],
|
|
421
|
+
}),
|
|
422
|
+
newMap,
|
|
423
|
+
);
|
|
424
|
+
});
|
|
425
|
+
},
|
|
426
|
+
|
|
427
|
+
moveBefore(key: Key, keys: Iterable<Key>) {
|
|
428
|
+
setTreeState((state) => {
|
|
429
|
+
const { items, nodeMap } = state;
|
|
430
|
+
const node = nodeMap.get(key);
|
|
431
|
+
if (!node) return state;
|
|
432
|
+
|
|
433
|
+
const toParentKey = node.parentKey ?? null;
|
|
434
|
+
let parent: TreeNode<T> | null = null;
|
|
435
|
+
if (toParentKey != null) {
|
|
436
|
+
parent = nodeMap.get(toParentKey) ?? null;
|
|
437
|
+
}
|
|
438
|
+
const toIndex = parent?.children ? parent.children.indexOf(node) : items.indexOf(node);
|
|
439
|
+
return moveItems(state, keys, parent, toIndex, updateTree, addNode);
|
|
440
|
+
});
|
|
441
|
+
},
|
|
442
|
+
|
|
443
|
+
moveAfter(key: Key, keys: Iterable<Key>) {
|
|
444
|
+
setTreeState((state) => {
|
|
445
|
+
const { items, nodeMap } = state;
|
|
446
|
+
const node = nodeMap.get(key);
|
|
447
|
+
if (!node) return state;
|
|
448
|
+
|
|
449
|
+
const toParentKey = node.parentKey ?? null;
|
|
450
|
+
let parent: TreeNode<T> | null = null;
|
|
451
|
+
if (toParentKey != null) {
|
|
452
|
+
parent = nodeMap.get(toParentKey) ?? null;
|
|
453
|
+
}
|
|
454
|
+
let toIndex = parent?.children ? parent.children.indexOf(node) : items.indexOf(node);
|
|
455
|
+
toIndex++;
|
|
456
|
+
return moveItems(state, keys, parent, toIndex, updateTree, addNode);
|
|
362
457
|
});
|
|
363
458
|
},
|
|
364
459
|
|
|
365
460
|
update(key: Key, newValue: T) {
|
|
366
|
-
setTreeState(state => {
|
|
461
|
+
setTreeState((state) => {
|
|
367
462
|
const { items, nodeMap } = state;
|
|
368
463
|
const newMap = new Map(nodeMap);
|
|
369
464
|
|
|
370
|
-
return updateTree(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
465
|
+
return updateTree(
|
|
466
|
+
items,
|
|
467
|
+
key,
|
|
468
|
+
(oldNode) => {
|
|
469
|
+
const node: TreeNode<T> = {
|
|
470
|
+
key: oldNode.key,
|
|
471
|
+
parentKey: oldNode.parentKey,
|
|
472
|
+
value: newValue,
|
|
473
|
+
children: null,
|
|
474
|
+
};
|
|
475
|
+
const tree = buildTree(getChildren(newValue), newMap, node.key, getKey, getChildren);
|
|
476
|
+
node.children = tree.items;
|
|
477
|
+
return node;
|
|
478
|
+
},
|
|
479
|
+
newMap,
|
|
480
|
+
);
|
|
381
481
|
});
|
|
382
482
|
},
|
|
383
483
|
};
|
|
@@ -396,9 +496,10 @@ function buildTree<T>(
|
|
|
396
496
|
const key = getKey(item);
|
|
397
497
|
const children = getChildren(item);
|
|
398
498
|
|
|
399
|
-
const childTree =
|
|
400
|
-
|
|
401
|
-
|
|
499
|
+
const childTree =
|
|
500
|
+
children.length > 0
|
|
501
|
+
? buildTree(children, nodeMap, key, getKey, getChildren)
|
|
502
|
+
: { items: [], nodeMap };
|
|
402
503
|
|
|
403
504
|
const node: TreeNode<T> = {
|
|
404
505
|
key,
|
|
@@ -431,3 +532,115 @@ function deleteNode<T>(node: TreeNode<T>, map: Map<Key, TreeNode<T>>): void {
|
|
|
431
532
|
}
|
|
432
533
|
}
|
|
433
534
|
}
|
|
535
|
+
|
|
536
|
+
function moveItems<T>(
|
|
537
|
+
state: TreeDataState<T>,
|
|
538
|
+
keys: Iterable<Key>,
|
|
539
|
+
toParent: TreeNode<T> | null,
|
|
540
|
+
toIndex: number,
|
|
541
|
+
updateTreeFn: (
|
|
542
|
+
items: TreeNode<T>[],
|
|
543
|
+
key: Key | null,
|
|
544
|
+
update: (node: TreeNode<T>) => TreeNode<T> | null,
|
|
545
|
+
originalMap: Map<Key, TreeNode<T>>,
|
|
546
|
+
) => TreeDataState<T>,
|
|
547
|
+
addNodeFn: (node: TreeNode<T>, map: Map<Key, TreeNode<T>>) => void,
|
|
548
|
+
): TreeDataState<T> {
|
|
549
|
+
const { items, nodeMap } = state;
|
|
550
|
+
|
|
551
|
+
// Cyclical move validation: prevent moving a node into its own subtree
|
|
552
|
+
const removeKeys = new Set(keys);
|
|
553
|
+
let ancestor: TreeNode<T> | null = toParent;
|
|
554
|
+
while (ancestor != null) {
|
|
555
|
+
if (removeKeys.has(ancestor.key)) {
|
|
556
|
+
throw new Error("Cannot move an item to be a child of itself.");
|
|
557
|
+
}
|
|
558
|
+
ancestor = ancestor.parentKey != null ? (nodeMap.get(ancestor.parentKey) ?? null) : null;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
const originalToIndex = toIndex;
|
|
562
|
+
const keyArray = [...removeKeys];
|
|
563
|
+
|
|
564
|
+
// Depth-first traversal to determine in-order positions and remove items
|
|
565
|
+
const inOrderKeys = new Map<Key, number>();
|
|
566
|
+
const removedItems: TreeNode<T>[] = [];
|
|
567
|
+
let newItems = items;
|
|
568
|
+
let newMap = nodeMap;
|
|
569
|
+
let i = 0;
|
|
570
|
+
|
|
571
|
+
function traversal(
|
|
572
|
+
node: { children?: TreeNode<T>[] | null },
|
|
573
|
+
callbacks: {
|
|
574
|
+
inorder?: (child: TreeNode<T>) => void;
|
|
575
|
+
postorder?: (child: TreeNode<T>) => void;
|
|
576
|
+
},
|
|
577
|
+
) {
|
|
578
|
+
callbacks.inorder?.(node as TreeNode<T>);
|
|
579
|
+
if (node.children) {
|
|
580
|
+
for (const child of node.children) {
|
|
581
|
+
traversal(child, callbacks);
|
|
582
|
+
callbacks.postorder?.(child);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
traversal(
|
|
588
|
+
{ children: items },
|
|
589
|
+
{
|
|
590
|
+
inorder(child) {
|
|
591
|
+
if (keyArray.includes(child.key)) {
|
|
592
|
+
inOrderKeys.set(child.key, i++);
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
postorder(child) {
|
|
596
|
+
if (keyArray.includes(child.key)) {
|
|
597
|
+
removedItems.push({ ...newMap.get(child.key)!, parentKey: toParent?.key ?? null });
|
|
598
|
+
const result = updateTreeFn(newItems, child.key, () => null, newMap);
|
|
599
|
+
newItems = result.items;
|
|
600
|
+
newMap = result.nodeMap;
|
|
601
|
+
}
|
|
602
|
+
// Decrement index if the removed child is in the target parent and before the target index
|
|
603
|
+
if (
|
|
604
|
+
(child.parentKey === toParent || child.parentKey === toParent?.key) &&
|
|
605
|
+
keyArray.includes(child.key) &&
|
|
606
|
+
(toParent?.children ? toParent.children.indexOf(child) : items.indexOf(child)) <
|
|
607
|
+
originalToIndex
|
|
608
|
+
) {
|
|
609
|
+
toIndex--;
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
},
|
|
613
|
+
);
|
|
614
|
+
|
|
615
|
+
const inOrderItems = removedItems.sort((a, b) =>
|
|
616
|
+
inOrderKeys.get(a.key)! > inOrderKeys.get(b.key)! ? 1 : -1,
|
|
617
|
+
);
|
|
618
|
+
|
|
619
|
+
// If parentKey is null, insert into the root.
|
|
620
|
+
if (!toParent || toParent.key == null) {
|
|
621
|
+
inOrderItems.forEach((movedNode) => {
|
|
622
|
+
addNodeFn(movedNode, newMap);
|
|
623
|
+
});
|
|
624
|
+
return {
|
|
625
|
+
items: [...newItems.slice(0, toIndex), ...inOrderItems, ...newItems.slice(toIndex)],
|
|
626
|
+
nodeMap: newMap,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// Otherwise, update the parent node and its ancestors.
|
|
631
|
+
return updateTreeFn(
|
|
632
|
+
newItems,
|
|
633
|
+
toParent.key,
|
|
634
|
+
(parentNode) => ({
|
|
635
|
+
key: parentNode.key,
|
|
636
|
+
parentKey: parentNode.parentKey,
|
|
637
|
+
value: parentNode.value,
|
|
638
|
+
children: [
|
|
639
|
+
...parentNode.children!.slice(0, toIndex),
|
|
640
|
+
...inOrderItems,
|
|
641
|
+
...parentNode.children!.slice(toIndex),
|
|
642
|
+
],
|
|
643
|
+
}),
|
|
644
|
+
newMap,
|
|
645
|
+
);
|
|
646
|
+
}
|
package/src/data/index.ts
CHANGED
|
@@ -4,14 +4,14 @@ export {
|
|
|
4
4
|
type ListData,
|
|
5
5
|
type Key as ListDataKey,
|
|
6
6
|
type Selection as ListDataSelection,
|
|
7
|
-
} from
|
|
7
|
+
} from "./createListData";
|
|
8
8
|
|
|
9
9
|
export {
|
|
10
10
|
createTreeData,
|
|
11
11
|
type TreeOptions,
|
|
12
12
|
type TreeData,
|
|
13
13
|
type TreeNode as TreeDataNode,
|
|
14
|
-
} from
|
|
14
|
+
} from "./createTreeData";
|
|
15
15
|
|
|
16
16
|
export {
|
|
17
17
|
createAsyncList,
|
|
@@ -22,4 +22,4 @@ export {
|
|
|
22
22
|
type AsyncListStateUpdate,
|
|
23
23
|
type SortDescriptor,
|
|
24
24
|
type LoadingState,
|
|
25
|
-
} from
|
|
25
|
+
} from "./createAsyncList";
|
package/src/datepicker/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export {
|
|
|
9
9
|
createDateFieldState,
|
|
10
10
|
createTimeFieldState,
|
|
11
11
|
createRangeCalendarState,
|
|
12
|
+
createDatePickerState,
|
|
12
13
|
type DateFieldStateProps as DateFieldStateOptions,
|
|
13
14
|
type DateFieldState,
|
|
14
15
|
type DateSegment,
|
|
@@ -19,18 +20,13 @@ export {
|
|
|
19
20
|
type TimeSegmentType,
|
|
20
21
|
type RangeCalendarStateProps as DateRangePickerStateOptions,
|
|
21
22
|
type RangeCalendarState as DateRangePickerState,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
createOverlayTriggerState,
|
|
26
|
-
type OverlayTriggerProps as DatePickerStateOptions,
|
|
27
|
-
type OverlayTriggerState as DatePickerState,
|
|
28
|
-
} from '../overlays';
|
|
23
|
+
type DatePickerState,
|
|
24
|
+
type DatePickerStateOptions,
|
|
25
|
+
} from "../calendar";
|
|
29
26
|
|
|
30
27
|
export {
|
|
31
28
|
createDateFieldState as useDateFieldState,
|
|
32
29
|
createTimeFieldState as useTimeFieldState,
|
|
33
30
|
createRangeCalendarState as useDateRangePickerState,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export { createOverlayTriggerState as useDatePickerState } from '../overlays';
|
|
31
|
+
createDatePickerState as useDatePickerState,
|
|
32
|
+
} from "../calendar";
|