-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathDraggableListInput.tsx
More file actions
124 lines (107 loc) · 3.14 KB
/
DraggableListInput.tsx
File metadata and controls
124 lines (107 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
/* eslint no-console: "off" */
import React, { PureComponent } from 'react';
import memoize from 'memoize-one';
import { DraggableItemList } from '@deephaven/components';
import { type Range } from '@deephaven/utils';
interface DraggableListInputProps {
draggablePrefix: string;
droppableId: string;
isDragDisabled: boolean;
isDropDisabled: boolean;
isMultiSelect: boolean;
items: Array<unknown>;
onSelectionChange: (listSelectedRanges: readonly Range[]) => void;
selectedRanges: Range[];
}
interface DraggableListInputState {
topRow: number | null;
bottomRow: number | null;
}
interface DraggableListInput {
itemList: React.RefObject<DraggableItemList<unknown>>;
selectedItems: Array<unknown>;
}
class DraggableListInput extends PureComponent<
DraggableListInputProps,
DraggableListInputState
> {
static defaultProps: {
items: never[];
draggablePrefix: string;
droppableId: string;
isDragDisabled: boolean;
isDropDisabled: boolean;
isMultiSelect: boolean;
onSelectionChange: () => void;
selectedRanges: never[];
};
constructor(props: DraggableListInputProps) {
super(props);
this.handleSelectionChange = this.handleSelectionChange.bind(this);
this.handleViewportChange = this.handleViewportChange.bind(this);
this.itemList = React.createRef();
this.selectedItems = [];
this.state = {
topRow: null,
bottomRow: null,
};
}
focusItem(itemIndex: number): void {
if (this.itemList.current) {
this.itemList.current.focusItem(itemIndex);
}
}
handleSelectionChange(selectedRanges: readonly Range[]): void {
console.log('Selection changed', selectedRanges);
const { onSelectionChange } = this.props;
onSelectionChange(selectedRanges);
}
handleViewportChange(top: number, bottom: number): void {
const { items } = this.props;
const viewportSize = bottom - top + 1;
const topRow = Math.max(0, top - viewportSize);
const bottomRow = Math.min(bottom + viewportSize, items.length);
this.setState({ topRow, bottomRow });
}
getViewportItems = memoize(
(
topRow: number | null,
bottomRow: number | null,
items: Array<unknown>
): Array<unknown> => {
if (topRow == null || bottomRow == null) {
return [];
}
return items.slice(topRow, bottomRow);
}
);
render(): React.ReactElement {
const {
draggablePrefix,
droppableId,
isDragDisabled,
isDropDisabled,
isMultiSelect,
items,
selectedRanges,
} = this.props;
const { topRow, bottomRow } = this.state;
return (
<DraggableItemList
draggablePrefix={draggablePrefix}
droppableId={droppableId}
isDragDisabled={isDragDisabled}
isDropDisabled={isDropDisabled}
isMultiSelect={isMultiSelect}
itemCount={items.length}
items={this.getViewportItems(topRow, bottomRow, items)}
offset={topRow ?? 0}
onSelectionChange={this.handleSelectionChange}
onViewportChange={this.handleViewportChange}
ref={this.itemList}
selectedRanges={selectedRanges}
/>
);
}
}
export default DraggableListInput;