react-aria-components 1.11.0 → 1.12.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.
- package/dist/Autocomplete.main.js +7 -20
- package/dist/Autocomplete.main.js.map +1 -1
- package/dist/Autocomplete.mjs +8 -20
- package/dist/Autocomplete.module.js +8 -20
- package/dist/Autocomplete.module.js.map +1 -1
- package/dist/Breadcrumbs.main.js +4 -1
- package/dist/Breadcrumbs.main.js.map +1 -1
- package/dist/Breadcrumbs.mjs +5 -2
- package/dist/Breadcrumbs.module.js +5 -2
- package/dist/Breadcrumbs.module.js.map +1 -1
- package/dist/GridList.main.js +96 -15
- package/dist/GridList.main.js.map +1 -1
- package/dist/GridList.mjs +98 -19
- package/dist/GridList.module.js +98 -19
- package/dist/GridList.module.js.map +1 -1
- package/dist/Header.main.js +1 -1
- package/dist/Header.main.js.map +1 -1
- package/dist/Header.mjs +2 -2
- package/dist/Header.module.js +2 -2
- package/dist/Header.module.js.map +1 -1
- package/dist/ListBox.main.js +6 -18
- package/dist/ListBox.main.js.map +1 -1
- package/dist/ListBox.mjs +8 -20
- package/dist/ListBox.module.js +8 -20
- package/dist/ListBox.module.js.map +1 -1
- package/dist/Menu.main.js +29 -15
- package/dist/Menu.main.js.map +1 -1
- package/dist/Menu.mjs +31 -17
- package/dist/Menu.module.js +31 -17
- package/dist/Menu.module.js.map +1 -1
- package/dist/Popover.main.js +7 -11
- package/dist/Popover.main.js.map +1 -1
- package/dist/Popover.mjs +8 -12
- package/dist/Popover.module.js +8 -12
- package/dist/Popover.module.js.map +1 -1
- package/dist/SearchField.main.js +6 -4
- package/dist/SearchField.main.js.map +1 -1
- package/dist/SearchField.mjs +7 -5
- package/dist/SearchField.module.js +7 -5
- package/dist/SearchField.module.js.map +1 -1
- package/dist/Separator.main.js +13 -1
- package/dist/Separator.main.js.map +1 -1
- package/dist/Separator.mjs +15 -3
- package/dist/Separator.module.js +15 -3
- package/dist/Separator.module.js.map +1 -1
- package/dist/Table.main.js +58 -17
- package/dist/Table.main.js.map +1 -1
- package/dist/Table.mjs +60 -19
- package/dist/Table.module.js +60 -19
- package/dist/Table.module.js.map +1 -1
- package/dist/Tabs.main.js +4 -1
- package/dist/Tabs.main.js.map +1 -1
- package/dist/Tabs.mjs +5 -2
- package/dist/Tabs.module.js +5 -2
- package/dist/Tabs.module.js.map +1 -1
- package/dist/TagGroup.main.js +13 -4
- package/dist/TagGroup.main.js.map +1 -1
- package/dist/TagGroup.mjs +15 -6
- package/dist/TagGroup.module.js +15 -6
- package/dist/TagGroup.module.js.map +1 -1
- package/dist/TextField.main.js +7 -5
- package/dist/TextField.main.js.map +1 -1
- package/dist/TextField.mjs +8 -6
- package/dist/TextField.module.js +8 -6
- package/dist/TextField.module.js.map +1 -1
- package/dist/Tooltip.main.js +4 -11
- package/dist/Tooltip.main.js.map +1 -1
- package/dist/Tooltip.mjs +6 -13
- package/dist/Tooltip.module.js +6 -13
- package/dist/Tooltip.module.js.map +1 -1
- package/dist/Tree.main.js +9 -3
- package/dist/Tree.main.js.map +1 -1
- package/dist/Tree.mjs +10 -4
- package/dist/Tree.module.js +10 -4
- package/dist/Tree.module.js.map +1 -1
- package/dist/context.main.js +25 -0
- package/dist/context.main.js.map +1 -0
- package/dist/context.mjs +19 -0
- package/dist/context.module.js +19 -0
- package/dist/context.module.js.map +1 -0
- package/dist/import.mjs +3 -3
- package/dist/main.js +3 -0
- package/dist/main.js.map +1 -1
- package/dist/module.js +3 -3
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +178 -171
- package/dist/types.d.ts.map +1 -1
- package/dist/useDragAndDrop.main.js.map +1 -1
- package/dist/useDragAndDrop.module.js.map +1 -1
- package/package.json +23 -22
- package/src/Autocomplete.tsx +14 -25
- package/src/Breadcrumbs.tsx +6 -2
- package/src/GridList.tsx +89 -21
- package/src/Header.tsx +2 -2
- package/src/ListBox.tsx +12 -15
- package/src/Menu.tsx +37 -17
- package/src/Popover.tsx +11 -11
- package/src/SearchField.tsx +5 -4
- package/src/Separator.tsx +17 -2
- package/src/Table.tsx +65 -22
- package/src/Tabs.tsx +6 -2
- package/src/TagGroup.tsx +15 -6
- package/src/TextField.tsx +8 -7
- package/src/Tooltip.tsx +10 -14
- package/src/Tree.tsx +13 -5
- package/src/context.tsx +34 -0
- package/src/index.ts +2 -2
- package/src/useDragAndDrop.tsx +9 -9
package/src/Table.tsx
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import {AriaLabelingProps, GlobalDOMAttributes, HoverEvents, Key, LinkDOMProps, PressEvents, RefObject} from '@react-types/shared';
|
|
2
|
-
import {BaseCollection, Collection, CollectionBuilder, CollectionNode, createBranchComponent, createLeafComponent, useCachedChildren} from '@react-aria/collections';
|
|
2
|
+
import {BaseCollection, Collection, CollectionBuilder, CollectionNode, createBranchComponent, createLeafComponent, FilterableNode, LoaderNode, useCachedChildren} from '@react-aria/collections';
|
|
3
3
|
import {buildHeaderRows, TableColumnResizeState} from '@react-stately/table';
|
|
4
4
|
import {ButtonContext} from './Button';
|
|
5
5
|
import {CheckboxContext} from './RSPContexts';
|
|
6
6
|
import {CollectionProps, CollectionRendererContext, DefaultCollectionRenderer, ItemRenderProps} from './Collection';
|
|
7
7
|
import {ColumnSize, ColumnStaticSize, TableCollection as ITableCollection, TableProps as SharedTableProps} from '@react-types/table';
|
|
8
8
|
import {ContextValue, DEFAULT_SLOT, DOMProps, Provider, RenderProps, SlotProps, StyleProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
|
|
9
|
-
import {DisabledBehavior, DraggableCollectionState, DroppableCollectionState, MultipleSelectionState, Node, SelectionBehavior, SelectionMode, SortDirection, TableState, useMultipleSelectionState, useTableColumnResizeState, useTableState} from 'react-stately';
|
|
9
|
+
import {DisabledBehavior, DraggableCollectionState, DroppableCollectionState, MultipleSelectionState, Node, SelectionBehavior, SelectionMode, SortDirection, TableState, UNSTABLE_useFilteredTableState, useMultipleSelectionState, useTableColumnResizeState, useTableState} from 'react-stately';
|
|
10
10
|
import {DragAndDropContext, DropIndicatorContext, DropIndicatorProps, useDndPersistedKeys, useRenderDropIndicator} from './DragAndDrop';
|
|
11
11
|
import {DragAndDropHooks} from './useDragAndDrop';
|
|
12
12
|
import {DraggableItemResult, DragPreviewRenderer, DropIndicatorAria, DroppableCollectionResult, FocusScope, ListKeyboardDelegate, mergeProps, useFocusRing, useHover, useLocale, useLocalizedStringFormatter, useTable, useTableCell, useTableColumnHeader, useTableColumnResize, useTableHeaderRow, useTableRow, useTableRowGroup, useTableSelectAllCheckbox, useTableSelectionCheckbox, useVisuallyHidden} from 'react-aria';
|
|
13
|
+
import {FieldInputContext, SelectableCollectionContext} from './context';
|
|
13
14
|
import {filterDOMProps, inertValue, isScrollable, LoadMoreSentinelProps, mergeRefs, useLayoutEffect, useLoadMoreSentinel, useObjectRef, useResizeObserver} from '@react-aria/utils';
|
|
14
15
|
import {GridNode} from '@react-types/grid';
|
|
15
16
|
// @ts-ignore
|
|
@@ -22,8 +23,8 @@ class TableCollection<T> extends BaseCollection<T> implements ITableCollection<T
|
|
|
22
23
|
columns: GridNode<T>[] = [];
|
|
23
24
|
rows: GridNode<T>[] = [];
|
|
24
25
|
rowHeaderColumnKeys: Set<Key> = new Set();
|
|
25
|
-
head
|
|
26
|
-
body
|
|
26
|
+
head = new TableHeaderNode<T>(-1);
|
|
27
|
+
body = new TableBodyNode<T>(-2);
|
|
27
28
|
columnsDirty = true;
|
|
28
29
|
|
|
29
30
|
addNode(node: CollectionNode<T>) {
|
|
@@ -65,7 +66,6 @@ class TableCollection<T> extends BaseCollection<T> implements ITableCollection<T
|
|
|
65
66
|
|
|
66
67
|
this.rowHeaderColumnKeys = new Set();
|
|
67
68
|
this.columns = [];
|
|
68
|
-
|
|
69
69
|
let columnKeyMap = new Map();
|
|
70
70
|
let visit = (node: Node<T>) => {
|
|
71
71
|
switch (node.type) {
|
|
@@ -363,23 +363,30 @@ interface TableInnerProps {
|
|
|
363
363
|
|
|
364
364
|
|
|
365
365
|
function TableInner({props, forwardedRef: ref, selectionState, collection}: TableInnerProps) {
|
|
366
|
+
let contextProps;
|
|
367
|
+
[contextProps] = useContextProps({}, null, SelectableCollectionContext);
|
|
368
|
+
let {filter, ...collectionProps} = contextProps;
|
|
369
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
370
|
+
let {shouldUseVirtualFocus, disallowTypeAhead, ...DOMCollectionProps} = collectionProps || {};
|
|
366
371
|
let tableContainerContext = useContext(ResizableTableContainerContext);
|
|
367
372
|
ref = useObjectRef(useMemo(() => mergeRefs(ref, tableContainerContext?.tableRef), [ref, tableContainerContext?.tableRef]));
|
|
368
|
-
let
|
|
373
|
+
let tableState = useTableState({
|
|
369
374
|
...props,
|
|
370
375
|
collection,
|
|
371
376
|
children: undefined,
|
|
372
377
|
UNSAFE_selectionState: selectionState
|
|
373
378
|
});
|
|
374
379
|
|
|
380
|
+
let filteredState = UNSTABLE_useFilteredTableState(tableState, filter);
|
|
375
381
|
let {isVirtualized, layoutDelegate, dropTargetDelegate: ctxDropTargetDelegate, CollectionRoot} = useContext(CollectionRendererContext);
|
|
376
382
|
let {dragAndDropHooks} = props;
|
|
377
383
|
let {gridProps} = useTable({
|
|
378
384
|
...props,
|
|
385
|
+
...DOMCollectionProps,
|
|
379
386
|
layoutDelegate,
|
|
380
387
|
isVirtualized
|
|
381
|
-
},
|
|
382
|
-
let selectionManager =
|
|
388
|
+
}, filteredState, ref);
|
|
389
|
+
let selectionManager = filteredState.selectionManager;
|
|
383
390
|
let hasDragHooks = !!dragAndDropHooks?.useDraggableCollectionState;
|
|
384
391
|
let hasDropHooks = !!dragAndDropHooks?.useDroppableCollectionState;
|
|
385
392
|
let dragHooksProvided = useRef(hasDragHooks);
|
|
@@ -405,7 +412,7 @@ function TableInner({props, forwardedRef: ref, selectionState, collection}: Tabl
|
|
|
405
412
|
|
|
406
413
|
if (hasDragHooks && dragAndDropHooks) {
|
|
407
414
|
dragState = dragAndDropHooks.useDraggableCollectionState!({
|
|
408
|
-
collection,
|
|
415
|
+
collection: filteredState.collection,
|
|
409
416
|
selectionManager,
|
|
410
417
|
preview: dragAndDropHooks.renderDragPreview ? preview : undefined
|
|
411
418
|
});
|
|
@@ -419,12 +426,12 @@ function TableInner({props, forwardedRef: ref, selectionState, collection}: Tabl
|
|
|
419
426
|
|
|
420
427
|
if (hasDropHooks && dragAndDropHooks) {
|
|
421
428
|
dropState = dragAndDropHooks.useDroppableCollectionState!({
|
|
422
|
-
collection,
|
|
429
|
+
collection: filteredState.collection,
|
|
423
430
|
selectionManager
|
|
424
431
|
});
|
|
425
432
|
|
|
426
433
|
let keyboardDelegate = new ListKeyboardDelegate({
|
|
427
|
-
collection,
|
|
434
|
+
collection: filteredState.collection,
|
|
428
435
|
disabledKeys: selectionManager.disabledKeys,
|
|
429
436
|
disabledBehavior: selectionManager.disabledBehavior,
|
|
430
437
|
ref,
|
|
@@ -448,7 +455,7 @@ function TableInner({props, forwardedRef: ref, selectionState, collection}: Tabl
|
|
|
448
455
|
isDropTarget: isRootDropTarget,
|
|
449
456
|
isFocused,
|
|
450
457
|
isFocusVisible,
|
|
451
|
-
state
|
|
458
|
+
state: filteredState
|
|
452
459
|
}
|
|
453
460
|
});
|
|
454
461
|
|
|
@@ -459,7 +466,7 @@ function TableInner({props, forwardedRef: ref, selectionState, collection}: Tabl
|
|
|
459
466
|
if (tableContainerContext) {
|
|
460
467
|
layoutState = tableContainerContext.useTableColumnResizeState({
|
|
461
468
|
tableWidth: tableContainerContext.tableWidth
|
|
462
|
-
},
|
|
469
|
+
}, filteredState);
|
|
463
470
|
if (!isVirtualized) {
|
|
464
471
|
style = {
|
|
465
472
|
...style,
|
|
@@ -475,10 +482,12 @@ function TableInner({props, forwardedRef: ref, selectionState, collection}: Tabl
|
|
|
475
482
|
return (
|
|
476
483
|
<Provider
|
|
477
484
|
values={[
|
|
478
|
-
[TableStateContext,
|
|
485
|
+
[TableStateContext, filteredState],
|
|
479
486
|
[TableColumnResizeStateContext, layoutState],
|
|
480
487
|
[DragAndDropContext, {dragAndDropHooks, dragState, dropState}],
|
|
481
|
-
[DropIndicatorContext, {render: TableDropIndicatorWrapper}]
|
|
488
|
+
[DropIndicatorContext, {render: TableDropIndicatorWrapper}],
|
|
489
|
+
[SelectableCollectionContext, null],
|
|
490
|
+
[FieldInputContext, null]
|
|
482
491
|
]}>
|
|
483
492
|
<FocusScope>
|
|
484
493
|
<ElementType
|
|
@@ -492,7 +501,7 @@ function TableInner({props, forwardedRef: ref, selectionState, collection}: Tabl
|
|
|
492
501
|
data-focused={isFocused || undefined}
|
|
493
502
|
data-focus-visible={isFocusVisible || undefined}>
|
|
494
503
|
<CollectionRoot
|
|
495
|
-
collection={collection}
|
|
504
|
+
collection={filteredState.collection}
|
|
496
505
|
scrollRef={tableContainerContext?.scrollRef ?? ref}
|
|
497
506
|
persistedKeys={useDndPersistedKeys(selectionManager, dragAndDropHooks, dropState)} />
|
|
498
507
|
</ElementType>
|
|
@@ -544,11 +553,15 @@ export interface TableHeaderProps<T> extends StyleRenderProps<TableHeaderRenderP
|
|
|
544
553
|
dependencies?: ReadonlyArray<any>
|
|
545
554
|
}
|
|
546
555
|
|
|
556
|
+
class TableHeaderNode<T> extends CollectionNode<T> {
|
|
557
|
+
static readonly type = 'tableheader';
|
|
558
|
+
}
|
|
559
|
+
|
|
547
560
|
/**
|
|
548
561
|
* A header within a `<Table>`, containing the table columns.
|
|
549
562
|
*/
|
|
550
563
|
export const TableHeader = /*#__PURE__*/ createBranchComponent(
|
|
551
|
-
|
|
564
|
+
TableHeaderNode,
|
|
552
565
|
<T extends object>(props: TableHeaderProps<T>, ref: ForwardedRef<HTMLTableSectionElement | HTMLDivElement>) => {
|
|
553
566
|
let collection = useContext(TableStateContext)!.collection as TableCollection<unknown>;
|
|
554
567
|
let headerRows = useCachedChildren({
|
|
@@ -681,10 +694,14 @@ export interface ColumnProps extends RenderProps<ColumnRenderProps>, GlobalDOMAt
|
|
|
681
694
|
maxWidth?: ColumnStaticSize | null
|
|
682
695
|
}
|
|
683
696
|
|
|
697
|
+
class TableColumnNode extends CollectionNode<unknown> {
|
|
698
|
+
static readonly type = 'column';
|
|
699
|
+
}
|
|
700
|
+
|
|
684
701
|
/**
|
|
685
702
|
* A column within a `<Table>`.
|
|
686
703
|
*/
|
|
687
|
-
export const Column = /*#__PURE__*/ createLeafComponent(
|
|
704
|
+
export const Column = /*#__PURE__*/ createLeafComponent(TableColumnNode, (props: ColumnProps, forwardedRef: ForwardedRef<HTMLTableCellElement | HTMLDivElement>, column: GridNode<unknown>) => {
|
|
688
705
|
let ref = useObjectRef<HTMLTableCellElement | HTMLDivElement>(forwardedRef);
|
|
689
706
|
let state = useContext(TableStateContext)!;
|
|
690
707
|
let {isVirtualized} = useContext(CollectionRendererContext);
|
|
@@ -916,10 +933,15 @@ export interface TableBodyProps<T> extends Omit<CollectionProps<T>, 'disabledKey
|
|
|
916
933
|
/** Provides content to display when there are no rows in the table. */
|
|
917
934
|
renderEmptyState?: (props: TableBodyRenderProps) => ReactNode
|
|
918
935
|
}
|
|
936
|
+
|
|
937
|
+
class TableBodyNode<T> extends FilterableNode<T> {
|
|
938
|
+
static readonly type = 'tablebody';
|
|
939
|
+
}
|
|
940
|
+
|
|
919
941
|
/**
|
|
920
942
|
* The body of a `<Table>`, containing the table rows.
|
|
921
943
|
*/
|
|
922
|
-
export const TableBody = /*#__PURE__*/ createBranchComponent(
|
|
944
|
+
export const TableBody = /*#__PURE__*/ createBranchComponent(TableBodyNode, <T extends object>(props: TableBodyProps<T>, ref: ForwardedRef<HTMLTableSectionElement | HTMLDivElement>) => {
|
|
923
945
|
let state = useContext(TableStateContext)!;
|
|
924
946
|
let {isVirtualized} = useContext(CollectionRendererContext);
|
|
925
947
|
let collection = state.collection;
|
|
@@ -1017,11 +1039,28 @@ export interface RowProps<T> extends StyleRenderProps<RowRenderProps>, LinkDOMPr
|
|
|
1017
1039
|
id?: Key
|
|
1018
1040
|
}
|
|
1019
1041
|
|
|
1042
|
+
class TableRowNode<T> extends CollectionNode<T> {
|
|
1043
|
+
static readonly type = 'item';
|
|
1044
|
+
|
|
1045
|
+
filter(collection: BaseCollection<T>, newCollection: BaseCollection<T>, filterFn: (textValue: string, node: Node<T>) => boolean): TableRowNode<T> | null {
|
|
1046
|
+
let cells = collection.getChildren(this.key);
|
|
1047
|
+
for (let cell of cells) {
|
|
1048
|
+
if (filterFn(cell.textValue, cell)) {
|
|
1049
|
+
let clone = this.clone();
|
|
1050
|
+
newCollection.addDescendants(clone, collection);
|
|
1051
|
+
return clone;
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
return null;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1020
1059
|
/**
|
|
1021
1060
|
* A row within a `<Table>`.
|
|
1022
1061
|
*/
|
|
1023
1062
|
export const Row = /*#__PURE__*/ createBranchComponent(
|
|
1024
|
-
|
|
1063
|
+
TableRowNode,
|
|
1025
1064
|
<T extends object>(props: RowProps<T>, forwardedRef: ForwardedRef<HTMLTableRowElement | HTMLDivElement>, item: GridNode<T>) => {
|
|
1026
1065
|
let ref = useObjectRef<HTMLTableRowElement | HTMLDivElement>(forwardedRef);
|
|
1027
1066
|
let state = useContext(TableStateContext)!;
|
|
@@ -1201,10 +1240,14 @@ export interface CellProps extends RenderProps<CellRenderProps>, GlobalDOMAttrib
|
|
|
1201
1240
|
colSpan?: number
|
|
1202
1241
|
}
|
|
1203
1242
|
|
|
1243
|
+
class TableCellNode extends CollectionNode<unknown> {
|
|
1244
|
+
static readonly type = 'cell';
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1204
1247
|
/**
|
|
1205
1248
|
* A cell within a table row.
|
|
1206
1249
|
*/
|
|
1207
|
-
export const Cell = /*#__PURE__*/ createLeafComponent(
|
|
1250
|
+
export const Cell = /*#__PURE__*/ createLeafComponent(TableCellNode, (props: CellProps, forwardedRef: ForwardedRef<HTMLTableCellElement | HTMLDivElement>, cell: GridNode<unknown>) => {
|
|
1208
1251
|
let ref = useObjectRef<HTMLTableCellElement | HTMLDivElement>(forwardedRef);
|
|
1209
1252
|
let state = useContext(TableStateContext)!;
|
|
1210
1253
|
let {dragState} = useContext(DragAndDropContext);
|
|
@@ -1359,7 +1402,7 @@ export interface TableLoadMoreItemProps extends Omit<LoadMoreSentinelProps, 'col
|
|
|
1359
1402
|
isLoading?: boolean
|
|
1360
1403
|
}
|
|
1361
1404
|
|
|
1362
|
-
export const TableLoadMoreItem = createLeafComponent(
|
|
1405
|
+
export const TableLoadMoreItem = createLeafComponent(LoaderNode, function TableLoadingIndicator(props: TableLoadMoreItemProps, ref: ForwardedRef<HTMLTableRowElement>, item: Node<object>) {
|
|
1363
1406
|
let state = useContext(TableStateContext)!;
|
|
1364
1407
|
let {isVirtualized} = useContext(CollectionRendererContext);
|
|
1365
1408
|
let {isLoading, onLoadMore, scrollOffset, ...otherProps} = props;
|
package/src/Tabs.tsx
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import {AriaLabelingProps, forwardRefType, GlobalDOMAttributes, HoverEvents, Key, LinkDOMProps, PressEvents, RefObject} from '@react-types/shared';
|
|
14
14
|
import {AriaTabListProps, AriaTabPanelProps, mergeProps, Orientation, useFocusRing, useHover, useTab, useTabList, useTabPanel} from 'react-aria';
|
|
15
|
-
import {Collection, CollectionBuilder, createHideableComponent, createLeafComponent} from '@react-aria/collections';
|
|
15
|
+
import {Collection, CollectionBuilder, CollectionNode, createHideableComponent, createLeafComponent} from '@react-aria/collections';
|
|
16
16
|
import {CollectionProps, CollectionRendererContext, DefaultCollectionRenderer, usePersistedKeys} from './Collection';
|
|
17
17
|
import {ContextValue, Provider, RenderProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps, useSlottedContext} from './utils';
|
|
18
18
|
import {filterDOMProps, inertValue, useObjectRef} from '@react-aria/utils';
|
|
@@ -235,10 +235,14 @@ function TabListInner<T extends object>({props, forwardedRef: ref}: TabListInner
|
|
|
235
235
|
);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
class TabItemNode extends CollectionNode<unknown> {
|
|
239
|
+
static readonly type = 'item';
|
|
240
|
+
}
|
|
241
|
+
|
|
238
242
|
/**
|
|
239
243
|
* A Tab provides a title for an individual item within a TabList.
|
|
240
244
|
*/
|
|
241
|
-
export const Tab = /*#__PURE__*/ createLeafComponent(
|
|
245
|
+
export const Tab = /*#__PURE__*/ createLeafComponent(TabItemNode, (props: TabProps, forwardedRef: ForwardedRef<HTMLDivElement>, item: Node<unknown>) => {
|
|
242
246
|
let state = useContext(TabListStateContext)!;
|
|
243
247
|
let ref = useObjectRef<any>(forwardedRef);
|
|
244
248
|
let {tabProps, isSelected, isDisabled, isPressed} = useTab({key: item.key, ...props}, state, ref);
|
package/src/TagGroup.tsx
CHANGED
|
@@ -12,15 +12,16 @@
|
|
|
12
12
|
|
|
13
13
|
import {AriaTagGroupProps, useFocusRing, useHover, useTag, useTagGroup} from 'react-aria';
|
|
14
14
|
import {ButtonContext} from './Button';
|
|
15
|
-
import {Collection, CollectionBuilder, createLeafComponent} from '@react-aria/collections';
|
|
15
|
+
import {Collection, CollectionBuilder, createLeafComponent, ItemNode} from '@react-aria/collections';
|
|
16
16
|
import {CollectionProps, CollectionRendererContext, DefaultCollectionRenderer, ItemRenderProps, usePersistedKeys} from './Collection';
|
|
17
17
|
import {ContextValue, DOMProps, Provider, RenderProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps, useSlot} from './utils';
|
|
18
18
|
import {filterDOMProps, mergeProps, useObjectRef} from '@react-aria/utils';
|
|
19
19
|
import {forwardRefType, GlobalDOMAttributes, HoverEvents, Key, LinkDOMProps, PressEvents} from '@react-types/shared';
|
|
20
20
|
import {LabelContext} from './Label';
|
|
21
|
-
import {ListState, Node, useListState} from 'react-stately';
|
|
21
|
+
import {ListState, Node, UNSTABLE_useFilteredListState, useListState} from 'react-stately';
|
|
22
22
|
import {ListStateContext} from './ListBox';
|
|
23
23
|
import React, {createContext, ForwardedRef, forwardRef, JSX, ReactNode, useContext, useEffect, useRef} from 'react';
|
|
24
|
+
import {SelectableCollectionContext} from './context';
|
|
24
25
|
import {TextContext} from './Text';
|
|
25
26
|
|
|
26
27
|
export interface TagGroupProps extends Omit<AriaTagGroupProps<unknown>, 'children' | 'items' | 'label' | 'description' | 'errorMessage' | 'keyboardDelegate'>, DOMProps, SlotProps, GlobalDOMAttributes<HTMLDivElement> {}
|
|
@@ -74,16 +75,23 @@ interface TagGroupInnerProps {
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
function TagGroupInner({props, forwardedRef: ref, collection}: TagGroupInnerProps) {
|
|
78
|
+
let contextProps;
|
|
79
|
+
[contextProps] = useContextProps({}, null, SelectableCollectionContext);
|
|
80
|
+
let {filter, ...collectionProps} = contextProps;
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
82
|
+
let {shouldUseVirtualFocus, disallowTypeAhead, ...DOMCollectionProps} = collectionProps || {};
|
|
77
83
|
let tagListRef = useRef<HTMLDivElement>(null);
|
|
78
84
|
let [labelRef, label] = useSlot(
|
|
79
85
|
!props['aria-label'] && !props['aria-labelledby']
|
|
80
86
|
);
|
|
81
|
-
let
|
|
87
|
+
let tagGroupState = useListState({
|
|
82
88
|
...props,
|
|
83
89
|
children: undefined,
|
|
84
90
|
collection
|
|
85
91
|
});
|
|
86
92
|
|
|
93
|
+
let filteredState = UNSTABLE_useFilteredListState(tagGroupState, filter);
|
|
94
|
+
|
|
87
95
|
// Prevent DOM props from going to two places.
|
|
88
96
|
let domProps = filterDOMProps(props, {global: true});
|
|
89
97
|
let domPropOverrides = Object.fromEntries(Object.entries(domProps).map(([k]) => [k, undefined]));
|
|
@@ -95,8 +103,9 @@ function TagGroupInner({props, forwardedRef: ref, collection}: TagGroupInnerProp
|
|
|
95
103
|
} = useTagGroup({
|
|
96
104
|
...props,
|
|
97
105
|
...domPropOverrides,
|
|
106
|
+
...DOMCollectionProps,
|
|
98
107
|
label
|
|
99
|
-
},
|
|
108
|
+
}, filteredState, tagListRef);
|
|
100
109
|
|
|
101
110
|
return (
|
|
102
111
|
<div
|
|
@@ -109,7 +118,7 @@ function TagGroupInner({props, forwardedRef: ref, collection}: TagGroupInnerProp
|
|
|
109
118
|
values={[
|
|
110
119
|
[LabelContext, {...labelProps, elementType: 'span', ref: labelRef}],
|
|
111
120
|
[TagListContext, {...gridProps, ref: tagListRef}],
|
|
112
|
-
[ListStateContext,
|
|
121
|
+
[ListStateContext, filteredState],
|
|
113
122
|
[TextContext, {
|
|
114
123
|
slots: {
|
|
115
124
|
description: descriptionProps,
|
|
@@ -197,7 +206,7 @@ export interface TagProps extends RenderProps<TagRenderProps>, LinkDOMProps, Hov
|
|
|
197
206
|
/**
|
|
198
207
|
* A Tag is an individual item within a TagList.
|
|
199
208
|
*/
|
|
200
|
-
export const Tag = /*#__PURE__*/ createLeafComponent(
|
|
209
|
+
export const Tag = /*#__PURE__*/ createLeafComponent(ItemNode, (props: TagProps, forwardedRef: ForwardedRef<HTMLDivElement>, item: Node<unknown>) => {
|
|
201
210
|
let state = useContext(ListStateContext)!;
|
|
202
211
|
let ref = useObjectRef<HTMLDivElement>(forwardedRef);
|
|
203
212
|
let {focusProps, isFocusVisible} = useFocusRing({within: false});
|
package/src/TextField.tsx
CHANGED
|
@@ -14,7 +14,8 @@ import {AriaTextFieldProps, useTextField} from 'react-aria';
|
|
|
14
14
|
import {ContextValue, DOMProps, Provider, RACValidation, removeDataAttributes, RenderProps, SlotProps, useContextProps, useRenderProps, useSlot, useSlottedContext} from './utils';
|
|
15
15
|
import {createHideableComponent} from '@react-aria/collections';
|
|
16
16
|
import {FieldErrorContext} from './FieldError';
|
|
17
|
-
import {
|
|
17
|
+
import {FieldInputContext} from './context';
|
|
18
|
+
import {filterDOMProps} from '@react-aria/utils';
|
|
18
19
|
import {FormContext} from './Form';
|
|
19
20
|
import {GlobalDOMAttributes} from '@react-types/shared';
|
|
20
21
|
import {GroupContext} from './Group';
|
|
@@ -61,8 +62,8 @@ export const TextField = /*#__PURE__*/ createHideableComponent(function TextFiel
|
|
|
61
62
|
[props, ref] = useContextProps(props, ref, TextFieldContext);
|
|
62
63
|
let {validationBehavior: formValidationBehavior} = useSlottedContext(FormContext) || {};
|
|
63
64
|
let validationBehavior = props.validationBehavior ?? formValidationBehavior ?? 'native';
|
|
64
|
-
let inputRef = useRef(null);
|
|
65
|
-
|
|
65
|
+
let inputRef = useRef<HTMLInputElement>(null);
|
|
66
|
+
[props, inputRef as unknown] = useContextProps(props, inputRef, FieldInputContext);
|
|
66
67
|
let [labelRef, label] = useSlot(
|
|
67
68
|
!props['aria-label'] && !props['aria-labelledby']
|
|
68
69
|
);
|
|
@@ -72,16 +73,16 @@ export const TextField = /*#__PURE__*/ createHideableComponent(function TextFiel
|
|
|
72
73
|
inputElementType,
|
|
73
74
|
label,
|
|
74
75
|
validationBehavior
|
|
75
|
-
},
|
|
76
|
+
}, inputRef);
|
|
76
77
|
|
|
77
78
|
// Intercept setting the input ref so we can determine what kind of element we have.
|
|
78
79
|
// useTextField uses this to determine what props to include.
|
|
79
80
|
let inputOrTextAreaRef = useCallback((el) => {
|
|
80
|
-
|
|
81
|
+
inputRef.current = el;
|
|
81
82
|
if (el) {
|
|
82
83
|
setInputElementType(el instanceof HTMLTextAreaElement ? 'textarea' : 'input');
|
|
83
84
|
}
|
|
84
|
-
}, [
|
|
85
|
+
}, [inputRef]);
|
|
85
86
|
|
|
86
87
|
let renderProps = useRenderProps({
|
|
87
88
|
...props,
|
|
@@ -110,7 +111,7 @@ export const TextField = /*#__PURE__*/ createHideableComponent(function TextFiel
|
|
|
110
111
|
<Provider
|
|
111
112
|
values={[
|
|
112
113
|
[LabelContext, {...labelProps, ref: labelRef}],
|
|
113
|
-
[InputContext, {...
|
|
114
|
+
[InputContext, {...inputProps, ref: inputOrTextAreaRef}],
|
|
114
115
|
[TextAreaContext, {...inputProps, ref: inputOrTextAreaRef}],
|
|
115
116
|
[GroupContext, {role: 'presentation', isInvalid: validation.isInvalid, isDisabled: props.isDisabled || false}],
|
|
116
117
|
[TextContext, {
|
package/src/Tooltip.tsx
CHANGED
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
import {AriaLabelingProps, FocusableElement, forwardRefType, GlobalDOMAttributes, RefObject} from '@react-types/shared';
|
|
14
14
|
import {AriaPositionProps, mergeProps, OverlayContainer, Placement, PlacementAxis, PositionProps, useOverlayPosition, useTooltip, useTooltipTrigger} from 'react-aria';
|
|
15
15
|
import {ContextValue, Provider, RenderProps, useContextProps, useRenderProps} from './utils';
|
|
16
|
-
import {filterDOMProps, useEnterAnimation, useExitAnimation
|
|
16
|
+
import {filterDOMProps, useEnterAnimation, useExitAnimation} from '@react-aria/utils';
|
|
17
17
|
import {FocusableProvider} from '@react-aria/focus';
|
|
18
18
|
import {OverlayArrowContext} from './OverlayArrow';
|
|
19
19
|
import {OverlayTriggerProps, TooltipTriggerProps, TooltipTriggerState, useTooltipTriggerState} from 'react-stately';
|
|
20
|
-
import React, {createContext, ForwardedRef, forwardRef, JSX, ReactNode, useContext, useRef
|
|
20
|
+
import React, {createContext, CSSProperties, ForwardedRef, forwardRef, JSX, ReactNode, useContext, useRef} from 'react';
|
|
21
21
|
|
|
22
22
|
export interface TooltipTriggerComponentProps extends TooltipTriggerProps {
|
|
23
23
|
children: ReactNode
|
|
@@ -121,27 +121,19 @@ export const Tooltip = /*#__PURE__*/ (forwardRef as forwardRefType)(function Too
|
|
|
121
121
|
|
|
122
122
|
function TooltipInner(props: TooltipProps & {isExiting: boolean, tooltipRef: RefObject<HTMLDivElement | null>}) {
|
|
123
123
|
let state = useContext(TooltipTriggerStateContext)!;
|
|
124
|
-
|
|
125
|
-
// Calculate the arrow size internally
|
|
126
|
-
// Referenced from: packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx
|
|
127
124
|
let arrowRef = useRef<HTMLDivElement>(null);
|
|
128
|
-
let [arrowWidth, setArrowWidth] = useState(0);
|
|
129
|
-
useLayoutEffect(() => {
|
|
130
|
-
if (arrowRef.current && state.isOpen) {
|
|
131
|
-
setArrowWidth(arrowRef.current.getBoundingClientRect().width);
|
|
132
|
-
}
|
|
133
|
-
}, [state.isOpen, arrowRef]);
|
|
134
125
|
|
|
135
|
-
let {overlayProps, arrowProps, placement} = useOverlayPosition({
|
|
126
|
+
let {overlayProps, arrowProps, placement, triggerAnchorPoint} = useOverlayPosition({
|
|
136
127
|
placement: props.placement || 'top',
|
|
137
128
|
targetRef: props.triggerRef!,
|
|
138
129
|
overlayRef: props.tooltipRef,
|
|
130
|
+
arrowRef,
|
|
139
131
|
offset: props.offset,
|
|
140
132
|
crossOffset: props.crossOffset,
|
|
141
133
|
isOpen: state.isOpen,
|
|
142
|
-
arrowSize: arrowWidth,
|
|
143
134
|
arrowBoundaryOffset: props.arrowBoundaryOffset,
|
|
144
135
|
shouldFlip: props.shouldFlip,
|
|
136
|
+
containerPadding: props.containerPadding,
|
|
145
137
|
onClose: () => state.close(true)
|
|
146
138
|
});
|
|
147
139
|
|
|
@@ -166,7 +158,11 @@ function TooltipInner(props: TooltipProps & {isExiting: boolean, tooltipRef: Ref
|
|
|
166
158
|
<div
|
|
167
159
|
{...mergeProps(DOMProps, renderProps, tooltipProps)}
|
|
168
160
|
ref={props.tooltipRef}
|
|
169
|
-
style={{
|
|
161
|
+
style={{
|
|
162
|
+
...overlayProps.style,
|
|
163
|
+
'--trigger-anchor-point': triggerAnchorPoint ? `${triggerAnchorPoint.x}px ${triggerAnchorPoint.y}px` : undefined,
|
|
164
|
+
...renderProps.style
|
|
165
|
+
} as CSSProperties}
|
|
170
166
|
data-placement={placement ?? undefined}
|
|
171
167
|
data-entering={isEntering || undefined}
|
|
172
168
|
data-exiting={props.isExiting || undefined}>
|
package/src/Tree.tsx
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import {AriaTreeItemOptions, AriaTreeProps, DraggableItemResult, DropIndicatorAria, DropIndicatorProps, DroppableCollectionResult, FocusScope, ListKeyboardDelegate, mergeProps, useCollator, useFocusRing, useGridListSelectionCheckbox, useHover, useId, useLocale, useTree, useTreeItem, useVisuallyHidden} from 'react-aria';
|
|
14
14
|
import {ButtonContext} from './Button';
|
|
15
15
|
import {CheckboxContext} from './RSPContexts';
|
|
16
|
-
import {Collection, CollectionBuilder, CollectionNode, createBranchComponent, createLeafComponent, useCachedChildren} from '@react-aria/collections';
|
|
16
|
+
import {Collection, CollectionBuilder, CollectionNode, createBranchComponent, createLeafComponent, LoaderNode, useCachedChildren} from '@react-aria/collections';
|
|
17
17
|
import {CollectionProps, CollectionRendererContext, DefaultCollectionRenderer, ItemRenderProps} from './Collection';
|
|
18
18
|
import {ContextValue, DEFAULT_SLOT, Provider, RenderProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps} from './utils';
|
|
19
19
|
import {DisabledBehavior, DragPreviewRenderer, Expandable, forwardRefType, GlobalDOMAttributes, HoverEvents, Key, LinkDOMProps, MultipleSelection, PressEvents, RefObject, SelectionMode} from '@react-types/shared';
|
|
@@ -148,7 +148,7 @@ export interface TreeProps<T> extends Omit<AriaTreeProps<T>, 'children'>, Multip
|
|
|
148
148
|
*/
|
|
149
149
|
disabledBehavior?: DisabledBehavior,
|
|
150
150
|
/** The drag and drop hooks returned by `useDragAndDrop` used to enable drag and drop behavior for the Tree. */
|
|
151
|
-
dragAndDropHooks?: DragAndDropHooks
|
|
151
|
+
dragAndDropHooks?: DragAndDropHooks<NoInfer<T>>
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
|
|
@@ -448,7 +448,11 @@ export interface TreeItemContentRenderProps extends TreeItemRenderProps {}
|
|
|
448
448
|
// need to do a bunch of check to figure out what is the Content and what are the actual collection elements (aka child rows) of the TreeItem
|
|
449
449
|
export interface TreeItemContentProps extends Pick<RenderProps<TreeItemContentRenderProps>, 'children'> {}
|
|
450
450
|
|
|
451
|
-
|
|
451
|
+
class TreeContentNode extends CollectionNode<any> {
|
|
452
|
+
static readonly type = 'content';
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export const TreeItemContent = /*#__PURE__*/ createLeafComponent(TreeContentNode, function TreeItemContent(props: TreeItemContentProps) {
|
|
452
456
|
let values = useContext(TreeItemContentContext)!;
|
|
453
457
|
let renderProps = useRenderProps({
|
|
454
458
|
children: props.children,
|
|
@@ -483,10 +487,14 @@ export interface TreeItemProps<T = object> extends StyleRenderProps<TreeItemRend
|
|
|
483
487
|
onAction?: () => void
|
|
484
488
|
}
|
|
485
489
|
|
|
490
|
+
class TreeItemNode extends CollectionNode<any> {
|
|
491
|
+
static readonly type = 'item';
|
|
492
|
+
}
|
|
493
|
+
|
|
486
494
|
/**
|
|
487
495
|
* A TreeItem represents an individual item in a Tree.
|
|
488
496
|
*/
|
|
489
|
-
export const TreeItem = /*#__PURE__*/ createBranchComponent(
|
|
497
|
+
export const TreeItem = /*#__PURE__*/ createBranchComponent(TreeItemNode, <T extends object>(props: TreeItemProps<T>, ref: ForwardedRef<HTMLDivElement>, item: Node<T>) => {
|
|
490
498
|
let state = useContext(TreeStateContext)!;
|
|
491
499
|
ref = useObjectRef<HTMLDivElement>(ref);
|
|
492
500
|
let {dragAndDropHooks, dragState, dropState} = useContext(DragAndDropContext)!;
|
|
@@ -719,7 +727,7 @@ export interface TreeLoadMoreItemProps extends Omit<LoadMoreSentinelProps, 'coll
|
|
|
719
727
|
isLoading?: boolean
|
|
720
728
|
}
|
|
721
729
|
|
|
722
|
-
export const TreeLoadMoreItem = createLeafComponent(
|
|
730
|
+
export const TreeLoadMoreItem = createLeafComponent(LoaderNode, function TreeLoadingSentinel<T extends object>(props: TreeLoadMoreItemProps, ref: ForwardedRef<HTMLDivElement>, item: Node<T>) {
|
|
723
731
|
let {isVirtualized} = useContext(CollectionRendererContext);
|
|
724
732
|
let state = useContext(TreeStateContext)!;
|
|
725
733
|
let {isLoading, onLoadMore, scrollOffset, ...otherProps} = props;
|
package/src/context.tsx
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {AriaLabelingProps, DOMProps, FocusableElement, FocusEvents, KeyboardEvents, Node, ValueBase} from '@react-types/shared';
|
|
14
|
+
import {AriaTextFieldProps} from '@react-aria/textfield';
|
|
15
|
+
import {ContextValue} from './utils';
|
|
16
|
+
import {createContext} from 'react';
|
|
17
|
+
|
|
18
|
+
export interface SelectableCollectionContextValue<T> extends DOMProps, AriaLabelingProps {
|
|
19
|
+
filter?: (nodeTextValue: string, node: Node<T>) => boolean,
|
|
20
|
+
/** Whether the collection items should use virtual focus instead of being focused directly. */
|
|
21
|
+
shouldUseVirtualFocus?: boolean,
|
|
22
|
+
/** Whether typeahead is disabled. */
|
|
23
|
+
disallowTypeAhead?: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface FieldInputContextValue<T = FocusableElement> extends
|
|
27
|
+
DOMProps,
|
|
28
|
+
FocusEvents<T>,
|
|
29
|
+
KeyboardEvents,
|
|
30
|
+
Pick<ValueBase<string>, 'onChange' | 'value'>,
|
|
31
|
+
Pick<AriaTextFieldProps, 'enterKeyHint' | 'aria-controls' | 'aria-autocomplete' | 'aria-activedescendant' | 'spellCheck' | 'autoCorrect' | 'autoComplete'> {}
|
|
32
|
+
|
|
33
|
+
export const SelectableCollectionContext = createContext<ContextValue<SelectableCollectionContextValue<any>, HTMLElement>>(null);
|
|
34
|
+
export const FieldInputContext = createContext<ContextValue<FieldInputContextValue, FocusableElement>>(null);
|
package/src/index.ts
CHANGED
|
@@ -39,7 +39,7 @@ export {DropZone, DropZoneContext} from './DropZone';
|
|
|
39
39
|
export {FieldError, FieldErrorContext} from './FieldError';
|
|
40
40
|
export {FileTrigger} from './FileTrigger';
|
|
41
41
|
export {Form, FormContext} from './Form';
|
|
42
|
-
export {GridListLoadMoreItem, GridList, GridListItem, GridListContext} from './GridList';
|
|
42
|
+
export {GridListLoadMoreItem, GridList, GridListItem, GridListContext, GridListHeader, GridListSection} from './GridList';
|
|
43
43
|
export {Group, GroupContext} from './Group';
|
|
44
44
|
export {Header, HeaderContext} from './Header';
|
|
45
45
|
export {Heading} from './Heading';
|
|
@@ -79,7 +79,7 @@ export {TreeLoadMoreItem, Tree, TreeItem, TreeContext, TreeItemContent, TreeStat
|
|
|
79
79
|
export {useDragAndDrop} from './useDragAndDrop';
|
|
80
80
|
export {DropIndicator, DropIndicatorContext, DragAndDropContext} from './DragAndDrop';
|
|
81
81
|
export {Virtualizer} from './Virtualizer';
|
|
82
|
-
export {DIRECTORY_DRAG_TYPE, isDirectoryDropItem, isFileDropItem, isTextDropItem, SSRProvider, RouterProvider, I18nProvider, useLocale, useFilter, Pressable, Focusable} from 'react-aria';
|
|
82
|
+
export {DIRECTORY_DRAG_TYPE, isDirectoryDropItem, isFileDropItem, isTextDropItem, SSRProvider, RouterProvider, I18nProvider, useLocale, useFilter, Pressable, Focusable, VisuallyHidden} from 'react-aria';
|
|
83
83
|
export {FormValidationContext, parseColor, getColorChannels, ToastQueue as UNSTABLE_ToastQueue} from 'react-stately';
|
|
84
84
|
export {ListLayout, GridLayout, WaterfallLayout} from '@react-stately/layout';
|
|
85
85
|
export {Layout, LayoutInfo, Size, Rect, Point} from '@react-stately/virtualizer';
|
package/src/useDragAndDrop.tsx
CHANGED
|
@@ -43,10 +43,10 @@ import {
|
|
|
43
43
|
import {isVirtualDragging} from '@react-aria/dnd';
|
|
44
44
|
import {JSX, useMemo} from 'react';
|
|
45
45
|
|
|
46
|
-
interface DraggableCollectionStateOpts extends Omit<DraggableCollectionStateOptions
|
|
46
|
+
interface DraggableCollectionStateOpts<T = object> extends Omit<DraggableCollectionStateOptions<T>, 'getItems'> {}
|
|
47
47
|
|
|
48
|
-
interface DragHooks {
|
|
49
|
-
useDraggableCollectionState?: (props: DraggableCollectionStateOpts) => DraggableCollectionState,
|
|
48
|
+
interface DragHooks<T = object> {
|
|
49
|
+
useDraggableCollectionState?: (props: DraggableCollectionStateOpts<T>) => DraggableCollectionState,
|
|
50
50
|
useDraggableCollection?: (props: DraggableCollectionOptions, state: DraggableCollectionState, ref: RefObject<HTMLElement | null>) => void,
|
|
51
51
|
useDraggableItem?: (props: DraggableItemProps, state: DraggableCollectionState) => DraggableItemResult,
|
|
52
52
|
DragPreview?: typeof DragPreview,
|
|
@@ -64,19 +64,19 @@ interface DropHooks {
|
|
|
64
64
|
ListDropTargetDelegate: typeof ListDropTargetDelegate
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
export type DragAndDropHooks = DragHooks & DropHooks
|
|
67
|
+
export type DragAndDropHooks<T = object> = DragHooks<T> & DropHooks
|
|
68
68
|
|
|
69
|
-
export interface DragAndDrop {
|
|
69
|
+
export interface DragAndDrop<T = object> {
|
|
70
70
|
/** Drag and drop hooks for the collection element. */
|
|
71
|
-
dragAndDropHooks: DragAndDropHooks
|
|
71
|
+
dragAndDropHooks: DragAndDropHooks<T>
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export interface DragAndDropOptions extends Omit<DraggableCollectionProps, 'preview' | 'getItems'>, DroppableCollectionProps {
|
|
74
|
+
export interface DragAndDropOptions<T = object> extends Omit<DraggableCollectionProps, 'preview' | 'getItems'>, DroppableCollectionProps {
|
|
75
75
|
/**
|
|
76
76
|
* A function that returns the items being dragged. If not specified, we assume that the collection is not draggable.
|
|
77
77
|
* @default () => []
|
|
78
78
|
*/
|
|
79
|
-
getItems?: (keys: Set<Key
|
|
79
|
+
getItems?: (keys: Set<Key>, items: T[]) => DragItem[],
|
|
80
80
|
/**
|
|
81
81
|
* A function that renders a drag preview, which is shown under the user's cursor while dragging.
|
|
82
82
|
* By default, a copy of the dragged element is rendered.
|
|
@@ -97,7 +97,7 @@ export interface DragAndDropOptions extends Omit<DraggableCollectionProps, 'prev
|
|
|
97
97
|
/**
|
|
98
98
|
* Provides the hooks required to enable drag and drop behavior for a drag and drop compatible collection component.
|
|
99
99
|
*/
|
|
100
|
-
export function useDragAndDrop(options: DragAndDropOptions): DragAndDrop {
|
|
100
|
+
export function useDragAndDrop<T = object>(options: DragAndDropOptions<T>): DragAndDrop<T> {
|
|
101
101
|
let dragAndDropHooks = useMemo(() => {
|
|
102
102
|
let {
|
|
103
103
|
onDrop,
|