@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.
Files changed (254) 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/IncompleteDate.d.ts +61 -0
  5. package/dist/calendar/createCalendarState.d.ts +41 -16
  6. package/dist/calendar/createDateFieldState.d.ts +39 -9
  7. package/dist/calendar/createDatePickerState.d.ts +60 -0
  8. package/dist/calendar/createRangeCalendarState.d.ts +37 -10
  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 +6 -6
  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 +11 -8
  15. package/dist/collections/createMenuState.d.ts +7 -7
  16. package/dist/collections/createSelectionState.d.ts +22 -10
  17. package/dist/collections/getChildNodes.d.ts +11 -0
  18. package/dist/collections/index.d.ts +6 -5
  19. package/dist/collections/types.d.ts +12 -12
  20. package/dist/color/Color.d.ts +1 -1
  21. package/dist/color/createColorAreaState.d.ts +4 -2
  22. package/dist/color/createColorFieldState.d.ts +38 -12
  23. package/dist/color/createColorSliderState.d.ts +9 -2
  24. package/dist/color/createColorWheelState.d.ts +13 -2
  25. package/dist/color/getColorChannels.d.ts +1 -1
  26. package/dist/color/index.d.ts +6 -6
  27. package/dist/color/types.d.ts +4 -4
  28. package/dist/combobox/createComboBoxState.d.ts +34 -13
  29. package/dist/combobox/index.d.ts +1 -1
  30. package/dist/data/createAsyncList.d.ts +4 -4
  31. package/dist/data/createListData.d.ts +2 -2
  32. package/dist/data/createTreeData.d.ts +6 -2
  33. package/dist/data/index.d.ts +3 -3
  34. package/dist/datepicker/index.d.ts +2 -4
  35. package/dist/disclosure/createDisclosureState.d.ts +2 -2
  36. package/dist/disclosure/index.d.ts +1 -1
  37. package/dist/dnd/createDragState.d.ts +2 -2
  38. package/dist/dnd/createDraggableCollectionState.d.ts +2 -2
  39. package/dist/dnd/createDropState.d.ts +2 -2
  40. package/dist/dnd/createDroppableCollectionState.d.ts +3 -3
  41. package/dist/dnd/index.d.ts +5 -5
  42. package/dist/dnd/types.d.ts +19 -17
  43. package/dist/form/createFormValidationState.d.ts +3 -3
  44. package/dist/form/index.d.ts +1 -1
  45. package/dist/grid/createGridState.d.ts +2 -2
  46. package/dist/grid/index.d.ts +2 -2
  47. package/dist/grid/types.d.ts +27 -11
  48. package/dist/index.d.ts +31 -30
  49. package/dist/index.js +9077 -7246
  50. package/dist/index.js.map +1 -1
  51. package/dist/menu/index.d.ts +2 -2
  52. package/dist/numberfield/createNumberFieldState.d.ts +2 -2
  53. package/dist/numberfield/index.d.ts +1 -1
  54. package/dist/overlays/createOverlayTriggerState.d.ts +2 -2
  55. package/dist/overlays/index.d.ts +1 -1
  56. package/dist/radio/createRadioGroupState.d.ts +7 -7
  57. package/dist/radio/index.d.ts +1 -1
  58. package/dist/searchfield/createSearchFieldState.d.ts +2 -2
  59. package/dist/searchfield/index.d.ts +2 -2
  60. package/dist/select/createSelectState.d.ts +14 -8
  61. package/dist/select/index.d.ts +1 -1
  62. package/dist/selection/Selection.d.ts +16 -0
  63. package/dist/selection/SelectionManager.d.ts +110 -0
  64. package/dist/selection/createMultipleSelectionState.d.ts +59 -0
  65. package/dist/selection/index.d.ts +6 -5
  66. package/dist/slider/createSliderState.d.ts +3 -3
  67. package/dist/slider/index.d.ts +2 -2
  68. package/dist/steplist/createStepListState.d.ts +48 -0
  69. package/dist/steplist/index.d.ts +1 -0
  70. package/dist/table/TableCollection.d.ts +33 -3
  71. package/dist/table/createTableColumnResizeState.d.ts +54 -0
  72. package/dist/table/createTableState.d.ts +2 -2
  73. package/dist/table/createTreeGridState.d.ts +15 -0
  74. package/dist/table/index.d.ts +6 -3
  75. package/dist/table/types.d.ts +68 -10
  76. package/dist/tabs/createTabListState.d.ts +5 -5
  77. package/dist/tabs/index.d.ts +1 -1
  78. package/dist/textfield/createTextFieldState.d.ts +2 -2
  79. package/dist/textfield/index.d.ts +1 -1
  80. package/dist/toast/createToastState.d.ts +24 -2
  81. package/dist/toast/index.d.ts +1 -1
  82. package/dist/toggle/createToggleGroupState.d.ts +4 -4
  83. package/dist/toggle/createToggleState.d.ts +2 -2
  84. package/dist/toggle/index.d.ts +2 -2
  85. package/dist/tooltip/createTooltipTriggerState.d.ts +2 -2
  86. package/dist/tooltip/index.d.ts +1 -1
  87. package/dist/tree/TreeCollection.d.ts +2 -2
  88. package/dist/tree/createTreeState.d.ts +2 -2
  89. package/dist/tree/index.d.ts +3 -3
  90. package/dist/tree/types.d.ts +27 -13
  91. package/dist/utils/index.d.ts +1 -1
  92. package/dist/utils/reactivity.d.ts +1 -1
  93. package/package.json +29 -30
  94. package/src/autocomplete/createAutocompleteState.d.ts +19 -17
  95. package/src/autocomplete/createAutocompleteState.ts +24 -30
  96. package/src/autocomplete/index.d.ts +6 -2
  97. package/src/autocomplete/index.ts +1 -1
  98. package/src/calendar/IncompleteDate.ts +430 -0
  99. package/src/calendar/createCalendarState.d.ts +139 -117
  100. package/src/calendar/createCalendarState.ts +308 -94
  101. package/src/calendar/createDateFieldState.d.ts +130 -95
  102. package/src/calendar/createDateFieldState.ts +447 -334
  103. package/src/calendar/createDatePickerState.ts +347 -0
  104. package/src/calendar/createRangeCalendarState.d.ts +154 -129
  105. package/src/calendar/createRangeCalendarState.ts +411 -85
  106. package/src/calendar/createTimeFieldState.d.ts +81 -79
  107. package/src/calendar/createTimeFieldState.ts +187 -108
  108. package/src/calendar/index.d.ts +80 -7
  109. package/src/calendar/index.ts +23 -12
  110. package/src/checkbox/createCheckboxGroupState.d.ts +57 -55
  111. package/src/checkbox/createCheckboxGroupState.ts +20 -29
  112. package/src/checkbox/index.d.ts +6 -2
  113. package/src/checkbox/index.ts +1 -1
  114. package/src/collections/ListCollection.d.ts +25 -22
  115. package/src/collections/ListCollection.ts +6 -6
  116. package/src/collections/createListState.d.ts +73 -58
  117. package/src/collections/createListState.ts +67 -35
  118. package/src/collections/createMenuState.d.ts +36 -31
  119. package/src/collections/createMenuState.ts +21 -12
  120. package/src/collections/createSelectionState.d.ts +78 -65
  121. package/src/collections/createSelectionState.ts +66 -52
  122. package/src/collections/getChildNodes.ts +98 -0
  123. package/src/collections/index.d.ts +38 -6
  124. package/src/collections/index.ts +14 -10
  125. package/src/collections/types.d.ts +101 -101
  126. package/src/collections/types.ts +12 -12
  127. package/src/color/Color.d.ts +20 -5
  128. package/src/color/Color.ts +357 -254
  129. package/src/color/createColorAreaState.d.ts +67 -65
  130. package/src/color/createColorAreaState.ts +21 -13
  131. package/src/color/createColorFieldState.d.ts +46 -44
  132. package/src/color/createColorFieldState.ts +285 -149
  133. package/src/color/createColorSliderState.d.ts +58 -56
  134. package/src/color/createColorSliderState.ts +45 -14
  135. package/src/color/createColorWheelState.d.ts +42 -40
  136. package/src/color/createColorWheelState.ts +101 -64
  137. package/src/color/getColorChannels.ts +7 -5
  138. package/src/color/index.d.ts +36 -7
  139. package/src/color/index.ts +6 -9
  140. package/src/color/types.d.ts +68 -63
  141. package/src/color/types.ts +11 -19
  142. package/src/combobox/createComboBoxState.d.ts +107 -105
  143. package/src/combobox/createComboBoxState.ts +184 -89
  144. package/src/combobox/index.d.ts +10 -2
  145. package/src/combobox/index.ts +1 -1
  146. package/src/data/createAsyncList.ts +89 -63
  147. package/src/data/createListData.ts +67 -67
  148. package/src/data/createTreeData.ts +304 -91
  149. package/src/data/index.ts +3 -3
  150. package/src/datepicker/index.ts +6 -10
  151. package/src/disclosure/createDisclosureState.d.ts +47 -43
  152. package/src/disclosure/createDisclosureState.ts +7 -21
  153. package/src/disclosure/index.d.ts +10 -2
  154. package/src/disclosure/index.ts +1 -1
  155. package/src/dnd/createDragState.d.ts +51 -42
  156. package/src/dnd/createDragState.ts +12 -14
  157. package/src/dnd/createDraggableCollectionState.d.ts +52 -41
  158. package/src/dnd/createDraggableCollectionState.ts +14 -21
  159. package/src/dnd/createDropState.d.ts +64 -45
  160. package/src/dnd/createDropState.ts +22 -32
  161. package/src/dnd/createDroppableCollectionState.d.ts +88 -59
  162. package/src/dnd/createDroppableCollectionState.ts +40 -43
  163. package/src/dnd/index.d.ts +55 -6
  164. package/src/dnd/index.ts +6 -18
  165. package/src/dnd/types.d.ts +170 -157
  166. package/src/dnd/types.ts +24 -22
  167. package/src/form/createFormValidationState.d.ts +47 -45
  168. package/src/form/createFormValidationState.ts +30 -63
  169. package/src/form/index.d.ts +16 -2
  170. package/src/form/index.ts +1 -1
  171. package/src/grid/createGridState.d.ts +7 -4
  172. package/src/grid/createGridState.ts +78 -51
  173. package/src/grid/index.d.ts +3 -3
  174. package/src/grid/index.ts +2 -8
  175. package/src/grid/types.d.ts +136 -129
  176. package/src/grid/types.ts +34 -18
  177. package/src/index.d.ts +311 -26
  178. package/src/index.ts +59 -89
  179. package/src/menu/index.ts +2 -4
  180. package/src/numberfield/createNumberFieldState.d.ts +56 -54
  181. package/src/numberfield/createNumberFieldState.ts +26 -31
  182. package/src/numberfield/index.d.ts +6 -2
  183. package/src/numberfield/index.ts +1 -1
  184. package/src/overlays/createOverlayTriggerState.d.ts +22 -20
  185. package/src/overlays/createOverlayTriggerState.ts +3 -4
  186. package/src/overlays/index.d.ts +6 -2
  187. package/src/overlays/index.ts +1 -1
  188. package/src/radio/createRadioGroupState.d.ts +54 -52
  189. package/src/radio/createRadioGroupState.ts +27 -29
  190. package/src/radio/index.d.ts +7 -2
  191. package/src/radio/index.ts +1 -1
  192. package/src/searchfield/createSearchFieldState.d.ts +16 -14
  193. package/src/searchfield/createSearchFieldState.ts +5 -11
  194. package/src/searchfield/index.d.ts +3 -3
  195. package/src/searchfield/index.ts +2 -5
  196. package/src/select/createSelectState.d.ts +63 -61
  197. package/src/select/createSelectState.ts +42 -29
  198. package/src/select/index.d.ts +2 -2
  199. package/src/select/index.ts +1 -5
  200. package/src/selection/Selection.ts +28 -0
  201. package/src/selection/SelectionManager.ts +526 -0
  202. package/src/selection/createMultipleSelectionState.ts +247 -0
  203. package/src/selection/index.ts +12 -7
  204. package/src/slider/createSliderState.d.ts +60 -60
  205. package/src/slider/createSliderState.ts +55 -33
  206. package/src/slider/index.d.ts +3 -3
  207. package/src/slider/index.ts +2 -6
  208. package/src/ssr/index.d.ts +1 -1
  209. package/src/ssr/index.ts +2 -2
  210. package/src/steplist/createStepListState.ts +191 -0
  211. package/src/steplist/index.ts +5 -0
  212. package/src/table/TableCollection.d.ts +42 -40
  213. package/src/table/TableCollection.ts +266 -99
  214. package/src/table/createTableColumnResizeState.ts +242 -0
  215. package/src/table/createTableState.d.ts +7 -4
  216. package/src/table/createTableState.ts +30 -7
  217. package/src/table/createTreeGridState.ts +146 -0
  218. package/src/table/index.d.ts +14 -4
  219. package/src/table/index.ts +13 -3
  220. package/src/table/types.d.ts +98 -92
  221. package/src/table/types.ts +83 -13
  222. package/src/tabs/createTabListState.d.ts +59 -57
  223. package/src/tabs/createTabListState.ts +34 -39
  224. package/src/tabs/index.d.ts +8 -2
  225. package/src/tabs/index.ts +1 -1
  226. package/src/textfield/createTextFieldState.d.ts +16 -14
  227. package/src/textfield/createTextFieldState.ts +7 -18
  228. package/src/textfield/index.d.ts +6 -2
  229. package/src/textfield/index.ts +1 -1
  230. package/src/toast/createToastState.d.ts +92 -86
  231. package/src/toast/createToastState.ts +90 -52
  232. package/src/toast/index.d.ts +12 -2
  233. package/src/toast/index.ts +2 -1
  234. package/src/toggle/createToggleGroupState.ts +11 -21
  235. package/src/toggle/createToggleState.d.ts +19 -19
  236. package/src/toggle/createToggleState.ts +2 -16
  237. package/src/toggle/index.d.ts +2 -2
  238. package/src/toggle/index.ts +2 -6
  239. package/src/tooltip/createTooltipTriggerState.d.ts +17 -17
  240. package/src/tooltip/createTooltipTriggerState.ts +12 -11
  241. package/src/tooltip/index.d.ts +7 -2
  242. package/src/tooltip/index.ts +1 -1
  243. package/src/tree/TreeCollection.d.ts +26 -23
  244. package/src/tree/TreeCollection.ts +29 -22
  245. package/src/tree/createTreeState.d.ts +7 -4
  246. package/src/tree/createTreeState.ts +70 -41
  247. package/src/tree/index.d.ts +10 -4
  248. package/src/tree/index.ts +3 -3
  249. package/src/tree/types.d.ts +131 -126
  250. package/src/tree/types.ts +30 -13
  251. package/src/utils/index.d.ts +2 -2
  252. package/src/utils/index.ts +1 -1
  253. package/src/utils/reactivity.d.ts +2 -2
  254. package/src/utils/reactivity.ts +3 -3
