@proyecto-viviana/solid-stately 0.2.7 → 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 (242) hide show
  1. package/README.md +30 -283
  2. package/dist/autocomplete/createAutocompleteState.d.ts +2 -2
  3. package/dist/autocomplete/index.d.ts +1 -1
  4. package/dist/calendar/createCalendarState.d.ts +22 -7
  5. package/dist/calendar/createDateFieldState.d.ts +30 -7
  6. package/dist/calendar/createDatePickerState.d.ts +60 -0
  7. package/dist/calendar/createRangeCalendarState.d.ts +27 -8
  8. package/dist/calendar/createTimeFieldState.d.ts +34 -7
  9. package/dist/calendar/index.d.ts +7 -6
  10. package/dist/checkbox/createCheckboxGroupState.d.ts +6 -6
  11. package/dist/checkbox/index.d.ts +1 -1
  12. package/dist/collections/ListCollection.d.ts +1 -1
  13. package/dist/collections/createListState.d.ts +8 -8
  14. package/dist/collections/createMenuState.d.ts +7 -7
  15. package/dist/collections/createSelectionState.d.ts +5 -5
  16. package/dist/collections/index.d.ts +5 -5
  17. package/dist/collections/types.d.ts +12 -12
  18. package/dist/color/Color.d.ts +1 -1
  19. package/dist/color/createColorAreaState.d.ts +4 -2
  20. package/dist/color/createColorFieldState.d.ts +38 -12
  21. package/dist/color/createColorSliderState.d.ts +9 -2
  22. package/dist/color/createColorWheelState.d.ts +13 -2
  23. package/dist/color/getColorChannels.d.ts +1 -1
  24. package/dist/color/index.d.ts +6 -6
  25. package/dist/color/types.d.ts +4 -4
  26. package/dist/combobox/createComboBoxState.d.ts +27 -13
  27. package/dist/combobox/index.d.ts +1 -1
  28. package/dist/data/createAsyncList.d.ts +4 -4
  29. package/dist/data/createListData.d.ts +2 -2
  30. package/dist/data/createTreeData.d.ts +6 -2
  31. package/dist/data/index.d.ts +3 -3
  32. package/dist/datepicker/index.d.ts +2 -4
  33. package/dist/disclosure/createDisclosureState.d.ts +2 -2
  34. package/dist/disclosure/index.d.ts +1 -1
  35. package/dist/dnd/createDragState.d.ts +2 -2
  36. package/dist/dnd/createDraggableCollectionState.d.ts +2 -2
  37. package/dist/dnd/createDropState.d.ts +2 -2
  38. package/dist/dnd/createDroppableCollectionState.d.ts +3 -3
  39. package/dist/dnd/index.d.ts +5 -5
  40. package/dist/dnd/types.d.ts +16 -16
  41. package/dist/form/createFormValidationState.d.ts +3 -3
  42. package/dist/form/index.d.ts +1 -1
  43. package/dist/grid/createGridState.d.ts +2 -2
  44. package/dist/grid/index.d.ts +2 -2
  45. package/dist/grid/types.d.ts +13 -11
  46. package/dist/index.d.ts +31 -30
  47. package/dist/index.js +7924 -7238
  48. package/dist/index.js.map +1 -1
  49. package/dist/menu/index.d.ts +2 -2
  50. package/dist/numberfield/createNumberFieldState.d.ts +2 -2
  51. package/dist/numberfield/index.d.ts +1 -1
  52. package/dist/overlays/createOverlayTriggerState.d.ts +2 -2
  53. package/dist/overlays/index.d.ts +1 -1
  54. package/dist/radio/createRadioGroupState.d.ts +7 -7
  55. package/dist/radio/index.d.ts +1 -1
  56. package/dist/searchfield/createSearchFieldState.d.ts +2 -2
  57. package/dist/searchfield/index.d.ts +2 -2
  58. package/dist/select/createSelectState.d.ts +8 -8
  59. package/dist/select/index.d.ts +1 -1
  60. package/dist/selection/index.d.ts +5 -5
  61. package/dist/slider/createSliderState.d.ts +3 -3
  62. package/dist/slider/index.d.ts +2 -2
  63. package/dist/steplist/createStepListState.d.ts +48 -0
  64. package/dist/steplist/index.d.ts +1 -0
  65. package/dist/table/TableCollection.d.ts +3 -3
  66. package/dist/table/createTableColumnResizeState.d.ts +54 -0
  67. package/dist/table/createTableState.d.ts +2 -2
  68. package/dist/table/index.d.ts +5 -3
  69. package/dist/table/types.d.ts +10 -10
  70. package/dist/tabs/createTabListState.d.ts +5 -5
  71. package/dist/tabs/index.d.ts +1 -1
  72. package/dist/textfield/createTextFieldState.d.ts +2 -2
  73. package/dist/textfield/index.d.ts +1 -1
  74. package/dist/toast/createToastState.d.ts +8 -2
  75. package/dist/toast/index.d.ts +1 -1
  76. package/dist/toggle/createToggleGroupState.d.ts +4 -4
  77. package/dist/toggle/createToggleState.d.ts +2 -2
  78. package/dist/toggle/index.d.ts +2 -2
  79. package/dist/tooltip/createTooltipTriggerState.d.ts +2 -2
  80. package/dist/tooltip/index.d.ts +1 -1
  81. package/dist/tree/TreeCollection.d.ts +2 -2
  82. package/dist/tree/createTreeState.d.ts +2 -2
  83. package/dist/tree/index.d.ts +3 -3
  84. package/dist/tree/types.d.ts +19 -13
  85. package/dist/utils/index.d.ts +1 -1
  86. package/dist/utils/reactivity.d.ts +1 -1
  87. package/package.json +29 -30
  88. package/src/autocomplete/createAutocompleteState.d.ts +19 -17
  89. package/src/autocomplete/createAutocompleteState.ts +24 -30
  90. package/src/autocomplete/index.d.ts +6 -2
  91. package/src/autocomplete/index.ts +1 -1
  92. package/src/calendar/createCalendarState.d.ts +139 -117
  93. package/src/calendar/createCalendarState.ts +221 -74
  94. package/src/calendar/createDateFieldState.d.ts +130 -95
  95. package/src/calendar/createDateFieldState.ts +263 -151
  96. package/src/calendar/createDatePickerState.ts +347 -0
  97. package/src/calendar/createRangeCalendarState.d.ts +154 -129
  98. package/src/calendar/createRangeCalendarState.ts +293 -79
  99. package/src/calendar/createTimeFieldState.d.ts +81 -79
  100. package/src/calendar/createTimeFieldState.ts +187 -108
  101. package/src/calendar/index.d.ts +80 -7
  102. package/src/calendar/index.ts +21 -12
  103. package/src/checkbox/createCheckboxGroupState.d.ts +57 -55
  104. package/src/checkbox/createCheckboxGroupState.ts +20 -29
  105. package/src/checkbox/index.d.ts +6 -2
  106. package/src/checkbox/index.ts +1 -1
  107. package/src/collections/ListCollection.d.ts +25 -22
  108. package/src/collections/ListCollection.ts +6 -6
  109. package/src/collections/createListState.d.ts +73 -58
  110. package/src/collections/createListState.ts +19 -18
  111. package/src/collections/createMenuState.d.ts +36 -31
  112. package/src/collections/createMenuState.ts +18 -12
  113. package/src/collections/createSelectionState.d.ts +78 -65
  114. package/src/collections/createSelectionState.ts +36 -32
  115. package/src/collections/index.d.ts +38 -6
  116. package/src/collections/index.ts +5 -10
  117. package/src/collections/types.d.ts +101 -101
  118. package/src/collections/types.ts +12 -12
  119. package/src/color/Color.d.ts +20 -5
  120. package/src/color/Color.ts +357 -254
  121. package/src/color/createColorAreaState.d.ts +67 -65
  122. package/src/color/createColorAreaState.ts +21 -13
  123. package/src/color/createColorFieldState.d.ts +46 -44
  124. package/src/color/createColorFieldState.ts +285 -149
  125. package/src/color/createColorSliderState.d.ts +58 -56
  126. package/src/color/createColorSliderState.ts +45 -14
  127. package/src/color/createColorWheelState.d.ts +42 -40
  128. package/src/color/createColorWheelState.ts +101 -64
  129. package/src/color/getColorChannels.ts +7 -5
  130. package/src/color/index.d.ts +36 -7
  131. package/src/color/index.ts +6 -9
  132. package/src/color/types.d.ts +68 -63
  133. package/src/color/types.ts +11 -19
  134. package/src/combobox/createComboBoxState.d.ts +107 -105
  135. package/src/combobox/createComboBoxState.ts +176 -89
  136. package/src/combobox/index.d.ts +10 -2
  137. package/src/combobox/index.ts +1 -1
  138. package/src/data/createAsyncList.ts +89 -63
  139. package/src/data/createListData.ts +67 -67
  140. package/src/data/createTreeData.ts +304 -91
  141. package/src/data/index.ts +3 -3
  142. package/src/datepicker/index.ts +6 -10
  143. package/src/disclosure/createDisclosureState.d.ts +47 -43
  144. package/src/disclosure/createDisclosureState.ts +7 -21
  145. package/src/disclosure/index.d.ts +10 -2
  146. package/src/disclosure/index.ts +1 -1
  147. package/src/dnd/createDragState.d.ts +51 -42
  148. package/src/dnd/createDragState.ts +12 -14
  149. package/src/dnd/createDraggableCollectionState.d.ts +52 -41
  150. package/src/dnd/createDraggableCollectionState.ts +14 -21
  151. package/src/dnd/createDropState.d.ts +64 -45
  152. package/src/dnd/createDropState.ts +22 -32
  153. package/src/dnd/createDroppableCollectionState.d.ts +88 -59
  154. package/src/dnd/createDroppableCollectionState.ts +40 -43
  155. package/src/dnd/index.d.ts +54 -6
  156. package/src/dnd/index.ts +5 -18
  157. package/src/dnd/types.d.ts +167 -156
  158. package/src/dnd/types.ts +20 -21
  159. package/src/form/createFormValidationState.d.ts +47 -45
  160. package/src/form/createFormValidationState.ts +30 -63
  161. package/src/form/index.d.ts +16 -2
  162. package/src/form/index.ts +1 -1
  163. package/src/grid/createGridState.d.ts +7 -4
  164. package/src/grid/createGridState.ts +44 -51
  165. package/src/grid/index.d.ts +3 -3
  166. package/src/grid/index.ts +2 -8
  167. package/src/grid/types.d.ts +136 -129
  168. package/src/grid/types.ts +20 -18
  169. package/src/index.d.ts +310 -26
  170. package/src/index.ts +48 -89
  171. package/src/menu/index.ts +2 -4
  172. package/src/numberfield/createNumberFieldState.d.ts +56 -54
  173. package/src/numberfield/createNumberFieldState.ts +26 -31
  174. package/src/numberfield/index.d.ts +6 -2
  175. package/src/numberfield/index.ts +1 -1
  176. package/src/overlays/createOverlayTriggerState.d.ts +22 -20
  177. package/src/overlays/createOverlayTriggerState.ts +3 -4
  178. package/src/overlays/index.d.ts +6 -2
  179. package/src/overlays/index.ts +1 -1
  180. package/src/radio/createRadioGroupState.d.ts +54 -52
  181. package/src/radio/createRadioGroupState.ts +27 -29
  182. package/src/radio/index.d.ts +7 -2
  183. package/src/radio/index.ts +1 -1
  184. package/src/searchfield/createSearchFieldState.d.ts +16 -14
  185. package/src/searchfield/createSearchFieldState.ts +5 -11
  186. package/src/searchfield/index.d.ts +3 -3
  187. package/src/searchfield/index.ts +2 -5
  188. package/src/select/createSelectState.d.ts +63 -61
  189. package/src/select/createSelectState.ts +27 -27
  190. package/src/select/index.d.ts +2 -2
  191. package/src/select/index.ts +1 -5
  192. package/src/selection/index.ts +6 -7
  193. package/src/slider/createSliderState.d.ts +60 -60
  194. package/src/slider/createSliderState.ts +55 -33
  195. package/src/slider/index.d.ts +3 -3
  196. package/src/slider/index.ts +2 -6
  197. package/src/ssr/index.d.ts +1 -1
  198. package/src/ssr/index.ts +2 -2
  199. package/src/steplist/createStepListState.ts +191 -0
  200. package/src/steplist/index.ts +5 -0
  201. package/src/table/TableCollection.d.ts +42 -40
  202. package/src/table/TableCollection.ts +61 -64
  203. package/src/table/createTableColumnResizeState.ts +242 -0
  204. package/src/table/createTableState.d.ts +7 -4
  205. package/src/table/createTableState.ts +10 -7
  206. package/src/table/index.d.ts +14 -4
  207. package/src/table/index.ts +10 -3
  208. package/src/table/types.d.ts +98 -92
  209. package/src/table/types.ts +17 -13
  210. package/src/tabs/createTabListState.d.ts +59 -57
  211. package/src/tabs/createTabListState.ts +24 -31
  212. package/src/tabs/index.d.ts +8 -2
  213. package/src/tabs/index.ts +1 -1
  214. package/src/textfield/createTextFieldState.d.ts +16 -14
  215. package/src/textfield/createTextFieldState.ts +7 -18
  216. package/src/textfield/index.d.ts +6 -2
  217. package/src/textfield/index.ts +1 -1
  218. package/src/toast/createToastState.d.ts +92 -86
  219. package/src/toast/createToastState.ts +48 -43
  220. package/src/toast/index.d.ts +12 -2
  221. package/src/toast/index.ts +1 -1
  222. package/src/toggle/createToggleGroupState.ts +11 -21
  223. package/src/toggle/createToggleState.d.ts +19 -19
  224. package/src/toggle/createToggleState.ts +2 -16
  225. package/src/toggle/index.d.ts +2 -2
  226. package/src/toggle/index.ts +2 -6
  227. package/src/tooltip/createTooltipTriggerState.d.ts +17 -17
  228. package/src/tooltip/createTooltipTriggerState.ts +12 -11
  229. package/src/tooltip/index.d.ts +7 -2
  230. package/src/tooltip/index.ts +1 -1
  231. package/src/tree/TreeCollection.d.ts +26 -23
  232. package/src/tree/TreeCollection.ts +29 -22
  233. package/src/tree/createTreeState.d.ts +7 -4
  234. package/src/tree/createTreeState.ts +39 -41
  235. package/src/tree/index.d.ts +10 -4
  236. package/src/tree/index.ts +3 -3
  237. package/src/tree/types.d.ts +131 -126
  238. package/src/tree/types.ts +22 -13
  239. package/src/utils/index.d.ts +2 -2
  240. package/src/utils/index.ts +1 -1
  241. package/src/utils/reactivity.d.ts +2 -2
  242. package/src/utils/reactivity.ts +3 -3
