@snack-uikit/list 0.29.5 → 0.29.6-preview-2bc759a5.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.
|
@@ -20,6 +20,7 @@ exports.ListPrivate = void 0;
|
|
|
20
20
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
21
21
|
const react_virtual_1 = require("@tanstack/react-virtual");
|
|
22
22
|
const classnames_1 = __importDefault(require("classnames"));
|
|
23
|
+
const merge_refs_1 = __importDefault(require("merge-refs"));
|
|
23
24
|
const react_1 = require("react");
|
|
24
25
|
const loaders_1 = require("@snack-uikit/loaders");
|
|
25
26
|
const scroll_1 = require("@snack-uikit/scroll");
|
|
@@ -83,16 +84,47 @@ exports.ListPrivate = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
83
84
|
errorDataState
|
|
84
85
|
});
|
|
85
86
|
const hasNoItems = items.length === 0;
|
|
87
|
+
const memoizedFocusFlattenItems = (0, react_1.useMemo)(() => Object.values(focusFlattenItems), [focusFlattenItems]);
|
|
88
|
+
const selectedItemIndex = (0, react_1.useMemo)(() => {
|
|
89
|
+
if (!scrollToSelectedItem || !value) {
|
|
90
|
+
return -1;
|
|
91
|
+
}
|
|
92
|
+
const selectedItem = isSelectionSingle ? flattenItems[value] : flattenItems[value[0]];
|
|
93
|
+
if (!(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id)) {
|
|
94
|
+
return -1;
|
|
95
|
+
}
|
|
96
|
+
return memoizedFocusFlattenItems.findIndex(item => item.originalId === selectedItem.id);
|
|
97
|
+
}, [flattenItems, memoizedFocusFlattenItems, isSelectionSingle, scrollToSelectedItem, value]);
|
|
86
98
|
const virtualizer = (0, react_virtual_1.useVirtualizer)({
|
|
87
99
|
count: itemsJSX.length,
|
|
88
100
|
getScrollElement: () => scroll ? innerScrollRef.current : null,
|
|
89
101
|
estimateSize: () => constants_1.ALL_SIZES[size],
|
|
90
|
-
enabled: virtualized
|
|
102
|
+
enabled: virtualized,
|
|
103
|
+
overscan: 5 // Amount of elements in DOM before/after visible ones
|
|
91
104
|
});
|
|
92
105
|
const virtualItems = virtualizer.getVirtualItems();
|
|
93
106
|
(0, react_1.useEffect)(() => {
|
|
94
107
|
virtualizer.measure();
|
|
95
108
|
}, [virtualizer]);
|
|
109
|
+
(0, react_1.useEffect)(() => {
|
|
110
|
+
if (scroll && scrollToSelectedItem && virtualized) {
|
|
111
|
+
if (selectedItemIndex < 0) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
setTimeout(() => {
|
|
115
|
+
virtualizer.scrollToIndex(selectedItemIndex, {
|
|
116
|
+
align: 'center'
|
|
117
|
+
});
|
|
118
|
+
setTimeout(() => {
|
|
119
|
+
var _a, _b;
|
|
120
|
+
const itemToScrollTo = memoizedFocusFlattenItems[selectedItemIndex];
|
|
121
|
+
(_b = (_a = itemToScrollTo === null || itemToScrollTo === void 0 ? void 0 : itemToScrollTo.itemRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.scrollIntoView({
|
|
122
|
+
block: 'center'
|
|
123
|
+
});
|
|
124
|
+
}, 0);
|
|
125
|
+
}, 0);
|
|
126
|
+
}
|
|
127
|
+
}, [selectedItemIndex, scroll, scrollToSelectedItem, virtualized, virtualizer, memoizedFocusFlattenItems]);
|
|
96
128
|
const loadingJSX = (0, react_1.useMemo)(() => loading && (0, jsx_runtime_1.jsx)("div", {
|
|
97
129
|
role: 'spinbutton',
|
|
98
130
|
tabIndex: -1,
|
|
@@ -104,55 +136,43 @@ exports.ListPrivate = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
104
136
|
size: size === 'l' ? 's' : 'xs'
|
|
105
137
|
})
|
|
106
138
|
}), [hasNoItems, loading, size]);
|
|
107
|
-
const content = (0, react_1.useMemo)(() => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
139
|
+
const content = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, {
|
|
140
|
+
children: [virtualized ? (0, jsx_runtime_1.jsx)("div", {
|
|
141
|
+
className: styles_module_scss_2.default.virtualizedContainer,
|
|
142
|
+
style: {
|
|
143
|
+
height: virtualizer.getTotalSize()
|
|
144
|
+
},
|
|
145
|
+
tabIndex: -1,
|
|
146
|
+
children: virtualItems.map(virtualRow => (0, jsx_runtime_1.jsx)("div", {
|
|
147
|
+
"data-index": virtualRow.index,
|
|
148
|
+
ref: virtualizer.measureElement,
|
|
149
|
+
tabIndex: -1,
|
|
150
|
+
className: styles_module_scss_2.default.virtualizedPositionBox,
|
|
113
151
|
style: {
|
|
114
|
-
height:
|
|
152
|
+
height: `${virtualRow.size}px`,
|
|
153
|
+
transform: `translateY(${virtualRow.start}px)`
|
|
115
154
|
},
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}, virtualRow.key))
|
|
129
|
-
})
|
|
130
|
-
}) : itemsJSX, loadingJSX, (0, jsx_runtime_1.jsx)(helperComponents_1.ListEmptyState, {
|
|
131
|
-
loading: loading,
|
|
132
|
-
dataError: dataError,
|
|
133
|
-
emptyStates: emptyStates,
|
|
134
|
-
hasNoItems: hasNoItems,
|
|
135
|
-
dataFiltered: dataFiltered !== null && dataFiltered !== void 0 ? dataFiltered : Boolean(search === null || search === void 0 ? void 0 : search.value),
|
|
136
|
-
size: size
|
|
137
|
-
})]
|
|
138
|
-
});
|
|
139
|
-
}, [dataError, dataFiltered, emptyStates, hasNoItems, itemsJSX, loading, loadingJSX, search === null || search === void 0 ? void 0 : search.value, size, virtualItems, virtualized, virtualizer]);
|
|
140
|
-
const onScrollInitialized = () => {
|
|
155
|
+
children: itemsJSX[virtualRow.index]
|
|
156
|
+
}, virtualRow.key))
|
|
157
|
+
}) : itemsJSX, loadingJSX, (0, jsx_runtime_1.jsx)(helperComponents_1.ListEmptyState, {
|
|
158
|
+
loading: loading,
|
|
159
|
+
dataError: dataError,
|
|
160
|
+
emptyStates: emptyStates,
|
|
161
|
+
hasNoItems: hasNoItems,
|
|
162
|
+
dataFiltered: dataFiltered !== null && dataFiltered !== void 0 ? dataFiltered : Boolean(search === null || search === void 0 ? void 0 : search.value),
|
|
163
|
+
size: size
|
|
164
|
+
})]
|
|
165
|
+
}), [dataError, dataFiltered, emptyStates, hasNoItems, itemsJSX, loading, loadingJSX, search === null || search === void 0 ? void 0 : search.value, size, virtualItems, virtualized, virtualizer]);
|
|
166
|
+
const onScrollInitialized = (0, react_1.useCallback)(() => {
|
|
141
167
|
var _a, _b;
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
const selectedItem = isSelectionSingle ? flattenItems[value] : flattenItems[value[0]];
|
|
147
|
-
if (!(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id)) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
const itemToScrollTo = Object.values(focusFlattenItems).find(item => item.originalId === selectedItem.id);
|
|
151
|
-
(_b = (_a = itemToScrollTo === null || itemToScrollTo === void 0 ? void 0 : itemToScrollTo.itemRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.scrollIntoView({
|
|
152
|
-
block: 'center'
|
|
153
|
-
});
|
|
168
|
+
if (selectedItemIndex < 0) {
|
|
169
|
+
return;
|
|
154
170
|
}
|
|
155
|
-
|
|
171
|
+
const itemToScrollTo = memoizedFocusFlattenItems[selectedItemIndex];
|
|
172
|
+
(_b = (_a = itemToScrollTo === null || itemToScrollTo === void 0 ? void 0 : itemToScrollTo.itemRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.scrollIntoView({
|
|
173
|
+
block: 'center'
|
|
174
|
+
});
|
|
175
|
+
}, [memoizedFocusFlattenItems, selectedItemIndex]);
|
|
156
176
|
const listJSX = (0, jsx_runtime_1.jsxs)("ul", Object.assign({
|
|
157
177
|
className: (0, classnames_1.default)(styles_module_scss_1.default.listContainer, className),
|
|
158
178
|
ref: ref,
|
|
@@ -175,10 +195,7 @@ exports.ListPrivate = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
175
195
|
}, scrollContainerClassName),
|
|
176
196
|
barHideStrategy: barHideStrategy,
|
|
177
197
|
size: size === 's' ? 's' : 'm',
|
|
178
|
-
ref:
|
|
179
|
-
innerScrollRef.current = ref;
|
|
180
|
-
if (scrollContainerRef) scrollContainerRef.current = ref;
|
|
181
|
-
},
|
|
198
|
+
ref: (0, merge_refs_1.default)(innerScrollRef, scrollContainerRef),
|
|
182
199
|
untouchableScrollbars: untouchableScrollbars,
|
|
183
200
|
onScroll: onScroll,
|
|
184
201
|
onInitialized: onScrollInitialized,
|
|
@@ -9,10 +9,11 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { jsx as _jsx,
|
|
12
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
14
14
|
import cn from 'classnames';
|
|
15
|
-
import
|
|
15
|
+
import mergeRefs from 'merge-refs';
|
|
16
|
+
import { forwardRef, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
16
17
|
import { Spinner } from '@snack-uikit/loaders';
|
|
17
18
|
import { Scroll } from '@snack-uikit/scroll';
|
|
18
19
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
@@ -33,21 +34,48 @@ export const ListPrivate = forwardRef((_a, ref) => {
|
|
|
33
34
|
const itemsPinBottomJSX = useRenderItems(pinBottom);
|
|
34
35
|
const emptyStates = useEmptyState({ noDataState, noResultsState, errorDataState });
|
|
35
36
|
const hasNoItems = items.length === 0;
|
|
37
|
+
const memoizedFocusFlattenItems = useMemo(() => Object.values(focusFlattenItems), [focusFlattenItems]);
|
|
38
|
+
const selectedItemIndex = useMemo(() => {
|
|
39
|
+
if (!scrollToSelectedItem || !value) {
|
|
40
|
+
return -1;
|
|
41
|
+
}
|
|
42
|
+
const selectedItem = isSelectionSingle ? flattenItems[value] : flattenItems[value[0]];
|
|
43
|
+
if (!(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id)) {
|
|
44
|
+
return -1;
|
|
45
|
+
}
|
|
46
|
+
return memoizedFocusFlattenItems.findIndex(item => item.originalId === selectedItem.id);
|
|
47
|
+
}, [flattenItems, memoizedFocusFlattenItems, isSelectionSingle, scrollToSelectedItem, value]);
|
|
36
48
|
const virtualizer = useVirtualizer({
|
|
37
49
|
count: itemsJSX.length,
|
|
38
50
|
getScrollElement: () => (scroll ? innerScrollRef.current : null),
|
|
39
51
|
estimateSize: () => ALL_SIZES[size],
|
|
40
52
|
enabled: virtualized,
|
|
53
|
+
overscan: 5, // Amount of elements in DOM before/after visible ones
|
|
41
54
|
});
|
|
42
55
|
const virtualItems = virtualizer.getVirtualItems();
|
|
43
56
|
useEffect(() => {
|
|
44
57
|
virtualizer.measure();
|
|
45
58
|
}, [virtualizer]);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (scroll && scrollToSelectedItem && virtualized) {
|
|
61
|
+
if (selectedItemIndex < 0) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
virtualizer.scrollToIndex(selectedItemIndex, { align: 'center' });
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
const itemToScrollTo = memoizedFocusFlattenItems[selectedItemIndex];
|
|
69
|
+
(_b = (_a = itemToScrollTo === null || itemToScrollTo === void 0 ? void 0 : itemToScrollTo.itemRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.scrollIntoView({ block: 'center' });
|
|
70
|
+
}, 0);
|
|
71
|
+
}, 0);
|
|
72
|
+
}
|
|
73
|
+
}, [selectedItemIndex, scroll, scrollToSelectedItem, virtualized, virtualizer, memoizedFocusFlattenItems]);
|
|
46
74
|
const loadingJSX = useMemo(() => loading && (_jsx("div", { role: 'spinbutton', tabIndex: -1, className: styles.loader, "data-size": size, "data-no-items": hasNoItems || undefined, "data-test-id": 'list__loader', children: _jsx(Spinner, { size: size === 'l' ? 's' : 'xs' }) })), [hasNoItems, loading, size]);
|
|
47
|
-
const content = useMemo(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
75
|
+
const content = useMemo(() => (_jsxs(_Fragment, { children: [virtualized ? (_jsx("div", { className: styles.virtualizedContainer, style: { height: virtualizer.getTotalSize() }, tabIndex: -1, children: virtualItems.map(virtualRow => (_jsx("div", { "data-index": virtualRow.index, ref: virtualizer.measureElement, tabIndex: -1, className: styles.virtualizedPositionBox, style: {
|
|
76
|
+
height: `${virtualRow.size}px`,
|
|
77
|
+
transform: `translateY(${virtualRow.start}px)`,
|
|
78
|
+
}, children: itemsJSX[virtualRow.index] }, virtualRow.key))) })) : (itemsJSX), loadingJSX, _jsx(ListEmptyState, { loading: loading, dataError: dataError, emptyStates: emptyStates, hasNoItems: hasNoItems, dataFiltered: dataFiltered !== null && dataFiltered !== void 0 ? dataFiltered : Boolean(search === null || search === void 0 ? void 0 : search.value), size: size })] })), [
|
|
51
79
|
dataError,
|
|
52
80
|
dataFiltered,
|
|
53
81
|
emptyStates,
|
|
@@ -61,29 +89,19 @@ export const ListPrivate = forwardRef((_a, ref) => {
|
|
|
61
89
|
virtualized,
|
|
62
90
|
virtualizer,
|
|
63
91
|
]);
|
|
64
|
-
const onScrollInitialized = () => {
|
|
92
|
+
const onScrollInitialized = useCallback(() => {
|
|
65
93
|
var _a, _b;
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
const selectedItem = isSelectionSingle ? flattenItems[value] : flattenItems[value[0]];
|
|
71
|
-
if (!(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id)) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const itemToScrollTo = Object.values(focusFlattenItems).find(item => item.originalId === selectedItem.id);
|
|
75
|
-
(_b = (_a = itemToScrollTo === null || itemToScrollTo === void 0 ? void 0 : itemToScrollTo.itemRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.scrollIntoView({ block: 'center' });
|
|
94
|
+
if (selectedItemIndex < 0) {
|
|
95
|
+
return;
|
|
76
96
|
}
|
|
77
|
-
|
|
97
|
+
const itemToScrollTo = memoizedFocusFlattenItems[selectedItemIndex];
|
|
98
|
+
(_b = (_a = itemToScrollTo === null || itemToScrollTo === void 0 ? void 0 : itemToScrollTo.itemRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.scrollIntoView({ block: 'center' });
|
|
99
|
+
}, [memoizedFocusFlattenItems, selectedItemIndex]);
|
|
78
100
|
const listJSX = (_jsxs("ul", Object.assign({ className: cn(commonStyles.listContainer, className), ref: ref, onKeyDown: onKeyDown, tabIndex: tabIndex, onFocus: onFocus, onBlur: onBlur, "data-active": active || undefined, role: 'menu' }, extractSupportProps(props), { children: [(Number(pinTop === null || pinTop === void 0 ? void 0 : pinTop.length) > 0 || search) && (_jsxs(PinTopGroupItem, { children: [search && _jsx(SearchItem, Object.assign({ search: search }, searchItem)), Number(pinTop === null || pinTop === void 0 ? void 0 : pinTop.length) > 0 && itemsPinTopJSX] })), scroll ? (_jsxs(Scroll, { className: cn({
|
|
79
101
|
[commonStyles.scrollContainerS]: scroll && limitedScrollHeight && size === 's',
|
|
80
102
|
[commonStyles.scrollContainerM]: scroll && limitedScrollHeight && size === 'm',
|
|
81
103
|
[commonStyles.scrollContainerL]: scroll && limitedScrollHeight && size === 'l',
|
|
82
|
-
}, scrollContainerClassName), barHideStrategy: barHideStrategy, size: size === 's' ? 's' : 'm', ref: ref
|
|
83
|
-
innerScrollRef.current = ref;
|
|
84
|
-
if (scrollContainerRef)
|
|
85
|
-
scrollContainerRef.current = ref;
|
|
86
|
-
}, untouchableScrollbars: untouchableScrollbars, onScroll: onScroll, onInitialized: onScrollInitialized, children: [content, _jsx("div", { className: styles.scrollStub, ref: scrollRef })] })) : (_jsx(_Fragment, { children: content })), Number(pinBottom === null || pinBottom === void 0 ? void 0 : pinBottom.length) > 0 && _jsx(PinBottomGroupItem, { children: itemsPinBottomJSX }), footer && (_jsx("div", { className: styles.footer, onFocus: stopPropagation, children: footer }))] })));
|
|
104
|
+
}, scrollContainerClassName), barHideStrategy: barHideStrategy, size: size === 's' ? 's' : 'm', ref: mergeRefs(innerScrollRef, scrollContainerRef), untouchableScrollbars: untouchableScrollbars, onScroll: onScroll, onInitialized: onScrollInitialized, children: [content, _jsx("div", { className: styles.scrollStub, ref: scrollRef })] })) : (_jsx(_Fragment, { children: content })), Number(pinBottom === null || pinBottom === void 0 ? void 0 : pinBottom.length) > 0 && _jsx(PinBottomGroupItem, { children: itemsPinBottomJSX }), footer && (_jsx("div", { className: styles.footer, onFocus: stopPropagation, children: footer }))] })));
|
|
87
105
|
if (!nested) {
|
|
88
106
|
return listJSX;
|
|
89
107
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "List",
|
|
7
|
-
"version": "0.29.
|
|
7
|
+
"version": "0.29.6-preview-2bc759a5.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@snack-uikit/locale": "*"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "9f2cb084807677cdd4c76d003d382d868943f948"
|
|
58
58
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
2
2
|
import cn from 'classnames';
|
|
3
|
-
import
|
|
3
|
+
import mergeRefs from 'merge-refs';
|
|
4
|
+
import { ForwardedRef, forwardRef, RefObject, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
4
5
|
|
|
5
6
|
import { Spinner } from '@snack-uikit/loaders';
|
|
6
7
|
import { Scroll } from '@snack-uikit/scroll';
|
|
@@ -62,11 +63,27 @@ export const ListPrivate = forwardRef(
|
|
|
62
63
|
const emptyStates = useEmptyState({ noDataState, noResultsState, errorDataState });
|
|
63
64
|
const hasNoItems = items.length === 0;
|
|
64
65
|
|
|
66
|
+
const memoizedFocusFlattenItems = useMemo(() => Object.values(focusFlattenItems), [focusFlattenItems]);
|
|
67
|
+
|
|
68
|
+
const selectedItemIndex = useMemo(() => {
|
|
69
|
+
if (!scrollToSelectedItem || !value) {
|
|
70
|
+
return -1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const selectedItem = isSelectionSingle ? flattenItems[value] : flattenItems[value[0]];
|
|
74
|
+
if (!selectedItem?.id) {
|
|
75
|
+
return -1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return memoizedFocusFlattenItems.findIndex(item => item.originalId === selectedItem.id);
|
|
79
|
+
}, [flattenItems, memoizedFocusFlattenItems, isSelectionSingle, scrollToSelectedItem, value]);
|
|
80
|
+
|
|
65
81
|
const virtualizer = useVirtualizer({
|
|
66
82
|
count: itemsJSX.length,
|
|
67
83
|
getScrollElement: () => (scroll ? innerScrollRef.current : null),
|
|
68
84
|
estimateSize: () => ALL_SIZES[size],
|
|
69
85
|
enabled: virtualized,
|
|
86
|
+
overscan: 5, // Amount of elements in DOM before/after visible ones
|
|
70
87
|
});
|
|
71
88
|
const virtualItems = virtualizer.getVirtualItems();
|
|
72
89
|
|
|
@@ -74,6 +91,23 @@ export const ListPrivate = forwardRef(
|
|
|
74
91
|
virtualizer.measure();
|
|
75
92
|
}, [virtualizer]);
|
|
76
93
|
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
if (scroll && scrollToSelectedItem && virtualized) {
|
|
96
|
+
if (selectedItemIndex < 0) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
virtualizer.scrollToIndex(selectedItemIndex, { align: 'center' });
|
|
102
|
+
|
|
103
|
+
setTimeout(() => {
|
|
104
|
+
const itemToScrollTo = memoizedFocusFlattenItems[selectedItemIndex];
|
|
105
|
+
itemToScrollTo?.itemRef?.current?.scrollIntoView({ block: 'center' });
|
|
106
|
+
}, 0);
|
|
107
|
+
}, 0);
|
|
108
|
+
}
|
|
109
|
+
}, [selectedItemIndex, scroll, scrollToSelectedItem, virtualized, virtualizer, memoizedFocusFlattenItems]);
|
|
110
|
+
|
|
77
111
|
const loadingJSX = useMemo(
|
|
78
112
|
() =>
|
|
79
113
|
loading && (
|
|
@@ -93,25 +127,24 @@ export const ListPrivate = forwardRef(
|
|
|
93
127
|
|
|
94
128
|
const content = useMemo(
|
|
95
129
|
() => (
|
|
96
|
-
|
|
130
|
+
<>
|
|
97
131
|
{virtualized ? (
|
|
98
132
|
<div className={styles.virtualizedContainer} style={{ height: virtualizer.getTotalSize() }} tabIndex={-1}>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
</div>
|
|
133
|
+
{virtualItems.map(virtualRow => (
|
|
134
|
+
<div
|
|
135
|
+
key={virtualRow.key}
|
|
136
|
+
data-index={virtualRow.index}
|
|
137
|
+
ref={virtualizer.measureElement}
|
|
138
|
+
tabIndex={-1}
|
|
139
|
+
className={styles.virtualizedPositionBox}
|
|
140
|
+
style={{
|
|
141
|
+
height: `${virtualRow.size}px`,
|
|
142
|
+
transform: `translateY(${virtualRow.start}px)`,
|
|
143
|
+
}}
|
|
144
|
+
>
|
|
145
|
+
{itemsJSX[virtualRow.index]}
|
|
146
|
+
</div>
|
|
147
|
+
))}
|
|
115
148
|
</div>
|
|
116
149
|
) : (
|
|
117
150
|
itemsJSX
|
|
@@ -126,7 +159,7 @@ export const ListPrivate = forwardRef(
|
|
|
126
159
|
dataFiltered={dataFiltered ?? Boolean(search?.value)}
|
|
127
160
|
size={size}
|
|
128
161
|
/>
|
|
129
|
-
|
|
162
|
+
</>
|
|
130
163
|
),
|
|
131
164
|
[
|
|
132
165
|
dataError,
|
|
@@ -144,22 +177,14 @@ export const ListPrivate = forwardRef(
|
|
|
144
177
|
],
|
|
145
178
|
);
|
|
146
179
|
|
|
147
|
-
const onScrollInitialized = () => {
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const selectedItem = isSelectionSingle ? flattenItems[value] : flattenItems[value[0]];
|
|
154
|
-
|
|
155
|
-
if (!selectedItem?.id) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const itemToScrollTo = Object.values(focusFlattenItems).find(item => item.originalId === selectedItem.id);
|
|
160
|
-
itemToScrollTo?.itemRef?.current?.scrollIntoView({ block: 'center' });
|
|
180
|
+
const onScrollInitialized = useCallback(() => {
|
|
181
|
+
if (selectedItemIndex < 0) {
|
|
182
|
+
return;
|
|
161
183
|
}
|
|
162
|
-
|
|
184
|
+
|
|
185
|
+
const itemToScrollTo = memoizedFocusFlattenItems[selectedItemIndex];
|
|
186
|
+
itemToScrollTo?.itemRef?.current?.scrollIntoView({ block: 'center' });
|
|
187
|
+
}, [memoizedFocusFlattenItems, selectedItemIndex]);
|
|
163
188
|
|
|
164
189
|
const listJSX = (
|
|
165
190
|
<ul
|
|
@@ -193,10 +218,7 @@ export const ListPrivate = forwardRef(
|
|
|
193
218
|
)}
|
|
194
219
|
barHideStrategy={barHideStrategy}
|
|
195
220
|
size={size === 's' ? 's' : 'm'}
|
|
196
|
-
ref={
|
|
197
|
-
innerScrollRef.current = ref;
|
|
198
|
-
if (scrollContainerRef) (scrollContainerRef as React.MutableRefObject<HTMLElement | null>).current = ref;
|
|
199
|
-
}}
|
|
221
|
+
ref={mergeRefs(innerScrollRef, scrollContainerRef)}
|
|
200
222
|
untouchableScrollbars={untouchableScrollbars}
|
|
201
223
|
onScroll={onScroll}
|
|
202
224
|
onInitialized={onScrollInitialized}
|