@proyecto-viviana/solidaria 0.2.4 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/actiongroup/createActionGroup.d.ts +29 -0
- package/dist/actiongroup/createActionGroup.d.ts.map +1 -0
- package/dist/actiongroup/index.d.ts +2 -0
- package/dist/actiongroup/index.d.ts.map +1 -0
- package/dist/autocomplete/createAutocomplete.d.ts +6 -2
- package/dist/autocomplete/createAutocomplete.d.ts.map +1 -1
- package/dist/breadcrumbs/createBreadcrumbs.d.ts +2 -0
- package/dist/breadcrumbs/createBreadcrumbs.d.ts.map +1 -1
- package/dist/button/createToggleButtonGroup.d.ts +32 -0
- package/dist/button/createToggleButtonGroup.d.ts.map +1 -0
- package/dist/button/index.d.ts +2 -0
- package/dist/button/index.d.ts.map +1 -1
- package/dist/calendar/createCalendarCell.d.ts +2 -0
- package/dist/calendar/createCalendarCell.d.ts.map +1 -1
- package/dist/calendar/createCalendarGrid.d.ts.map +1 -1
- package/dist/calendar/createRangeCalendarCell.d.ts +3 -1
- package/dist/calendar/createRangeCalendarCell.d.ts.map +1 -1
- package/dist/checkbox/createCheckboxGroup.d.ts +5 -1
- package/dist/checkbox/createCheckboxGroup.d.ts.map +1 -1
- package/dist/collections/index.d.ts +56 -0
- package/dist/collections/index.d.ts.map +1 -0
- package/dist/color/createColorArea.d.ts.map +1 -1
- package/dist/color/createColorSlider.d.ts.map +1 -1
- package/dist/color/createColorWheel.d.ts.map +1 -1
- package/dist/combobox/createComboBox.d.ts +6 -0
- package/dist/combobox/createComboBox.d.ts.map +1 -1
- package/dist/datepicker/createDatePicker.d.ts +6 -0
- package/dist/datepicker/createDatePicker.d.ts.map +1 -1
- package/dist/datepicker/createDateRangePicker.d.ts +40 -0
- package/dist/datepicker/createDateRangePicker.d.ts.map +1 -0
- package/dist/datepicker/createDateSegment.d.ts +1 -1
- package/dist/datepicker/createDateSegment.d.ts.map +1 -1
- package/dist/datepicker/createTimeSegment.d.ts +29 -0
- package/dist/datepicker/createTimeSegment.d.ts.map +1 -0
- package/dist/datepicker/index.d.ts +2 -0
- package/dist/datepicker/index.d.ts.map +1 -1
- package/dist/disclosure/createDisclosureGroup.d.ts +2 -1
- package/dist/disclosure/createDisclosureGroup.d.ts.map +1 -1
- package/dist/dnd/createDrag.d.ts.map +1 -1
- package/dist/dnd/createDraggableCollection.d.ts +4 -0
- package/dist/dnd/createDraggableCollection.d.ts.map +1 -1
- package/dist/dnd/createDraggableItem.d.ts.map +1 -1
- package/dist/dnd/createDrop.d.ts.map +1 -1
- package/dist/dnd/createDroppableCollection.d.ts +32 -1
- package/dist/dnd/createDroppableCollection.d.ts.map +1 -1
- package/dist/dnd/createDroppableItem.d.ts.map +1 -1
- package/dist/dnd/index.d.ts +1 -1
- package/dist/dnd/index.d.ts.map +1 -1
- package/dist/grid/createGrid.d.ts.map +1 -1
- package/dist/gridlist/createGridList.d.ts.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4659 -3452
- package/dist/index.js.map +1 -7
- package/dist/index.ssr.js +4659 -3452
- package/dist/index.ssr.js.map +1 -7
- package/dist/interactions/createFocus.d.ts.map +1 -1
- package/dist/interactions/createFocusWithin.d.ts.map +1 -1
- package/dist/link/createLink.d.ts +10 -0
- package/dist/link/createLink.d.ts.map +1 -1
- package/dist/listbox/createListBox.d.ts +1 -0
- package/dist/listbox/createListBox.d.ts.map +1 -1
- package/dist/listbox/createOption.d.ts.map +1 -1
- package/dist/menu/createMenu.d.ts +1 -0
- package/dist/menu/createMenu.d.ts.map +1 -1
- package/dist/meter/createMeter.d.ts.map +1 -1
- package/dist/numberfield/createNumberField.d.ts +18 -0
- package/dist/numberfield/createNumberField.d.ts.map +1 -1
- package/dist/overlays/createModal.d.ts +16 -0
- package/dist/overlays/createModal.d.ts.map +1 -1
- package/dist/overlays/createOverlay.d.ts.map +1 -1
- package/dist/overlays/index.d.ts +1 -1
- package/dist/overlays/index.d.ts.map +1 -1
- package/dist/popover/createOverlayPosition.d.ts.map +1 -1
- package/dist/popover/createPopover.d.ts.map +1 -1
- package/dist/progress/createProgressBar.d.ts.map +1 -1
- package/dist/radio/createRadioGroup.d.ts +2 -2
- package/dist/radio/createRadioGroup.d.ts.map +1 -1
- package/dist/searchfield/createSearchField.d.ts.map +1 -1
- package/dist/select/createHiddenSelect.d.ts.map +1 -1
- package/dist/select/createSelect.d.ts.map +1 -1
- package/dist/slider/createSlider.d.ts.map +1 -1
- package/dist/table/createTable.d.ts.map +1 -1
- package/dist/tabs/createTabs.d.ts +1 -1
- package/dist/tabs/createTabs.d.ts.map +1 -1
- package/dist/tag/createTag.d.ts.map +1 -1
- package/dist/tag/createTagGroup.d.ts.map +1 -1
- package/dist/toast/createToast.d.ts +4 -0
- package/dist/toast/createToast.d.ts.map +1 -1
- package/dist/toast/createToastRegion.d.ts.map +1 -1
- package/dist/toolbar/createToolbar.d.ts.map +1 -1
- package/dist/tooltip/createTooltipTrigger.d.ts.map +1 -1
- package/dist/tree/createTree.d.ts.map +1 -1
- package/dist/tree/createTreeItem.d.ts.map +1 -1
- package/dist/tree/types.d.ts +4 -0
- package/dist/tree/types.d.ts.map +1 -1
- package/dist/utils/env.d.ts +1 -1
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/platform.d.ts.map +1 -1
- package/dist/visually-hidden/createVisuallyHidden.d.ts.map +1 -1
- package/package.json +8 -6
- package/src/actiongroup/createActionGroup.ts +324 -0
- package/src/actiongroup/index.ts +8 -0
- package/src/autocomplete/createAutocomplete.ts +32 -9
- package/src/breadcrumbs/createBreadcrumbs.ts +10 -15
- package/src/button/createButton.ts +1 -1
- package/src/button/createToggleButtonGroup.ts +128 -0
- package/src/button/index.ts +9 -0
- package/src/calendar/createCalendarCell.ts +6 -4
- package/src/calendar/createCalendarGrid.ts +27 -18
- package/src/calendar/createRangeCalendarCell.ts +26 -9
- package/src/checkbox/createCheckboxGroup.ts +21 -4
- package/src/collections/index.ts +242 -0
- package/src/color/createColorArea.ts +380 -314
- package/src/color/createColorField.ts +137 -137
- package/src/color/createColorSlider.ts +286 -197
- package/src/color/createColorSwatch.ts +40 -40
- package/src/color/createColorWheel.ts +218 -208
- package/src/color/index.ts +24 -24
- package/src/color/types.ts +116 -116
- package/src/combobox/createComboBox.ts +670 -647
- package/src/combobox/index.ts +6 -6
- package/src/datepicker/createDatePicker.ts +54 -16
- package/src/datepicker/createDateRangePicker.ts +246 -0
- package/src/datepicker/createDateSegment.ts +185 -31
- package/src/datepicker/createTimeSegment.ts +370 -0
- package/src/datepicker/index.ts +14 -0
- package/src/dialog/createDialog.ts +120 -120
- package/src/dialog/index.ts +2 -2
- package/src/dialog/types.ts +19 -19
- package/src/disclosure/createDisclosureGroup.ts +5 -2
- package/src/dnd/createDrag.ts +224 -209
- package/src/dnd/createDraggableCollection.ts +96 -63
- package/src/dnd/createDraggableItem.ts +259 -243
- package/src/dnd/createDrop.ts +322 -321
- package/src/dnd/createDroppableCollection.ts +682 -293
- package/src/dnd/createDroppableItem.ts +215 -213
- package/src/dnd/index.ts +55 -47
- package/src/dnd/types.ts +89 -89
- package/src/dnd/utils.ts +294 -294
- package/src/focus/createAutoFocus.ts +321 -321
- package/src/focus/createFocusRestore.ts +313 -313
- package/src/focus/createVirtualFocus.ts +396 -396
- package/src/form/createFormValidation.ts +224 -224
- package/src/form/index.ts +11 -11
- package/src/grid/createGrid.ts +3 -1
- package/src/gridlist/createGridList.ts +16 -0
- package/src/gridlist/createGridListItem.ts +1 -1
- package/src/i18n/NumberFormatter.ts +266 -266
- package/src/i18n/createCollator.ts +79 -79
- package/src/i18n/createDateFormatter.ts +83 -83
- package/src/i18n/createFilter.ts +131 -131
- package/src/i18n/createNumberFormatter.ts +52 -52
- package/src/i18n/index.ts +40 -40
- package/src/i18n/locale.tsx +188 -188
- package/src/i18n/utils.ts +99 -99
- package/src/index.ts +51 -0
- package/src/interactions/createFocus.ts +6 -5
- package/src/interactions/createFocusWithin.ts +6 -5
- package/src/interactions/createLongPress.ts +174 -174
- package/src/interactions/createMove.ts +289 -289
- package/src/interactions/createPress.ts +5 -5
- package/src/landmark/createLandmark.ts +377 -377
- package/src/landmark/index.ts +8 -8
- package/src/link/createLink.ts +23 -8
- package/src/listbox/createListBox.ts +308 -269
- package/src/listbox/createOption.ts +162 -151
- package/src/listbox/index.ts +12 -12
- package/src/live-announcer/announce.ts +322 -322
- package/src/live-announcer/index.ts +9 -9
- package/src/menu/createMenu.ts +405 -396
- package/src/menu/createMenuItem.ts +149 -149
- package/src/menu/createMenuTrigger.ts +88 -88
- package/src/menu/index.ts +18 -18
- package/src/meter/createMeter.ts +1 -6
- package/src/numberfield/createNumberField.ts +311 -268
- package/src/numberfield/index.ts +5 -5
- package/src/overlays/ariaHideOutside.ts +219 -219
- package/src/overlays/createInteractOutside.ts +149 -149
- package/src/overlays/createModal.tsx +238 -202
- package/src/overlays/createOverlay.ts +165 -155
- package/src/overlays/createOverlayTrigger.ts +85 -85
- package/src/overlays/createPreventScroll.ts +266 -266
- package/src/overlays/index.ts +48 -44
- package/src/popover/calculatePosition.ts +6 -6
- package/src/popover/createOverlayPosition.ts +7 -4
- package/src/popover/createPopover.ts +21 -7
- package/src/progress/createProgressBar.ts +6 -1
- package/src/radio/createRadioGroup.ts +88 -14
- package/src/searchfield/createSearchField.ts +241 -186
- package/src/searchfield/index.ts +2 -2
- package/src/select/createHiddenSelect.tsx +263 -236
- package/src/select/createSelect.ts +373 -395
- package/src/select/index.ts +14 -14
- package/src/slider/createSlider.ts +364 -349
- package/src/slider/index.ts +2 -2
- package/src/ssr/index.tsx +370 -370
- package/src/table/createTable.ts +3 -1
- package/src/table/createTableColumnHeader.ts +1 -1
- package/src/table/createTableRow.ts +1 -1
- package/src/tabs/createTabs.ts +80 -51
- package/src/tag/createTag.ts +135 -6
- package/src/tag/createTagGroup.ts +7 -2
- package/src/toast/createToast.ts +8 -2
- package/src/toast/createToastRegion.ts +0 -1
- package/src/toolbar/createToolbar.ts +75 -1
- package/src/tooltip/createTooltip.ts +79 -79
- package/src/tooltip/createTooltipTrigger.ts +226 -222
- package/src/tooltip/index.ts +6 -6
- package/src/tree/createTree.ts +261 -246
- package/src/tree/createTreeItem.ts +282 -233
- package/src/tree/createTreeSelectionCheckbox.ts +68 -68
- package/src/tree/index.ts +16 -16
- package/src/tree/types.ts +91 -87
- package/src/utils/env.ts +55 -54
- package/src/utils/platform.ts +16 -6
- package/src/visually-hidden/createVisuallyHidden.ts +139 -124
- package/src/visually-hidden/index.ts +6 -6
package/src/tree/createTree.ts
CHANGED
|
@@ -1,246 +1,261 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* createTree - Provides accessibility for a tree component.
|
|
3
|
-
* Based on @react-aria/tree/useTree.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { createMemo, type Accessor } from 'solid-js';
|
|
7
|
-
import type { JSX } from 'solid-js';
|
|
8
|
-
import { createId } from '@proyecto-viviana/solid-stately';
|
|
9
|
-
import type { TreeState, TreeCollection, Key } from '@proyecto-viviana/solid-stately';
|
|
10
|
-
import type { AriaTreeProps, TreeAria } from './types';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Metadata stored for a tree instance.
|
|
14
|
-
*/
|
|
15
|
-
interface TreeData {
|
|
16
|
-
/** The generated ID for the tree. */
|
|
17
|
-
treeId: string;
|
|
18
|
-
/** Actions registered for the tree. */
|
|
19
|
-
actions: {
|
|
20
|
-
onAction?: (key: Key) => void;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* WeakMap to store tree data for child components to access.
|
|
26
|
-
*/
|
|
27
|
-
const treeDataMap = new WeakMap<object, TreeData>();
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Gets the tree data for a given state.
|
|
31
|
-
*/
|
|
32
|
-
export function getTreeData<T extends object, C extends TreeCollection<T>>(
|
|
33
|
-
state: TreeState<T, C>
|
|
34
|
-
): TreeData | undefined {
|
|
35
|
-
return treeDataMap.get(state);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Creates accessibility props for a tree.
|
|
40
|
-
*/
|
|
41
|
-
export function createTree<T extends object, C extends TreeCollection<T> = TreeCollection<T>>(
|
|
42
|
-
props: Accessor<AriaTreeProps>,
|
|
43
|
-
state: Accessor<TreeState<T, C>>,
|
|
44
|
-
_ref: Accessor<HTMLDivElement | null>
|
|
45
|
-
): TreeAria {
|
|
46
|
-
// Generate a unique ID for the tree
|
|
47
|
-
const treeId = props().id ?? createId();
|
|
48
|
-
|
|
49
|
-
// Store tree data for child components
|
|
50
|
-
const treeData: TreeData = {
|
|
51
|
-
treeId,
|
|
52
|
-
actions: {
|
|
53
|
-
get onAction() {
|
|
54
|
-
return props().onAction;
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// Store in WeakMap using the state as key
|
|
60
|
-
treeDataMap.set(state(), treeData);
|
|
61
|
-
|
|
62
|
-
// Handle keyboard navigation
|
|
63
|
-
const onKeyDown = (e: KeyboardEvent) => {
|
|
64
|
-
const s = state();
|
|
65
|
-
const p = props();
|
|
66
|
-
const collection = s.collection;
|
|
67
|
-
const focusedKey = s.focusedKey;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
case '
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
case '
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* createTree - Provides accessibility for a tree component.
|
|
3
|
+
* Based on @react-aria/tree/useTree.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createMemo, type Accessor } from 'solid-js';
|
|
7
|
+
import type { JSX } from 'solid-js';
|
|
8
|
+
import { createId } from '@proyecto-viviana/solid-stately';
|
|
9
|
+
import type { TreeState, TreeCollection, Key } from '@proyecto-viviana/solid-stately';
|
|
10
|
+
import type { AriaTreeProps, TreeAria } from './types';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Metadata stored for a tree instance.
|
|
14
|
+
*/
|
|
15
|
+
interface TreeData {
|
|
16
|
+
/** The generated ID for the tree. */
|
|
17
|
+
treeId: string;
|
|
18
|
+
/** Actions registered for the tree. */
|
|
19
|
+
actions: {
|
|
20
|
+
onAction?: (key: Key) => void;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* WeakMap to store tree data for child components to access.
|
|
26
|
+
*/
|
|
27
|
+
const treeDataMap = new WeakMap<object, TreeData>();
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Gets the tree data for a given state.
|
|
31
|
+
*/
|
|
32
|
+
export function getTreeData<T extends object, C extends TreeCollection<T>>(
|
|
33
|
+
state: TreeState<T, C>
|
|
34
|
+
): TreeData | undefined {
|
|
35
|
+
return treeDataMap.get(state);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Creates accessibility props for a tree.
|
|
40
|
+
*/
|
|
41
|
+
export function createTree<T extends object, C extends TreeCollection<T> = TreeCollection<T>>(
|
|
42
|
+
props: Accessor<AriaTreeProps>,
|
|
43
|
+
state: Accessor<TreeState<T, C>>,
|
|
44
|
+
_ref: Accessor<HTMLDivElement | null>
|
|
45
|
+
): TreeAria {
|
|
46
|
+
// Generate a unique ID for the tree
|
|
47
|
+
const treeId = props().id ?? createId();
|
|
48
|
+
|
|
49
|
+
// Store tree data for child components
|
|
50
|
+
const treeData: TreeData = {
|
|
51
|
+
treeId,
|
|
52
|
+
actions: {
|
|
53
|
+
get onAction() {
|
|
54
|
+
return props().onAction;
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Store in WeakMap using the state as key
|
|
60
|
+
treeDataMap.set(state(), treeData);
|
|
61
|
+
|
|
62
|
+
// Handle keyboard navigation
|
|
63
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
64
|
+
const s = state();
|
|
65
|
+
const p = props();
|
|
66
|
+
const collection = s.collection;
|
|
67
|
+
const focusedKey = s.focusedKey;
|
|
68
|
+
const direction = p.direction ?? 'ltr';
|
|
69
|
+
// In RTL, ArrowLeft expands and ArrowRight collapses (opposite of LTR)
|
|
70
|
+
const expandKey = direction === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
|
|
71
|
+
const collapseKey = direction === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
|
|
72
|
+
|
|
73
|
+
if (p.isDisabled) return;
|
|
74
|
+
|
|
75
|
+
switch (e.key) {
|
|
76
|
+
case 'ArrowDown': {
|
|
77
|
+
e.preventDefault();
|
|
78
|
+
if (focusedKey != null) {
|
|
79
|
+
const nextKey = collection.getKeyAfter(focusedKey);
|
|
80
|
+
if (nextKey != null) {
|
|
81
|
+
s.setFocusedKey(nextKey);
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
const firstKey = collection.getFirstKey();
|
|
85
|
+
if (firstKey != null) {
|
|
86
|
+
s.setFocusedKey(firstKey);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case 'ArrowUp': {
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
if (focusedKey != null) {
|
|
94
|
+
const prevKey = collection.getKeyBefore(focusedKey);
|
|
95
|
+
if (prevKey != null) {
|
|
96
|
+
s.setFocusedKey(prevKey);
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
const lastKey = collection.getLastKey();
|
|
100
|
+
if (lastKey != null) {
|
|
101
|
+
s.setFocusedKey(lastKey);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case 'ArrowRight':
|
|
107
|
+
case 'ArrowLeft': {
|
|
108
|
+
e.preventDefault();
|
|
109
|
+
if (focusedKey != null) {
|
|
110
|
+
const node = collection.getItem(focusedKey);
|
|
111
|
+
if (e.key === expandKey) {
|
|
112
|
+
// Expand or move to first child
|
|
113
|
+
if (node?.isExpandable) {
|
|
114
|
+
if (!s.isExpanded(focusedKey)) {
|
|
115
|
+
s.expandKey(focusedKey);
|
|
116
|
+
} else {
|
|
117
|
+
const children = [...collection.getChildren(focusedKey)];
|
|
118
|
+
if (children.length > 0) {
|
|
119
|
+
s.setFocusedKey(children[0].key);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} else if (e.key === collapseKey) {
|
|
124
|
+
// Collapse or move to parent
|
|
125
|
+
if (node?.isExpandable && s.isExpanded(focusedKey)) {
|
|
126
|
+
s.collapseKey(focusedKey);
|
|
127
|
+
} else if (node?.parentKey != null) {
|
|
128
|
+
s.setFocusedKey(node.parentKey);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case 'Home': {
|
|
135
|
+
e.preventDefault();
|
|
136
|
+
const firstKey = collection.getFirstKey();
|
|
137
|
+
if (firstKey != null) {
|
|
138
|
+
s.setFocusedKey(firstKey);
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
case 'End': {
|
|
143
|
+
e.preventDefault();
|
|
144
|
+
const lastKey = collection.getLastKey();
|
|
145
|
+
if (lastKey != null) {
|
|
146
|
+
s.setFocusedKey(lastKey);
|
|
147
|
+
}
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
case 'a':
|
|
151
|
+
case 'A': {
|
|
152
|
+
if ((e.ctrlKey || e.metaKey) && s.selectionMode === 'multiple') {
|
|
153
|
+
e.preventDefault();
|
|
154
|
+
s.selectAll();
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case ' ':
|
|
159
|
+
case 'Space':
|
|
160
|
+
case 'Spacebar': {
|
|
161
|
+
if (focusedKey != null && s.selectionMode !== 'none' && !s.isDisabled(focusedKey)) {
|
|
162
|
+
e.preventDefault();
|
|
163
|
+
s.toggleSelection(focusedKey);
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case 'Enter': {
|
|
168
|
+
if (focusedKey != null && !s.isDisabled(focusedKey)) {
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
p.onAction?.(focusedKey);
|
|
171
|
+
}
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
case 'Escape': {
|
|
175
|
+
if (s.selectionMode !== 'none') {
|
|
176
|
+
e.preventDefault();
|
|
177
|
+
s.clearSelection();
|
|
178
|
+
}
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
case '*': {
|
|
182
|
+
// Expand all siblings at current level
|
|
183
|
+
e.preventDefault();
|
|
184
|
+
if (focusedKey != null) {
|
|
185
|
+
const node = collection.getItem(focusedKey);
|
|
186
|
+
if (node) {
|
|
187
|
+
// Find all siblings at the same level
|
|
188
|
+
const parentKey = node.parentKey;
|
|
189
|
+
let siblings: Key[];
|
|
190
|
+
if (parentKey != null) {
|
|
191
|
+
siblings = [...collection.getChildren(parentKey)].map((n) => n.key);
|
|
192
|
+
} else {
|
|
193
|
+
// Root level siblings
|
|
194
|
+
siblings = collection.rows
|
|
195
|
+
.filter((n) => n.level === 0)
|
|
196
|
+
.map((n) => n.key);
|
|
197
|
+
}
|
|
198
|
+
// Expand all expandable siblings
|
|
199
|
+
for (const siblingKey of siblings) {
|
|
200
|
+
const sibling = collection.getItem(siblingKey);
|
|
201
|
+
if (sibling?.isExpandable && !s.isExpanded(siblingKey)) {
|
|
202
|
+
s.expandKey(siblingKey);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const onFocus = () => {
|
|
213
|
+
const s = state();
|
|
214
|
+
s.setFocused(true);
|
|
215
|
+
|
|
216
|
+
// If nothing is focused, focus the first item
|
|
217
|
+
if (s.focusedKey == null) {
|
|
218
|
+
const firstKey = s.collection.getFirstKey();
|
|
219
|
+
if (firstKey != null) {
|
|
220
|
+
s.setFocusedKey(firstKey);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const onBlur = () => {
|
|
226
|
+
const s = state();
|
|
227
|
+
s.setFocused(false);
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const treeProps = createMemo(() => {
|
|
231
|
+
const p = props();
|
|
232
|
+
const s = state();
|
|
233
|
+
|
|
234
|
+
const baseProps: Record<string, unknown> = {
|
|
235
|
+
role: 'treegrid',
|
|
236
|
+
id: treeId,
|
|
237
|
+
'aria-label': p['aria-label'],
|
|
238
|
+
'aria-labelledby': p['aria-labelledby'],
|
|
239
|
+
'aria-describedby': p['aria-describedby'],
|
|
240
|
+
'aria-multiselectable': s.selectionMode === 'multiple' ? true : undefined,
|
|
241
|
+
'aria-disabled': p.isDisabled || undefined,
|
|
242
|
+
tabIndex: p.isDisabled ? undefined : 0,
|
|
243
|
+
onKeyDown,
|
|
244
|
+
onFocus,
|
|
245
|
+
onBlur,
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// Add row count for virtualized trees
|
|
249
|
+
if (p.isVirtualized) {
|
|
250
|
+
baseProps['aria-rowcount'] = s.collection.rowCount;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return baseProps as JSX.HTMLAttributes<HTMLDivElement>;
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
get treeProps() {
|
|
258
|
+
return treeProps();
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
}
|