@@ -6,17 +6,17 @@
6
6
  * states, pagination, and sorting.
7
7
  */
8
8
 
9
- import { createSignal, untrack } from 'solid-js';
9
+ import { createSignal, untrack } from "solid-js";
10
10
 
11
11
  export type Key = string | number;
12
- export type Selection = 'all' | Set<Key>;
13
- export type LoadingState = 'idle' | 'loading' | 'loadingMore' | 'sorting' | 'filtering' | 'error';
12
+ export type Selection = "all" | Set<Key>;
13
+ export type LoadingState = "idle" | "loading" | "loadingMore" | "sorting" | "filtering" | "error";
14
14
 
15
15
  export interface SortDescriptor {
16
16
  /** The key of the column to sort by. */
17
17
  column?: Key;
18
18
  /** The direction to sort by. */
19
- direction?: 'ascending' | 'descending';
19
+ direction?: "ascending" | "descending";
20
20
  }
21
21
 
22
22
  export interface AsyncListLoadOptions<T, C> {
@@ -50,12 +50,12 @@ export interface AsyncListStateUpdate<T, C> {
50
50
  }
51
51
 
52
52
  export type AsyncListLoadFunction<T, C> = (
53
- state: AsyncListLoadOptions<T, C>
53
+ state: AsyncListLoadOptions<T, C>,
54
54
  ) => AsyncListStateUpdate<T, C> | Promise<AsyncListStateUpdate<T, C>>;
55
55
 
56
56
  export interface AsyncListOptions<T, C> {
57
57
  /** The keys for the initially selected items. */
58
- initialSelectedKeys?: 'all' | Iterable<Key>;
58
+ initialSelectedKeys?: "all" | Iterable<Key>;
59
59
  /** The initial sort descriptor. */
60
60
  initialSortDescriptor?: SortDescriptor;
61
61
  /** The initial filter text. */
@@ -135,25 +135,30 @@ interface InternalState<T, C> {
135
135
  * states, pagination, and sorting.
136
136
  */
137
137
  export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>): AsyncListData<T> {
138
+ const defaultGetKey = (item: T): Key => {
139
+ const candidate = item as { id?: Key; key?: Key };
140
+ return candidate.id ?? candidate.key ?? String(item);
141
+ };
142
+
138
143
  const {
139
144
  load,
140
145
  sort: sortFn,
141
146
  initialSelectedKeys,
142
147
  initialSortDescriptor,
143
- getKey = (item: any) => item.id || item.key,
144
- initialFilterText = '',
148
+ getKey = defaultGetKey,
149
+ initialFilterText = "",
145
150
  } = options;
146
151
 
147
152
  const [state, setState] = createSignal<InternalState<T, C>>({
148
- loadingState: 'idle',
153
+ loadingState: "idle",
149
154
  items: [],
150
- selectedKeys: initialSelectedKeys === 'all' ? 'all' : new Set(initialSelectedKeys || []),
155
+ selectedKeys: initialSelectedKeys === "all" ? "all" : new Set(initialSelectedKeys || []),
151
156
  sortDescriptor: initialSortDescriptor,
152
157
  filterText: initialFilterText,
153
158
  });
154
159
 
155
160
  async function dispatchFetch(
156
- type: 'loading' | 'loadingMore' | 'sorting' | 'filtering',
161
+ type: "loading" | "loadingMore" | "sorting" | "filtering",
157
162
  fn: AsyncListLoadFunction<T, C>,
158
163
  opts?: { sortDescriptor?: SortDescriptor; filterText?: string },
159
164
  ) {
@@ -161,7 +166,7 @@ export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>):
161
166
  const currentState = untrack(state);
162
167
 
163
168
  // Update to loading state
164
- setState(s => {
169
+ setState((s) => {
165
170
  // Abort previous request if one is in progress
166
171
  if (s.abortController) {
167
172
  s.abortController.abort();
@@ -169,7 +174,7 @@ export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>):
169
174
  return {
170
175
  ...s,
171
176
  loadingState: type,
172
- items: type === 'loading' ? [] : s.items,
177
+ items: type === "loading" ? [] : s.items,
173
178
  sortDescriptor: opts?.sortDescriptor ?? s.sortDescriptor,
174
179
  filterText: opts?.filterText ?? s.filterText,
175
180
  abortController,
@@ -183,37 +188,35 @@ export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>):
183
188
  selectedKeys: currentState.selectedKeys,
184
189
  sortDescriptor: opts?.sortDescriptor ?? currentState.sortDescriptor,
185
190
  signal: abortController.signal,
186
- cursor: type === 'loadingMore' ? currentState.cursor : undefined,
191
+ cursor: type === "loadingMore" ? currentState.cursor : undefined,
187
192
  filterText: previousFilterText,
188
193
  loadingState: currentState.loadingState,
189
194
  });
190
195
 
191
- setState(s => {
196
+ setState((s) => {
192
197
  // Ignore stale response
193
198
  if (s.abortController !== abortController) return s;
194
199
 
195
200
  const newItems = [...(response.items ?? [])];
196
- const items = type === 'loadingMore'
197
- ? [...s.items, ...newItems]
198
- : newItems;
201
+ const items = type === "loadingMore" ? [...s.items, ...newItems] : newItems;
199
202
 
200
203
  let selectedKeys: Selection;
201
- if (type === 'loadingMore') {
202
- selectedKeys = (s.selectedKeys === 'all' || response.selectedKeys === 'all')
203
- ? 'all'
204
- : new Set([
205
- ...(s.selectedKeys as Set<Key>),
206
- ...(response.selectedKeys ?? []),
207
- ]);
204
+ if (type === "loadingMore") {
205
+ selectedKeys =
206
+ s.selectedKeys === "all" || response.selectedKeys === "all"
207
+ ? "all"
208
+ : new Set([...(s.selectedKeys as Set<Key>), ...(response.selectedKeys ?? [])]);
208
209
  } else {
209
210
  selectedKeys = response.selectedKeys
210
- ? (response.selectedKeys === 'all' ? 'all' : new Set(response.selectedKeys))
211
+ ? response.selectedKeys === "all"
212
+ ? "all"
213
+ : new Set(response.selectedKeys)
211
214
  : s.selectedKeys;
212
215
  }
213
216
 
214
217
  return {
215
218
  ...s,
216
- loadingState: 'idle',
219
+ loadingState: "idle",
217
220
  items,
218
221
  selectedKeys,
219
222
  sortDescriptor: response.sortDescriptor ?? s.sortDescriptor,
@@ -226,15 +229,19 @@ export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>):
226
229
 
227
230
  // Trigger another filter if filterText changed in the response
228
231
  const responseFilterText = response.filterText ?? previousFilterText;
229
- if (responseFilterText && responseFilterText !== previousFilterText && !abortController.signal.aborted) {
230
- dispatchFetch('filtering', load, { filterText: responseFilterText });
232
+ if (
233
+ responseFilterText &&
234
+ responseFilterText !== previousFilterText &&
235
+ !abortController.signal.aborted
236
+ ) {
237
+ dispatchFetch("filtering", load, { filterText: responseFilterText });
231
238
  }
232
239
  } catch (e) {
233
- setState(s => {
240
+ setState((s) => {
234
241
  if (s.abortController !== abortController) return s;
235
242
  return {
236
243
  ...s,
237
- loadingState: 'error',
244
+ loadingState: "error",
238
245
  error: e as Error,
239
246
  abortController: undefined,
240
247
  };
@@ -243,58 +250,77 @@ export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>):
243
250
  }
244
251
 
245
252
  // Trigger initial load immediately
246
- dispatchFetch('loading', load);
253
+ dispatchFetch("loading", load);
247
254
 
248
255
  return {
249
- get items() { return state().items; },
250
- get selectedKeys() { return state().selectedKeys; },
251
- get sortDescriptor() { return state().sortDescriptor; },
256
+ get items() {
257
+ return state().items;
258
+ },
259
+ get selectedKeys() {
260
+ return state().selectedKeys;
261
+ },
262
+ get sortDescriptor() {
263
+ return state().sortDescriptor;
264
+ },
252
265
  get isLoading() {
253
266
  const ls = state().loadingState;
254
- return ls === 'loading' || ls === 'loadingMore' || ls === 'sorting' || ls === 'filtering';
267
+ return ls === "loading" || ls === "loadingMore" || ls === "sorting" || ls === "filtering";
268
+ },
269
+ get error() {
270
+ return state().error;
271
+ },
272
+ get filterText() {
273
+ return state().filterText;
274
+ },
275
+ get loadingState() {
276
+ return state().loadingState;
255
277
  },
256
- get error() { return state().error; },
257
- get filterText() { return state().filterText; },
258
- get loadingState() { return state().loadingState; },
259
278
 
260
279
  reload() {
261
- dispatchFetch('loading', load);
280
+ dispatchFetch("loading", load);
262
281
  },
263
282
 
264
283
  loadMore() {
265
284
  const s = state();
266
- if (s.loadingState === 'loading' || s.loadingState === 'loadingMore' || s.loadingState === 'filtering' || s.cursor == null) {
285
+ if (
286
+ s.loadingState === "loading" ||
287
+ s.loadingState === "loadingMore" ||
288
+ s.loadingState === "filtering" ||
289
+ s.cursor == null
290
+ ) {
267
291
  return;
268
292
  }
269
- dispatchFetch('loadingMore', load);
293
+ dispatchFetch("loadingMore", load);
270
294
  },
271
295
 
272
296
  sort(descriptor: SortDescriptor) {
273
- dispatchFetch('sorting', (sortFn || load) as AsyncListLoadFunction<T, C>, { sortDescriptor: descriptor });
297
+ dispatchFetch("sorting", (sortFn || load) as AsyncListLoadFunction<T, C>, {
298
+ sortDescriptor: descriptor,
299
+ });
274
300
  },
275
301
 
276
302
  setSelectedKeys(keys: Selection) {
277
- setState(s => ({ ...s, selectedKeys: keys }));
303
+ setState((s) => ({ ...s, selectedKeys: keys }));
278
304
  },
279
305
 
280
306
  setFilterText(filterText: string) {
281
- dispatchFetch('filtering', load, { filterText });
307
+ dispatchFetch("filtering", load, { filterText });
282
308
  },
283
309
 
284
310
  getItem(key: Key) {
285
- return state().items.find(item => getKey(item) === key);
311
+ return state().items.find((item) => getKey(item) === key);
286
312
  },
287
313
 
288
314
  insert(index: number, ...values: T[]) {
289
- setState(s => ({
315
+ setState((s) => ({
290
316
  ...s,
291
317
  items: [...s.items.slice(0, index), ...values, ...s.items.slice(index)],
292
318
  }));
293
319
  },
294
320
 
295
321
  insertBefore(key: Key, ...values: T[]) {
296
- setState(s => {
297
- const index = s.items.findIndex(item => getKey(item) === key);
322
+ setState((s) => {
323
+ const index = s.items.findIndex((item) => getKey(item) === key);
298
324
  if (index === -1) return s;
299
325
  return {
300
326
  ...s,
@@ -304,8 +330,8 @@ export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>):
304
330
  },
305
331
 
306
332
  insertAfter(key: Key, ...values: T[]) {
307
- setState(s => {
308
- const index = s.items.findIndex(item => getKey(item) === key);
333
+ setState((s) => {
334
+ const index = s.items.findIndex((item) => getKey(item) === key);
309
335
  if (index === -1) return s;
310
336
  return {
311
337
  ...s,
@@ -315,19 +341,19 @@ export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>):
315
341
  },
316
342
 
317
343
  append(...values: T[]) {
318
- setState(s => ({ ...s, items: [...s.items, ...values] }));
344
+ setState((s) => ({ ...s, items: [...s.items, ...values] }));
319
345
  },
320
346
 
321
347
  prepend(...values: T[]) {
322
- setState(s => ({ ...s, items: [...values, ...s.items] }));
348
+ setState((s) => ({ ...s, items: [...values, ...s.items] }));
323
349
  },
324
350
 
325
351
  remove(...keys: Key[]) {
326
- setState(s => {
352
+ setState((s) => {
327
353
  const keySet = new Set(keys);
328
- const items = s.items.filter(item => !keySet.has(getKey(item)));
354
+ const items = s.items.filter((item) => !keySet.has(getKey(item)));
329
355
  let selectedKeys = s.selectedKeys;
330
- if (selectedKeys !== 'all') {
356
+ if (selectedKeys !== "all") {
331
357
  const newSelection = new Set(selectedKeys);
332
358
  for (const key of keys) {
333
359
  newSelection.delete(key);
@@ -339,22 +365,22 @@ export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>):
339
365
  },
340
366
 
341
367
  removeSelectedItems() {
342
- setState(s => {
343
- if (s.selectedKeys === 'all') {
368
+ setState((s) => {
369
+ if (s.selectedKeys === "all") {
344
370
  return { ...s, items: [], selectedKeys: new Set() };
345
371
  }
346
372
  const sel = s.selectedKeys;
347
373
  return {
348
374
  ...s,
349
- items: s.items.filter(item => !sel.has(getKey(item))),
375
+ items: s.items.filter((item) => !sel.has(getKey(item))),
350
376
  selectedKeys: new Set(),
351
377
  };
352
378
  });
353
379
  },
354
380
 
355
381
  move(key: Key, toIndex: number) {
356
- setState(s => {
357
- const index = s.items.findIndex(item => getKey(item) === key);
382
+ setState((s) => {
383
+ const index = s.items.findIndex((item) => getKey(item) === key);
358
384
  if (index === -1) return s;
359
385
  const copy = s.items.slice();
360
386
  const [item] = copy.splice(index, 1);
@@ -364,8 +390,8 @@ export function createAsyncList<T, C = string>(options: AsyncListOptions<T, C>):
364
390
  },
365
391
 
366
392
  update(key: Key, newValue: T) {
367
- setState(s => {
368
- const index = s.items.findIndex(item => getKey(item) === key);
393
+ setState((s) => {
394
+ const index = s.items.findIndex((item) => getKey(item) === key);
369
395
  if (index === -1) return s;
370
396
  return {
371
397
  ...s,
@@ -5,16 +5,16 @@
5
5
  * convenience methods to update the data over time.
6
6
  */
7
7
 
8
- import { createSignal, createMemo } from 'solid-js';
8
+ import { createSignal, createMemo } from "solid-js";
9
9
 
10
10
  export type Key = string | number;
11
- export type Selection = 'all' | Set<Key>;
11
+ export type Selection = "all" | Set<Key>;
12
12
 
13
13
  export interface ListOptions<T> {
14
14
  /** Initial items in the list. */
15
15
  initialItems?: T[];
16
16
  /** The keys for the initially selected items. */
17
- initialSelectedKeys?: 'all' | Iterable<Key>;
17
+ initialSelectedKeys?: "all" | Iterable<Key>;
18
18
  /** The initial text to filter the list by. */
19
19
  initialFilterText?: string;
20
20
  /** A function that returns a unique key for an item object. */
@@ -75,48 +75,58 @@ interface ListState<T> {
75
75
  * convenience methods to update the data over time.
76
76
  */
77
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
+
78
83
  const {
79
84
  initialItems = [],
80
85
  initialSelectedKeys,
81
- getKey = (item: any) => item.id ?? item.key,
86
+ getKey = defaultGetKey,
82
87
  filter,
83
- initialFilterText = '',
88
+ initialFilterText = "",
84
89
  } = options;
85
90
 
86
91
  const [state, setState] = createSignal<ListState<T>>({
87
92
  items: initialItems,
88
- selectedKeys: initialSelectedKeys === 'all' ? 'all' : new Set(initialSelectedKeys || []),
93
+ selectedKeys: initialSelectedKeys === "all" ? "all" : new Set(initialSelectedKeys || []),
89
94
  filterText: initialFilterText,
90
95
  });
91
96
 
92
97
  const filteredItems = createMemo(() => {
93
98
  const s = state();
94
- return filter ? s.items.filter(item => filter(item, s.filterText)) : s.items;
99
+ return filter ? s.items.filter((item) => filter(item, s.filterText)) : s.items;
95
100
  });
96
101
 
97
102
  return {
98
- get items() { return filteredItems(); },
99
- get selectedKeys() { return state().selectedKeys; },
100
- get filterText() { return state().filterText; },
103
+ get items() {
104
+ return filteredItems();
105
+ },
106
+ get selectedKeys() {
107
+ return state().selectedKeys;
108
+ },
109
+ get filterText() {
110
+ return state().filterText;
111
+ },
101
112
 
102
113
  setSelectedKeys(selectedKeys: Selection) {
103
- setState(s => ({ ...s, selectedKeys }));
114
+ setState((s) => ({ ...s, selectedKeys }));
104
115
  },
105
116
 
106
117
  addKeysToSelection(selectedKeys: Selection) {
107
- setState(s => {
108
- if (s.selectedKeys === 'all') return s;
109
- if (selectedKeys === 'all') return { ...s, selectedKeys: 'all' };
118
+ setState((s) => {
119
+ if (s.selectedKeys === "all") return s;
120
+ if (selectedKeys === "all") return { ...s, selectedKeys: "all" };
110
121
  return { ...s, selectedKeys: new Set([...s.selectedKeys, ...selectedKeys]) };
111
122
  });
112
123
  },
113
124
 
114
125
  removeKeysFromSelection(selectedKeys: Selection) {
115
- setState(s => {
116
- if (selectedKeys === 'all') return { ...s, selectedKeys: new Set() };
117
- const selection: Set<Key> = s.selectedKeys === 'all'
118
- ? new Set(s.items.map(getKey))
119
- : new Set(s.selectedKeys);
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);
120
130
  for (const key of selectedKeys) {
121
131
  selection.delete(key);
122
132
  }
@@ -125,54 +135,53 @@ export function createListData<T>(options: ListOptions<T>): ListData<T> {
125
135
  },
126
136
 
127
137
  setFilterText(filterText: string) {
128
- setState(s => ({ ...s, filterText }));
138
+ setState((s) => ({ ...s, filterText }));
129
139
  },
130
140
 
131
141
  getItem(key: Key) {
132
- return state().items.find(item => getKey(item) === key);
142
+ return state().items.find((item) => getKey(item) === key);
133
143
  },
134
144
 
135
145
  insert(index: number, ...values: T[]) {
136
- setState(s => insertItems(s, index, ...values));
146
+ setState((s) => insertItems(s, index, ...values));
137
147
  },
138
148
 
139
149
  insertBefore(key: Key, ...values: T[]) {
140
- setState(s => {
141
- let index = s.items.findIndex(item => getKey(item) === key);
142
- if (index === -1) {
143
- index = s.items.length === 0 ? 0 : -1;
144
- if (index === -1) return s;
145
- }
150
+ setState((s) => {
151
+ const index = s.items.findIndex((item) => getKey(item) === key);
152
+ if (index === -1) return s;
146
153
  return insertItems(s, index, ...values);
147
154
  });
148
155
  },
149
156
 
150
157
  insertAfter(key: Key, ...values: T[]) {
151
- setState(s => {
152
- let index = s.items.findIndex(item => getKey(item) === key);
158
+ setState((s) => {
159
+ let index = s.items.findIndex((item) => getKey(item) === key);
153
160
  if (index === -1) {
154
- index = s.items.length === 0 ? -1 : -1;
155
- if (index === -1 && s.items.length > 0) return s;
156
- if (s.items.length === 0) return insertItems(s, 0, ...values);
161
+ if (s.items.length === 0) {
162
+ index = 0;
163
+ } else {
164
+ return s;
165
+ }
157
166
  }
158
167
  return insertItems(s, index + 1, ...values);
159
168
  });
160
169
  },
161
170
 
162
171
  prepend(...values: T[]) {
163
- setState(s => insertItems(s, 0, ...values));
172
+ setState((s) => insertItems(s, 0, ...values));
164
173
  },
165
174
 
166
175
  append(...values: T[]) {
167
- setState(s => insertItems(s, s.items.length, ...values));
176
+ setState((s) => insertItems(s, s.items.length, ...values));
168
177
  },
169
178
 
170
179
  remove(...keys: Key[]) {
171
- setState(s => {
180
+ setState((s) => {
172
181
  const keySet = new Set(keys);
173
- const items = s.items.filter(item => !keySet.has(getKey(item)));
174
- let selection: Selection = 'all';
175
- if (s.selectedKeys !== 'all') {
182
+ const items = s.items.filter((item) => !keySet.has(getKey(item)));
183
+ let selection: Selection = "all";
184
+ if (s.selectedKeys !== "all") {
176
185
  selection = new Set(s.selectedKeys);
177
186
  for (const key of keys) {
178
187
  (selection as Set<Key>).delete(key);
@@ -184,19 +193,19 @@ export function createListData<T>(options: ListOptions<T>): ListData<T> {
184
193
  },
185
194
 
186
195
  removeSelectedItems() {
187
- setState(s => {
188
- if (s.selectedKeys === 'all') {
196
+ setState((s) => {
197
+ if (s.selectedKeys === "all") {
189
198
  return { ...s, items: [], selectedKeys: new Set() };
190
199
  }
191
200
  const selectedKeys = s.selectedKeys;
192
- const items = s.items.filter(item => !selectedKeys.has(getKey(item)));
201
+ const items = s.items.filter((item) => !selectedKeys.has(getKey(item)));
193
202
  return { ...s, items, selectedKeys: new Set() };
194
203
  });
195
204
  },
196
205
 
197
206
  move(key: Key, toIndex: number) {
198
- setState(s => {
199
- const index = s.items.findIndex(item => getKey(item) === key);
207
+ setState((s) => {
208
+ const index = s.items.findIndex((item) => getKey(item) === key);
200
209
  if (index === -1) return s;
201
210
  const copy = s.items.slice();
202
211
  const [item] = copy.splice(index, 1);
@@ -206,43 +215,38 @@ export function createListData<T>(options: ListOptions<T>): ListData<T> {
206
215
  },
207
216
 
208
217
  moveBefore(key: Key, keys: Iterable<Key>) {
209
- setState(s => {
210
- const toIndex = s.items.findIndex(item => getKey(item) === key);
218
+ setState((s) => {
219
+ const toIndex = s.items.findIndex((item) => getKey(item) === key);
211
220
  if (toIndex === -1) return s;
212
221
  const keyArray = Array.isArray(keys) ? keys : [...keys];
213
222
  const indices = keyArray
214
- .map(k => s.items.findIndex(item => getKey(item) === k))
223
+ .map((k) => s.items.findIndex((item) => getKey(item) === k))
215
224
  .sort((a, b) => a - b);
216
225
  return moveItems(s, indices, toIndex);
217
226
  });
218
227
  },
219
228
 
220
229
  moveAfter(key: Key, keys: Iterable<Key>) {
221
- setState(s => {
222
- const toIndex = s.items.findIndex(item => getKey(item) === key);
230
+ setState((s) => {
231
+ const toIndex = s.items.findIndex((item) => getKey(item) === key);
223
232
  if (toIndex === -1) return s;
224
233
  const keyArray = Array.isArray(keys) ? keys : [...keys];
225
234
  const indices = keyArray
226
- .map(k => s.items.findIndex(item => getKey(item) === k))
235
+ .map((k) => s.items.findIndex((item) => getKey(item) === k))
227
236
  .sort((a, b) => a - b);
228
237
  return moveItems(s, indices, toIndex + 1);
229
238
  });
230
239
  },
231
240
 
232
241
  update(key: Key, newValue: T | ((prev: T) => T)) {
233
- setState(s => {
234
- const index = s.items.findIndex(item => getKey(item) === key);
242
+ setState((s) => {
243
+ const index = s.items.findIndex((item) => getKey(item) === key);
235
244
  if (index === -1) return s;
236
- const updatedValue = typeof newValue === 'function'
237
- ? (newValue as (prev: T) => T)(s.items[index])
238
- : newValue;
245
+ const updatedValue =
246
+ typeof newValue === "function" ? (newValue as (prev: T) => T)(s.items[index]) : newValue;
239
247
  return {
240
248
  ...s,
241
- items: [
242
- ...s.items.slice(0, index),
243
- updatedValue,
244
- ...s.items.slice(index + 1),
245
- ],
249
+ items: [...s.items.slice(0, index), updatedValue, ...s.items.slice(index + 1)],
246
250
  };
247
251
  });
248
252
  },
@@ -252,18 +256,14 @@ export function createListData<T>(options: ListOptions<T>): ListData<T> {
252
256
  function insertItems<T>(state: ListState<T>, index: number, ...values: T[]): ListState<T> {
253
257
  return {
254
258
  ...state,
255
- items: [
256
- ...state.items.slice(0, index),
257
- ...values,
258
- ...state.items.slice(index),
259
- ],
259
+ items: [...state.items.slice(0, index), ...values, ...state.items.slice(index)],
260
260
  };
261
261
  }
262
262
 
263
263
  function moveItems<T>(state: ListState<T>, indices: number[], toIndex: number): ListState<T> {
264
- toIndex -= indices.filter(index => index < toIndex).length;
264
+ toIndex -= indices.filter((index) => index < toIndex).length;
265
265
 
266
- const moves = indices.map(from => ({
266
+ const moves = indices.map((from) => ({
267
267
  from,
268
268
  to: toIndex++,
269
269
  }));