@homecode/ui 4.30.6 → 4.30.8

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.
@@ -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, useEffect, useMemo } from 'react';
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,26 @@ 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);
89
+ const [selectedLabel, setSelectedLabel] = useState(null);
81
90
  const isFocusedRef = useRef(false);
82
91
  const searchValRef = useRef(value);
83
92
  const [searchValue, _setSearchValue] = useState(value);
@@ -88,8 +97,16 @@ function Autocomplete(props) {
88
97
  const currentRequest = useRef('');
89
98
  // @ts-ignore
90
99
  const inputRef = useRef(null);
91
- const displayItems = currentFilter ? filteredItems : items || [];
92
- const hasMore = currentFilter ? filteredItems.length < totalCount : false;
100
+ const inputDisplayValue = selectable && !isFocused && selectedLabel != null
101
+ ? selectedLabel
102
+ : searchValue;
103
+ const displayItems = currentFilter
104
+ ? filteredItems
105
+ : itemsWithoutFilter.length
106
+ ? itemsWithoutFilter
107
+ : (items ?? []);
108
+ const displayCount = displayItems.length;
109
+ const hasMore = totalCount > 0 && displayCount < totalCount;
93
110
  const classes = cn(S.root, className, popupProps.className);
94
111
  const handleFocus = (e) => {
95
112
  isFocusedRef.current = true;
@@ -108,30 +125,41 @@ function Autocomplete(props) {
108
125
  if (!val) {
109
126
  setCurrentFilter('');
110
127
  setFilteredItems([]);
128
+ setItemsWithoutFilter(items ?? []);
111
129
  setCurrentOffset(0);
112
130
  setTotalCount(0);
131
+ setScrollTop(0); // Reset scroll when filter is cleared
113
132
  }
114
133
  else {
115
134
  setCurrentFilter(val);
116
135
  setCurrentOffset(0);
136
+ setScrollTop(0); // Reset scroll when filter changes
117
137
  fetchOptions(val, 0);
118
138
  }
119
139
  return true;
120
140
  };
121
141
  const handleSelect = (option) => {
142
+ if (selectable) {
143
+ setSelectedId(option.id);
144
+ setSelectedLabel(option.label);
145
+ onSelect?.(option);
146
+ return;
147
+ }
122
148
  setSearchValue(option.label);
123
- setCurrentFilter('');
149
+ setCurrentFilter(option.label);
124
150
  setFilteredItems([]);
125
151
  setCurrentOffset(0);
126
152
  setTotalCount(0);
127
- onSelect(option);
153
+ setScrollTop(0);
154
+ fetchOptionsCore(option.label, 0);
155
+ onSelect?.(option);
128
156
  // set input caret to the end
129
157
  requestAnimationFrame(() => {
130
158
  const input = inputRef.current;
131
159
  if (!input)
132
160
  return;
133
161
  input.focus();
134
- input.setSelectionRange(value.length, value.length);
162
+ input.setSelectionRange(option.label.length, option.label.length);
135
163
  });
136
164
  };
137
165
  const { focusedIndex, setFocusedIndex } = useListKeyboardControl({
@@ -139,11 +167,7 @@ function Autocomplete(props) {
139
167
  itemsCount: displayItems.length,
140
168
  onSelect: index => handleSelect(displayItems[index]),
141
169
  });
142
- const fetchOptions = debounce(async (filter, offset) => {
143
- if (!filter) {
144
- setFilteredItems([]);
145
- return;
146
- }
170
+ const fetchOptionsCore = useCallback(async (filter, offset) => {
147
171
  const requestKey = `${filter}:${offset}`;
148
172
  currentRequest.current = requestKey;
149
173
  if (offset === 0) {
@@ -153,26 +177,51 @@ function Autocomplete(props) {
153
177
  setIsLoadingMore(true);
154
178
  }
155
179
  try {
156
- const newOptions = await getOptions(filter, offset);
180
+ const result = await getOptions(filter, offset);
181
+ const newOptions = result.items;
182
+ const total = result.total;
157
183
  if (!isMounted.current)
158
184
  return;
159
185
  if (currentRequest.current !== requestKey)
160
186
  return;
161
- if (offset === 0) {
162
- setFilteredItems(newOptions);
163
- setCurrentOffset(newOptions.length);
164
- setTotalCount(newOptions.length + (newOptions.length === pageSize ? 1 : 0));
187
+ const newTotal = getTotalCount(total, newOptions.length, offset + newOptions.length, pageSize);
188
+ if (filter) {
189
+ if (offset === 0) {
190
+ setFilteredItems(newOptions);
191
+ setScrollTop(0); // Reset scroll when new filter results load
192
+ }
193
+ else {
194
+ setFilteredItems(prev => [...prev, ...newOptions]);
195
+ }
196
+ setCurrentOffset(offset + newOptions.length);
197
+ setTotalCount(newTotal);
165
198
  }
166
199
  else {
167
- setFilteredItems(prev => [...prev, ...newOptions]);
168
- const newOffset = offset + newOptions.length;
169
- setCurrentOffset(newOffset);
170
- setTotalCount(newOffset + (newOptions.length === pageSize ? 1 : 0));
200
+ if (offset === 0) {
201
+ setItemsWithoutFilter(newOptions);
202
+ setScrollTop(0); // Reset scroll when loading initial items
203
+ }
204
+ else {
205
+ setItemsWithoutFilter(prev => [...prev, ...newOptions]);
206
+ }
207
+ setCurrentOffset(offset + newOptions.length);
208
+ setTotalCount(newTotal);
209
+ }
210
+ // Clear scrollTop after reset to allow normal scrolling
211
+ if (offset === 0) {
212
+ requestAnimationFrame(() => {
213
+ setScrollTop(undefined);
214
+ });
171
215
  }
172
216
  }
173
217
  catch (error) {
174
218
  if (offset === 0) {
175
- setFilteredItems([]);
219
+ if (filter) {
220
+ setFilteredItems([]);
221
+ }
222
+ else {
223
+ setItemsWithoutFilter(items ?? []);
224
+ }
176
225
  setCurrentOffset(0);
177
226
  setTotalCount(0);
178
227
  }
@@ -181,10 +230,21 @@ function Autocomplete(props) {
181
230
  setIsLoading(false);
182
231
  setIsLoadingMore(false);
183
232
  }
184
- }, debounceDelay);
233
+ }, [getOptions, isMounted, pageSize, items]);
234
+ const fetchOptions = useMemo(() => debounce(fetchOptionsCore, debounceDelay), [fetchOptionsCore, debounceDelay]);
185
235
  const handleScrollEnd = useCallback(() => {
186
- if (currentFilter && hasMore && !isLoading && !isLoadingMore) {
187
- fetchOptions(currentFilter, currentOffset);
236
+ if (!hasMore || isLoading || isLoadingMore)
237
+ return;
238
+ const filter = currentFilter;
239
+ const offset = currentOffset;
240
+ if (offset > 0) {
241
+ setIsLoadingMore(true);
242
+ requestAnimationFrame(() => {
243
+ fetchOptionsCore(filter, offset);
244
+ });
245
+ }
246
+ else {
247
+ fetchOptionsCore(filter, offset);
188
248
  }
189
249
  }, [
190
250
  currentFilter,
@@ -192,7 +252,7 @@ function Autocomplete(props) {
192
252
  isLoading,
193
253
  isLoadingMore,
194
254
  currentOffset,
195
- fetchOptions,
255
+ fetchOptionsCore,
196
256
  ]);
197
257
  useEffect(() => {
198
258
  if (typeof value !== 'string')
@@ -201,15 +261,42 @@ function Autocomplete(props) {
201
261
  if (!value) {
202
262
  setCurrentFilter('');
203
263
  setFilteredItems([]);
264
+ setItemsWithoutFilter(items ?? []);
204
265
  setCurrentOffset(0);
205
266
  setTotalCount(0);
267
+ setScrollTop(0); // Reset scroll when value is cleared
206
268
  }
207
269
  else if (isFocusedRef.current) {
208
270
  setCurrentFilter(value);
209
271
  setCurrentOffset(0);
272
+ setScrollTop(0); // Reset scroll when filter changes
210
273
  fetchOptions(value, 0);
211
274
  }
212
275
  }, [value]);
276
+ useEffect(() => {
277
+ if (selectable && !value) {
278
+ setSelectedId(null);
279
+ setSelectedLabel(null);
280
+ }
281
+ }, [selectable, value]);
282
+ useEffect(() => {
283
+ if (!currentFilter && items?.length) {
284
+ setItemsWithoutFilter(items);
285
+ }
286
+ }, [currentFilter, items]);
287
+ useEffect(() => {
288
+ const open = isOpen ?? isFocused;
289
+ if (open && !currentFilter && items?.length && totalCount === 0) {
290
+ fetchOptionsCore('', 0);
291
+ }
292
+ }, [
293
+ isOpen,
294
+ isFocused,
295
+ currentFilter,
296
+ items?.length,
297
+ totalCount,
298
+ fetchOptionsCore,
299
+ ]);
213
300
  const renderItem = useCallback((itemProps) => {
214
301
  const option = displayItems[itemProps.key];
215
302
  if (!option)
@@ -220,36 +307,40 @@ function Autocomplete(props) {
220
307
  className: cn(S.option, itemProps.className),
221
308
  style: itemProps.style,
222
309
  focused: focusedIndex === itemProps.key,
310
+ isSelected: selectable && option.id === selectedId,
223
311
  onClick: () => handleSelect(option),
224
312
  onMouseEnter: () => setFocusedIndex(itemProps.key),
225
313
  };
226
314
  if (props.renderItem) {
227
315
  return props.renderItem(itemPropsForRender);
228
316
  }
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 }));
317
+ 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
318
  }, [
231
319
  displayItems,
232
320
  focusedIndex,
321
+ selectedId,
322
+ selectable,
233
323
  handleSelect,
234
324
  setFocusedIndex,
235
325
  props.renderItem,
236
326
  ]);
327
+ const LoadingPlaceholder = loadingPlaceholder ?? (jsxs("div", { className: S.loadingPlaceholder, children: [isLoadingMore && jsx(Shimmer, { size: size, round: round }), "Loading..."] }));
237
328
  const optionsList = useMemo(() => {
238
- if (!displayItems.length)
239
- return null;
240
- const computedTotalCount = currentFilter ? totalCount : displayItems.length;
241
- return (jsx(ListScroll, { className: cn(S.options, menuProps.className), scrollProps: {
329
+ if (!displayItems.length) {
330
+ return !selectable && isLoading ? LoadingPlaceholder : null;
331
+ }
332
+ const computedTotalCount = totalCount > 0 ? totalCount : displayItems.length;
333
+ return (jsx(ListScroll, { ...(selectable && { id: selectedId ?? 'none' }), className: cn(S.options, menuProps.className), scrollProps: {
242
334
  y: true,
243
335
  ...scrollProps,
244
336
  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 }) })) }));
337
+ }, itemHeight: itemHeight, itemsCount: displayItems.length, totalCount: computedTotalCount, overlapCount: 10, pageSize: pageSize, scrollTop: scrollTop, onScrollEnd: handleScrollEnd, renderItem: renderItem, contentAfter: hasMore && LoadingPlaceholder }));
247
338
  }, [
248
339
  displayItems,
249
340
  focusedIndex,
250
- currentFilter,
251
341
  totalCount,
252
342
  hasMore,
343
+ isLoading,
253
344
  isLoadingMore,
254
345
  itemHeight,
255
346
  pageSize,
@@ -258,10 +349,15 @@ function Autocomplete(props) {
258
349
  size,
259
350
  round,
260
351
  menuProps.className,
352
+ scrollProps,
353
+ scrollTop,
354
+ selectable,
355
+ selectedId,
356
+ LoadingPlaceholder,
261
357
  ]);
262
- return (jsx(Popup, { className: classes, isOpen: isOpen, focusControl: true, round: round, size: size, blur: blur, direction: "bottom", ...popupProps, trigger: jsxs("div", { className: inputWrapperClassName, children: [jsx(Input, { ref: inputRef,
263
- // @ts-ignore
264
- size: size, round: round, ...inputProps, value: searchValue, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, className: inputProps.className }), isLoading && (jsx(Shimmer, { className: S.shimmer, size: size, round: round }))] }), content: optionsList, contentProps: {
358
+ return (jsx(Popup, { className: classes, isOpen: isOpen, focusControl: true, round: round, size: size, blur: blur, direction: "bottom", ...popupProps, trigger: jsx(Input, { ref: inputRef,
359
+ // @ts-ignore
360
+ size: size, round: round, ...inputProps, value: inputDisplayValue, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, className: cn(inputProps.className, selectable && !isFocused && S.inputSelectableDisplay) }), content: optionsList, contentProps: {
265
361
  ...popupProps?.contentProps,
266
362
  className: cn(S.popupContent, popupProps?.contentProps?.className),
267
363
  } }));
@@ -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_inputSelectableDisplay__rgFwu{overflow:hidden;text-overflow:ellipsis}.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","inputSelectableDisplay":"Autocomplete_inputSelectableDisplay__rgFwu","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
- return (jsx(Popup, { size: size, focusControl: true, direction: "bottom-right", ...popupProps, trigger:
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
- return;
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<Option[]>;
19
- onSelect: (option: Option) => void;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homecode/ui",
3
- "version": "4.30.6",
3
+ "version": "4.30.8",
4
4
  "description": "React UI components library",
5
5
  "scripts": {
6
6
  "tests": "jest",