@@ -3,8 +3,8 @@
3
3
  * Based on @react-stately/selection.
4
4
  */
5
5
 
6
- import { createSignal, createMemo, type Accessor } from 'solid-js';
7
- import { access, type MaybeAccessor } from '../utils';
6
+ import { createSignal, createMemo, type Accessor } from "solid-js";
7
+ import { access, type MaybeAccessor } from "../utils";
8
8
  import type {
9
9
  Collection,
10
10
  DisabledBehavior,
@@ -13,7 +13,7 @@ import type {
13
13
  Selection,
14
14
  SelectionBehavior,
15
15
  SelectionMode,
16
- } from './types';
16
+ } from "./types";
17
17
 
18
18
  export interface SelectionStateProps {
19
19
  /** The selection mode. */
@@ -23,9 +23,9 @@ export interface SelectionStateProps {
23
23
  /** Whether empty selection is disallowed. */
24
24
  disallowEmptySelection?: boolean;
25
25
  /** Currently selected keys (controlled). */
26
- selectedKeys?: 'all' | Iterable<Key>;
26
+ selectedKeys?: "all" | Iterable<Key>;
27
27
  /** Default selected keys (uncontrolled). */
28
- defaultSelectedKeys?: 'all' | Iterable<Key>;
28
+ defaultSelectedKeys?: "all" | Iterable<Key>;
29
29
  /** Handler for selection changes. */
30
30
  onSelectionChange?: (keys: Selection) => void;
31
31
  /** Keys of disabled items. */
@@ -74,30 +74,47 @@ export interface SelectionState {
74
74
  /** Extend selection to a key (for shift-click). */
75
75
  extendSelection(toKey: Key, collection: Collection): void;
76
76
  /** Select a key based on interaction. */
77
- select(key: Key, e?: { shiftKey?: boolean; ctrlKey?: boolean; metaKey?: boolean }, collection?: Collection): void;
77
+ select(key: Key, e?: SelectionPressEvent): void;
78
+ }
79
+
80
+ /**
81
+ * The press/pointer interaction consulted by {@link SelectionState.select}.
82
+ * Mirrors react-stately's `SelectionManager.select(e)`: only `pointerType` is
83
+ * read here (touch / virtual force toggle, since those devices have no modifier
84
+ * keys). Modifier keys (ctrl / meta / shift) are resolved one layer up in the
85
+ * aria-layer `onSelect` (solidaria `selectItem`), matching upstream's split
86
+ * between react-stately and react-aria. The modifier fields are accepted so a
87
+ * full press/pointer event is assignable, but they are not read here.
88
+ */
89
+ export interface SelectionPressEvent {
90
+ pointerType?: "mouse" | "pen" | "touch" | "keyboard" | "virtual";
91
+ shiftKey?: boolean;
92
+ ctrlKey?: boolean;
93
+ metaKey?: boolean;
94
+ altKey?: boolean;
78
95
  }
79
96
 
80
97
  /**
81
98
  * Creates selection state for a collection.
82
99
  */
83
100
  export function createSelectionState(
84
- props: MaybeAccessor<SelectionStateProps> = {}
101
+ props: MaybeAccessor<SelectionStateProps> = {},
85
102
  ): SelectionState {
86
103
  const getProps = () => access(props);
87
104
 
88
105
  // Selection behavior state
89
- const [internalBehavior, setInternalBehavior] = createSignal<SelectionBehavior>('toggle');
106
+ const [internalBehavior, setInternalBehavior] = createSignal<SelectionBehavior>("toggle");
90
107
 
91
108
  // Internal selection state
92
109
  const [internalSelectedKeys, setInternalSelectedKeys] = createSignal<Selection>(
93
- getInitialSelection(getProps().defaultSelectedKeys)
110
+ getInitialSelection(getProps().defaultSelectedKeys),
94
111
  );
95
112
 
96
113
  // Track anchor for range selection
97
114
  const [anchorKey, setAnchorKey] = createSignal<Key | null>(null);
98
115
 
99
116
  // Computed values
100
- const selectionMode: Accessor<SelectionMode> = () => getProps().selectionMode ?? 'none';
117
+ const selectionMode: Accessor<SelectionMode> = () => getProps().selectionMode ?? "none";
101
118
 
102
119
  const selectionBehavior: Accessor<SelectionBehavior> = () => {
103
120
  return getProps().selectionBehavior ?? internalBehavior();
@@ -121,22 +138,22 @@ export function createSelectionState(
121
138
  });
122
139
 
123
140
  const disabledBehavior: Accessor<DisabledBehavior> = () => {
124
- return getProps().disabledBehavior ?? 'all';
141
+ return getProps().disabledBehavior ?? "all";
125
142
  };
126
143
 
127
144
  const isEmpty: Accessor<boolean> = () => {
128
145
  const keys = selectedKeys();
129
- return keys !== 'all' && keys.size === 0;
146
+ return keys !== "all" && keys.size === 0;
130
147
  };
131
148
 
132
149
  const isSelectAll: Accessor<boolean> = () => {
133
- return selectedKeys() === 'all';
150
+ return selectedKeys() === "all";
134
151
  };
135
152
 
136
153
  // Methods
137
154
  const isSelected = (key: Key): boolean => {
138
155
  const keys = selectedKeys();
139
- if (keys === 'all') return true;
156
+ if (keys === "all") return true;
140
157
  return keys.has(key);
141
158
  };
142
159
 
@@ -156,8 +173,8 @@ export function createSelectionState(
156
173
  // Uncontrolled mode
157
174
  const current = internalSelectedKeys();
158
175
  const isDifferent =
159
- current === 'all' ||
160
- newSelection === 'all' ||
176
+ current === "all" ||
177
+ newSelection === "all" ||
161
178
  current.size !== (newSelection as Set<Key>).size ||
162
179
  ![...current].every((k) => (newSelection as Set<Key>).has(k));
163
180
 
@@ -169,11 +186,11 @@ export function createSelectionState(
169
186
 
170
187
  const toggleSelection = (key: Key) => {
171
188
  if (isDisabled(key)) return;
172
- if (selectionMode() === 'none') return;
189
+ if (selectionMode() === "none") return;
173
190
 
174
191
  const current = selectedKeys();
175
192
 
176
- if (selectionMode() === 'single') {
193
+ if (selectionMode() === "single") {
177
194
  if (isSelected(key) && !disallowEmptySelection()) {
178
195
  updateSelection(new Set());
179
196
  } else {
@@ -183,7 +200,7 @@ export function createSelectionState(
183
200
  }
184
201
 
185
202
  // Multiple selection
186
- if (current === 'all') {
203
+ if (current === "all") {
187
204
  // Can't toggle when all selected without collection
188
205
  return;
189
206
  }
@@ -203,7 +220,7 @@ export function createSelectionState(
203
220
 
204
221
  const replaceSelection = (key: Key) => {
205
222
  if (isDisabled(key)) return;
206
- if (selectionMode() === 'none') return;
223
+ if (selectionMode() === "none") return;
207
224
 
208
225
  updateSelection(new Set([key]));
209
226
  setAnchorKey(key);
@@ -215,8 +232,8 @@ export function createSelectionState(
215
232
  };
216
233
 
217
234
  const selectAll = () => {
218
- if (selectionMode() !== 'multiple') return;
219
- updateSelection('all');
235
+ if (selectionMode() !== "multiple") return;
236
+ updateSelection("all");
220
237
  };
221
238
 
222
239
  const clearSelection = () => {
@@ -225,7 +242,7 @@ export function createSelectionState(
225
242
  };
226
243
 
227
244
  const toggleSelectAll = () => {
228
- if (selectionMode() !== 'multiple') return;
245
+ if (selectionMode() !== "multiple") return;
229
246
 
230
247
  if (isSelectAll()) {
231
248
  clearSelection();
@@ -236,7 +253,7 @@ export function createSelectionState(
236
253
 
237
254
  const extendSelection = (toKey: Key, collection: Collection) => {
238
255
  if (isDisabled(toKey)) return;
239
- if (selectionMode() !== 'multiple') {
256
+ if (selectionMode() !== "multiple") {
240
257
  replaceSelection(toKey);
241
258
  return;
242
259
  }
@@ -264,33 +281,30 @@ export function createSelectionState(
264
281
  updateSelection(new Set(rangeKeys));
265
282
  };
266
283
 
267
- const select = (
268
- key: Key,
269
- e?: { shiftKey?: boolean; ctrlKey?: boolean; metaKey?: boolean },
270
- collection?: Collection
271
- ) => {
272
- if (isDisabled(key)) return;
273
- if (selectionMode() === 'none') return;
274
-
275
- const mode = selectionMode();
276
- const behavior = selectionBehavior();
277
-
278
- if (mode === 'single') {
279
- if (behavior === 'replace' || !isSelected(key)) {
284
+ const select = (key: Key, e?: SelectionPressEvent) => {
285
+ // Mirrors react-stately's SelectionManager.select: only pointerType +
286
+ // selectionBehavior are consulted here. Modifier-key handling (ctrl / meta
287
+ // ⇒ toggle, shift ⇒ extend) lives one layer up in solidaria's aria-layer
288
+ // `selectItem`, which is where the platform-aware isCtrlKeyPressed is
289
+ // available. The primitives self-guard disabled keys, so no guard is
290
+ // needed here (matching upstream).
291
+ if (selectionMode() === "none") return;
292
+
293
+ if (selectionMode() === "single") {
294
+ // Single mode ignores selectionBehavior. Re-selecting the current item
295
+ // deselects it when empty selection is allowed; otherwise it stays
296
+ // selected (replace).
297
+ if (isSelected(key) && !disallowEmptySelection()) {
298
+ toggleSelection(key);
299
+ } else {
280
300
  replaceSelection(key);
281
- } else if (!disallowEmptySelection()) {
282
- clearSelection();
283
301
  }
284
- return;
285
- }
286
-
287
- // Multiple selection
288
- if (e?.shiftKey && collection) {
289
- extendSelection(key, collection);
290
- return;
291
- }
292
-
293
- if (e?.ctrlKey || e?.metaKey || behavior === 'toggle') {
302
+ } else if (
303
+ selectionBehavior() === "toggle" ||
304
+ (e != null && (e.pointerType === "touch" || e.pointerType === "virtual"))
305
+ ) {
306
+ // touch / virtual (VoiceOver) have no modifier keys, so multi-select is
307
+ // only reachable by toggling.
294
308
  toggleSelection(key);
295
309
  } else {
296
310
  replaceSelection(key);
@@ -325,12 +339,12 @@ export function createSelectionState(
325
339
  }
326
340
 
327
341
  // Helper functions
328
- function getInitialSelection(defaultKeys?: 'all' | Iterable<Key>): Selection {
342
+ function getInitialSelection(defaultKeys?: "all" | Iterable<Key>): Selection {
329
343
  if (defaultKeys === undefined) return new Set();
330
344
  return normalizeSelection(defaultKeys);
331
345
  }
332
346
 
333
- function normalizeSelection(keys: 'all' | Iterable<Key>): Selection {
334
- if (keys === 'all') return 'all';
347
+ function normalizeSelection(keys: "all" | Iterable<Key>): Selection {
348
+ if (keys === "all") return "all";
335
349
  return new Set(keys);
336
350
  }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Helpers for traversing collection nodes and comparing their document order.
3
+ *
4
+ * Based on @react-stately/collections.
5
+ */
6
+
7
+ import type { Collection, CollectionNode } from "./types";
8
+
9
+ export function getChildNodes<T>(
10
+ node: CollectionNode<T>,
11
+ collection: Collection<T>,
12
+ ): Iterable<CollectionNode<T>> {
13
+ // New API: call collection.getChildren with the node key.
14
+ if (typeof collection.getChildren === "function") {
15
+ return collection.getChildren(node.key);
16
+ }
17
+
18
+ // Old API: access childNodes directly.
19
+ return node.childNodes;
20
+ }
21
+
22
+ export function getFirstItem<T>(iterable: Iterable<T>): T | undefined {
23
+ return getNthItem(iterable, 0);
24
+ }
25
+
26
+ export function getNthItem<T>(iterable: Iterable<T>, index: number): T | undefined {
27
+ if (index < 0) {
28
+ return undefined;
29
+ }
30
+
31
+ let i = 0;
32
+ for (const item of iterable) {
33
+ if (i === index) {
34
+ return item;
35
+ }
36
+
37
+ i++;
38
+ }
39
+ }
40
+
41
+ export function getLastItem<T>(iterable: Iterable<T>): T | undefined {
42
+ let lastItem: T | undefined = undefined;
43
+ for (const value of iterable) {
44
+ lastItem = value;
45
+ }
46
+
47
+ return lastItem;
48
+ }
49
+
50
+ export function compareNodeOrder<T>(
51
+ collection: Collection<T>,
52
+ a: CollectionNode<T>,
53
+ b: CollectionNode<T>,
54
+ ): number {
55
+ // If the two nodes have the same parent, compare their indices.
56
+ if (a.parentKey === b.parentKey) {
57
+ return a.index - b.index;
58
+ }
59
+
60
+ // Otherwise, collect all of the ancestors from each node, and find the first one that doesn't match starting from the root.
61
+ // Include the base nodes in case we are comparing nodes of different levels so that we can compare the higher node to the lower level node's
62
+ // ancestor of the same level
63
+ const aAncestors = [...getAncestors(collection, a), a];
64
+ const bAncestors = [...getAncestors(collection, b), b];
65
+ const firstNonMatchingAncestor = aAncestors
66
+ .slice(0, bAncestors.length)
67
+ .findIndex((a, i) => a !== bAncestors[i]);
68
+ if (firstNonMatchingAncestor !== -1) {
69
+ // Compare the indices of two children within the common ancestor.
70
+ a = aAncestors[firstNonMatchingAncestor];
71
+ b = bAncestors[firstNonMatchingAncestor];
72
+ return a.index - b.index;
73
+ }
74
+
75
+ // If there isn't a non matching ancestor, we might be in a case where one of the nodes is the ancestor of the other.
76
+ if (aAncestors.findIndex((node) => node === b) >= 0) {
77
+ return 1;
78
+ } else if (bAncestors.findIndex((node) => node === a) >= 0) {
79
+ return -1;
80
+ }
81
+
82
+ // 🤷
83
+ return -1;
84
+ }
85
+
86
+ function getAncestors<T>(collection: Collection<T>, node: CollectionNode<T>): CollectionNode<T>[] {
87
+ const parents: CollectionNode<T>[] = [];
88
+
89
+ let currNode: CollectionNode<T> | null = node;
90
+ while (currNode?.parentKey != null) {
91
+ currNode = collection.getItem(currNode.parentKey);
92
+ if (currNode) {
93
+ parents.unshift(currNode);
94
+ }
95
+ }
96
+
97
+ return parents;
98
+ }
@@ -1,6 +1,38 @@
1
- export type { Key, SelectionMode, SelectionBehavior, Selection, FocusStrategy, DisabledBehavior, CollectionNode, Collection, ItemProps, SectionProps, CollectionBase, SingleSelection, MultipleSelection, } from './types';
2
- export { ListCollection, createListCollection } from './ListCollection';
3
- export { createSelectionState, type SelectionStateProps, type SelectionState, } from './createSelectionState';
4
- export { createListState, createSingleSelectListState, type ListStateProps, type ListState, type SingleSelectListStateProps, type SingleSelectListState, } from './createListState';
5
- export { createMenuState, createMenuTriggerState, type MenuStateProps, type MenuState, type MenuTriggerStateProps, type MenuTriggerState, } from './createMenuState';
6
- //# sourceMappingURL=index.d.ts.map
1
+ export type {
2
+ Key,
3
+ SelectionMode,
4
+ SelectionBehavior,
5
+ Selection,
6
+ FocusStrategy,
7
+ DisabledBehavior,
8
+ CollectionNode,
9
+ Collection,
10
+ ItemProps,
11
+ SectionProps,
12
+ CollectionBase,
13
+ SingleSelection,
14
+ MultipleSelection,
15
+ } from "./types";
16
+ export { ListCollection, createListCollection } from "./ListCollection";
17
+ export {
18
+ createSelectionState,
19
+ type SelectionStateProps,
20
+ type SelectionState,
21
+ } from "./createSelectionState";
22
+ export {
23
+ createListState,
24
+ createSingleSelectListState,
25
+ type ListStateProps,
26
+ type ListState,
27
+ type SingleSelectListStateProps,
28
+ type SingleSelectListState,
29
+ } from "./createListState";
30
+ export {
31
+ createMenuState,
32
+ createMenuTriggerState,
33
+ type MenuStateProps,
34
+ type MenuState,
35
+ type MenuTriggerStateProps,
36
+ type MenuTriggerState,
37
+ } from "./createMenuState";
38
+ //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,3 @@
1
- // Types
2
1
  export type {
3
2
  Key,
4
3
  SelectionMode,
@@ -13,19 +12,25 @@ export type {
13
12
  CollectionBase,
14
13
  SingleSelection,
15
14
  MultipleSelection,
16
- } from './types';
15
+ } from "./types";
17
16
 
18
- // List Collection
19
- export { ListCollection, createListCollection } from './ListCollection';
17
+ export { ListCollection, createListCollection } from "./ListCollection";
18
+
19
+ export {
20
+ getChildNodes,
21
+ getFirstItem,
22
+ getNthItem,
23
+ getLastItem,
24
+ compareNodeOrder,
25
+ } from "./getChildNodes";
20
26
 
21
- // Selection State
22
27
  export {
23
28
  createSelectionState,
24
29
  type SelectionStateProps,
25
30
  type SelectionState,
26
- } from './createSelectionState';
31
+ type SelectionPressEvent,
32
+ } from "./createSelectionState";
27
33
 
28
- // List State
29
34
  export {
30
35
  createListState,
31
36
  createSingleSelectListState,
@@ -33,9 +38,8 @@ export {
33
38
  type ListState,
34
39
  type SingleSelectListStateProps,
35
40
  type SingleSelectListState,
36
- } from './createListState';
41
+ } from "./createListState";
37
42
 
38
- // Menu State
39
43
  export {
40
44
  createMenuState,
41
45
  createMenuTriggerState,
@@ -43,4 +47,4 @@ export {
43
47
  type MenuState,
44
48
  type MenuTriggerStateProps,
45
49
  type MenuTriggerState,
46
- } from './createMenuState';
50
+ } from "./createMenuState";