@proyecto-viviana/solid-stately 0.2.4 → 0.3.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.
Files changed (243) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -283
  3. package/dist/autocomplete/createAutocompleteState.d.ts +3 -2
  4. package/dist/autocomplete/index.d.ts +1 -1
  5. package/dist/calendar/createCalendarState.d.ts +22 -7
  6. package/dist/calendar/createDateFieldState.d.ts +30 -7
  7. package/dist/calendar/createDatePickerState.d.ts +60 -0
  8. package/dist/calendar/createRangeCalendarState.d.ts +27 -8
  9. package/dist/calendar/createTimeFieldState.d.ts +34 -7
  10. package/dist/calendar/index.d.ts +7 -6
  11. package/dist/checkbox/createCheckboxGroupState.d.ts +12 -3
  12. package/dist/checkbox/index.d.ts +1 -1
  13. package/dist/collections/ListCollection.d.ts +1 -1
  14. package/dist/collections/createListState.d.ts +8 -8
  15. package/dist/collections/createMenuState.d.ts +7 -7
  16. package/dist/collections/createSelectionState.d.ts +5 -5
  17. package/dist/collections/index.d.ts +5 -5
  18. package/dist/collections/types.d.ts +23 -12
  19. package/dist/color/Color.d.ts +1 -1
  20. package/dist/color/createColorAreaState.d.ts +4 -2
  21. package/dist/color/createColorFieldState.d.ts +38 -12
  22. package/dist/color/createColorSliderState.d.ts +9 -2
  23. package/dist/color/createColorWheelState.d.ts +13 -2
  24. package/dist/color/getColorChannels.d.ts +20 -0
  25. package/dist/color/index.d.ts +6 -6
  26. package/dist/color/types.d.ts +4 -4
  27. package/dist/combobox/createComboBoxState.d.ts +27 -13
  28. package/dist/combobox/index.d.ts +1 -1
  29. package/dist/data/createAsyncList.d.ts +111 -0
  30. package/dist/data/createListData.d.ts +65 -0
  31. package/dist/data/createTreeData.d.ts +65 -0
  32. package/dist/data/index.d.ts +3 -0
  33. package/dist/datepicker/index.d.ts +8 -0
  34. package/dist/disclosure/createDisclosureState.d.ts +2 -2
  35. package/dist/disclosure/index.d.ts +1 -1
  36. package/dist/dnd/createDragState.d.ts +2 -2
  37. package/dist/dnd/createDraggableCollectionState.d.ts +2 -2
  38. package/dist/dnd/createDropState.d.ts +2 -2
  39. package/dist/dnd/createDroppableCollectionState.d.ts +3 -3
  40. package/dist/dnd/index.d.ts +5 -5
  41. package/dist/dnd/types.d.ts +16 -16
  42. package/dist/form/createFormValidationState.d.ts +3 -3
  43. package/dist/form/index.d.ts +1 -1
  44. package/dist/grid/createGridState.d.ts +2 -2
  45. package/dist/grid/index.d.ts +2 -2
  46. package/dist/grid/types.d.ts +17 -11
  47. package/dist/index.d.ts +31 -25
  48. package/dist/index.js +7990 -6264
  49. package/dist/index.js.map +1 -7
  50. package/dist/menu/index.d.ts +8 -0
  51. package/dist/numberfield/createNumberFieldState.d.ts +2 -2
  52. package/dist/numberfield/index.d.ts +1 -1
  53. package/dist/overlays/createOverlayTriggerState.d.ts +2 -2
  54. package/dist/overlays/index.d.ts +1 -1
  55. package/dist/radio/createRadioGroupState.d.ts +13 -4
  56. package/dist/radio/index.d.ts +1 -1
  57. package/dist/searchfield/createSearchFieldState.d.ts +2 -2
  58. package/dist/searchfield/index.d.ts +2 -2
  59. package/dist/select/createSelectState.d.ts +20 -3
  60. package/dist/select/index.d.ts +1 -1
  61. package/dist/selection/index.d.ts +11 -0
  62. package/dist/slider/createSliderState.d.ts +3 -3
  63. package/dist/slider/index.d.ts +2 -2
  64. package/dist/steplist/createStepListState.d.ts +48 -0
  65. package/dist/steplist/index.d.ts +1 -0
  66. package/dist/table/TableCollection.d.ts +3 -3
  67. package/dist/table/createTableColumnResizeState.d.ts +54 -0
  68. package/dist/table/createTableState.d.ts +2 -2
  69. package/dist/table/index.d.ts +5 -3
  70. package/dist/table/types.d.ts +10 -10
  71. package/dist/tabs/createTabListState.d.ts +5 -5
  72. package/dist/tabs/index.d.ts +1 -1
  73. package/dist/textfield/createTextFieldState.d.ts +2 -2
  74. package/dist/textfield/index.d.ts +1 -1
  75. package/dist/toast/createToastState.d.ts +15 -3
  76. package/dist/toast/index.d.ts +1 -1
  77. package/dist/toggle/createToggleGroupState.d.ts +45 -0
  78. package/dist/toggle/createToggleState.d.ts +2 -2
  79. package/dist/toggle/index.d.ts +2 -1
  80. package/dist/tooltip/createTooltipTriggerState.d.ts +2 -2
  81. package/dist/tooltip/index.d.ts +1 -1
  82. package/dist/tree/TreeCollection.d.ts +5 -4
  83. package/dist/tree/createTreeState.d.ts +2 -2
  84. package/dist/tree/index.d.ts +3 -3
  85. package/dist/tree/types.d.ts +19 -13
  86. package/dist/utils/index.d.ts +1 -1
  87. package/dist/utils/reactivity.d.ts +1 -1
  88. package/package.json +30 -30
  89. package/src/autocomplete/createAutocompleteState.d.ts +19 -17
  90. package/src/autocomplete/createAutocompleteState.ts +25 -32
  91. package/src/autocomplete/index.d.ts +6 -2
  92. package/src/autocomplete/index.ts +1 -1
  93. package/src/calendar/createCalendarState.d.ts +139 -117
  94. package/src/calendar/createCalendarState.ts +221 -74
  95. package/src/calendar/createDateFieldState.d.ts +130 -95
  96. package/src/calendar/createDateFieldState.ts +286 -151
  97. package/src/calendar/createDatePickerState.ts +347 -0
  98. package/src/calendar/createRangeCalendarState.d.ts +154 -129
  99. package/src/calendar/createRangeCalendarState.ts +293 -79
  100. package/src/calendar/createTimeFieldState.d.ts +81 -79
  101. package/src/calendar/createTimeFieldState.ts +187 -108
  102. package/src/calendar/index.d.ts +80 -7
  103. package/src/calendar/index.ts +21 -12
  104. package/src/checkbox/createCheckboxGroupState.d.ts +57 -55
  105. package/src/checkbox/createCheckboxGroupState.ts +57 -30
  106. package/src/checkbox/index.d.ts +6 -2
  107. package/src/checkbox/index.ts +1 -1
  108. package/src/collections/ListCollection.d.ts +25 -22
  109. package/src/collections/ListCollection.ts +152 -146
  110. package/src/collections/createListState.d.ts +73 -58
  111. package/src/collections/createListState.ts +267 -264
  112. package/src/collections/createMenuState.d.ts +36 -31
  113. package/src/collections/createMenuState.ts +112 -106
  114. package/src/collections/createSelectionState.d.ts +78 -65
  115. package/src/collections/createSelectionState.ts +340 -336
  116. package/src/collections/index.d.ts +38 -6
  117. package/src/collections/index.ts +41 -46
  118. package/src/collections/types.d.ts +101 -101
  119. package/src/collections/types.ts +181 -169
  120. package/src/color/Color.d.ts +20 -5
  121. package/src/color/Color.ts +1054 -951
  122. package/src/color/createColorAreaState.d.ts +67 -65
  123. package/src/color/createColorAreaState.ts +301 -293
  124. package/src/color/createColorFieldState.d.ts +46 -44
  125. package/src/color/createColorFieldState.ts +428 -292
  126. package/src/color/createColorSliderState.d.ts +58 -56
  127. package/src/color/createColorSliderState.ts +272 -241
  128. package/src/color/createColorWheelState.d.ts +42 -40
  129. package/src/color/createColorWheelState.ts +248 -211
  130. package/src/color/getColorChannels.ts +36 -0
  131. package/src/color/index.d.ts +36 -7
  132. package/src/color/index.ts +44 -47
  133. package/src/color/types.d.ts +68 -63
  134. package/src/color/types.ts +119 -127
  135. package/src/combobox/createComboBoxState.d.ts +107 -105
  136. package/src/combobox/createComboBoxState.ts +790 -703
  137. package/src/combobox/index.d.ts +10 -2
  138. package/src/combobox/index.ts +13 -13
  139. package/src/data/createAsyncList.ts +403 -0
  140. package/src/data/createListData.ts +298 -0
  141. package/src/data/createTreeData.ts +646 -0
  142. package/src/data/index.ts +25 -0
  143. package/src/datepicker/index.ts +32 -0
  144. package/src/disclosure/createDisclosureState.d.ts +47 -43
  145. package/src/disclosure/createDisclosureState.ts +9 -23
  146. package/src/disclosure/index.d.ts +10 -2
  147. package/src/disclosure/index.ts +1 -1
  148. package/src/dnd/createDragState.d.ts +51 -42
  149. package/src/dnd/createDragState.ts +151 -153
  150. package/src/dnd/createDraggableCollectionState.d.ts +52 -41
  151. package/src/dnd/createDraggableCollectionState.ts +158 -165
  152. package/src/dnd/createDropState.d.ts +64 -45
  153. package/src/dnd/createDropState.ts +202 -212
  154. package/src/dnd/createDroppableCollectionState.d.ts +88 -59
  155. package/src/dnd/createDroppableCollectionState.ts +354 -357
  156. package/src/dnd/index.d.ts +54 -6
  157. package/src/dnd/index.ts +63 -76
  158. package/src/dnd/types.d.ts +167 -156
  159. package/src/dnd/types.ts +316 -317
  160. package/src/form/createFormValidationState.d.ts +47 -45
  161. package/src/form/createFormValidationState.ts +356 -389
  162. package/src/form/index.d.ts +16 -2
  163. package/src/form/index.ts +15 -15
  164. package/src/grid/createGridState.d.ts +7 -4
  165. package/src/grid/createGridState.ts +44 -51
  166. package/src/grid/index.d.ts +3 -3
  167. package/src/grid/index.ts +2 -8
  168. package/src/grid/types.d.ts +136 -129
  169. package/src/grid/types.ts +24 -17
  170. package/src/index.d.ts +310 -26
  171. package/src/index.ts +87 -79
  172. package/src/menu/index.ts +17 -0
  173. package/src/numberfield/createNumberFieldState.d.ts +56 -54
  174. package/src/numberfield/createNumberFieldState.ts +422 -383
  175. package/src/numberfield/index.d.ts +6 -2
  176. package/src/numberfield/index.ts +5 -5
  177. package/src/overlays/createOverlayTriggerState.d.ts +22 -20
  178. package/src/overlays/createOverlayTriggerState.ts +66 -67
  179. package/src/overlays/index.d.ts +6 -2
  180. package/src/overlays/index.ts +5 -5
  181. package/src/radio/createRadioGroupState.d.ts +54 -52
  182. package/src/radio/createRadioGroupState.ts +66 -30
  183. package/src/radio/index.d.ts +7 -2
  184. package/src/radio/index.ts +1 -1
  185. package/src/searchfield/createSearchFieldState.d.ts +16 -14
  186. package/src/searchfield/createSearchFieldState.ts +56 -62
  187. package/src/searchfield/index.d.ts +3 -3
  188. package/src/searchfield/index.ts +2 -5
  189. package/src/select/createSelectState.d.ts +63 -61
  190. package/src/select/createSelectState.ts +290 -181
  191. package/src/select/index.d.ts +2 -2
  192. package/src/select/index.ts +1 -5
  193. package/src/selection/index.ts +27 -0
  194. package/src/slider/createSliderState.d.ts +60 -60
  195. package/src/slider/createSliderState.ts +233 -211
  196. package/src/slider/index.d.ts +3 -3
  197. package/src/slider/index.ts +2 -6
  198. package/src/ssr/index.d.ts +1 -1
  199. package/src/ssr/index.ts +2 -2
  200. package/src/steplist/createStepListState.ts +191 -0
  201. package/src/steplist/index.ts +5 -0
  202. package/src/table/TableCollection.d.ts +42 -40
  203. package/src/table/TableCollection.ts +61 -64
  204. package/src/table/createTableColumnResizeState.ts +242 -0
  205. package/src/table/createTableState.d.ts +7 -4
  206. package/src/table/createTableState.ts +10 -7
  207. package/src/table/index.d.ts +14 -4
  208. package/src/table/index.ts +10 -3
  209. package/src/table/types.d.ts +98 -92
  210. package/src/table/types.ts +17 -13
  211. package/src/tabs/createTabListState.d.ts +59 -57
  212. package/src/tabs/createTabListState.ts +58 -39
  213. package/src/tabs/index.d.ts +8 -2
  214. package/src/tabs/index.ts +1 -1
  215. package/src/textfield/createTextFieldState.d.ts +16 -14
  216. package/src/textfield/createTextFieldState.ts +7 -18
  217. package/src/textfield/index.d.ts +6 -2
  218. package/src/textfield/index.ts +1 -1
  219. package/src/toast/createToastState.d.ts +92 -81
  220. package/src/toast/createToastState.ts +56 -44
  221. package/src/toast/index.d.ts +12 -2
  222. package/src/toast/index.ts +1 -1
  223. package/src/toggle/createToggleGroupState.ts +117 -0
  224. package/src/toggle/createToggleState.d.ts +19 -19
  225. package/src/toggle/createToggleState.ts +2 -16
  226. package/src/toggle/index.d.ts +2 -2
  227. package/src/toggle/index.ts +6 -4
  228. package/src/tooltip/createTooltipTriggerState.d.ts +17 -17
  229. package/src/tooltip/createTooltipTriggerState.ts +184 -183
  230. package/src/tooltip/index.d.ts +7 -2
  231. package/src/tooltip/index.ts +6 -6
  232. package/src/tree/TreeCollection.d.ts +26 -23
  233. package/src/tree/TreeCollection.ts +215 -175
  234. package/src/tree/createTreeState.d.ts +7 -4
  235. package/src/tree/createTreeState.ts +390 -392
  236. package/src/tree/index.d.ts +10 -4
  237. package/src/tree/index.ts +13 -13
  238. package/src/tree/types.d.ts +131 -126
  239. package/src/tree/types.ts +183 -174
  240. package/src/utils/index.d.ts +2 -2
  241. package/src/utils/index.ts +1 -1
  242. package/src/utils/reactivity.d.ts +2 -2
  243. package/src/utils/reactivity.ts +3 -3
