@homecode/ui 4.30.6 → 4.30.7
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/.cursor/debug-a8590a.log +26 -0
- package/.cursor/debug-cdef6d.log +694 -0
- package/.cursor/debug.log +207 -217
- package/dist/esm/src/components/Autocomplete/Autocomplete.js +122 -37
- package/dist/esm/src/components/Autocomplete/Autocomplete.styl.js +2 -2
- package/dist/esm/src/components/DatePickerInput/DatePickerInput.js +27 -3
- package/dist/esm/src/components/Shimmer/Shimmer.js +1 -1
- package/dist/esm/src/components/Virtualized/Virtualized.js +3 -2
- package/dist/esm/types/src/components/Autocomplete/Autocomplete.types.d.ts +8 -2
- package/dist/esm/types/src/components/Shimmer/Shimmer.d.ts +2 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import cn from 'classnames';
|
|
3
3
|
import '../AssistiveText/AssistiveText.styl.js';
|
|
4
|
-
import { useState, useRef, useCallback,
|
|
4
|
+
import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
5
5
|
import S from './Autocomplete.styl.js';
|
|
6
6
|
import { Shimmer } from '../Shimmer/Shimmer.js';
|
|
7
7
|
import debounce from '../../tools/debounce.js';
|
|
@@ -67,17 +67,25 @@ const SIZE_TO_ITEM_HEIGHT = {
|
|
|
67
67
|
m: 40,
|
|
68
68
|
l: 50,
|
|
69
69
|
};
|
|
70
|
+
const getTotalCount = (total, newItemsCount = 0, offset = 0, pageSize = 20) => {
|
|
71
|
+
if (total !== undefined)
|
|
72
|
+
return total;
|
|
73
|
+
return offset + (newItemsCount === pageSize ? 1 : 0);
|
|
74
|
+
};
|
|
70
75
|
function Autocomplete(props) {
|
|
71
|
-
const { className, inputWrapperClassName, value, onChange, size = 'm', getOptions, onSelect, items, itemHeight = SIZE_TO_ITEM_HEIGHT[size], pageSize = 20, debounceDelay = 300, round = false, blur = false, inputProps = {}, popupProps = {}, menuProps = {}, scrollProps = {}, } = props;
|
|
76
|
+
const { className, inputWrapperClassName, value, onChange, size = 'm', getOptions, onSelect, items, itemHeight = SIZE_TO_ITEM_HEIGHT[size], pageSize = 20, debounceDelay = 300, round = false, blur = false, selectable = false, inputProps = {}, popupProps = {}, menuProps = {}, scrollProps = {}, loadingPlaceholder, } = props;
|
|
72
77
|
const isMounted = useIsMounted();
|
|
73
78
|
const [filteredItems, setFilteredItems] = useState([]);
|
|
79
|
+
const [itemsWithoutFilter, setItemsWithoutFilter] = useState(() => items ?? []);
|
|
74
80
|
const [currentFilter, setCurrentFilter] = useState('');
|
|
75
81
|
const [currentOffset, setCurrentOffset] = useState(0);
|
|
76
82
|
const [totalCount, setTotalCount] = useState(0);
|
|
83
|
+
const [scrollTop, setScrollTop] = useState(undefined);
|
|
77
84
|
const [isLoading, setIsLoading] = useState(false);
|
|
78
85
|
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
79
86
|
const [isOpen, setIsOpen] = useState(props.isOpen);
|
|
80
87
|
const [isFocused, setIsFocused] = useState(isOpen);
|
|
88
|
+
const [selectedId, setSelectedId] = useState(null);
|
|
81
89
|
const isFocusedRef = useRef(false);
|
|
82
90
|
const searchValRef = useRef(value);
|
|
83
91
|
const [searchValue, _setSearchValue] = useState(value);
|
|
@@ -88,8 +96,13 @@ function Autocomplete(props) {
|
|
|
88
96
|
const currentRequest = useRef('');
|
|
89
97
|
// @ts-ignore
|
|
90
98
|
const inputRef = useRef(null);
|
|
91
|
-
const displayItems = currentFilter
|
|
92
|
-
|
|
99
|
+
const displayItems = currentFilter
|
|
100
|
+
? filteredItems
|
|
101
|
+
: itemsWithoutFilter.length
|
|
102
|
+
? itemsWithoutFilter
|
|
103
|
+
: items ?? [];
|
|
104
|
+
const displayCount = displayItems.length;
|
|
105
|
+
const hasMore = totalCount > 0 && displayCount < totalCount;
|
|
93
106
|
const classes = cn(S.root, className, popupProps.className);
|
|
94
107
|
const handleFocus = (e) => {
|
|
95
108
|
isFocusedRef.current = true;
|
|
@@ -108,30 +121,40 @@ function Autocomplete(props) {
|
|
|
108
121
|
if (!val) {
|
|
109
122
|
setCurrentFilter('');
|
|
110
123
|
setFilteredItems([]);
|
|
124
|
+
setItemsWithoutFilter(items ?? []);
|
|
111
125
|
setCurrentOffset(0);
|
|
112
126
|
setTotalCount(0);
|
|
127
|
+
setScrollTop(0); // Reset scroll when filter is cleared
|
|
113
128
|
}
|
|
114
129
|
else {
|
|
115
130
|
setCurrentFilter(val);
|
|
116
131
|
setCurrentOffset(0);
|
|
132
|
+
setScrollTop(0); // Reset scroll when filter changes
|
|
117
133
|
fetchOptions(val, 0);
|
|
118
134
|
}
|
|
119
135
|
return true;
|
|
120
136
|
};
|
|
121
137
|
const handleSelect = (option) => {
|
|
138
|
+
if (selectable) {
|
|
139
|
+
setSelectedId(option.id);
|
|
140
|
+
onSelect?.(option);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
122
143
|
setSearchValue(option.label);
|
|
123
|
-
setCurrentFilter(
|
|
144
|
+
setCurrentFilter(option.label);
|
|
124
145
|
setFilteredItems([]);
|
|
125
146
|
setCurrentOffset(0);
|
|
126
147
|
setTotalCount(0);
|
|
127
|
-
|
|
148
|
+
setScrollTop(0);
|
|
149
|
+
fetchOptionsCore(option.label, 0);
|
|
150
|
+
onSelect?.(option);
|
|
128
151
|
// set input caret to the end
|
|
129
152
|
requestAnimationFrame(() => {
|
|
130
153
|
const input = inputRef.current;
|
|
131
154
|
if (!input)
|
|
132
155
|
return;
|
|
133
156
|
input.focus();
|
|
134
|
-
input.setSelectionRange(
|
|
157
|
+
input.setSelectionRange(option.label.length, option.label.length);
|
|
135
158
|
});
|
|
136
159
|
};
|
|
137
160
|
const { focusedIndex, setFocusedIndex } = useListKeyboardControl({
|
|
@@ -139,11 +162,7 @@ function Autocomplete(props) {
|
|
|
139
162
|
itemsCount: displayItems.length,
|
|
140
163
|
onSelect: index => handleSelect(displayItems[index]),
|
|
141
164
|
});
|
|
142
|
-
const
|
|
143
|
-
if (!filter) {
|
|
144
|
-
setFilteredItems([]);
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
165
|
+
const fetchOptionsCore = useCallback(async (filter, offset) => {
|
|
147
166
|
const requestKey = `${filter}:${offset}`;
|
|
148
167
|
currentRequest.current = requestKey;
|
|
149
168
|
if (offset === 0) {
|
|
@@ -153,26 +172,51 @@ function Autocomplete(props) {
|
|
|
153
172
|
setIsLoadingMore(true);
|
|
154
173
|
}
|
|
155
174
|
try {
|
|
156
|
-
const
|
|
175
|
+
const result = await getOptions(filter, offset);
|
|
176
|
+
const newOptions = result.items;
|
|
177
|
+
const total = result.total;
|
|
157
178
|
if (!isMounted.current)
|
|
158
179
|
return;
|
|
159
180
|
if (currentRequest.current !== requestKey)
|
|
160
181
|
return;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
182
|
+
const newTotal = getTotalCount(total, newOptions.length, offset + newOptions.length, pageSize);
|
|
183
|
+
if (filter) {
|
|
184
|
+
if (offset === 0) {
|
|
185
|
+
setFilteredItems(newOptions);
|
|
186
|
+
setScrollTop(0); // Reset scroll when new filter results load
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
setFilteredItems(prev => [...prev, ...newOptions]);
|
|
190
|
+
}
|
|
191
|
+
setCurrentOffset(offset + newOptions.length);
|
|
192
|
+
setTotalCount(newTotal);
|
|
165
193
|
}
|
|
166
194
|
else {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
195
|
+
if (offset === 0) {
|
|
196
|
+
setItemsWithoutFilter(newOptions);
|
|
197
|
+
setScrollTop(0); // Reset scroll when loading initial items
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
setItemsWithoutFilter(prev => [...prev, ...newOptions]);
|
|
201
|
+
}
|
|
202
|
+
setCurrentOffset(offset + newOptions.length);
|
|
203
|
+
setTotalCount(newTotal);
|
|
204
|
+
}
|
|
205
|
+
// Clear scrollTop after reset to allow normal scrolling
|
|
206
|
+
if (offset === 0) {
|
|
207
|
+
requestAnimationFrame(() => {
|
|
208
|
+
setScrollTop(undefined);
|
|
209
|
+
});
|
|
171
210
|
}
|
|
172
211
|
}
|
|
173
212
|
catch (error) {
|
|
174
213
|
if (offset === 0) {
|
|
175
|
-
|
|
214
|
+
if (filter) {
|
|
215
|
+
setFilteredItems([]);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
setItemsWithoutFilter(items ?? []);
|
|
219
|
+
}
|
|
176
220
|
setCurrentOffset(0);
|
|
177
221
|
setTotalCount(0);
|
|
178
222
|
}
|
|
@@ -181,10 +225,21 @@ function Autocomplete(props) {
|
|
|
181
225
|
setIsLoading(false);
|
|
182
226
|
setIsLoadingMore(false);
|
|
183
227
|
}
|
|
184
|
-
},
|
|
228
|
+
}, [getOptions, isMounted, pageSize, items]);
|
|
229
|
+
const fetchOptions = useMemo(() => debounce(fetchOptionsCore, debounceDelay), [fetchOptionsCore, debounceDelay]);
|
|
185
230
|
const handleScrollEnd = useCallback(() => {
|
|
186
|
-
if (
|
|
187
|
-
|
|
231
|
+
if (!hasMore || isLoading || isLoadingMore)
|
|
232
|
+
return;
|
|
233
|
+
const filter = currentFilter;
|
|
234
|
+
const offset = currentOffset;
|
|
235
|
+
if (offset > 0) {
|
|
236
|
+
setIsLoadingMore(true);
|
|
237
|
+
requestAnimationFrame(() => {
|
|
238
|
+
fetchOptionsCore(filter, offset);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
fetchOptionsCore(filter, offset);
|
|
188
243
|
}
|
|
189
244
|
}, [
|
|
190
245
|
currentFilter,
|
|
@@ -192,7 +247,7 @@ function Autocomplete(props) {
|
|
|
192
247
|
isLoading,
|
|
193
248
|
isLoadingMore,
|
|
194
249
|
currentOffset,
|
|
195
|
-
|
|
250
|
+
fetchOptionsCore,
|
|
196
251
|
]);
|
|
197
252
|
useEffect(() => {
|
|
198
253
|
if (typeof value !== 'string')
|
|
@@ -201,15 +256,36 @@ function Autocomplete(props) {
|
|
|
201
256
|
if (!value) {
|
|
202
257
|
setCurrentFilter('');
|
|
203
258
|
setFilteredItems([]);
|
|
259
|
+
setItemsWithoutFilter(items ?? []);
|
|
204
260
|
setCurrentOffset(0);
|
|
205
261
|
setTotalCount(0);
|
|
262
|
+
setScrollTop(0); // Reset scroll when value is cleared
|
|
206
263
|
}
|
|
207
264
|
else if (isFocusedRef.current) {
|
|
208
265
|
setCurrentFilter(value);
|
|
209
266
|
setCurrentOffset(0);
|
|
267
|
+
setScrollTop(0); // Reset scroll when filter changes
|
|
210
268
|
fetchOptions(value, 0);
|
|
211
269
|
}
|
|
212
270
|
}, [value]);
|
|
271
|
+
useEffect(() => {
|
|
272
|
+
if (!currentFilter && items?.length) {
|
|
273
|
+
setItemsWithoutFilter(items);
|
|
274
|
+
}
|
|
275
|
+
}, [currentFilter, items]);
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
const open = isOpen ?? isFocused;
|
|
278
|
+
if (open && !currentFilter && items?.length && totalCount === 0) {
|
|
279
|
+
fetchOptionsCore('', 0);
|
|
280
|
+
}
|
|
281
|
+
}, [
|
|
282
|
+
isOpen,
|
|
283
|
+
isFocused,
|
|
284
|
+
currentFilter,
|
|
285
|
+
items?.length,
|
|
286
|
+
totalCount,
|
|
287
|
+
fetchOptionsCore,
|
|
288
|
+
]);
|
|
213
289
|
const renderItem = useCallback((itemProps) => {
|
|
214
290
|
const option = displayItems[itemProps.key];
|
|
215
291
|
if (!option)
|
|
@@ -220,36 +296,40 @@ function Autocomplete(props) {
|
|
|
220
296
|
className: cn(S.option, itemProps.className),
|
|
221
297
|
style: itemProps.style,
|
|
222
298
|
focused: focusedIndex === itemProps.key,
|
|
299
|
+
isSelected: selectable && option.id === selectedId,
|
|
223
300
|
onClick: () => handleSelect(option),
|
|
224
301
|
onMouseEnter: () => setFocusedIndex(itemProps.key),
|
|
225
302
|
};
|
|
226
303
|
if (props.renderItem) {
|
|
227
304
|
return props.renderItem(itemPropsForRender);
|
|
228
305
|
}
|
|
229
|
-
return (jsx(Menu.Item, { ...itemProps, focused: itemPropsForRender.focused, className: itemPropsForRender.className, onClick: itemPropsForRender.onClick, onMouseEnter: itemPropsForRender.onMouseEnter, style: itemPropsForRender.style, children: option.render ? option.render(option) : option.label }));
|
|
306
|
+
return (jsx(Menu.Item, { ...itemProps, focused: itemPropsForRender.focused, selected: itemPropsForRender.isSelected, className: itemPropsForRender.className, onClick: itemPropsForRender.onClick, onMouseEnter: itemPropsForRender.onMouseEnter, style: itemPropsForRender.style, children: option.render ? option.render(option) : option.label }));
|
|
230
307
|
}, [
|
|
231
308
|
displayItems,
|
|
232
309
|
focusedIndex,
|
|
310
|
+
selectedId,
|
|
311
|
+
selectable,
|
|
233
312
|
handleSelect,
|
|
234
313
|
setFocusedIndex,
|
|
235
314
|
props.renderItem,
|
|
236
315
|
]);
|
|
316
|
+
const LoadingPlaceholder = loadingPlaceholder ?? (jsxs("div", { className: S.loadingPlaceholder, children: [isLoadingMore && jsx(Shimmer, { size: size, round: round }), "Loading..."] }));
|
|
237
317
|
const optionsList = useMemo(() => {
|
|
238
|
-
if (!displayItems.length)
|
|
239
|
-
return null;
|
|
240
|
-
|
|
241
|
-
|
|
318
|
+
if (!displayItems.length) {
|
|
319
|
+
return !selectable && isLoading ? LoadingPlaceholder : null;
|
|
320
|
+
}
|
|
321
|
+
const computedTotalCount = totalCount > 0 ? totalCount : displayItems.length;
|
|
322
|
+
return (jsx(ListScroll, { ...(selectable && { id: selectedId ?? 'none' }), className: cn(S.options, menuProps.className), scrollProps: {
|
|
242
323
|
y: true,
|
|
243
324
|
...scrollProps,
|
|
244
325
|
className: cn(S.scroll, scrollProps?.className),
|
|
245
|
-
}, itemHeight: itemHeight, itemsCount: displayItems.length, totalCount: computedTotalCount, overlapCount: 10, pageSize: pageSize, onScrollEnd: handleScrollEnd, renderItem: renderItem, contentAfter: hasMore &&
|
|
246
|
-
isLoadingMore && (jsx("div", { style: { padding: '8px 12px', textAlign: 'center' }, children: jsx(Shimmer, { size: size, round: round }) })) }));
|
|
326
|
+
}, itemHeight: itemHeight, itemsCount: displayItems.length, totalCount: computedTotalCount, overlapCount: 10, pageSize: pageSize, scrollTop: scrollTop, onScrollEnd: handleScrollEnd, renderItem: renderItem, contentAfter: hasMore && LoadingPlaceholder }));
|
|
247
327
|
}, [
|
|
248
328
|
displayItems,
|
|
249
329
|
focusedIndex,
|
|
250
|
-
currentFilter,
|
|
251
330
|
totalCount,
|
|
252
331
|
hasMore,
|
|
332
|
+
isLoading,
|
|
253
333
|
isLoadingMore,
|
|
254
334
|
itemHeight,
|
|
255
335
|
pageSize,
|
|
@@ -258,10 +338,15 @@ function Autocomplete(props) {
|
|
|
258
338
|
size,
|
|
259
339
|
round,
|
|
260
340
|
menuProps.className,
|
|
341
|
+
scrollProps,
|
|
342
|
+
scrollTop,
|
|
343
|
+
selectable,
|
|
344
|
+
selectedId,
|
|
345
|
+
LoadingPlaceholder,
|
|
261
346
|
]);
|
|
262
|
-
return (jsx(Popup, { className: classes, isOpen: isOpen, focusControl: true, round: round, size: size, blur: blur, direction: "bottom", ...popupProps, trigger:
|
|
263
|
-
|
|
264
|
-
|
|
347
|
+
return (jsx(Popup, { className: classes, isOpen: isOpen, focusControl: true, round: round, size: size, blur: blur, direction: "bottom", ...popupProps, trigger: jsx(Input, { ref: inputRef,
|
|
348
|
+
// @ts-ignore
|
|
349
|
+
size: size, round: round, ...inputProps, value: searchValue, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, className: inputProps.className }), content: optionsList, contentProps: {
|
|
265
350
|
...popupProps?.contentProps,
|
|
266
351
|
className: cn(S.popupContent, popupProps?.contentProps?.className),
|
|
267
352
|
} }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".Autocomplete_root__86RQs{position:relative}.Autocomplete_popupContent__Aet6P{margin-top:8px;width:100%}.Autocomplete_scroll__bFG6f{height:200px}.Autocomplete_options__NtttU{max-height:200px;overflow-y:auto}.Autocomplete_option__uBuih{cursor:pointer;padding:8px 12px;position:absolute}.Autocomplete_option__uBuih>span{align-items:center;display:flex}.Autocomplete_shimmer__s6rri{height:100%;left:0;position:absolute;top:0;width:100%}";
|
|
4
|
-
var S = {"root":"Autocomplete_root__86RQs","popupContent":"Autocomplete_popupContent__Aet6P","scroll":"Autocomplete_scroll__bFG6f","options":"Autocomplete_options__NtttU","option":"Autocomplete_option__uBuih","shimmer":"Autocomplete_shimmer__s6rri"};
|
|
3
|
+
var css_248z = ".Autocomplete_root__86RQs{position:relative}.Autocomplete_popupContent__Aet6P{margin-top:8px;width:100%}.Autocomplete_scroll__bFG6f{height:200px}.Autocomplete_options__NtttU{max-height:200px;overflow-y:auto}.Autocomplete_option__uBuih{cursor:pointer;padding:8px 12px;position:absolute}.Autocomplete_option__uBuih>span{align-items:center;display:flex}.Autocomplete_loadingPlaceholder__Dn0dT{padding:8px 12px;text-align:center}.Autocomplete_shimmer__s6rri{height:100%;left:0;position:absolute;top:0;width:100%}";
|
|
4
|
+
var S = {"root":"Autocomplete_root__86RQs","popupContent":"Autocomplete_popupContent__Aet6P","scroll":"Autocomplete_scroll__bFG6f","options":"Autocomplete_options__NtttU","option":"Autocomplete_option__uBuih","loadingPlaceholder":"Autocomplete_loadingPlaceholder__Dn0dT","shimmer":"Autocomplete_shimmer__s6rri"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { S as default };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useCallback } from 'react';
|
|
2
3
|
import cn from 'classnames';
|
|
3
4
|
import { strToDate } from '../../tools/date.js';
|
|
4
5
|
import { DateTime } from '../DateTime/DateTime.js';
|
|
@@ -8,13 +9,36 @@ import { Popup } from '../Popup/Popup.js';
|
|
|
8
9
|
import S from './DatePickerInput.styl.js';
|
|
9
10
|
|
|
10
11
|
function DatePickerInput(props) {
|
|
11
|
-
const { value, variant = 'default', size = 'm', popupProps, buttonProps, displayFormat = 'MMM Do YYYY', } = props;
|
|
12
|
+
const { value, onChange, variant = 'default', size = 'm', popupProps, buttonProps, displayFormat = 'MMM Do YYYY', } = props;
|
|
12
13
|
const isRange = Array.isArray(value);
|
|
13
|
-
|
|
14
|
+
const isControlled = popupProps?.isOpen !== undefined;
|
|
15
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
16
|
+
const handleChange = useCallback((newValue) => {
|
|
17
|
+
onChange(newValue);
|
|
18
|
+
if (!isRange) {
|
|
19
|
+
if (!isControlled) {
|
|
20
|
+
setIsOpen(false);
|
|
21
|
+
}
|
|
22
|
+
popupProps?.onClose?.();
|
|
23
|
+
}
|
|
24
|
+
}, [onChange, isRange, isControlled, popupProps]);
|
|
25
|
+
const handleClose = useCallback(() => {
|
|
26
|
+
if (!isControlled) {
|
|
27
|
+
setIsOpen(false);
|
|
28
|
+
}
|
|
29
|
+
popupProps?.onClose?.();
|
|
30
|
+
}, [popupProps, isControlled]);
|
|
31
|
+
const handleOpen = useCallback(() => {
|
|
32
|
+
if (!isControlled) {
|
|
33
|
+
setIsOpen(true);
|
|
34
|
+
}
|
|
35
|
+
popupProps?.onOpen?.();
|
|
36
|
+
}, [popupProps, isControlled]);
|
|
37
|
+
return (jsx(Popup, { size: size, focusControl: true, direction: "bottom-right", isOpen: isControlled ? popupProps.isOpen : isOpen, onOpen: isControlled ? popupProps.onOpen : handleOpen, onClose: isControlled ? popupProps.onClose : handleClose, ...popupProps, trigger:
|
|
14
38
|
// @ts-ignore
|
|
15
39
|
jsx(Button, { variant: variant, size: size, ...buttonProps, children: isRange ? (jsxs(Fragment, { children: [jsx(DateTime, { value: strToDate(value[0]), format: displayFormat }), ' - ', jsx(DateTime, { value: strToDate(value[1]), format: displayFormat })] })) : (jsx(DateTime, { value: strToDate(value), format: displayFormat })) }), contentProps: {
|
|
16
40
|
className: cn(S.popupContent, props.doubleCalendar && S.doubleCalendar, S[`size-${size}`], popupProps?.contentProps?.className),
|
|
17
|
-
}, content: jsx(DatePicker, { ...props, className: S.content, calendarProps: { className: S.calendar } }) }));
|
|
41
|
+
}, content: jsx(DatePicker, { ...props, onChange: handleChange, className: S.content, calendarProps: { className: S.calendar } }) }));
|
|
18
42
|
}
|
|
19
43
|
|
|
20
44
|
export { DatePickerInput };
|
|
@@ -2,6 +2,6 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import S from './Shimmer.styl.js';
|
|
3
3
|
import cn from 'classnames';
|
|
4
4
|
|
|
5
|
-
const Shimmer = ({ className, size = 'm', round = false, }) => (jsx("div", { className: cn(S.root, className, S[`size-${size}`], round && S.round), children: jsx("div", { className: S.inner }) }));
|
|
5
|
+
const Shimmer = ({ className, size = 'm', round = false, children, }) => (jsx("div", { className: cn(S.root, className, S[`size-${size}`], round && S.round), children: jsx("div", { className: S.inner, children: children }) }));
|
|
6
6
|
|
|
7
7
|
export { Shimmer };
|
|
@@ -148,8 +148,9 @@ class Virtualized extends Component {
|
|
|
148
148
|
const { itemsCount, totalCount, pageSize, onScrollEnd } = this.props;
|
|
149
149
|
if (itemsCount === totalCount)
|
|
150
150
|
return;
|
|
151
|
-
if (itemsCount < this.lastScrollEndIndex)
|
|
152
|
-
|
|
151
|
+
if (itemsCount < this.lastScrollEndIndex) {
|
|
152
|
+
this.lastScrollEndIndex = 0; // Reset when list shrinks (e.g. filter cleared)
|
|
153
|
+
}
|
|
153
154
|
this.lastScrollEndIndex = Math.min(itemsCount + pageSize, totalCount);
|
|
154
155
|
onScrollEnd?.();
|
|
155
156
|
};
|
|
@@ -15,8 +15,11 @@ export type Props = FormControl<Value, HTMLInputElement> & {
|
|
|
15
15
|
size?: Size;
|
|
16
16
|
value: Value;
|
|
17
17
|
isOpen?: boolean;
|
|
18
|
-
getOptions: (filter: string, offset: number) => Promise<
|
|
19
|
-
|
|
18
|
+
getOptions: (filter: string, offset: number) => Promise<{
|
|
19
|
+
items: Option[];
|
|
20
|
+
total?: number;
|
|
21
|
+
}>;
|
|
22
|
+
onSelect?: (option: Option) => void;
|
|
20
23
|
items?: Option[];
|
|
21
24
|
itemHeight?: number;
|
|
22
25
|
pageSize?: number;
|
|
@@ -27,7 +30,9 @@ export type Props = FormControl<Value, HTMLInputElement> & {
|
|
|
27
30
|
menuProps?: Partial<MenuProps>;
|
|
28
31
|
round?: boolean;
|
|
29
32
|
blur?: boolean;
|
|
33
|
+
selectable?: boolean;
|
|
30
34
|
renderItem?: (props: RenderItemProps) => React.ReactElement;
|
|
35
|
+
loadingPlaceholder?: React.ReactNode;
|
|
31
36
|
};
|
|
32
37
|
export type RenderItemProps = {
|
|
33
38
|
option: Option;
|
|
@@ -35,6 +40,7 @@ export type RenderItemProps = {
|
|
|
35
40
|
className?: string;
|
|
36
41
|
style?: React.CSSProperties;
|
|
37
42
|
focused: boolean;
|
|
43
|
+
isSelected: boolean;
|
|
38
44
|
onClick: () => void;
|
|
39
45
|
onMouseEnter: () => void;
|
|
40
46
|
};
|
|
@@ -3,5 +3,6 @@ export type ShimmerProps = {
|
|
|
3
3
|
className?: string;
|
|
4
4
|
size?: Size;
|
|
5
5
|
round?: boolean;
|
|
6
|
+
children?: React.ReactNode;
|
|
6
7
|
};
|
|
7
|
-
export declare const Shimmer: ({ className, size, round, }: ShimmerProps) => JSX.Element;
|
|
8
|
+
export declare const Shimmer: ({ className, size, round, children, }: ShimmerProps) => JSX.Element;
|