@octanejs/aria 0.0.5 → 0.0.7
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/package.json +7 -7
- package/src/components/Table.ts +2618 -0
- package/src/components/Tree.ts +1450 -0
- package/src/components/TreeDropTargetDelegate.ts +363 -0
- package/src/components/index.ts +57 -0
- package/src/components/utils.ts +3 -6
- package/src/grid/GridKeyboardDelegate.ts +514 -0
- package/src/grid/useGrid.ts +263 -0
- package/src/grid/useGridCell.ts +346 -0
- package/src/grid/useGridRow.ts +108 -0
- package/src/grid/useGridRowGroup.ts +29 -0
- package/src/grid/utils.ts +24 -0
- package/src/index.ts +38 -0
- package/src/intl/autocomplete/index.ts +9 -2
- package/src/intl/breadcrumbs/index.ts +9 -2
- package/src/intl/combobox/index.ts +9 -2
- package/src/intl/compileMessages.ts +356 -0
- package/src/intl/grid/index.ts +9 -2
- package/src/intl/gridlist/index.ts +9 -2
- package/src/intl/menu/index.ts +9 -2
- package/src/intl/numberfield/index.ts +9 -2
- package/src/intl/overlays/index.ts +9 -2
- package/src/intl/searchfield/index.ts +9 -2
- package/src/intl/spinbutton/index.ts +9 -2
- package/src/intl/table/ar-AE.json +13 -0
- package/src/intl/table/bg-BG.json +13 -0
- package/src/intl/table/cs-CZ.json +13 -0
- package/src/intl/table/da-DK.json +13 -0
- package/src/intl/table/de-DE.json +13 -0
- package/src/intl/table/el-GR.json +13 -0
- package/src/intl/table/en-US.json +13 -0
- package/src/intl/table/es-ES.json +13 -0
- package/src/intl/table/et-EE.json +13 -0
- package/src/intl/table/fi-FI.json +13 -0
- package/src/intl/table/fr-FR.json +13 -0
- package/src/intl/table/he-IL.json +13 -0
- package/src/intl/table/hr-HR.json +13 -0
- package/src/intl/table/hu-HU.json +13 -0
- package/src/intl/table/index.ts +82 -0
- package/src/intl/table/it-IT.json +13 -0
- package/src/intl/table/ja-JP.json +13 -0
- package/src/intl/table/ko-KR.json +13 -0
- package/src/intl/table/lt-LT.json +13 -0
- package/src/intl/table/lv-LV.json +13 -0
- package/src/intl/table/nb-NO.json +13 -0
- package/src/intl/table/nl-NL.json +13 -0
- package/src/intl/table/pl-PL.json +13 -0
- package/src/intl/table/pt-BR.json +13 -0
- package/src/intl/table/pt-PT.json +13 -0
- package/src/intl/table/ro-RO.json +13 -0
- package/src/intl/table/ru-RU.json +13 -0
- package/src/intl/table/sk-SK.json +13 -0
- package/src/intl/table/sl-SI.json +13 -0
- package/src/intl/table/sr-SP.json +13 -0
- package/src/intl/table/sv-SE.json +13 -0
- package/src/intl/table/tr-TR.json +13 -0
- package/src/intl/table/uk-UA.json +13 -0
- package/src/intl/table/zh-CN.json +13 -0
- package/src/intl/table/zh-TW.json +13 -0
- package/src/intl/tag/index.ts +9 -2
- package/src/intl/tree/ar-AE.json +4 -0
- package/src/intl/tree/bg-BG.json +4 -0
- package/src/intl/tree/cs-CZ.json +4 -0
- package/src/intl/tree/da-DK.json +4 -0
- package/src/intl/tree/de-DE.json +4 -0
- package/src/intl/tree/el-GR.json +4 -0
- package/src/intl/tree/en-US.json +4 -0
- package/src/intl/tree/es-ES.json +4 -0
- package/src/intl/tree/et-EE.json +4 -0
- package/src/intl/tree/fi-FI.json +4 -0
- package/src/intl/tree/fr-FR.json +4 -0
- package/src/intl/tree/he-IL.json +4 -0
- package/src/intl/tree/hr-HR.json +4 -0
- package/src/intl/tree/hu-HU.json +4 -0
- package/src/intl/tree/index.ts +82 -0
- package/src/intl/tree/it-IT.json +4 -0
- package/src/intl/tree/ja-JP.json +4 -0
- package/src/intl/tree/ko-KR.json +4 -0
- package/src/intl/tree/lt-LT.json +4 -0
- package/src/intl/tree/lv-LV.json +4 -0
- package/src/intl/tree/nb-NO.json +4 -0
- package/src/intl/tree/nl-NL.json +4 -0
- package/src/intl/tree/pl-PL.json +4 -0
- package/src/intl/tree/pt-BR.json +4 -0
- package/src/intl/tree/pt-PT.json +4 -0
- package/src/intl/tree/ro-RO.json +4 -0
- package/src/intl/tree/ru-RU.json +4 -0
- package/src/intl/tree/sk-SK.json +4 -0
- package/src/intl/tree/sl-SI.json +4 -0
- package/src/intl/tree/sr-SP.json +4 -0
- package/src/intl/tree/sv-SE.json +4 -0
- package/src/intl/tree/tr-TR.json +4 -0
- package/src/intl/tree/uk-UA.json +4 -0
- package/src/intl/tree/zh-CN.json +4 -0
- package/src/intl/tree/zh-TW.json +4 -0
- package/src/stately/grid/GridCollection.ts +200 -0
- package/src/stately/grid/useGridState.ts +160 -0
- package/src/stately/index.ts +43 -0
- package/src/stately/table/Cell.ts +49 -0
- package/src/stately/table/Column.ts +121 -0
- package/src/stately/table/Row.ts +145 -0
- package/src/stately/table/TableBody.ts +66 -0
- package/src/stately/table/TableCollection.ts +390 -0
- package/src/stately/table/TableColumnLayout.ts +148 -0
- package/src/stately/table/TableHeader.ts +65 -0
- package/src/stately/table/TableUtils.ts +269 -0
- package/src/stately/table/useTableColumnResizeState.ts +202 -0
- package/src/stately/table/useTableState.ts +235 -0
- package/src/stately/table/useTreeGridState.ts +248 -0
- package/src/table/TableKeyboardDelegate.ts +205 -0
- package/src/table/useTable.ts +175 -0
- package/src/table/useTableCell.ts +81 -0
- package/src/table/useTableColumnHeader.ts +155 -0
- package/src/table/useTableColumnResize.ts +374 -0
- package/src/table/useTableHeaderRow.ts +57 -0
- package/src/table/useTableRow.ts +198 -0
- package/src/table/useTableRowGroup.ts +13 -0
- package/src/table/useTableSelectionCheckbox.ts +105 -0
- package/src/table/utils.ts +42 -0
- package/src/tree/useTree.ts +76 -0
- package/src/tree/useTreeItem.ts +109 -0
- package/src/utils/mergeRefs.ts +1 -4
- package/src/utils/useFormReset.ts +1 -2
- package/src/utils/useObjectRef.ts +2 -8
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
// Ported from react-aria-components (source: .react-spectrum/packages/react-aria-components/src/TreeDropTargetDelegate.ts).
|
|
2
|
+
// The geometry/target-resolution logic is verbatim. All referenced types
|
|
3
|
+
// (Direction/DropTarget/DropTargetDelegate/ItemDropTarget/RootDropTarget) are the
|
|
4
|
+
// real @react-types/shared types, exactly as upstream. PHASE-7: this delegate is
|
|
5
|
+
// only exercised through consumer-provided `dragAndDropHooks` (the dnd engine),
|
|
6
|
+
// which cannot be constructed until `useDragAndDrop` is ported — Tree wires it up
|
|
7
|
+
// in its inert dnd branch.
|
|
8
|
+
import type {
|
|
9
|
+
Direction,
|
|
10
|
+
DropTarget,
|
|
11
|
+
DropTargetDelegate,
|
|
12
|
+
ItemDropTarget,
|
|
13
|
+
Key,
|
|
14
|
+
Node,
|
|
15
|
+
RootDropTarget,
|
|
16
|
+
} from '@react-types/shared';
|
|
17
|
+
|
|
18
|
+
interface TreeCollection<T> extends Iterable<Node<T>> {
|
|
19
|
+
getItem(key: Key): Node<T> | null;
|
|
20
|
+
getChildren?(key: Key): Iterable<Node<T>>;
|
|
21
|
+
getKeyAfter(key: Key): Key | null;
|
|
22
|
+
getKeyBefore(key: Key): Key | null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface TreeState<T> {
|
|
26
|
+
collection: TreeCollection<T>;
|
|
27
|
+
expandedKeys: Set<Key>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface PointerTracking {
|
|
31
|
+
lastY: number;
|
|
32
|
+
lastX: number;
|
|
33
|
+
yDirection: 'up' | 'down' | null;
|
|
34
|
+
xDirection: 'left' | 'right' | null;
|
|
35
|
+
boundaryContext: {
|
|
36
|
+
parentKey: Key;
|
|
37
|
+
lastSwitchY: number;
|
|
38
|
+
lastSwitchX: number;
|
|
39
|
+
preferredTargetIndex?: number;
|
|
40
|
+
} | null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const X_SWITCH_THRESHOLD = 10;
|
|
44
|
+
const Y_SWITCH_THRESHOLD = 5;
|
|
45
|
+
export class TreeDropTargetDelegate<T> {
|
|
46
|
+
private delegate: DropTargetDelegate | null = null;
|
|
47
|
+
private state: TreeState<T> | null = null;
|
|
48
|
+
private direction: Direction = 'ltr';
|
|
49
|
+
private pointerTracking: PointerTracking = {
|
|
50
|
+
lastY: 0,
|
|
51
|
+
lastX: 0,
|
|
52
|
+
yDirection: null,
|
|
53
|
+
xDirection: null,
|
|
54
|
+
boundaryContext: null,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
setup(delegate: DropTargetDelegate, state: TreeState<T>, direction: Direction): void {
|
|
58
|
+
this.delegate = delegate;
|
|
59
|
+
this.state = state;
|
|
60
|
+
this.direction = direction;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getDropTargetFromPoint(
|
|
64
|
+
x: number,
|
|
65
|
+
y: number,
|
|
66
|
+
isValidDropTarget: (target: DropTarget) => boolean,
|
|
67
|
+
): DropTarget | null {
|
|
68
|
+
let baseTarget = this.delegate!.getDropTargetFromPoint(x, y, isValidDropTarget);
|
|
69
|
+
if (!baseTarget || baseTarget.type === 'root') {
|
|
70
|
+
return baseTarget;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return this.resolveDropTarget(baseTarget, x, y, isValidDropTarget);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private resolveDropTarget(
|
|
77
|
+
target: ItemDropTarget,
|
|
78
|
+
x: number,
|
|
79
|
+
y: number,
|
|
80
|
+
isValidDropTarget: (target: DropTarget) => boolean,
|
|
81
|
+
): RootDropTarget | ItemDropTarget | null {
|
|
82
|
+
let tracking = this.pointerTracking;
|
|
83
|
+
|
|
84
|
+
// Calculate movement directions
|
|
85
|
+
let deltaY = y - tracking.lastY;
|
|
86
|
+
let deltaX = x - tracking.lastX;
|
|
87
|
+
let currentYMovement: 'up' | 'down' | null = tracking.yDirection;
|
|
88
|
+
let currentXMovement: 'left' | 'right' | null = tracking.xDirection;
|
|
89
|
+
|
|
90
|
+
if (Math.abs(deltaY) > Y_SWITCH_THRESHOLD) {
|
|
91
|
+
currentYMovement = deltaY > 0 ? 'down' : 'up';
|
|
92
|
+
tracking.yDirection = currentYMovement;
|
|
93
|
+
tracking.lastY = y;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (Math.abs(deltaX) > X_SWITCH_THRESHOLD) {
|
|
97
|
+
currentXMovement = deltaX > 0 ? 'right' : 'left';
|
|
98
|
+
tracking.xDirection = currentXMovement;
|
|
99
|
+
tracking.lastX = x;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Normalize to 'after'
|
|
103
|
+
if (target.dropPosition === 'before') {
|
|
104
|
+
let keyBefore = this.state!.collection.getKeyBefore(target.key);
|
|
105
|
+
|
|
106
|
+
while (keyBefore != null) {
|
|
107
|
+
let node = this.state!.collection.getItem(keyBefore);
|
|
108
|
+
if (node?.type === 'item') {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
keyBefore = node?.parentKey ?? null;
|
|
112
|
+
}
|
|
113
|
+
if (keyBefore != null) {
|
|
114
|
+
let convertedTarget = {
|
|
115
|
+
type: 'item',
|
|
116
|
+
key: keyBefore,
|
|
117
|
+
dropPosition: 'after',
|
|
118
|
+
} as const;
|
|
119
|
+
|
|
120
|
+
if (isValidDropTarget(convertedTarget)) {
|
|
121
|
+
target = convertedTarget;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let potentialTargets = this.getPotentialTargets(target, isValidDropTarget);
|
|
127
|
+
|
|
128
|
+
if (potentialTargets.length === 0) {
|
|
129
|
+
return { type: 'root' };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
let resolvedItemTarget: ItemDropTarget;
|
|
133
|
+
if (potentialTargets.length > 1) {
|
|
134
|
+
resolvedItemTarget = this.selectTarget(
|
|
135
|
+
potentialTargets,
|
|
136
|
+
target,
|
|
137
|
+
x,
|
|
138
|
+
y,
|
|
139
|
+
currentYMovement,
|
|
140
|
+
currentXMovement,
|
|
141
|
+
);
|
|
142
|
+
} else {
|
|
143
|
+
resolvedItemTarget = potentialTargets[0];
|
|
144
|
+
// Reset boundary context since we're not in a boundary case
|
|
145
|
+
tracking.boundaryContext = null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return resolvedItemTarget;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Returns potential targets for an ambiguous drop position (e.g. after the last child of a parent, or after the parent itself)
|
|
152
|
+
// Ordered by level, from innermost to outermost.
|
|
153
|
+
private getPotentialTargets(
|
|
154
|
+
originalTarget: ItemDropTarget,
|
|
155
|
+
isValidDropTarget: (target: DropTarget) => boolean,
|
|
156
|
+
): ItemDropTarget[] {
|
|
157
|
+
if (originalTarget.dropPosition === 'on') {
|
|
158
|
+
return [originalTarget];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
let target = originalTarget;
|
|
162
|
+
let collection = this.state!.collection;
|
|
163
|
+
|
|
164
|
+
let currentItem = collection.getItem(target.key);
|
|
165
|
+
while (currentItem && currentItem?.type !== 'item' && currentItem.nextKey != null) {
|
|
166
|
+
target.key = currentItem.nextKey;
|
|
167
|
+
currentItem = collection.getItem(currentItem.nextKey);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
let potentialTargets = [target];
|
|
171
|
+
|
|
172
|
+
// If target has children and is expanded, use "before first child"
|
|
173
|
+
if (
|
|
174
|
+
currentItem &&
|
|
175
|
+
currentItem.hasChildNodes &&
|
|
176
|
+
this.state!.expandedKeys.has(currentItem.key) &&
|
|
177
|
+
collection.getChildren &&
|
|
178
|
+
target.dropPosition === 'after'
|
|
179
|
+
) {
|
|
180
|
+
// Find the first item child (traverse keys directly instead of using collection.getChildren, which may only include cells).
|
|
181
|
+
let firstChildItemNode =
|
|
182
|
+
currentItem.firstChildKey != null ? collection.getItem(currentItem.firstChildKey) : null;
|
|
183
|
+
while (firstChildItemNode && firstChildItemNode.type !== 'item') {
|
|
184
|
+
firstChildItemNode =
|
|
185
|
+
firstChildItemNode.nextKey != null
|
|
186
|
+
? collection.getItem(firstChildItemNode.nextKey)
|
|
187
|
+
: null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (firstChildItemNode?.type === 'item') {
|
|
191
|
+
const beforeFirstChildTarget = {
|
|
192
|
+
type: 'item',
|
|
193
|
+
key: firstChildItemNode.key,
|
|
194
|
+
dropPosition: 'before',
|
|
195
|
+
} as const;
|
|
196
|
+
|
|
197
|
+
if (isValidDropTarget(beforeFirstChildTarget)) {
|
|
198
|
+
return [beforeFirstChildTarget];
|
|
199
|
+
} else {
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (currentItem?.nextKey != null) {
|
|
206
|
+
return [originalTarget];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Walk up the parent chain to find ancestors that are the last child at their level
|
|
210
|
+
let parentKey = currentItem?.parentKey;
|
|
211
|
+
let ancestorTargets: ItemDropTarget[] = [];
|
|
212
|
+
|
|
213
|
+
while (parentKey != null) {
|
|
214
|
+
let parentItem = collection.getItem(parentKey);
|
|
215
|
+
let nextItem = parentItem?.nextKey != null ? collection.getItem(parentItem.nextKey) : null;
|
|
216
|
+
let isLastChildAtLevel = !nextItem || nextItem.parentKey !== parentKey;
|
|
217
|
+
|
|
218
|
+
if (isLastChildAtLevel) {
|
|
219
|
+
let afterParentTarget = {
|
|
220
|
+
type: 'item',
|
|
221
|
+
key: parentKey,
|
|
222
|
+
dropPosition: 'after',
|
|
223
|
+
} as const;
|
|
224
|
+
|
|
225
|
+
if (isValidDropTarget(afterParentTarget)) {
|
|
226
|
+
ancestorTargets.push(afterParentTarget);
|
|
227
|
+
}
|
|
228
|
+
if (nextItem) {
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
parentKey = parentItem?.parentKey;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (ancestorTargets.length > 0) {
|
|
237
|
+
potentialTargets.push(...ancestorTargets);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Handle converting "after" to "before next" for non-ambiguous cases
|
|
241
|
+
if (potentialTargets.length === 1) {
|
|
242
|
+
let nextKey = collection.getKeyAfter(target.key);
|
|
243
|
+
let nextNode = nextKey != null ? collection.getItem(nextKey) : null;
|
|
244
|
+
if (
|
|
245
|
+
nextKey != null &&
|
|
246
|
+
nextNode &&
|
|
247
|
+
currentItem &&
|
|
248
|
+
nextNode.level != null &&
|
|
249
|
+
currentItem.level != null &&
|
|
250
|
+
nextNode.level > currentItem.level
|
|
251
|
+
) {
|
|
252
|
+
let beforeTarget = {
|
|
253
|
+
type: 'item',
|
|
254
|
+
key: nextKey,
|
|
255
|
+
dropPosition: 'before',
|
|
256
|
+
} as const;
|
|
257
|
+
if (isValidDropTarget(beforeTarget)) {
|
|
258
|
+
return [beforeTarget];
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return potentialTargets.filter(isValidDropTarget);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private selectTarget(
|
|
267
|
+
potentialTargets: ItemDropTarget[],
|
|
268
|
+
originalTarget: ItemDropTarget,
|
|
269
|
+
x: number,
|
|
270
|
+
y: number,
|
|
271
|
+
currentYMovement: 'up' | 'down' | null,
|
|
272
|
+
currentXMovement: 'left' | 'right' | null,
|
|
273
|
+
): ItemDropTarget {
|
|
274
|
+
if (potentialTargets.length < 2) {
|
|
275
|
+
return potentialTargets[0];
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
let tracking = this.pointerTracking;
|
|
279
|
+
let currentItem = this.state!.collection.getItem(originalTarget.key);
|
|
280
|
+
let parentKey = currentItem?.parentKey;
|
|
281
|
+
|
|
282
|
+
if (parentKey == null) {
|
|
283
|
+
return potentialTargets[0];
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// More than 1 potential target - use Y for initial target, then X for switching levels
|
|
287
|
+
// Initialize boundary context if needed
|
|
288
|
+
if (!tracking.boundaryContext || tracking.boundaryContext.parentKey !== parentKey) {
|
|
289
|
+
// If entering from below, start with outer-most
|
|
290
|
+
let initialTargetIndex = tracking.yDirection === 'up' ? potentialTargets.length - 1 : 0;
|
|
291
|
+
tracking.boundaryContext = {
|
|
292
|
+
parentKey,
|
|
293
|
+
preferredTargetIndex: initialTargetIndex,
|
|
294
|
+
lastSwitchY: y,
|
|
295
|
+
lastSwitchX: x,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
let boundaryContext = tracking.boundaryContext;
|
|
300
|
+
let distanceFromLastXSwitch = Math.abs(x - boundaryContext.lastSwitchX);
|
|
301
|
+
let distanceFromLastYSwitch = Math.abs(y - boundaryContext.lastSwitchY);
|
|
302
|
+
|
|
303
|
+
// Switch between targets based on Y movement
|
|
304
|
+
if (distanceFromLastYSwitch > Y_SWITCH_THRESHOLD && currentYMovement) {
|
|
305
|
+
let currentIndex = boundaryContext.preferredTargetIndex || 0;
|
|
306
|
+
|
|
307
|
+
if (currentYMovement === 'down' && currentIndex === 0) {
|
|
308
|
+
// Moving down from inner-most, switch to outer-most
|
|
309
|
+
boundaryContext.preferredTargetIndex = potentialTargets.length - 1;
|
|
310
|
+
} else if (currentYMovement === 'up' && currentIndex === potentialTargets.length - 1) {
|
|
311
|
+
// Moving up from outer-most, switch to inner-most
|
|
312
|
+
boundaryContext.preferredTargetIndex = 0;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Reset x tracking so that moving diagonally doesn't cause flickering.
|
|
316
|
+
tracking.xDirection = null;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// X movement controls level selection
|
|
320
|
+
if (distanceFromLastXSwitch > X_SWITCH_THRESHOLD && currentXMovement) {
|
|
321
|
+
let currentTargetIndex = boundaryContext.preferredTargetIndex || 0;
|
|
322
|
+
|
|
323
|
+
if (currentXMovement === 'left') {
|
|
324
|
+
if (this.direction === 'ltr') {
|
|
325
|
+
// LTR: left = move to higher level in tree (increase index)
|
|
326
|
+
if (currentTargetIndex < potentialTargets.length - 1) {
|
|
327
|
+
boundaryContext.preferredTargetIndex = currentTargetIndex + 1;
|
|
328
|
+
boundaryContext.lastSwitchX = x;
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
// RTL: left = move to lower level in tree (decrease index)
|
|
332
|
+
if (currentTargetIndex > 0) {
|
|
333
|
+
boundaryContext.preferredTargetIndex = currentTargetIndex - 1;
|
|
334
|
+
boundaryContext.lastSwitchX = x;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
} else if (currentXMovement === 'right') {
|
|
338
|
+
if (this.direction === 'ltr') {
|
|
339
|
+
// LTR: right = move to lower level in tree (decrease index)
|
|
340
|
+
if (currentTargetIndex > 0) {
|
|
341
|
+
boundaryContext.preferredTargetIndex = currentTargetIndex - 1;
|
|
342
|
+
boundaryContext.lastSwitchX = x;
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
// RTL: right = move to higher level in tree (increase index)
|
|
346
|
+
if (currentTargetIndex < potentialTargets.length - 1) {
|
|
347
|
+
boundaryContext.preferredTargetIndex = currentTargetIndex + 1;
|
|
348
|
+
boundaryContext.lastSwitchX = x;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Reset y tracking so that moving diagonally doesn't cause flickering.
|
|
354
|
+
tracking.yDirection = null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
let targetIndex = Math.max(
|
|
358
|
+
0,
|
|
359
|
+
Math.min(boundaryContext.preferredTargetIndex || 0, potentialTargets.length - 1),
|
|
360
|
+
);
|
|
361
|
+
return potentialTargets[targetIndex];
|
|
362
|
+
}
|
|
363
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -300,3 +300,60 @@ export type { VisuallyHiddenProps } from '../visually-hidden/VisuallyHidden';
|
|
|
300
300
|
export type { Placement } from '../overlays/useOverlayPosition';
|
|
301
301
|
export { useFilter } from '../i18n/useFilter';
|
|
302
302
|
export type { Filter } from '../i18n/useFilter';
|
|
303
|
+
|
|
304
|
+
// tree + table (Tree/Table phase)
|
|
305
|
+
export {
|
|
306
|
+
TreeLoadMoreItem,
|
|
307
|
+
Tree,
|
|
308
|
+
TreeItem,
|
|
309
|
+
TreeContext,
|
|
310
|
+
TreeItemContent,
|
|
311
|
+
TreeHeader,
|
|
312
|
+
TreeSection,
|
|
313
|
+
TreeStateContext,
|
|
314
|
+
} from './Tree';
|
|
315
|
+
export type {
|
|
316
|
+
TreeProps,
|
|
317
|
+
TreeRenderProps,
|
|
318
|
+
TreeEmptyStateRenderProps,
|
|
319
|
+
TreeItemProps,
|
|
320
|
+
TreeItemRenderProps,
|
|
321
|
+
TreeItemContentProps,
|
|
322
|
+
TreeItemContentRenderProps,
|
|
323
|
+
TreeLoadMoreItemProps,
|
|
324
|
+
TreeLoadMoreItemRenderProps,
|
|
325
|
+
} from './Tree';
|
|
326
|
+
export {
|
|
327
|
+
TableLoadMoreItem,
|
|
328
|
+
Table,
|
|
329
|
+
Row,
|
|
330
|
+
Cell,
|
|
331
|
+
Column,
|
|
332
|
+
ColumnResizer,
|
|
333
|
+
TableHeader,
|
|
334
|
+
TableBody,
|
|
335
|
+
TableContext,
|
|
336
|
+
ResizableTableContainer,
|
|
337
|
+
useTableOptions,
|
|
338
|
+
TableStateContext,
|
|
339
|
+
TableColumnResizeStateContext,
|
|
340
|
+
TableFooter,
|
|
341
|
+
} from './Table';
|
|
342
|
+
export type {
|
|
343
|
+
TableProps,
|
|
344
|
+
TableRenderProps,
|
|
345
|
+
TableHeaderProps,
|
|
346
|
+
TableBodyProps,
|
|
347
|
+
TableBodyRenderProps,
|
|
348
|
+
ResizableTableContainerProps,
|
|
349
|
+
ColumnProps,
|
|
350
|
+
ColumnRenderProps,
|
|
351
|
+
ColumnResizerProps,
|
|
352
|
+
ColumnResizerRenderProps,
|
|
353
|
+
RowProps,
|
|
354
|
+
RowRenderProps,
|
|
355
|
+
CellProps,
|
|
356
|
+
CellRenderProps,
|
|
357
|
+
TableLoadMoreItemProps,
|
|
358
|
+
TableFooterProps,
|
|
359
|
+
} from './Table';
|
package/src/components/utils.ts
CHANGED
|
@@ -160,11 +160,9 @@ export interface DOMProps extends StyleProps, SharedDOMProps {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
export type ClassNameOrFunction<T> =
|
|
163
|
-
| string
|
|
164
|
-
| ((values: T & { defaultClassName: string | undefined }) => string);
|
|
163
|
+
string | ((values: T & { defaultClassName: string | undefined }) => string);
|
|
165
164
|
type StyleOrFunction<T> =
|
|
166
|
-
| CSSProperties
|
|
167
|
-
| ((values: T & { defaultStyle: CSSProperties }) => CSSProperties | undefined);
|
|
165
|
+
CSSProperties | ((values: T & { defaultStyle: CSSProperties }) => CSSProperties | undefined);
|
|
168
166
|
|
|
169
167
|
export interface StyleRenderProps<T, E extends string = 'div'> extends DOMRenderProps<E, T> {
|
|
170
168
|
/**
|
|
@@ -180,8 +178,7 @@ export interface StyleRenderProps<T, E extends string = 'div'> extends DOMRender
|
|
|
180
178
|
}
|
|
181
179
|
|
|
182
180
|
export type ChildrenOrFunction<T> =
|
|
183
|
-
| ReactNode
|
|
184
|
-
| ((values: T & { defaultChildren: ReactNode | undefined }) => ReactNode);
|
|
181
|
+
ReactNode | ((values: T & { defaultChildren: ReactNode | undefined }) => ReactNode);
|
|
185
182
|
|
|
186
183
|
export interface RenderProps<T, E extends string = 'div'> extends StyleRenderProps<T, E> {
|
|
187
184
|
/**
|