@@ -0,0 +1,298 @@
1
+ /**
2
+ * createListData - SolidJS port of React Spectrum's useListData
3
+ *
4
+ * Manages state for an immutable list data structure, and provides
5
+ * convenience methods to update the data over time.
6
+ */
7
+
8
+ import { createSignal, createMemo } from "solid-js";
9
+
10
+ export type Key = string | number;
11
+ export type Selection = "all" | Set<Key>;
12
+
13
+ export interface ListOptions<T> {
14
+ /** Initial items in the list. */
15
+ initialItems?: T[];
16
+ /** The keys for the initially selected items. */
17
+ initialSelectedKeys?: "all" | Iterable<Key>;
18
+ /** The initial text to filter the list by. */
19
+ initialFilterText?: string;
20
+ /** A function that returns a unique key for an item object. */
21
+ getKey?: (item: T) => Key;
22
+ /** A function that returns whether an item matches the current filter text. */
23
+ filter?: (item: T, filterText: string) => boolean;
24
+ }
25
+
26
+ export interface ListData<T> {
27
+ /** The items in the list. */
28
+ readonly items: T[];
29
+ /** The keys of the currently selected items in the list. */
30
+ readonly selectedKeys: Selection;
31
+ /** The current filter text. */
32
+ readonly filterText: string;
33
+ /** Sets the selected keys. */
34
+ setSelectedKeys(keys: Selection): void;
35
+ /** Adds the given keys to the current selected keys. */
36
+ addKeysToSelection(keys: Selection): void;
37
+ /** Removes the given keys from the current selected keys. */
38
+ removeKeysFromSelection(keys: Selection): void;
39
+ /** Sets the filter text. */
40
+ setFilterText(filterText: string): void;
41
+ /** Gets an item from the list by key. */
42
+ getItem(key: Key): T | undefined;
43
+ /** Inserts items into the list at the given index. */
44
+ insert(index: number, ...values: T[]): void;
45
+ /** Inserts items into the list before the item at the given key. */
46
+ insertBefore(key: Key, ...values: T[]): void;
47
+ /** Inserts items into the list after the item at the given key. */
48
+ insertAfter(key: Key, ...values: T[]): void;
49
+ /** Appends items to the list. */
50
+ append(...values: T[]): void;
51
+ /** Prepends items to the list. */
52
+ prepend(...values: T[]): void;
53
+ /** Removes items from the list by their keys. */
54
+ remove(...keys: Key[]): void;
55
+ /** Removes all items from the list that are currently in the set of selected items. */
56
+ removeSelectedItems(): void;
57
+ /** Moves an item within the list. */
58
+ move(key: Key, toIndex: number): void;
59
+ /** Moves one or more items before a given key. */
60
+ moveBefore(key: Key, keys: Iterable<Key>): void;
61
+ /** Moves one or more items after a given key. */
62
+ moveAfter(key: Key, keys: Iterable<Key>): void;
63
+ /** Updates an item in the list. */
64
+ update(key: Key, newValue: T | ((prev: T) => T)): void;
65
+ }
66
+
67
+ interface ListState<T> {
68
+ items: T[];
69
+ selectedKeys: Selection;
70
+ filterText: string;
71
+ }
72
+
73
+ /**
74
+ * Manages state for an immutable list data structure, and provides
75
+ * convenience methods to update the data over time.
76
+ */
77
+ export function createListData<T>(options: ListOptions<T>): ListData<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
+
83
+ const {
84
+ initialItems = [],
85
+ initialSelectedKeys,
86
+ getKey = defaultGetKey,
87
+ filter,
88
+ initialFilterText = "",
89
+ } = options;
90
+
91
+ const [state, setState] = createSignal<ListState<T>>({
92
+ items: initialItems,
93
+ selectedKeys: initialSelectedKeys === "all" ? "all" : new Set(initialSelectedKeys || []),
94
+ filterText: initialFilterText,
95
+ });
96
+
97
+ const filteredItems = createMemo(() => {
98
+ const s = state();
99
+ return filter ? s.items.filter((item) => filter(item, s.filterText)) : s.items;
100
+ });
101
+
102
+ return {
103
+ get items() {
104
+ return filteredItems();
105
+ },
106
+ get selectedKeys() {
107
+ return state().selectedKeys;
108
+ },
109
+ get filterText() {
110
+ return state().filterText;
111
+ },
112
+
113
+ setSelectedKeys(selectedKeys: Selection) {
114
+ setState((s) => ({ ...s, selectedKeys }));
115
+ },
116
+
117
+ addKeysToSelection(selectedKeys: Selection) {
118
+ setState((s) => {
119
+ if (s.selectedKeys === "all") return s;
120
+ if (selectedKeys === "all") return { ...s, selectedKeys: "all" };
121
+ return { ...s, selectedKeys: new Set([...s.selectedKeys, ...selectedKeys]) };
122
+ });
123
+ },
124
+
125
+ removeKeysFromSelection(selectedKeys: Selection) {
126
+ setState((s) => {
127
+ if (selectedKeys === "all") return { ...s, selectedKeys: new Set() };
128
+ const selection: Set<Key> =
129
+ s.selectedKeys === "all" ? new Set(s.items.map(getKey)) : new Set(s.selectedKeys);
130
+ for (const key of selectedKeys) {
131
+ selection.delete(key);
132
+ }
133
+ return { ...s, selectedKeys: selection };
134
+ });
135
+ },
136
+
137
+ setFilterText(filterText: string) {
138
+ setState((s) => ({ ...s, filterText }));
139
+ },
140
+
141
+ getItem(key: Key) {
142
+ return state().items.find((item) => getKey(item) === key);
143
+ },
144
+
145
+ insert(index: number, ...values: T[]) {
146
+ setState((s) => insertItems(s, index, ...values));
147
+ },
148
+
149
+ insertBefore(key: Key, ...values: T[]) {
150
+ setState((s) => {
151
+ const index = s.items.findIndex((item) => getKey(item) === key);
152
+ if (index === -1) return s;
153
+ return insertItems(s, index, ...values);
154
+ });
155
+ },
156
+
157
+ insertAfter(key: Key, ...values: T[]) {
158
+ setState((s) => {
159
+ let index = s.items.findIndex((item) => getKey(item) === key);
160
+ if (index === -1) {
161
+ if (s.items.length === 0) {
162
+ index = 0;
163
+ } else {
164
+ return s;
165
+ }
166
+ }
167
+ return insertItems(s, index + 1, ...values);
168
+ });
169
+ },
170
+
171
+ prepend(...values: T[]) {
172
+ setState((s) => insertItems(s, 0, ...values));
173
+ },
174
+
175
+ append(...values: T[]) {
176
+ setState((s) => insertItems(s, s.items.length, ...values));
177
+ },
178
+
179
+ remove(...keys: Key[]) {
180
+ setState((s) => {
181
+ const keySet = new Set(keys);
182
+ const items = s.items.filter((item) => !keySet.has(getKey(item)));
183
+ let selection: Selection = "all";
184
+ if (s.selectedKeys !== "all") {
185
+ selection = new Set(s.selectedKeys);
186
+ for (const key of keys) {
187
+ (selection as Set<Key>).delete(key);
188
+ }
189
+ }
190
+ if (items.length === 0) selection = new Set();
191
+ return { ...s, items, selectedKeys: selection };
192
+ });
193
+ },
194
+
195
+ removeSelectedItems() {
196
+ setState((s) => {
197
+ if (s.selectedKeys === "all") {
198
+ return { ...s, items: [], selectedKeys: new Set() };
199
+ }
200
+ const selectedKeys = s.selectedKeys;
201
+ const items = s.items.filter((item) => !selectedKeys.has(getKey(item)));
202
+ return { ...s, items, selectedKeys: new Set() };
203
+ });
204
+ },
205
+
206
+ move(key: Key, toIndex: number) {
207
+ setState((s) => {
208
+ const index = s.items.findIndex((item) => getKey(item) === key);
209
+ if (index === -1) return s;
210
+ const copy = s.items.slice();
211
+ const [item] = copy.splice(index, 1);
212
+ copy.splice(toIndex, 0, item);
213
+ return { ...s, items: copy };
214
+ });
215
+ },
216
+
217
+ moveBefore(key: Key, keys: Iterable<Key>) {
218
+ setState((s) => {
219
+ const toIndex = s.items.findIndex((item) => getKey(item) === key);
220
+ if (toIndex === -1) return s;
221
+ const keyArray = Array.isArray(keys) ? keys : [...keys];
222
+ const indices = keyArray
223
+ .map((k) => s.items.findIndex((item) => getKey(item) === k))
224
+ .sort((a, b) => a - b);
225
+ return moveItems(s, indices, toIndex);
226
+ });
227
+ },
228
+
229
+ moveAfter(key: Key, keys: Iterable<Key>) {
230
+ setState((s) => {
231
+ const toIndex = s.items.findIndex((item) => getKey(item) === key);
232
+ if (toIndex === -1) return s;
233
+ const keyArray = Array.isArray(keys) ? keys : [...keys];
234
+ const indices = keyArray
235
+ .map((k) => s.items.findIndex((item) => getKey(item) === k))
236
+ .sort((a, b) => a - b);
237
+ return moveItems(s, indices, toIndex + 1);
238
+ });
239
+ },
240
+
241
+ update(key: Key, newValue: T | ((prev: T) => T)) {
242
+ setState((s) => {
243
+ const index = s.items.findIndex((item) => getKey(item) === key);
244
+ if (index === -1) return s;
245
+ const updatedValue =
246
+ typeof newValue === "function" ? (newValue as (prev: T) => T)(s.items[index]) : newValue;
247
+ return {
248
+ ...s,
249
+ items: [...s.items.slice(0, index), updatedValue, ...s.items.slice(index + 1)],
250
+ };
251
+ });
252
+ },
253
+ };
254
+ }
255
+
256
+ function insertItems<T>(state: ListState<T>, index: number, ...values: T[]): ListState<T> {
257
+ return {
258
+ ...state,
259
+ items: [...state.items.slice(0, index), ...values, ...state.items.slice(index)],
260
+ };
261
+ }
262
+
263
+ function moveItems<T>(state: ListState<T>, indices: number[], toIndex: number): ListState<T> {
264
+ toIndex -= indices.filter((index) => index < toIndex).length;
265
+
266
+ const moves = indices.map((from) => ({
267
+ from,
268
+ to: toIndex++,
269
+ }));
270
+
271
+ for (let i = 0; i < moves.length; i++) {
272
+ const a = moves[i].from;
273
+ for (let j = i; j < moves.length; j++) {
274
+ const b = moves[j].from;
275
+ if (b > a) moves[j].from--;
276
+ }
277
+ }
278
+
279
+ for (let i = 0; i < moves.length; i++) {
280
+ const a = moves[i];
281
+ for (let j = moves.length - 1; j > i; j--) {
282
+ const b = moves[j];
283
+ if (b.from < a.to) {
284
+ a.to++;
285
+ } else {
286
+ b.from++;
287
+ }
288
+ }
289
+ }
290
+
291
+ const copy = state.items.slice();
292
+ for (const m of moves) {
293
+ const [item] = copy.splice(m.from, 1);
294
+ copy.splice(m.to, 0, item);
295
+ }
296
+
297
+ return { ...state, items: copy };
298
+ }