@homecode/ui 4.30.8 → 4.30.10
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.
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleFocus","message":"popup opening (focus)","data":{"scrollTop":0},"hypothesisId":"C","timestamp":1771711527049}
|
|
2
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":true,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":true},"hypothesisId":"B","timestamp":1771711527054}
|
|
3
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:fetchOptionsCore","message":"setScrollTop(0) initial items","data":{"filter":"","offset":0,"totalCount":0},"hypothesisId":"B","timestamp":1771711527555}
|
|
4
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":true,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711527556}
|
|
5
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:fetchOptionsCore-RAF","message":"setScrollTop(undefined) clear","data":{"filter":"","offset":0},"hypothesisId":"E","timestamp":1771711527557}
|
|
6
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleBlur","message":"popup closing (blur)","data":{},"hypothesisId":"A","timestamp":1771711528848}
|
|
7
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711528850}
|
|
8
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleSelect","message":"select","data":{"selectable":true,"label":"Option 15"},"hypothesisId":"A","timestamp":1771711528971}
|
|
9
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleFocus","message":"popup opening (focus)","data":{"savedScrollTop":521.1111450195312},"hypothesisId":"C","timestamp":1771711532390}
|
|
10
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":true,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711532394}
|
|
11
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleBlur","message":"popup closing (blur)","data":{},"hypothesisId":"A","timestamp":1771711535314}
|
|
12
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711535317}
|
|
13
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleSelect","message":"select","data":{"selectable":true,"label":"Option 27"},"hypothesisId":"A","timestamp":1771711535455}
|
|
14
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleFocus","message":"popup opening (focus)","data":{"savedScrollTop":962.2222290039062},"hypothesisId":"C","timestamp":1771711540906}
|
|
15
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":true,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711540911}
|
|
16
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleBlur","message":"popup closing (blur)","data":{},"hypothesisId":"A","timestamp":1771711542255}
|
|
17
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711542257}
|
|
18
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleFocus","message":"popup opening (focus)","data":{"savedScrollTop":962.2222290039062},"hypothesisId":"C","timestamp":1771711543181}
|
|
19
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":true,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711543185}
|
|
20
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleBlur","message":"popup closing (blur)","data":{},"hypothesisId":"A","timestamp":1771711543773}
|
|
21
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711543776}
|
|
22
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleFocus","message":"popup opening (focus)","data":{"savedScrollTop":962.2222290039062},"hypothesisId":"C","timestamp":1771711544455}
|
|
23
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":true,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711544459}
|
|
24
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:handleBlur","message":"popup closing (blur)","data":{},"hypothesisId":"A","timestamp":1771711545022}
|
|
25
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711545023}
|
|
26
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-value","message":"setScrollTop(0) value cleared","data":{"value":""},"hypothesisId":"D","timestamp":1771711551359}
|
|
27
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":200,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711551359}
|
|
28
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711551360}
|
|
29
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-value","message":"setScrollTop(0) value cleared","data":{"value":""},"hypothesisId":"D","timestamp":1771711552110}
|
|
30
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711552111}
|
|
31
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-value","message":"setScrollTop(0) value cleared","data":{"value":""},"hypothesisId":"D","timestamp":1771711552853}
|
|
32
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711552853}
|
|
33
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-value","message":"setScrollTop(0) value cleared","data":{"value":""},"hypothesisId":"D","timestamp":1771711553442}
|
|
34
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711553443}
|
|
35
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-value","message":"setScrollTop(0) value cleared","data":{"value":""},"hypothesisId":"D","timestamp":1771711553951}
|
|
36
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711553951}
|
|
37
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-value","message":"setScrollTop(0) value cleared","data":{"value":""},"hypothesisId":"D","timestamp":1771711554564}
|
|
38
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711554564}
|
|
39
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-value","message":"setScrollTop(0) value cleared","data":{"value":""},"hypothesisId":"D","timestamp":1771711555318}
|
|
40
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711555319}
|
|
41
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-value","message":"setScrollTop(0) value cleared","data":{"value":""},"hypothesisId":"D","timestamp":1771711555975}
|
|
42
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711555975}
|
|
43
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711556573}
|
|
44
|
+
{"sessionId":"8c6f78","location":"Autocomplete.tsx:useEffect-open","message":"open/fetch effect","data":{"open":false,"currentFilter":"","totalCount":0,"itemsLen":20,"willFetch":false},"hypothesisId":"B","timestamp":1771711557126}
|
|
@@ -73,7 +73,7 @@ const getTotalCount = (total, newItemsCount = 0, offset = 0, pageSize = 20) => {
|
|
|
73
73
|
return offset + (newItemsCount === pageSize ? 1 : 0);
|
|
74
74
|
};
|
|
75
75
|
function Autocomplete(props) {
|
|
76
|
-
const { className,
|
|
76
|
+
const { className, value, onChange, size = 'm', getOptions, onSelect, items, itemHeight = SIZE_TO_ITEM_HEIGHT[size], pageSize = 20, debounceDelay = 300, round = false, blur = false, selectable = false, defaultSelected, scrollToSelected = false, inputProps = {}, popupProps = {}, menuProps = {}, scrollProps = {}, loadingPlaceholder, isOpen, } = props;
|
|
77
77
|
const isMounted = useIsMounted();
|
|
78
78
|
const [filteredItems, setFilteredItems] = useState([]);
|
|
79
79
|
const [itemsWithoutFilter, setItemsWithoutFilter] = useState(() => items ?? []);
|
|
@@ -83,7 +83,6 @@ function Autocomplete(props) {
|
|
|
83
83
|
const [scrollTop, setScrollTop] = useState(undefined);
|
|
84
84
|
const [isLoading, setIsLoading] = useState(false);
|
|
85
85
|
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
86
|
-
const [isOpen, setIsOpen] = useState(props.isOpen);
|
|
87
86
|
const [isFocused, setIsFocused] = useState(isOpen);
|
|
88
87
|
const [selectedId, setSelectedId] = useState(null);
|
|
89
88
|
const [selectedLabel, setSelectedLabel] = useState(null);
|
|
@@ -95,6 +94,8 @@ function Autocomplete(props) {
|
|
|
95
94
|
_setSearchValue(val);
|
|
96
95
|
};
|
|
97
96
|
const currentRequest = useRef('');
|
|
97
|
+
const savedScrollTopRef = useRef(undefined);
|
|
98
|
+
const defaultSelectedAppliedRef = useRef(false);
|
|
98
99
|
// @ts-ignore
|
|
99
100
|
const inputRef = useRef(null);
|
|
100
101
|
const inputDisplayValue = selectable && !isFocused && selectedLabel != null
|
|
@@ -104,13 +105,20 @@ function Autocomplete(props) {
|
|
|
104
105
|
? filteredItems
|
|
105
106
|
: itemsWithoutFilter.length
|
|
106
107
|
? itemsWithoutFilter
|
|
107
|
-
:
|
|
108
|
+
: items ?? [];
|
|
108
109
|
const displayCount = displayItems.length;
|
|
109
110
|
const hasMore = totalCount > 0 && displayCount < totalCount;
|
|
110
111
|
const classes = cn(S.root, className, popupProps.className);
|
|
111
112
|
const handleFocus = (e) => {
|
|
112
113
|
isFocusedRef.current = true;
|
|
113
114
|
setIsFocused(true);
|
|
115
|
+
if (!scrollToSelected || !selectable || !selectedId) {
|
|
116
|
+
const saved = savedScrollTopRef.current;
|
|
117
|
+
if (saved != null && saved > 0) {
|
|
118
|
+
setScrollTop(saved);
|
|
119
|
+
requestAnimationFrame(() => setScrollTop(undefined));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
114
122
|
inputProps?.onFocus?.(e);
|
|
115
123
|
};
|
|
116
124
|
const handleBlur = (e) => {
|
|
@@ -123,6 +131,7 @@ function Autocomplete(props) {
|
|
|
123
131
|
setSearchValue(val);
|
|
124
132
|
onChange(e, val);
|
|
125
133
|
if (!val) {
|
|
134
|
+
savedScrollTopRef.current = undefined;
|
|
126
135
|
setCurrentFilter('');
|
|
127
136
|
setFilteredItems([]);
|
|
128
137
|
setItemsWithoutFilter(items ?? []);
|
|
@@ -131,6 +140,7 @@ function Autocomplete(props) {
|
|
|
131
140
|
setScrollTop(0); // Reset scroll when filter is cleared
|
|
132
141
|
}
|
|
133
142
|
else {
|
|
143
|
+
savedScrollTopRef.current = undefined;
|
|
134
144
|
setCurrentFilter(val);
|
|
135
145
|
setCurrentOffset(0);
|
|
136
146
|
setScrollTop(0); // Reset scroll when filter changes
|
|
@@ -150,7 +160,6 @@ function Autocomplete(props) {
|
|
|
150
160
|
setFilteredItems([]);
|
|
151
161
|
setCurrentOffset(0);
|
|
152
162
|
setTotalCount(0);
|
|
153
|
-
setScrollTop(0);
|
|
154
163
|
fetchOptionsCore(option.label, 0);
|
|
155
164
|
onSelect?.(option);
|
|
156
165
|
// set input caret to the end
|
|
@@ -187,6 +196,7 @@ function Autocomplete(props) {
|
|
|
187
196
|
const newTotal = getTotalCount(total, newOptions.length, offset + newOptions.length, pageSize);
|
|
188
197
|
if (filter) {
|
|
189
198
|
if (offset === 0) {
|
|
199
|
+
savedScrollTopRef.current = undefined;
|
|
190
200
|
setFilteredItems(newOptions);
|
|
191
201
|
setScrollTop(0); // Reset scroll when new filter results load
|
|
192
202
|
}
|
|
@@ -198,6 +208,7 @@ function Autocomplete(props) {
|
|
|
198
208
|
}
|
|
199
209
|
else {
|
|
200
210
|
if (offset === 0) {
|
|
211
|
+
savedScrollTopRef.current = undefined;
|
|
201
212
|
setItemsWithoutFilter(newOptions);
|
|
202
213
|
setScrollTop(0); // Reset scroll when loading initial items
|
|
203
214
|
}
|
|
@@ -232,6 +243,9 @@ function Autocomplete(props) {
|
|
|
232
243
|
}
|
|
233
244
|
}, [getOptions, isMounted, pageSize, items]);
|
|
234
245
|
const fetchOptions = useMemo(() => debounce(fetchOptionsCore, debounceDelay), [fetchOptionsCore, debounceDelay]);
|
|
246
|
+
const handleScroll = useCallback(({ scrollTop: top }) => {
|
|
247
|
+
savedScrollTopRef.current = top;
|
|
248
|
+
}, []);
|
|
235
249
|
const handleScrollEnd = useCallback(() => {
|
|
236
250
|
if (!hasMore || isLoading || isLoadingMore)
|
|
237
251
|
return;
|
|
@@ -259,6 +273,7 @@ function Autocomplete(props) {
|
|
|
259
273
|
return;
|
|
260
274
|
setSearchValue(value);
|
|
261
275
|
if (!value) {
|
|
276
|
+
savedScrollTopRef.current = undefined;
|
|
262
277
|
setCurrentFilter('');
|
|
263
278
|
setFilteredItems([]);
|
|
264
279
|
setItemsWithoutFilter(items ?? []);
|
|
@@ -267,6 +282,7 @@ function Autocomplete(props) {
|
|
|
267
282
|
setScrollTop(0); // Reset scroll when value is cleared
|
|
268
283
|
}
|
|
269
284
|
else if (isFocusedRef.current) {
|
|
285
|
+
savedScrollTopRef.current = undefined;
|
|
270
286
|
setCurrentFilter(value);
|
|
271
287
|
setCurrentOffset(0);
|
|
272
288
|
setScrollTop(0); // Reset scroll when filter changes
|
|
@@ -277,8 +293,22 @@ function Autocomplete(props) {
|
|
|
277
293
|
if (selectable && !value) {
|
|
278
294
|
setSelectedId(null);
|
|
279
295
|
setSelectedLabel(null);
|
|
296
|
+
defaultSelectedAppliedRef.current = false;
|
|
280
297
|
}
|
|
281
298
|
}, [selectable, value]);
|
|
299
|
+
useEffect(() => {
|
|
300
|
+
if (selectable &&
|
|
301
|
+
defaultSelected &&
|
|
302
|
+
!defaultSelectedAppliedRef.current &&
|
|
303
|
+
displayItems.length) {
|
|
304
|
+
const item = displayItems.find(o => o.id === defaultSelected);
|
|
305
|
+
if (item) {
|
|
306
|
+
defaultSelectedAppliedRef.current = true;
|
|
307
|
+
setSelectedId(item.id);
|
|
308
|
+
setSelectedLabel(item.label);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}, [selectable, defaultSelected, displayItems]);
|
|
282
312
|
useEffect(() => {
|
|
283
313
|
if (!currentFilter && items?.length) {
|
|
284
314
|
setItemsWithoutFilter(items);
|
|
@@ -330,11 +360,20 @@ function Autocomplete(props) {
|
|
|
330
360
|
return !selectable && isLoading ? LoadingPlaceholder : null;
|
|
331
361
|
}
|
|
332
362
|
const computedTotalCount = totalCount > 0 ? totalCount : displayItems.length;
|
|
333
|
-
|
|
363
|
+
const open = isOpen ?? isFocused;
|
|
364
|
+
let initialScrollTop;
|
|
365
|
+
if (open && scrollToSelected && selectable && selectedId) {
|
|
366
|
+
const idx = displayItems.findIndex(o => o.id === selectedId);
|
|
367
|
+
initialScrollTop =
|
|
368
|
+
idx >= 0 ? Math.max(0, idx * itemHeight - itemHeight) : undefined;
|
|
369
|
+
}
|
|
370
|
+
return (jsx(ListScroll, { ...(selectable && { id: selectedId ?? 'none' }), ...(typeof initialScrollTop === 'number' && {
|
|
371
|
+
initialScrollTop,
|
|
372
|
+
}), className: cn(S.options, menuProps.className), scrollProps: {
|
|
334
373
|
y: true,
|
|
335
374
|
...scrollProps,
|
|
336
375
|
className: cn(S.scroll, scrollProps?.className),
|
|
337
|
-
}, itemHeight: itemHeight, itemsCount: displayItems.length, totalCount: computedTotalCount, overlapCount: 10, pageSize: pageSize, scrollTop: scrollTop, onScrollEnd: handleScrollEnd, renderItem: renderItem, contentAfter: hasMore && LoadingPlaceholder }));
|
|
376
|
+
}, itemHeight: itemHeight, itemsCount: displayItems.length, totalCount: computedTotalCount, overlapCount: 10, pageSize: pageSize, scrollTop: scrollTop, onScroll: handleScroll, onScrollEnd: handleScrollEnd, renderItem: renderItem, contentAfter: hasMore && LoadingPlaceholder }));
|
|
338
377
|
}, [
|
|
339
378
|
displayItems,
|
|
340
379
|
focusedIndex,
|
|
@@ -344,6 +383,7 @@ function Autocomplete(props) {
|
|
|
344
383
|
isLoadingMore,
|
|
345
384
|
itemHeight,
|
|
346
385
|
pageSize,
|
|
386
|
+
handleScroll,
|
|
347
387
|
handleScrollEnd,
|
|
348
388
|
renderItem,
|
|
349
389
|
size,
|
|
@@ -353,6 +393,9 @@ function Autocomplete(props) {
|
|
|
353
393
|
scrollTop,
|
|
354
394
|
selectable,
|
|
355
395
|
selectedId,
|
|
396
|
+
isOpen,
|
|
397
|
+
isFocused,
|
|
398
|
+
scrollToSelected,
|
|
356
399
|
LoadingPlaceholder,
|
|
357
400
|
]);
|
|
358
401
|
return (jsx(Popup, { className: classes, isOpen: isOpen, focusControl: true, round: round, size: size, blur: blur, direction: "bottom", ...popupProps, trigger: jsx(Input, { ref: inputRef,
|
|
@@ -11,7 +11,6 @@ export type Option = {
|
|
|
11
11
|
export type Value = string;
|
|
12
12
|
export type Props = FormControl<Value, HTMLInputElement> & {
|
|
13
13
|
className?: string;
|
|
14
|
-
inputWrapperClassName?: string;
|
|
15
14
|
size?: Size;
|
|
16
15
|
value: Value;
|
|
17
16
|
isOpen?: boolean;
|
|
@@ -31,6 +30,8 @@ export type Props = FormControl<Value, HTMLInputElement> & {
|
|
|
31
30
|
round?: boolean;
|
|
32
31
|
blur?: boolean;
|
|
33
32
|
selectable?: boolean;
|
|
33
|
+
defaultSelected?: string;
|
|
34
|
+
scrollToSelected?: boolean;
|
|
34
35
|
renderItem?: (props: RenderItemProps) => React.ReactElement;
|
|
35
36
|
loadingPlaceholder?: React.ReactNode;
|
|
36
37
|
};
|