@react-spectrum/table 3.12.11-nightly.4649 → 3.12.11-nightly.4656
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/TableViewBase.main.js +113 -97
- package/dist/TableViewBase.main.js.map +1 -1
- package/dist/TableViewBase.mjs +115 -99
- package/dist/TableViewBase.module.js +115 -99
- package/dist/TableViewBase.module.js.map +1 -1
- package/package.json +29 -29
- package/src/TableViewBase.tsx +157 -117
package/src/TableViewBase.tsx
CHANGED
|
@@ -35,13 +35,13 @@ import {InsertionIndicator} from './InsertionIndicator';
|
|
|
35
35
|
// @ts-ignore
|
|
36
36
|
import intlMessages from '../intl/*.json';
|
|
37
37
|
import {Item, Menu, MenuTrigger} from '@react-spectrum/menu';
|
|
38
|
+
import {LayoutInfo, ReusableView, useVirtualizerState} from '@react-stately/virtualizer';
|
|
38
39
|
import {layoutInfoToStyle, ScrollView, setScrollLeft, useVirtualizer, VirtualizerItem} from '@react-aria/virtualizer';
|
|
39
40
|
import ListGripper from '@spectrum-icons/ui/ListGripper';
|
|
40
41
|
import {Nubbin} from './Nubbin';
|
|
41
42
|
import {ProgressCircle} from '@react-spectrum/progress';
|
|
42
43
|
import React, {DOMAttributes, HTMLAttributes, ReactElement, ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
|
|
43
44
|
import {Resizer} from './Resizer';
|
|
44
|
-
import {ReusableView, useVirtualizerState} from '@react-stately/virtualizer';
|
|
45
45
|
import {RootDropIndicator} from './RootDropIndicator';
|
|
46
46
|
import {DragPreview as SpectrumDragPreview} from './DragPreview';
|
|
47
47
|
import {SpectrumTableProps} from './TableViewWrapper';
|
|
@@ -122,7 +122,8 @@ export interface TableContextValue<T> {
|
|
|
122
122
|
onResize: (widths: Map<Key, ColumnSize>) => void,
|
|
123
123
|
onResizeEnd: (widths: Map<Key, ColumnSize>) => void,
|
|
124
124
|
headerMenuOpen: boolean,
|
|
125
|
-
setHeaderMenuOpen: (val: boolean) => void
|
|
125
|
+
setHeaderMenuOpen: (val: boolean) => void,
|
|
126
|
+
renderEmptyState?: () => ReactElement
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
export const TableContext = React.createContext<TableContextValue<unknown>>(null);
|
|
@@ -166,7 +167,6 @@ function TableViewBase<T extends object>(props: TableBaseProps<T>, ref: DOMRef<H
|
|
|
166
167
|
}, [isTableDraggable, isTableDroppable, state]);
|
|
167
168
|
|
|
168
169
|
let {styleProps} = useStyleProps(props);
|
|
169
|
-
let {direction} = useLocale();
|
|
170
170
|
let {scale} = useProvider();
|
|
171
171
|
|
|
172
172
|
const getDefaultWidth = useCallback(({props: {hideHeader, isSelectionCell, showDivider, isDragButtonCell}}: GridNode<T>): ColumnSize | null | undefined => {
|
|
@@ -203,7 +203,6 @@ function TableViewBase<T extends object>(props: TableBaseProps<T>, ref: DOMRef<H
|
|
|
203
203
|
let domRef = useDOMRef(ref);
|
|
204
204
|
let headerRef = useRef<HTMLDivElement>();
|
|
205
205
|
let bodyRef = useRef<HTMLDivElement>();
|
|
206
|
-
let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/table');
|
|
207
206
|
|
|
208
207
|
let density = props.density || 'regular';
|
|
209
208
|
let columnLayout = useMemo(
|
|
@@ -278,25 +277,21 @@ function TableViewBase<T extends object>(props: TableBaseProps<T>, ref: DOMRef<H
|
|
|
278
277
|
...props,
|
|
279
278
|
isVirtualized: true,
|
|
280
279
|
layout,
|
|
281
|
-
onRowAction: onAction
|
|
280
|
+
onRowAction: onAction,
|
|
281
|
+
scrollRef: bodyRef
|
|
282
282
|
}, state, domRef);
|
|
283
283
|
let [headerMenuOpen, setHeaderMenuOpen] = useState(false);
|
|
284
284
|
let [headerRowHovered, setHeaderRowHovered] = useState(false);
|
|
285
285
|
|
|
286
286
|
// This overrides collection view's renderWrapper to support DOM hierarchy.
|
|
287
287
|
type View = ReusableView<GridNode<T>, ReactNode>;
|
|
288
|
-
let renderWrapper = (parent: View, reusableView: View, children: View[], renderChildren: (views: View[]) => ReactElement[]) => {
|
|
289
|
-
let style = layoutInfoToStyle(reusableView.layoutInfo, direction, parent && parent.layoutInfo);
|
|
290
|
-
if (style.overflow === 'hidden') {
|
|
291
|
-
style.overflow = 'visible'; // needed to support position: sticky
|
|
292
|
-
}
|
|
293
|
-
|
|
288
|
+
let renderWrapper = useCallback((parent: View, reusableView: View, children: View[], renderChildren: (views: View[]) => ReactElement[]) => {
|
|
294
289
|
if (reusableView.viewType === 'rowgroup') {
|
|
295
290
|
return (
|
|
296
|
-
<TableRowGroup
|
|
297
|
-
{
|
|
298
|
-
|
|
299
|
-
}
|
|
291
|
+
<TableRowGroup
|
|
292
|
+
key={reusableView.key}
|
|
293
|
+
layoutInfo={reusableView.layoutInfo}
|
|
294
|
+
parent={parent?.layoutInfo}>
|
|
300
295
|
{renderChildren(children)}
|
|
301
296
|
</TableRowGroup>
|
|
302
297
|
);
|
|
@@ -306,7 +301,8 @@ function TableViewBase<T extends object>(props: TableBaseProps<T>, ref: DOMRef<H
|
|
|
306
301
|
return (
|
|
307
302
|
<TableHeader
|
|
308
303
|
key={reusableView.key}
|
|
309
|
-
|
|
304
|
+
layoutInfo={reusableView.layoutInfo}
|
|
305
|
+
parent={parent?.layoutInfo}>
|
|
310
306
|
{renderChildren(children)}
|
|
311
307
|
</TableHeader>
|
|
312
308
|
);
|
|
@@ -317,10 +313,8 @@ function TableViewBase<T extends object>(props: TableBaseProps<T>, ref: DOMRef<H
|
|
|
317
313
|
<TableRow
|
|
318
314
|
key={reusableView.key}
|
|
319
315
|
item={reusableView.content}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
isTableDroppable={isTableDroppable}
|
|
323
|
-
isTableDraggable={isTableDraggable}>
|
|
316
|
+
layoutInfo={reusableView.layoutInfo}
|
|
317
|
+
parent={parent?.layoutInfo}>
|
|
324
318
|
{renderChildren(children)}
|
|
325
319
|
</TableRow>
|
|
326
320
|
);
|
|
@@ -331,46 +325,26 @@ function TableViewBase<T extends object>(props: TableBaseProps<T>, ref: DOMRef<H
|
|
|
331
325
|
<TableHeaderRow
|
|
332
326
|
onHoverChange={setHeaderRowHovered}
|
|
333
327
|
key={reusableView.key}
|
|
334
|
-
|
|
328
|
+
layoutInfo={reusableView.layoutInfo}
|
|
329
|
+
parent={parent?.layoutInfo}
|
|
335
330
|
item={reusableView.content}>
|
|
336
331
|
{renderChildren(children)}
|
|
337
332
|
</TableHeaderRow>
|
|
338
333
|
);
|
|
339
334
|
}
|
|
340
|
-
|
|
341
|
-
let isRootDroptarget: boolean;
|
|
342
|
-
if (isTableDroppable) {
|
|
343
|
-
if (parent.content) {
|
|
344
|
-
isDropTarget = dropState.isDropTarget({type: 'item', dropPosition: 'on', key: parent.content.key});
|
|
345
|
-
}
|
|
346
|
-
isRootDroptarget = dropState.isDropTarget({type: 'root'});
|
|
347
|
-
}
|
|
348
|
-
|
|
335
|
+
|
|
349
336
|
return (
|
|
350
|
-
<
|
|
337
|
+
<TableCellWrapper
|
|
351
338
|
key={reusableView.key}
|
|
352
339
|
layoutInfo={reusableView.layoutInfo}
|
|
353
340
|
virtualizer={reusableView.virtualizer}
|
|
354
|
-
parent={parent
|
|
355
|
-
className={
|
|
356
|
-
classNames(
|
|
357
|
-
styles,
|
|
358
|
-
'spectrum-Table-cellWrapper',
|
|
359
|
-
classNames(
|
|
360
|
-
stylesOverrides,
|
|
361
|
-
{
|
|
362
|
-
'react-spectrum-Table-cellWrapper': !reusableView.layoutInfo.estimatedSize,
|
|
363
|
-
'react-spectrum-Table-cellWrapper--dropTarget': isDropTarget || isRootDroptarget
|
|
364
|
-
}
|
|
365
|
-
)
|
|
366
|
-
)
|
|
367
|
-
}>
|
|
341
|
+
parent={parent}>
|
|
368
342
|
{reusableView.rendered}
|
|
369
|
-
</
|
|
343
|
+
</TableCellWrapper>
|
|
370
344
|
);
|
|
371
|
-
};
|
|
345
|
+
}, []);
|
|
372
346
|
|
|
373
|
-
let renderView = (type: string, item: GridNode<T>) => {
|
|
347
|
+
let renderView = useCallback((type: string, item: GridNode<T>) => {
|
|
374
348
|
switch (type) {
|
|
375
349
|
case 'header':
|
|
376
350
|
case 'rowgroup':
|
|
@@ -417,34 +391,19 @@ function TableViewBase<T extends object>(props: TableBaseProps<T>, ref: DOMRef<H
|
|
|
417
391
|
}
|
|
418
392
|
|
|
419
393
|
if (item.props.allowsResizing && !item.hasChildNodes) {
|
|
420
|
-
return <ResizableTableColumnHeader
|
|
394
|
+
return <ResizableTableColumnHeader column={item} />;
|
|
421
395
|
}
|
|
422
396
|
|
|
423
397
|
return (
|
|
424
398
|
<TableColumnHeader column={item} />
|
|
425
399
|
);
|
|
426
400
|
case 'loader':
|
|
427
|
-
return
|
|
428
|
-
<CenteredWrapper>
|
|
429
|
-
<ProgressCircle
|
|
430
|
-
isIndeterminate
|
|
431
|
-
aria-label={state.collection.size > 0 ? stringFormatter.format('loadingMore') : stringFormatter.format('loading')} />
|
|
432
|
-
</CenteredWrapper>
|
|
433
|
-
);
|
|
401
|
+
return <LoadingState />;
|
|
434
402
|
case 'empty': {
|
|
435
|
-
|
|
436
|
-
if (emptyState == null) {
|
|
437
|
-
return null;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
return (
|
|
441
|
-
<CenteredWrapper>
|
|
442
|
-
{emptyState}
|
|
443
|
-
</CenteredWrapper>
|
|
444
|
-
);
|
|
403
|
+
return <EmptyState />;
|
|
445
404
|
}
|
|
446
405
|
}
|
|
447
|
-
};
|
|
406
|
+
}, []);
|
|
448
407
|
|
|
449
408
|
let [isVerticalScrollbarVisible, setVerticalScollbarVisible] = useState(false);
|
|
450
409
|
let [isHorizontalScrollbarVisible, setHorizontalScollbarVisible] = useState(false);
|
|
@@ -489,7 +448,27 @@ function TableViewBase<T extends object>(props: TableBaseProps<T>, ref: DOMRef<H
|
|
|
489
448
|
);
|
|
490
449
|
|
|
491
450
|
return (
|
|
492
|
-
<TableContext.Provider
|
|
451
|
+
<TableContext.Provider
|
|
452
|
+
value={{
|
|
453
|
+
state,
|
|
454
|
+
dragState,
|
|
455
|
+
dropState,
|
|
456
|
+
dragAndDropHooks,
|
|
457
|
+
isTableDraggable,
|
|
458
|
+
isTableDroppable,
|
|
459
|
+
layout,
|
|
460
|
+
onResizeStart,
|
|
461
|
+
onResize: props.onResize,
|
|
462
|
+
onResizeEnd,
|
|
463
|
+
headerRowHovered,
|
|
464
|
+
isInResizeMode,
|
|
465
|
+
setIsInResizeMode,
|
|
466
|
+
isEmpty,
|
|
467
|
+
onFocusedResizer,
|
|
468
|
+
headerMenuOpen,
|
|
469
|
+
setHeaderMenuOpen,
|
|
470
|
+
renderEmptyState: props.renderEmptyState
|
|
471
|
+
}}>
|
|
493
472
|
<TableVirtualizer
|
|
494
473
|
{...mergedProps}
|
|
495
474
|
{...styleProps}
|
|
@@ -512,7 +491,9 @@ function TableViewBase<T extends object>(props: TableBaseProps<T>, ref: DOMRef<H
|
|
|
512
491
|
styleProps.className
|
|
513
492
|
)
|
|
514
493
|
}
|
|
515
|
-
layout
|
|
494
|
+
// This should be `tableLayout` rather than `layout` so it doesn't
|
|
495
|
+
// change objects and invalidate virtualizer.
|
|
496
|
+
layout={tableLayout}
|
|
516
497
|
collection={state.collection}
|
|
517
498
|
focusedKey={focusedKey}
|
|
518
499
|
renderView={renderView}
|
|
@@ -549,14 +530,7 @@ function TableVirtualizer(props) {
|
|
|
549
530
|
let loadingState = collection.body.props.loadingState;
|
|
550
531
|
let isLoading = loadingState === 'loading' || loadingState === 'loadingMore';
|
|
551
532
|
let onLoadMore = collection.body.props.onLoadMore;
|
|
552
|
-
|
|
553
|
-
if (isLoading) {
|
|
554
|
-
transitionDuration = 160;
|
|
555
|
-
}
|
|
556
|
-
if (layout.resizingColumn != null) {
|
|
557
|
-
// while resizing, prop changes should not cause animations
|
|
558
|
-
transitionDuration = 0;
|
|
559
|
-
}
|
|
533
|
+
|
|
560
534
|
let state = useVirtualizerState<object, ReactNode, ReactNode>({
|
|
561
535
|
layout,
|
|
562
536
|
collection,
|
|
@@ -566,39 +540,18 @@ function TableVirtualizer(props) {
|
|
|
566
540
|
bodyRef.current.scrollTop = rect.y;
|
|
567
541
|
setScrollLeft(bodyRef.current, direction, rect.x);
|
|
568
542
|
},
|
|
569
|
-
|
|
543
|
+
persistedKeys: useMemo(() => focusedKey ? new Set([focusedKey]) : new Set(), [focusedKey])
|
|
570
544
|
});
|
|
571
545
|
|
|
572
|
-
let scrollToItem = useCallback((key) => {
|
|
573
|
-
let item = collection.getItem(key);
|
|
574
|
-
let column = collection.columns[0];
|
|
575
|
-
let virtualizer = state.virtualizer;
|
|
576
|
-
|
|
577
|
-
virtualizer.scrollToItem(key, {
|
|
578
|
-
duration: 0,
|
|
579
|
-
// Prevent scrolling to the top when clicking on column headers.
|
|
580
|
-
shouldScrollY: item?.type !== 'column',
|
|
581
|
-
// Offset scroll position by width of selection cell
|
|
582
|
-
// (which is sticky and will overlap the cell we're scrolling to).
|
|
583
|
-
offsetX: column.props.isSelectionCell || column.props.isDragButtonCell
|
|
584
|
-
? layout.getColumnWidth(column.key)
|
|
585
|
-
: 0
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
// Sync the scroll positions of the column headers and the body so scrollIntoViewport can
|
|
589
|
-
// properly decide if the column is outside the viewport or not
|
|
590
|
-
headerRef.current.scrollLeft = bodyRef.current.scrollLeft;
|
|
591
|
-
}, [collection, bodyRef, headerRef, layout, state.virtualizer]);
|
|
592
|
-
|
|
593
546
|
let memoedVirtualizerProps = useMemo(() => ({
|
|
594
547
|
tabIndex: otherProps.tabIndex,
|
|
595
548
|
focusedKey,
|
|
596
|
-
scrollToItem,
|
|
597
549
|
isLoading,
|
|
598
550
|
onLoadMore
|
|
599
|
-
}), [otherProps.tabIndex, focusedKey,
|
|
551
|
+
}), [otherProps.tabIndex, focusedKey, isLoading, onLoadMore]);
|
|
600
552
|
|
|
601
553
|
let {virtualizerProps, scrollViewProps: {onVisibleRectChange}} = useVirtualizer(memoedVirtualizerProps, state, domRef);
|
|
554
|
+
let onVisibleRectChangeMemo = useMemo(() => chain(onVisibleRectChange, onVisibleRectChangeProp), [onVisibleRectChange, onVisibleRectChangeProp]);
|
|
602
555
|
|
|
603
556
|
// this effect runs whenever the contentSize changes, it doesn't matter what the content size is
|
|
604
557
|
// only that it changes in a resize, and when that happens, we want to sync the body to the
|
|
@@ -638,6 +591,12 @@ function TableVirtualizer(props) {
|
|
|
638
591
|
isVirtualDragging && {tabIndex: null}
|
|
639
592
|
);
|
|
640
593
|
|
|
594
|
+
let firstColumn = collection.columns[0];
|
|
595
|
+
let scrollPadding = 0;
|
|
596
|
+
if (firstColumn.props.isSelectionCell || firstColumn.props.isDragButtonCell) {
|
|
597
|
+
scrollPadding = layout.getColumnWidth(firstColumn.key);
|
|
598
|
+
}
|
|
599
|
+
|
|
641
600
|
return (
|
|
642
601
|
<VirtualizerContext.Provider value={resizingColumn}>
|
|
643
602
|
<FocusScope>
|
|
@@ -652,7 +611,7 @@ function TableVirtualizer(props) {
|
|
|
652
611
|
overflow: 'hidden',
|
|
653
612
|
position: 'relative',
|
|
654
613
|
willChange: state.isScrolling ? 'scroll-position' : undefined,
|
|
655
|
-
|
|
614
|
+
scrollPaddingInlineStart: scrollPadding
|
|
656
615
|
}}
|
|
657
616
|
ref={headerRef}>
|
|
658
617
|
{state.visibleViews[0]}
|
|
@@ -677,11 +636,14 @@ function TableVirtualizer(props) {
|
|
|
677
636
|
)
|
|
678
637
|
}
|
|
679
638
|
tabIndex={isVirtualDragging ? null : -1}
|
|
680
|
-
style={{
|
|
681
|
-
|
|
639
|
+
style={{
|
|
640
|
+
flex: 1,
|
|
641
|
+
scrollPaddingInlineStart: scrollPadding
|
|
642
|
+
}}
|
|
643
|
+
innerStyle={{overflow: 'visible'}}
|
|
682
644
|
ref={bodyRef}
|
|
683
645
|
contentSize={state.contentSize}
|
|
684
|
-
onVisibleRectChange={
|
|
646
|
+
onVisibleRectChange={onVisibleRectChangeMemo}
|
|
685
647
|
onScrollStart={state.startScrolling}
|
|
686
648
|
onScrollEnd={state.endScrolling}
|
|
687
649
|
onScroll={onScroll}>
|
|
@@ -696,11 +658,21 @@ function TableVirtualizer(props) {
|
|
|
696
658
|
);
|
|
697
659
|
}
|
|
698
660
|
|
|
699
|
-
function
|
|
661
|
+
function useStyle(layoutInfo: LayoutInfo, parent: LayoutInfo | null) {
|
|
662
|
+
let {direction} = useLocale();
|
|
663
|
+
let style = layoutInfoToStyle(layoutInfo, direction, parent);
|
|
664
|
+
if (style.overflow === 'hidden') {
|
|
665
|
+
style.overflow = 'visible'; // needed to support position: sticky
|
|
666
|
+
}
|
|
667
|
+
return style;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
function TableHeader({children, layoutInfo, parent, ...otherProps}) {
|
|
700
671
|
let {rowGroupProps} = useTableRowGroup();
|
|
672
|
+
let style = useStyle(layoutInfo, parent);
|
|
701
673
|
|
|
702
674
|
return (
|
|
703
|
-
<div {...rowGroupProps} {...otherProps} className={classNames(styles, 'spectrum-Table-head')}>
|
|
675
|
+
<div {...rowGroupProps} {...otherProps} className={classNames(styles, 'spectrum-Table-head')} style={style}>
|
|
704
676
|
{children}
|
|
705
677
|
</div>
|
|
706
678
|
);
|
|
@@ -1047,11 +1019,16 @@ function TableDragHeaderCell({column}) {
|
|
|
1047
1019
|
);
|
|
1048
1020
|
}
|
|
1049
1021
|
|
|
1050
|
-
function TableRowGroup({children, ...otherProps}) {
|
|
1022
|
+
function TableRowGroup({children, layoutInfo, parent, ...otherProps}) {
|
|
1051
1023
|
let {rowGroupProps} = useTableRowGroup();
|
|
1024
|
+
let {isTableDroppable} = useContext(TableContext);
|
|
1025
|
+
let style = useStyle(layoutInfo, parent);
|
|
1052
1026
|
|
|
1053
1027
|
return (
|
|
1054
|
-
<div {...rowGroupProps} {...otherProps}>
|
|
1028
|
+
<div {...rowGroupProps} style={style} {...otherProps}>
|
|
1029
|
+
{isTableDroppable &&
|
|
1030
|
+
<RootDropIndicator key="root" />
|
|
1031
|
+
}
|
|
1055
1032
|
{children}
|
|
1056
1033
|
</div>
|
|
1057
1034
|
);
|
|
@@ -1091,19 +1068,18 @@ export function useTableRowContext() {
|
|
|
1091
1068
|
return useContext(TableRowContext);
|
|
1092
1069
|
}
|
|
1093
1070
|
|
|
1094
|
-
function TableRow({item, children,
|
|
1071
|
+
function TableRow({item, children, layoutInfo, parent, ...otherProps}) {
|
|
1095
1072
|
let ref = useRef();
|
|
1096
|
-
let {state, layout, dragAndDropHooks, dragState, dropState} = useTableContext();
|
|
1097
|
-
let allowsInteraction = state.selectionManager.selectionMode !== 'none' || hasActions;
|
|
1098
|
-
let isDisabled = !allowsInteraction || state.disabledKeys.has(item.key);
|
|
1099
|
-
let isDroppable = isTableDroppable && !isDisabled;
|
|
1073
|
+
let {state, layout, dragAndDropHooks, isTableDraggable, isTableDroppable, dragState, dropState} = useTableContext();
|
|
1100
1074
|
let isSelected = state.selectionManager.isSelected(item.key);
|
|
1101
|
-
let {rowProps} = useTableRow({
|
|
1075
|
+
let {rowProps, hasAction, allowsSelection} = useTableRow({
|
|
1102
1076
|
node: item,
|
|
1103
1077
|
isVirtualized: true,
|
|
1104
1078
|
shouldSelectOnPressUp: isTableDraggable
|
|
1105
1079
|
}, state, ref);
|
|
1106
1080
|
|
|
1081
|
+
let isDisabled = !allowsSelection && !hasAction;
|
|
1082
|
+
let isDroppable = isTableDroppable && !isDisabled;
|
|
1107
1083
|
let {pressProps, isPressed} = usePress({isDisabled});
|
|
1108
1084
|
|
|
1109
1085
|
// The row should show the focus background style when any cell inside it is focused.
|
|
@@ -1120,7 +1096,7 @@ function TableRow({item, children, hasActions, isTableDraggable, isTableDroppabl
|
|
|
1120
1096
|
// border corners of the last row when selected.
|
|
1121
1097
|
let isFlushWithContainerBottom = false;
|
|
1122
1098
|
if (isLastRow) {
|
|
1123
|
-
if (layout.getContentSize()?.height >= layout.virtualizer?.
|
|
1099
|
+
if (layout.getContentSize()?.height >= layout.virtualizer?.visibleRect.height) {
|
|
1124
1100
|
isFlushWithContainerBottom = true;
|
|
1125
1101
|
}
|
|
1126
1102
|
}
|
|
@@ -1150,9 +1126,12 @@ function TableRow({item, children, hasActions, isTableDraggable, isTableDroppabl
|
|
|
1150
1126
|
elementType: 'div'
|
|
1151
1127
|
}, dragButtonRef);
|
|
1152
1128
|
|
|
1129
|
+
let style = useStyle(layoutInfo, parent);
|
|
1130
|
+
|
|
1153
1131
|
let props = mergeProps(
|
|
1154
1132
|
rowProps,
|
|
1155
1133
|
otherProps,
|
|
1134
|
+
{style},
|
|
1156
1135
|
focusWithinProps,
|
|
1157
1136
|
focusProps,
|
|
1158
1137
|
hoverProps,
|
|
@@ -1220,11 +1199,12 @@ function TableRow({item, children, hasActions, isTableDraggable, isTableDroppabl
|
|
|
1220
1199
|
);
|
|
1221
1200
|
}
|
|
1222
1201
|
|
|
1223
|
-
function TableHeaderRow({item, children,
|
|
1202
|
+
function TableHeaderRow({item, children, layoutInfo, parent, ...props}) {
|
|
1224
1203
|
let {state, headerMenuOpen} = useTableContext();
|
|
1225
1204
|
let ref = useRef();
|
|
1226
1205
|
let {rowProps} = useTableHeaderRow({node: item, isVirtualized: true}, state, ref);
|
|
1227
1206
|
let {hoverProps} = useHover({...props, isDisabled: headerMenuOpen});
|
|
1207
|
+
let style = useStyle(layoutInfo, parent);
|
|
1228
1208
|
|
|
1229
1209
|
return (
|
|
1230
1210
|
<div {...mergeProps(rowProps, hoverProps)} ref={ref} style={style}>
|
|
@@ -1378,6 +1358,40 @@ function TableCell({cell}) {
|
|
|
1378
1358
|
);
|
|
1379
1359
|
}
|
|
1380
1360
|
|
|
1361
|
+
function TableCellWrapper({layoutInfo, virtualizer, parent, children}) {
|
|
1362
|
+
let {isTableDroppable, dropState} = useContext(TableContext);
|
|
1363
|
+
let isDropTarget: boolean;
|
|
1364
|
+
let isRootDroptarget: boolean;
|
|
1365
|
+
if (isTableDroppable) {
|
|
1366
|
+
if (parent.content) {
|
|
1367
|
+
isDropTarget = dropState.isDropTarget({type: 'item', dropPosition: 'on', key: parent.content.key});
|
|
1368
|
+
}
|
|
1369
|
+
isRootDroptarget = dropState.isDropTarget({type: 'root'});
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
return (
|
|
1373
|
+
<VirtualizerItem
|
|
1374
|
+
layoutInfo={layoutInfo}
|
|
1375
|
+
virtualizer={virtualizer}
|
|
1376
|
+
parent={parent?.layoutInfo}
|
|
1377
|
+
className={
|
|
1378
|
+
useMemo(() => classNames(
|
|
1379
|
+
styles,
|
|
1380
|
+
'spectrum-Table-cellWrapper',
|
|
1381
|
+
classNames(
|
|
1382
|
+
stylesOverrides,
|
|
1383
|
+
{
|
|
1384
|
+
'react-spectrum-Table-cellWrapper': !layoutInfo.estimatedSize,
|
|
1385
|
+
'react-spectrum-Table-cellWrapper--dropTarget': isDropTarget || isRootDroptarget
|
|
1386
|
+
}
|
|
1387
|
+
)
|
|
1388
|
+
), [layoutInfo.estimatedSize, isDropTarget, isRootDroptarget])
|
|
1389
|
+
}>
|
|
1390
|
+
{children}
|
|
1391
|
+
</VirtualizerItem>
|
|
1392
|
+
);
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1381
1395
|
function ExpandableRowChevron({cell}) {
|
|
1382
1396
|
// TODO: move some/all of the chevron button setup into a separate hook?
|
|
1383
1397
|
let {direction} = useLocale();
|
|
@@ -1424,6 +1438,32 @@ function ExpandableRowChevron({cell}) {
|
|
|
1424
1438
|
);
|
|
1425
1439
|
}
|
|
1426
1440
|
|
|
1441
|
+
function LoadingState() {
|
|
1442
|
+
let {state} = useContext(TableContext);
|
|
1443
|
+
let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/table');
|
|
1444
|
+
return (
|
|
1445
|
+
<CenteredWrapper>
|
|
1446
|
+
<ProgressCircle
|
|
1447
|
+
isIndeterminate
|
|
1448
|
+
aria-label={state.collection.size > 0 ? stringFormatter.format('loadingMore') : stringFormatter.format('loading')} />
|
|
1449
|
+
</CenteredWrapper>
|
|
1450
|
+
);
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
function EmptyState() {
|
|
1454
|
+
let {renderEmptyState} = useContext(TableContext);
|
|
1455
|
+
let emptyState = renderEmptyState ? renderEmptyState() : null;
|
|
1456
|
+
if (emptyState == null) {
|
|
1457
|
+
return null;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
return (
|
|
1461
|
+
<CenteredWrapper>
|
|
1462
|
+
{emptyState}
|
|
1463
|
+
</CenteredWrapper>
|
|
1464
|
+
);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1427
1467
|
function CenteredWrapper({children}) {
|
|
1428
1468
|
let {state} = useTableContext();
|
|
1429
1469
|
let rowProps;
|