@proyecto-viviana/solid-stately 0.3.0 → 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.
Files changed (63) hide show
  1. package/dist/calendar/IncompleteDate.d.ts +61 -0
  2. package/dist/calendar/createCalendarState.d.ts +20 -10
  3. package/dist/calendar/createDateFieldState.d.ts +10 -3
  4. package/dist/calendar/createRangeCalendarState.d.ts +10 -2
  5. package/dist/calendar/index.d.ts +1 -1
  6. package/dist/collections/createListState.d.ts +4 -1
  7. package/dist/collections/createSelectionState.d.ts +17 -5
  8. package/dist/collections/getChildNodes.d.ts +11 -0
  9. package/dist/collections/index.d.ts +2 -1
  10. package/dist/combobox/createComboBoxState.d.ts +7 -0
  11. package/dist/dnd/index.d.ts +1 -1
  12. package/dist/dnd/types.d.ts +3 -1
  13. package/dist/grid/types.d.ts +17 -3
  14. package/dist/index.d.ts +6 -6
  15. package/dist/index.js +1570 -425
  16. package/dist/index.js.map +1 -1
  17. package/dist/select/createSelectState.d.ts +6 -0
  18. package/dist/selection/Selection.d.ts +16 -0
  19. package/dist/selection/SelectionManager.d.ts +110 -0
  20. package/dist/selection/createMultipleSelectionState.d.ts +59 -0
  21. package/dist/selection/index.d.ts +1 -0
  22. package/dist/table/TableCollection.d.ts +30 -0
  23. package/dist/table/createTreeGridState.d.ts +15 -0
  24. package/dist/table/index.d.ts +2 -1
  25. package/dist/table/types.d.ts +58 -0
  26. package/dist/toast/createToastState.d.ts +16 -0
  27. package/dist/toast/index.d.ts +1 -1
  28. package/dist/tree/types.d.ts +14 -6
  29. package/package.json +1 -1
  30. package/src/calendar/IncompleteDate.ts +430 -0
  31. package/src/calendar/createCalendarState.ts +104 -37
  32. package/src/calendar/createDateFieldState.ts +262 -261
  33. package/src/calendar/createRangeCalendarState.ts +131 -19
  34. package/src/calendar/index.ts +2 -0
  35. package/src/collections/createListState.ts +50 -19
  36. package/src/collections/createMenuState.ts +3 -0
  37. package/src/collections/createSelectionState.ts +38 -28
  38. package/src/collections/getChildNodes.ts +98 -0
  39. package/src/collections/index.ts +9 -0
  40. package/src/combobox/createComboBoxState.ts +8 -0
  41. package/src/dnd/index.d.ts +1 -0
  42. package/src/dnd/index.ts +1 -0
  43. package/src/dnd/types.d.ts +3 -1
  44. package/src/dnd/types.ts +4 -1
  45. package/src/grid/createGridState.ts +36 -2
  46. package/src/grid/types.ts +17 -3
  47. package/src/index.d.ts +1 -0
  48. package/src/index.ts +11 -0
  49. package/src/select/createSelectState.ts +15 -2
  50. package/src/selection/Selection.ts +28 -0
  51. package/src/selection/SelectionManager.ts +526 -0
  52. package/src/selection/createMultipleSelectionState.ts +247 -0
  53. package/src/selection/index.ts +6 -0
  54. package/src/table/TableCollection.ts +213 -43
  55. package/src/table/createTableState.ts +20 -0
  56. package/src/table/createTreeGridState.ts +146 -0
  57. package/src/table/index.ts +3 -0
  58. package/src/table/types.ts +66 -0
  59. package/src/tabs/createTabListState.ts +11 -9
  60. package/src/toast/createToastState.ts +43 -10
  61. package/src/toast/index.ts +1 -0
  62. package/src/tree/createTreeState.ts +37 -6
  63. package/src/tree/types.ts +14 -6
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { createSignal, createEffect, createMemo, on, type Accessor } from "solid-js";
7
7
  import type { GridState, GridStateOptions, GridCollection, GridNode } from "./types";
8
- import type { Key, FocusStrategy } from "../collections/types";
8
+ import type { Key, FocusStrategy, SelectionBehavior, Selection } from "../collections/types";
9
9
 
10
10
  /**
11
11
  * Creates state management for a grid component.
@@ -40,11 +40,33 @@ export function createGridState<T extends object, C extends GridCollection<T> =
40
40
  });
41
41
 
42
42
  const selectionMode = createMemo(() => getOptions().selectionMode ?? "none");
43
- const selectionBehavior = createMemo(() => getOptions().selectionBehavior ?? "toggle");
43
+ const selectionBehaviorProp = (): SelectionBehavior => getOptions().selectionBehavior ?? "toggle";
44
+ const [selectionBehaviorState, setSelectionBehaviorState] =
45
+ createSignal<SelectionBehavior>(selectionBehaviorProp());
46
+ const selectionBehavior = createMemo(() => selectionBehaviorState());
44
47
  const disallowEmptySelection = createMemo(() => getOptions().disallowEmptySelection ?? false);
48
+ const disabledBehavior = createMemo(() => getOptions().disabledBehavior ?? "all");
45
49
 
46
50
  const focusMode = createMemo(() => getOptions().focusMode ?? "row");
47
51
 
52
+ createEffect(
53
+ on(selectionBehaviorProp, (behavior) => {
54
+ setSelectionBehaviorState(behavior);
55
+ }),
56
+ );
57
+
58
+ createEffect(() => {
59
+ const keys = selectedKeys();
60
+ if (
61
+ selectionBehaviorProp() === "replace" &&
62
+ selectionBehaviorState() === "toggle" &&
63
+ keys !== "all" &&
64
+ keys.size === 0
65
+ ) {
66
+ setSelectionBehaviorState("replace");
67
+ }
68
+ });
69
+
48
70
  const setFocusedKey = (key: Key | null, strategy: FocusStrategy = "first") => {
49
71
  const opts = getOptions();
50
72
  const collection = opts.collection;
@@ -215,6 +237,10 @@ export function createGridState<T extends object, C extends GridCollection<T> =
215
237
  setAnchorKey(key);
216
238
  };
217
239
 
240
+ const setSelectedKeys = (keys: Selection | Iterable<Key>) => {
241
+ updateSelection(normalizeSelection(keys));
242
+ };
243
+
218
244
  const extendSelection = (toKey: Key) => {
219
245
  if (isDisabled(toKey)) return;
220
246
  if (selectionMode() !== "multiple") {
@@ -273,6 +299,9 @@ export function createGridState<T extends object, C extends GridCollection<T> =
273
299
  get disabledKeys() {
274
300
  return disabledKeys();
275
301
  },
302
+ get disabledBehavior() {
303
+ return disabledBehavior();
304
+ },
276
305
  get isKeyboardNavigationDisabled() {
277
306
  return isKeyboardNavigationDisabled();
278
307
  },
@@ -291,6 +320,9 @@ export function createGridState<T extends object, C extends GridCollection<T> =
291
320
  get selectionBehavior() {
292
321
  return selectionBehavior();
293
322
  },
323
+ get disallowEmptySelection() {
324
+ return disallowEmptySelection();
325
+ },
294
326
  get selectedKeys() {
295
327
  return selectedKeys();
296
328
  },
@@ -298,8 +330,10 @@ export function createGridState<T extends object, C extends GridCollection<T> =
298
330
  isDisabled,
299
331
  setFocusedKey,
300
332
  setFocused: setIsFocused,
333
+ setSelectionBehavior: setSelectionBehaviorState,
301
334
  toggleSelection,
302
335
  replaceSelection,
336
+ setSelectedKeys,
303
337
  extendSelection,
304
338
  selectAll,
305
339
  clearSelection,
package/src/grid/types.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Based on @react-types/grid.
4
4
  */
5
5
 
6
- import type { Key, FocusStrategy } from "../collections/types";
6
+ import type { Key, FocusStrategy, Selection, SelectionBehavior } from "../collections/types";
7
7
 
8
8
  /**
9
9
  * Represents the type of a grid node.
@@ -42,6 +42,10 @@ export interface GridNode<T = unknown> {
42
42
  prevKey?: Key | null;
43
43
  /** Next sibling key (visible order). */
44
44
  nextKey?: Key | null;
45
+ /** Key of the first child node, if any (used by tree grids). */
46
+ firstChildKey?: Key | null;
47
+ /** Key of the last child node, if any (used by tree grids). */
48
+ lastChildKey?: Key | null;
45
49
  /** Whether this node has child nodes. */
46
50
  hasChildNodes: boolean;
47
51
  /** Child nodes (cells for rows, rows for sections). */
@@ -123,6 +127,8 @@ export interface GridState<T, C extends GridCollection<T> = GridCollection<T>> {
123
127
  readonly collection: C;
124
128
  /** Keys of disabled rows. */
125
129
  readonly disabledKeys: Set<Key>;
130
+ /** Whether `disabledKeys` applies to all interactions, or only selection. */
131
+ readonly disabledBehavior: "selection" | "all";
126
132
  /** Whether keyboard navigation is disabled. */
127
133
  readonly isKeyboardNavigationDisabled: boolean;
128
134
  /** Currently focused key. */
@@ -134,7 +140,9 @@ export interface GridState<T, C extends GridCollection<T> = GridCollection<T>> {
134
140
  /** The selection mode. */
135
141
  readonly selectionMode: "none" | "single" | "multiple";
136
142
  /** The selection behavior. */
137
- readonly selectionBehavior: "toggle" | "replace";
143
+ readonly selectionBehavior: SelectionBehavior;
144
+ /** Whether empty selection is disallowed. */
145
+ readonly disallowEmptySelection: boolean;
138
146
  /** The currently selected keys. */
139
147
  readonly selectedKeys: "all" | Set<Key>;
140
148
  /** Check if a key is selected. */
@@ -145,10 +153,14 @@ export interface GridState<T, C extends GridCollection<T> = GridCollection<T>> {
145
153
  setFocusedKey(key: Key | null, childFocusStrategy?: FocusStrategy): void;
146
154
  /** Set focused state. */
147
155
  setFocused(isFocused: boolean): void;
156
+ /** Set the selection behavior. */
157
+ setSelectionBehavior(behavior: SelectionBehavior): void;
148
158
  /** Toggle selection for a key. */
149
159
  toggleSelection(key: Key): void;
150
160
  /** Replace selection with a key. */
151
161
  replaceSelection(key: Key): void;
162
+ /** Set multiple selected keys. */
163
+ setSelectedKeys(keys: Selection | Iterable<Key>): void;
152
164
  /** Extend selection to a key (shift-click). */
153
165
  extendSelection(toKey: Key): void;
154
166
  /** Select all rows. */
@@ -169,12 +181,14 @@ export interface GridStateOptions<T, C extends GridCollection<T> = GridCollectio
169
181
  collection: C;
170
182
  /** Keys of disabled rows. */
171
183
  disabledKeys?: Iterable<Key>;
184
+ /** Whether `disabledKeys` applies to all interactions, or only selection. @default "all" */
185
+ disabledBehavior?: "selection" | "all";
172
186
  /** Focus mode: 'row' or 'cell'. */
173
187
  focusMode?: "row" | "cell";
174
188
  /** Selection mode. */
175
189
  selectionMode?: "none" | "single" | "multiple";
176
190
  /** Selection behavior. */
177
- selectionBehavior?: "toggle" | "replace";
191
+ selectionBehavior?: SelectionBehavior;
178
192
  /** Whether empty selection is disallowed. */
179
193
  disallowEmptySelection?: boolean;
180
194
  /** Currently selected keys (controlled). */
package/src/index.d.ts CHANGED
@@ -266,6 +266,7 @@ export {
266
266
  type DroppableCollectionRootDropEvent,
267
267
  type DroppableCollectionOnItemDropEvent,
268
268
  type DroppableCollectionReorderEvent,
269
+ type DragType,
269
270
  type DragTypes,
270
271
  type DropTargetDelegate,
271
272
  type DraggableCollectionStartEvent,
package/src/index.ts CHANGED
@@ -53,6 +53,7 @@ export {
53
53
  createSelectionState,
54
54
  type SelectionStateProps,
55
55
  type SelectionState,
56
+ type SelectionPressEvent,
56
57
  createListState,
57
58
  createSingleSelectListState,
58
59
  type ListStateProps,
@@ -72,6 +73,9 @@ export {
72
73
  useMultipleSelectionState,
73
74
  type MultipleSelectionStateProps,
74
75
  type MultipleSelectionState,
76
+ SelectionManager,
77
+ type SelectionManagerOptions,
78
+ type LayoutDelegate,
75
79
  } from "./selection";
76
80
 
77
81
  // Menu (module-compat aliases)
@@ -143,6 +147,7 @@ export {
143
147
  type ToastOptions,
144
148
  type QueuedToast,
145
149
  type ToastQueueOptions,
150
+ type ToastAction,
146
151
  type ToastStateProps,
147
152
  type ToastState,
148
153
  } from "./toast";
@@ -161,6 +166,8 @@ export {
161
166
  createCalendarState,
162
167
  type CalendarStateProps,
163
168
  type CalendarState,
169
+ type CalendarSelectionMode,
170
+ type CalendarValueType,
164
171
  type ValidationState,
165
172
  type CalendarPageBehavior,
166
173
  type CalendarSelectionAlignment,
@@ -240,12 +247,15 @@ export {
240
247
 
241
248
  export {
242
249
  createTableState,
250
+ createTreeGridState,
243
251
  createTableColumnResizeState,
244
252
  TableCollection,
245
253
  createTableCollection,
246
254
  type TableState,
247
255
  type TableStateOptions,
248
256
  type ITableCollection,
257
+ type TreeGridState,
258
+ type TreeGridStateOptions,
249
259
  type SortDescriptor,
250
260
  type SortDirection,
251
261
  type Sortable,
@@ -324,6 +334,7 @@ export {
324
334
  type DroppableCollectionRootDropEvent,
325
335
  type DroppableCollectionOnItemDropEvent,
326
336
  type DroppableCollectionReorderEvent,
337
+ type DragType,
327
338
  type DragTypes,
328
339
  type DropTargetDelegate,
329
340
  type DraggableCollectionStartEvent,
@@ -9,6 +9,7 @@ import { createListState } from "../collections/createListState";
9
9
  import { createOverlayTriggerState } from "../overlays";
10
10
  import type { Key, CollectionNode, Collection } from "../collections/types";
11
11
  import type { SelectionMode, Selection } from "../collections/types";
12
+ import type { SelectionManager } from "../selection/SelectionManager";
12
13
 
13
14
  export interface SelectStateProps<T = unknown> {
14
15
  /** The items to display in the select. */
@@ -50,6 +51,11 @@ export interface SelectStateProps<T = unknown> {
50
51
  export interface SelectState<T = unknown> {
51
52
  /** The collection of items. */
52
53
  readonly collection: Accessor<Collection<T>>;
54
+ /**
55
+ * The collection-aware selection manager. Mirrors upstream `useSelectState`,
56
+ * which spreads the underlying `useListState` (including its selection manager).
57
+ */
58
+ readonly selectionManager: SelectionManager<T>;
53
59
  /** Whether the select dropdown is open. */
54
60
  readonly isOpen: Accessor<boolean>;
55
61
  /** Open the select dropdown. */
@@ -234,6 +240,12 @@ export function createSelectState<T = unknown>(
234
240
  },
235
241
  });
236
242
 
243
+ // The select's own focus state (the trigger), separate from the collection's
244
+ // focus-within state on the selection manager — upstream useSelectState keeps
245
+ // these apart with a dedicated useState. Sharing the manager's signal makes
246
+ // trigger focus re-arm the item roving-focus effect and steal focus back.
247
+ const [isFocused, setFocused] = createSignal(false);
248
+
237
249
  // Get the selected item from the collection (memoized)
238
250
  const selectedItem: Accessor<CollectionNode<T> | null> = createMemo(() => {
239
251
  const key = selectedKey();
@@ -258,12 +270,13 @@ export function createSelectState<T = unknown>(
258
270
  return {
259
271
  // Collection
260
272
  collection: listState.collection,
273
+ selectionManager: listState.selectionManager,
261
274
 
262
275
  // Focus management
263
276
  focusedKey: listState.focusedKey,
264
277
  setFocusedKey: listState.setFocusedKey,
265
- isFocused: listState.isFocused,
266
- setFocused: listState.setFocused,
278
+ isFocused,
279
+ setFocused,
267
280
 
268
281
  // Overlay state
269
282
  isOpen: overlayState.isOpen,
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A Selection is a special Set containing Keys, which also has an anchor
3
+ * and current selected key for use when range selecting.
4
+ *
5
+ * Based on @react-stately/selection.
6
+ */
7
+
8
+ import type { Key } from "../collections/types";
9
+
10
+ /**
11
+ * A Selection is a special Set containing Keys, which also has an anchor
12
+ * and current selected key for use when range selecting.
13
+ */
14
+ export class Selection extends Set<Key> {
15
+ anchorKey: Key | null;
16
+ currentKey: Key | null;
17
+
18
+ constructor(keys?: Iterable<Key> | Selection, anchorKey?: Key | null, currentKey?: Key | null) {
19
+ super(keys);
20
+ if (keys instanceof Selection) {
21
+ this.anchorKey = anchorKey ?? keys.anchorKey;
22
+ this.currentKey = currentKey ?? keys.currentKey;
23
+ } else {
24
+ this.anchorKey = anchorKey ?? null;
25
+ this.currentKey = currentKey ?? null;
26
+ }
27
+ }
28
+ }