@rio-cloud/rio-uikit 1.8.0 → 1.9.1
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/.DS_Store +0 -0
- package/BarList.d.ts +2 -0
- package/BarList.js +2 -0
- package/SaveableDateInput.d.ts +2 -0
- package/SaveableDateInput.js +2 -0
- package/components/activity/Activity.d.ts +2 -2
- package/components/assetTree/Tree.d.ts +12 -0
- package/components/assetTree/Tree.js +72 -37
- package/components/assetTree/TreeNodeContainer.d.ts +1 -1
- package/components/assetTree/useTreeExpansion.d.ts +4 -0
- package/components/assetTree/useTreeExpansion.js +25 -0
- package/components/assetTree/useTreeHeight.d.ts +1 -0
- package/components/assetTree/useTreeHeight.js +60 -0
- package/components/assetTree/useTreeScrollPosition.d.ts +3 -0
- package/components/assetTree/useTreeScrollPosition.js +19 -0
- package/components/assetTree/useTreeVirtualization.d.ts +17 -0
- package/components/assetTree/useTreeVirtualization.js +71 -0
- package/components/barList/BarList.d.ts +97 -0
- package/components/barList/BarList.js +42 -0
- package/components/barList/useSortedBars.d.ts +2 -0
- package/components/barList/useSortedBars.js +14 -0
- package/components/charts/PieChart.js +1 -1
- package/components/clearableInput/ClearableInput.js +1 -1
- package/components/formLabel/FormLabel.d.ts +2 -2
- package/components/listMenu/ListMenu.js +3 -1
- package/components/map/components/Map.js +20 -5
- package/components/map/components/constants.d.ts +2 -0
- package/components/map/components/constants.js +3 -0
- package/components/map/utils/mapTypes.d.ts +5 -0
- package/components/map/utils/rendering.d.ts +5 -2
- package/components/map/utils/rendering.js +46 -39
- package/components/overlay/OverlayTrigger.js +2 -2
- package/components/saveableInput/SaveableDateInput.d.ts +83 -0
- package/components/saveableInput/SaveableDateInput.js +122 -0
- package/components/smoothScrollbars/SmoothScrollbars.d.ts +1 -0
- package/components/smoothScrollbars/SmoothScrollbars.js +2 -2
- package/components/statsWidget/StatsWidget.d.ts +2 -2
- package/components/statsWidget/StatsWidgets.d.ts +2 -2
- package/components/svgImage/SvgImage.d.ts +1 -1
- package/components/svgImage/SvgImage.js +1 -1
- package/components/table/TableCol.d.ts +1 -1
- package/components/table/TableCol.js +2 -2
- package/components/table/TableHead.js +2 -2
- package/components/tooltip/SimpleTooltip.d.ts +1 -1
- package/hooks/useIsFocusWithin.d.ts +33 -0
- package/hooks/useIsFocusWithin.js +55 -0
- package/hooks/useTableExport.d.ts +49 -0
- package/hooks/useTableExport.js +57 -0
- package/hooks/useTableSelection.d.ts +15 -0
- package/hooks/useTableSelection.js +6 -1
- package/lib/es/BarList.d.ts +2 -0
- package/lib/es/BarList.js +7 -0
- package/lib/es/SaveableDateInput.d.ts +2 -0
- package/lib/es/SaveableDateInput.js +7 -0
- package/lib/es/components/activity/Activity.d.ts +2 -2
- package/lib/es/components/assetTree/Tree.d.ts +12 -0
- package/lib/es/components/assetTree/Tree.js +71 -36
- package/lib/es/components/assetTree/TreeNodeContainer.d.ts +1 -1
- package/lib/es/components/assetTree/useTreeExpansion.d.ts +4 -0
- package/lib/es/components/assetTree/useTreeExpansion.js +29 -0
- package/lib/es/components/assetTree/useTreeHeight.d.ts +1 -0
- package/lib/es/components/assetTree/useTreeHeight.js +64 -0
- package/lib/es/components/assetTree/useTreeScrollPosition.d.ts +3 -0
- package/lib/es/components/assetTree/useTreeScrollPosition.js +23 -0
- package/lib/es/components/assetTree/useTreeVirtualization.d.ts +17 -0
- package/lib/es/components/assetTree/useTreeVirtualization.js +76 -0
- package/lib/es/components/barList/BarList.d.ts +97 -0
- package/lib/es/components/barList/BarList.js +45 -0
- package/lib/es/components/barList/useSortedBars.d.ts +2 -0
- package/lib/es/components/barList/useSortedBars.js +17 -0
- package/lib/es/components/charts/PieChart.js +1 -1
- package/lib/es/components/clearableInput/ClearableInput.js +1 -1
- package/lib/es/components/formLabel/FormLabel.d.ts +2 -2
- package/lib/es/components/listMenu/ListMenu.js +3 -1
- package/lib/es/components/map/components/Map.js +19 -4
- package/lib/es/components/map/components/constants.d.ts +2 -0
- package/lib/es/components/map/components/constants.js +4 -1
- package/lib/es/components/map/utils/mapTypes.d.ts +5 -0
- package/lib/es/components/map/utils/rendering.d.ts +5 -2
- package/lib/es/components/map/utils/rendering.js +46 -39
- package/lib/es/components/overlay/OverlayTrigger.js +2 -2
- package/lib/es/components/saveableInput/SaveableDateInput.d.ts +83 -0
- package/lib/es/components/saveableInput/SaveableDateInput.js +125 -0
- package/lib/es/components/smoothScrollbars/SmoothScrollbars.d.ts +1 -0
- package/lib/es/components/smoothScrollbars/SmoothScrollbars.js +2 -2
- package/lib/es/components/statsWidget/StatsWidget.d.ts +2 -2
- package/lib/es/components/statsWidget/StatsWidgets.d.ts +2 -2
- package/lib/es/components/svgImage/SvgImage.d.ts +1 -1
- package/lib/es/components/svgImage/SvgImage.js +1 -3
- package/lib/es/components/table/TableCol.d.ts +1 -1
- package/lib/es/components/table/TableCol.js +2 -2
- package/lib/es/components/table/TableHead.js +2 -2
- package/lib/es/components/tooltip/SimpleTooltip.d.ts +1 -1
- package/lib/es/hooks/useIsFocusWithin.d.ts +33 -0
- package/lib/es/hooks/useIsFocusWithin.js +57 -0
- package/lib/es/hooks/useTableExport.d.ts +49 -0
- package/lib/es/hooks/useTableExport.js +59 -0
- package/lib/es/hooks/useTableSelection.d.ts +15 -0
- package/lib/es/hooks/useTableSelection.js +6 -1
- package/lib/es/useIsFocusWithin.d.ts +2 -0
- package/lib/es/useIsFocusWithin.js +7 -0
- package/lib/es/useTableExport.d.ts +2 -0
- package/lib/es/useTableExport.js +7 -0
- package/lib/es/version.json +1 -1
- package/package.json +8 -7
- package/useIsFocusWithin.d.ts +2 -0
- package/useIsFocusWithin.js +2 -0
- package/useTableExport.d.ts +2 -0
- package/useTableExport.js +2 -0
- package/version.json +1 -1
package/.DS_Store
CHANGED
|
Binary file
|
package/BarList.d.ts
ADDED
package/BarList.js
ADDED
|
@@ -7,13 +7,13 @@ declare const STATUS_MAP: {
|
|
|
7
7
|
readonly RESTING: "resting";
|
|
8
8
|
readonly WORKING: "working";
|
|
9
9
|
};
|
|
10
|
-
type ActivityStatus = ObjectValues<typeof STATUS_MAP>;
|
|
10
|
+
export type ActivityStatus = ObjectValues<typeof STATUS_MAP>;
|
|
11
11
|
declare const SIZE_MAP: {
|
|
12
12
|
readonly SIZE_SM: "sm";
|
|
13
13
|
readonly SIZE_LG: "lg";
|
|
14
14
|
readonly SIZE_XL: "xl";
|
|
15
15
|
};
|
|
16
|
-
type ActivitySize = ObjectValues<typeof SIZE_MAP>;
|
|
16
|
+
export type ActivitySize = ObjectValues<typeof SIZE_MAP>;
|
|
17
17
|
export type ActivityProps = {
|
|
18
18
|
/**
|
|
19
19
|
* Defines the type of activity.
|
|
@@ -200,6 +200,18 @@ export type TreeProps = {
|
|
|
200
200
|
* @default false
|
|
201
201
|
*/
|
|
202
202
|
disableAnimation?: boolean;
|
|
203
|
+
/**
|
|
204
|
+
* The number of items (including groups and children) used for virtualizing the tree.
|
|
205
|
+
*
|
|
206
|
+
* @default 50
|
|
207
|
+
*/
|
|
208
|
+
virtualizeThreshold?: number;
|
|
209
|
+
/**
|
|
210
|
+
* The number of items rendered beyond the visible area of a virtualized tree.
|
|
211
|
+
*
|
|
212
|
+
* @default 5
|
|
213
|
+
*/
|
|
214
|
+
overscan?: number;
|
|
203
215
|
/**
|
|
204
216
|
* Additional classes added to the wrapping element.
|
|
205
217
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/* eslint-disable no-use-before-define */
|
|
3
|
-
import React, { useEffect, useReducer, useRef
|
|
3
|
+
import React, { useCallback, useEffect, useReducer, useRef } from 'react';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
5
|
import isNil from 'lodash/fp/isNil';
|
|
6
6
|
import isEmpty from 'lodash/fp/isEmpty';
|
|
@@ -27,6 +27,11 @@ import TreeRoot from './TreeRoot';
|
|
|
27
27
|
import TypeCounter from './TypeCounter';
|
|
28
28
|
import { containsItemById, debounceFn, filterAssetByType, filterEmptyGroups, filterOutByItemId, getTypeCounts, getFlatItems, getListIds, notEmpty, notEqual, excludeFromList, getMappedItemsToGroups, sortGroupItemsByName, sortGroupsByName, addOrRemoveFromList, } from './treeUtils';
|
|
29
29
|
import { treeReducer, assetCounted, allCheckedChanged, visibleTypeCountersChanged, searchValueChanged, flatItemsChanged, emptyGroupsChanged, groupedItemsChanged, typeFilterChanged, } from './treeReducer';
|
|
30
|
+
import { useTreeVirtualization } from './useTreeVirtualization';
|
|
31
|
+
import { useTreeExpansion } from './useTreeExpansion';
|
|
32
|
+
import { useTreeHeight } from './useTreeHeight';
|
|
33
|
+
import { useTreeScrollPosition } from './useTreeScrollPosition';
|
|
34
|
+
import SmoothScrollbars from '../../SmoothScrollbars';
|
|
30
35
|
export { getTypeCounts, getSubTypeCounts } from './treeUtils';
|
|
31
36
|
const filterProps = omit([
|
|
32
37
|
'expandedGroups',
|
|
@@ -36,8 +41,10 @@ const filterProps = omit([
|
|
|
36
41
|
'treeOptions',
|
|
37
42
|
]);
|
|
38
43
|
const customCompare = (prevProps, nextProps) => isEqual(filterProps(prevProps), filterProps(nextProps));
|
|
44
|
+
const VIRTUALIZED_THRESHOLD = 50;
|
|
45
|
+
const DEFAULT_VIRTUALIZED_OVERSCAN = 5;
|
|
39
46
|
const Tree = React.memo((props) => {
|
|
40
|
-
const { groups = [], items = [], selectedGroups = [], selectedItems = [], onSelectionChange = noop, hasMultiselect = true, showRadioButtons = false, hideSearch = false, hideTreeHead, treeHeaderContent, summary, hideSummary = false, search, searchPlaceholder = 'Type here to filter by name', onSearchChange = noop, className, scrollHeight, expandedGroups, onExpandGroupsChange = noop, showEmptyGroups = true, treeOptions = [], treeOptionsTooltip, disableAnimation = false, onTypeFilterChange = noop, ...remainingProps } = props;
|
|
47
|
+
const { groups = [], items = [], selectedGroups = [], selectedItems = [], onSelectionChange = noop, hasMultiselect = true, showRadioButtons = false, hideSearch = false, hideTreeHead, treeHeaderContent, summary, hideSummary = false, search, searchPlaceholder = 'Type here to filter by name', onSearchChange = noop, className, scrollHeight, expandedGroups, onExpandGroupsChange = noop, showEmptyGroups = true, treeOptions = [], treeOptionsTooltip, disableAnimation = false, onTypeFilterChange = noop, virtualizeThreshold = VIRTUALIZED_THRESHOLD, overscan = DEFAULT_VIRTUALIZED_OVERSCAN, ...remainingProps } = props;
|
|
41
48
|
const [state, dispatch] = useReducer(treeReducer, {
|
|
42
49
|
groupedItems: [],
|
|
43
50
|
flatItems: [],
|
|
@@ -52,7 +59,26 @@ const Tree = React.memo((props) => {
|
|
|
52
59
|
const previousItems = useRef();
|
|
53
60
|
const previousGroups = useRef();
|
|
54
61
|
const previousSearchValue = useRef('');
|
|
55
|
-
const internalExpandedGroups =
|
|
62
|
+
const { internalExpandedGroups, handleToggleNode } = useTreeExpansion(props.expandedGroups, props.onExpandGroupsChange);
|
|
63
|
+
const hasGroups = () => groups && notEmpty(groups);
|
|
64
|
+
const hasInternalSearchValue = () => notEmpty(state.searchValue);
|
|
65
|
+
const hasSearchAndGroups = () => hasInternalSearchValue() && hasGroups();
|
|
66
|
+
const hasNoSearchAndGroups = () => !hasInternalSearchValue() && hasGroups();
|
|
67
|
+
const scrollElementRef = useRef(null);
|
|
68
|
+
const { virtualizedItems, virtualizer } = useTreeVirtualization(state.groupedItems, state.flatItems, hasInternalSearchValue(), hasGroups(), internalExpandedGroups, scrollElementRef, overscan);
|
|
69
|
+
const { scrollToTop } = useTreeScrollPosition(virtualizer, scrollElementRef);
|
|
70
|
+
// Enhance the handleToggleNode function
|
|
71
|
+
const enhancedHandleToggleNode = useCallback((nodeId) => {
|
|
72
|
+
// Execute the original toggle logic
|
|
73
|
+
handleToggleNode(nodeId);
|
|
74
|
+
}, [handleToggleNode]);
|
|
75
|
+
// Create a callback for scroll events that works with the virtualizer
|
|
76
|
+
const handleVirtualizedScroll = useCallback((event) => {
|
|
77
|
+
if (virtualizer && event?.target) {
|
|
78
|
+
const scrollElement = event.target;
|
|
79
|
+
virtualizer.scrollToOffset(scrollElement.scrollTop, { align: 'start' });
|
|
80
|
+
}
|
|
81
|
+
}, [virtualizer]);
|
|
56
82
|
useEffect(() => {
|
|
57
83
|
// Update Tree when items or groups have changed
|
|
58
84
|
if (notEqual(previousItems.current, items) || notEqual(previousGroups.current, groups)) {
|
|
@@ -79,12 +105,6 @@ const Tree = React.memo((props) => {
|
|
|
79
105
|
useEffect(() => makeTree(groups, items), [state.typeFilter]);
|
|
80
106
|
// Update tree when empty groups are toggled from outside
|
|
81
107
|
useEffect(() => makeTree(groups, items), [showEmptyGroups]);
|
|
82
|
-
// Update expanded groups from outside
|
|
83
|
-
const [previousExpandedGroups, setPreviousExpandedGroups] = useState(expandedGroups);
|
|
84
|
-
if (!isEqual(expandedGroups, previousExpandedGroups)) {
|
|
85
|
-
internalExpandedGroups.current = expandedGroups;
|
|
86
|
-
setPreviousExpandedGroups(expandedGroups);
|
|
87
|
-
}
|
|
88
108
|
// Update "select all" state from outside when groups are selected outside programmatically
|
|
89
109
|
// without using the "select all" checkbox
|
|
90
110
|
useEffect(() => {
|
|
@@ -115,28 +135,6 @@ const Tree = React.memo((props) => {
|
|
|
115
135
|
const unselectedItems = updatedItems.filter(filterOutByItemId(updatedSelectedItems));
|
|
116
136
|
return isEmpty(unselectedItems);
|
|
117
137
|
};
|
|
118
|
-
const handleToggleNode = (nodeId) => {
|
|
119
|
-
const nodeContainer = getNodeContainerDomElementById(nodeId);
|
|
120
|
-
if (!internalExpandedGroups?.current || !nodeContainer) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const openGroups = internalExpandedGroups.current;
|
|
124
|
-
const newExpandedNodes = openGroups.includes(nodeId)
|
|
125
|
-
? openGroups.filter(item => item !== nodeId)
|
|
126
|
-
: [...openGroups, nodeId];
|
|
127
|
-
// Performance improvement to skip on render cycle and change "open" class directly
|
|
128
|
-
if (openGroups.includes(nodeId)) {
|
|
129
|
-
nodeContainer.classList.remove('open');
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
nodeContainer.classList.add('open');
|
|
133
|
-
}
|
|
134
|
-
internalExpandedGroups.current = newExpandedNodes;
|
|
135
|
-
onExpandGroupsChange(newExpandedNodes);
|
|
136
|
-
};
|
|
137
|
-
const getNodeContainerDomElementById = (nodeId) => {
|
|
138
|
-
return treeRef?.current?.querySelector(`.TreeNodeContainer[data-id="${nodeId}"]`);
|
|
139
|
-
};
|
|
140
138
|
const selectAllSearchResultItems = (shouldSelect) => selectAllFlatItems(shouldSelect);
|
|
141
139
|
const handleSelectAll = (shouldSelect, isStateIndeterminate) => {
|
|
142
140
|
const shouldSelectAll = shouldSelect && !isStateIndeterminate;
|
|
@@ -178,10 +176,13 @@ const Tree = React.memo((props) => {
|
|
|
178
176
|
const handleSearchChange = (updatedSearchValue) => {
|
|
179
177
|
onSearchChange(updatedSearchValue);
|
|
180
178
|
dispatch(searchValueChanged(updatedSearchValue));
|
|
179
|
+
if (virtualizer) {
|
|
180
|
+
// Every time search changes or is cleared, scroll to the top
|
|
181
|
+
setTimeout(() => {
|
|
182
|
+
scrollToTop();
|
|
183
|
+
}, 10);
|
|
184
|
+
}
|
|
181
185
|
};
|
|
182
|
-
const hasGroups = () => groups && notEmpty(groups);
|
|
183
|
-
const hasSearchAndGroups = () => hasInternalSearchValue() && hasGroups();
|
|
184
|
-
const hasNoSearchAndGroups = () => !hasInternalSearchValue() && hasGroups();
|
|
185
186
|
const setFlatItemList = (updatedItems, searchValue) => {
|
|
186
187
|
const flatItems = getFlatItems(updatedItems, searchValue);
|
|
187
188
|
dispatch(flatItemsChanged(flatItems));
|
|
@@ -218,30 +219,64 @@ const Tree = React.memo((props) => {
|
|
|
218
219
|
[otherwise, setFlatItems],
|
|
219
220
|
])();
|
|
220
221
|
};
|
|
222
|
+
const containerHeight = useTreeHeight(treeRef, scrollHeight);
|
|
223
|
+
const renderVirtualizedTree = () => {
|
|
224
|
+
const items = virtualizer.getVirtualItems();
|
|
225
|
+
const isGroupedList = hasGroups() && !hasInternalSearchValue();
|
|
226
|
+
return (_jsx(SmoothScrollbars, { ref: scrollElementRef, className: 'tree-virtual-scrollbar', onScroll: handleVirtualizedScroll, autoHeight: false, slideIn: true, style: {
|
|
227
|
+
height: `${containerHeight}px`,
|
|
228
|
+
}, children: _jsx("div", { className: isGroupedList ? 'grouped-list' : 'flat-list', style: {
|
|
229
|
+
height: `${virtualizer.getTotalSize()}px`,
|
|
230
|
+
position: 'relative',
|
|
231
|
+
}, children: items.map(virtualItem => {
|
|
232
|
+
const item = virtualizedItems[virtualItem.index];
|
|
233
|
+
if (!item) {
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
const isGroupSelected = selectedGroups.includes(item.id) ||
|
|
237
|
+
(item.type === 'leaf' && selectedGroups.includes(item.groupId));
|
|
238
|
+
return (_jsx("div", { "data-index": virtualItem.index, ref: virtualizer.measureElement, className: `virtualized-tree-item ${item.type === 'group' ? 'group-item' : 'leaf-item'} ${isGroupSelected ? 'checked' : ''}`, style: {
|
|
239
|
+
position: 'absolute',
|
|
240
|
+
top: 0,
|
|
241
|
+
left: 0,
|
|
242
|
+
width: '100%',
|
|
243
|
+
height: `${virtualItem.size}px`,
|
|
244
|
+
transform: `translateY(${virtualItem.start}px)`,
|
|
245
|
+
}, children: item.type === 'group' ? (_jsx(TreeNodeContainer, { groupId: item.id, isOpen: item.isExpanded, disableAnimation: disableAnimation, children: _jsx(TreeNode, { node: item.data, hasMultiselect: hasMultiselect, onToggleNode: enhancedHandleToggleNode, onSelect: handleGroupSelection, isSelected: isGroupSelected, isIndeterminate: !isGroupSelected &&
|
|
246
|
+
item.data.items.some(groupItem => selectedItems.includes(groupItem.id)) }) }, item.id)) : (
|
|
247
|
+
// Render individual leaf item with proper styling
|
|
248
|
+
_jsx(TreeNodeContainer, { isOpen: true, disableAnimation: disableAnimation, children: _jsx(TreeLeafList, { leafList: [item.data], hasMultiselect: hasMultiselect, showRadioButtons: showRadioButtons, selectedItems: selectedItems, selectedGroups: selectedGroups, onSelectionChange: respondSelection }) }, item.id)) }, `${item.type}-${item.id}-${virtualItem.index}`));
|
|
249
|
+
}) }) }));
|
|
250
|
+
};
|
|
221
251
|
const renderTree = () => {
|
|
222
252
|
const { groupedItems } = state;
|
|
223
253
|
if (isEmpty(groupedItems)) {
|
|
224
254
|
return _jsx(TreeNothingFound, {});
|
|
225
255
|
}
|
|
256
|
+
if (virtualizedItems.length > virtualizeThreshold) {
|
|
257
|
+
return renderVirtualizedTree();
|
|
258
|
+
}
|
|
226
259
|
const result = map((group) => {
|
|
227
260
|
const groupId = group.id;
|
|
228
261
|
const groupItems = group.items;
|
|
229
|
-
const isOpen = internalExpandedGroups
|
|
262
|
+
const isOpen = internalExpandedGroups?.includes(groupId) ?? false;
|
|
230
263
|
const numSelectedGroupItems = filter(containsItemById(selectedItems))(groupItems).length;
|
|
231
264
|
const isGroupSelected = selectedGroups.includes(groupId);
|
|
232
265
|
const isStateIndeterminate = !isGroupSelected && numSelectedGroupItems > 0;
|
|
233
|
-
return (_jsxs(TreeNodeContainer, { groupId: groupId, isOpen: isOpen, disableAnimation: disableAnimation, children: [_jsx(TreeNode, { node: group, hasMultiselect: hasMultiselect, onToggleNode: handleToggleNode, onSelect: handleGroupSelection, isSelected: isGroupSelected, isIndeterminate: isStateIndeterminate }), _jsx(TreeLeafList, { leafList: groupItems, hasMultiselect: hasMultiselect, showRadioButtons: showRadioButtons, selectedItems: selectedItems, selectedGroups: selectedGroups, onSelectionChange: respondSelection })] }, groupId));
|
|
266
|
+
return (_jsxs(TreeNodeContainer, { groupId: groupId, isOpen: isOpen, disableAnimation: disableAnimation, children: [_jsx(TreeNode, { node: group, hasMultiselect: hasMultiselect, onToggleNode: handleToggleNode, onSelect: handleGroupSelection, isSelected: isGroupSelected, isIndeterminate: isStateIndeterminate }), isOpen && (_jsx(TreeLeafList, { leafList: groupItems, hasMultiselect: hasMultiselect, showRadioButtons: showRadioButtons, selectedItems: selectedItems, selectedGroups: selectedGroups, onSelectionChange: respondSelection }))] }, groupId));
|
|
234
267
|
})(groupedItems);
|
|
235
268
|
return result;
|
|
236
269
|
};
|
|
237
270
|
const renderFlatList = () => {
|
|
238
271
|
const { flatItems } = state;
|
|
239
272
|
const hasLeafs = isEmpty(flatItems);
|
|
273
|
+
if (virtualizedItems.length > virtualizeThreshold) {
|
|
274
|
+
return renderVirtualizedTree();
|
|
275
|
+
}
|
|
240
276
|
const getLeafs = () => (_jsx(TreeLeafList, { leafList: flatItems, hasMultiselect: hasMultiselect, showRadioButtons: showRadioButtons, selectedItems: selectedItems, selectedGroups: selectedGroups, onSelectionChange: respondSelection }));
|
|
241
277
|
return (_jsx(TreeNodeContainer, { disableAnimation: disableAnimation, isOpen: true, children: hasLeafs ? _jsx(TreeNothingFound, {}) : getLeafs() }));
|
|
242
278
|
};
|
|
243
279
|
const hasExternalGroups = notEmpty(groups);
|
|
244
|
-
const hasInternalSearchValue = () => notEmpty(state.searchValue);
|
|
245
280
|
const hasSelectedAllItems = () => isEqual(size(selectedItems), size(state.flatItems));
|
|
246
281
|
const hasPartiallySelectedItems = () => notEmpty(selectedItems) && !hasSelectedAllItems();
|
|
247
282
|
const hasSelectedAllGroups = () => {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { isEqual } from 'lodash/fp';
|
|
3
|
+
export const useTreeExpansion = (expandedGroups, onExpandGroupsChange) => {
|
|
4
|
+
const [internalExpandedGroups, setInternalExpandedGroups] = useState(expandedGroups);
|
|
5
|
+
const [previousExpandedGroups, setPreviousExpandedGroups] = useState(expandedGroups);
|
|
6
|
+
// Sync with external prop changes and update expanded groups from outside in case
|
|
7
|
+
if (!isEqual(expandedGroups, previousExpandedGroups)) {
|
|
8
|
+
setInternalExpandedGroups(expandedGroups);
|
|
9
|
+
setPreviousExpandedGroups(expandedGroups);
|
|
10
|
+
}
|
|
11
|
+
const handleToggleNode = (nodeId) => {
|
|
12
|
+
if (!internalExpandedGroups) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const newExpandedNodes = internalExpandedGroups.includes(nodeId)
|
|
16
|
+
? internalExpandedGroups.filter(item => item !== nodeId)
|
|
17
|
+
: [...internalExpandedGroups, nodeId];
|
|
18
|
+
setInternalExpandedGroups(newExpandedNodes);
|
|
19
|
+
onExpandGroupsChange?.(newExpandedNodes);
|
|
20
|
+
};
|
|
21
|
+
return {
|
|
22
|
+
internalExpandedGroups,
|
|
23
|
+
handleToggleNode,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useTreeHeight: (treeRef: React.RefObject<HTMLDivElement>, scrollHeight?: number) => number;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
const DEFAULT_TREE_ROOT_HEIGHT = 300;
|
|
3
|
+
export const useTreeHeight = (treeRef, scrollHeight) => {
|
|
4
|
+
const [containerHeight, setContainerHeight] = useState(350);
|
|
5
|
+
// Enhanced height calculation with multiple fallback strategies
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const calculateHeight = () => {
|
|
8
|
+
if (!treeRef.current) {
|
|
9
|
+
return DEFAULT_TREE_ROOT_HEIGHT;
|
|
10
|
+
}
|
|
11
|
+
const parentElement = treeRef.current;
|
|
12
|
+
const treeHeaderElement = parentElement.querySelector('.TreeHeader');
|
|
13
|
+
if (scrollHeight) {
|
|
14
|
+
// Use scrollHeight prop if provided
|
|
15
|
+
return scrollHeight;
|
|
16
|
+
}
|
|
17
|
+
const treeRoot = treeRef.current.querySelector('.TreeRoot');
|
|
18
|
+
return treeRoot?.clientHeight ?? DEFAULT_TREE_ROOT_HEIGHT;
|
|
19
|
+
};
|
|
20
|
+
const updateHeight = () => {
|
|
21
|
+
const newHeight = calculateHeight();
|
|
22
|
+
setContainerHeight(newHeight);
|
|
23
|
+
};
|
|
24
|
+
// Debounce height updates to avoid excessive recalculations
|
|
25
|
+
let timeoutId;
|
|
26
|
+
const debouncedUpdate = () => {
|
|
27
|
+
clearTimeout(timeoutId);
|
|
28
|
+
timeoutId = setTimeout(updateHeight, 16); // ~60fps
|
|
29
|
+
};
|
|
30
|
+
// Initial calculation with small delay to ensure DOM is ready
|
|
31
|
+
const initialTimeout = setTimeout(updateHeight, 50);
|
|
32
|
+
// Set up observers
|
|
33
|
+
const resizeObserver = new ResizeObserver(debouncedUpdate);
|
|
34
|
+
const mutationObserver = new MutationObserver(debouncedUpdate);
|
|
35
|
+
if (treeRef.current) {
|
|
36
|
+
// Watch parent for size changes
|
|
37
|
+
resizeObserver.observe(treeRef.current);
|
|
38
|
+
if (treeRef.current.parentElement) {
|
|
39
|
+
resizeObserver.observe(treeRef.current.parentElement);
|
|
40
|
+
}
|
|
41
|
+
// Watch for DOM changes that might affect layout
|
|
42
|
+
mutationObserver.observe(treeRef.current, {
|
|
43
|
+
childList: true,
|
|
44
|
+
subtree: true,
|
|
45
|
+
attributes: true,
|
|
46
|
+
attributeFilter: ['style', 'class'],
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
// Window resize listener
|
|
50
|
+
window.addEventListener('resize', debouncedUpdate);
|
|
51
|
+
return () => {
|
|
52
|
+
clearTimeout(initialTimeout);
|
|
53
|
+
clearTimeout(timeoutId);
|
|
54
|
+
resizeObserver.disconnect();
|
|
55
|
+
mutationObserver.disconnect();
|
|
56
|
+
window.removeEventListener('resize', debouncedUpdate);
|
|
57
|
+
};
|
|
58
|
+
}, [scrollHeight, treeRef]); // Re-run if scrollHeight prop changes or treeRef changes
|
|
59
|
+
return containerHeight;
|
|
60
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useCallback, useRef } from 'react';
|
|
2
|
+
export const useTreeScrollPosition = (virtualizer, scrollElementRef) => {
|
|
3
|
+
const scrollOffsetRef = useRef(0);
|
|
4
|
+
const scrollToTop = useCallback(() => {
|
|
5
|
+
if (scrollElementRef.current) {
|
|
6
|
+
requestAnimationFrame(() => {
|
|
7
|
+
// Reset scroll position to top
|
|
8
|
+
scrollElementRef.current.scrollTop(0);
|
|
9
|
+
// Also reset the stored scroll offset
|
|
10
|
+
scrollOffsetRef.current = 0;
|
|
11
|
+
// Force virtualizer to sync
|
|
12
|
+
if (virtualizer) {
|
|
13
|
+
virtualizer.scrollToOffset(0);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}, [scrollElementRef, virtualizer]);
|
|
18
|
+
return { scrollToTop };
|
|
19
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TreeItem, GroupedItem } from './Tree';
|
|
2
|
+
type VirtualizedItem = {
|
|
3
|
+
type: 'group';
|
|
4
|
+
data: GroupedItem;
|
|
5
|
+
id: string;
|
|
6
|
+
isExpanded: boolean;
|
|
7
|
+
} | {
|
|
8
|
+
type: 'leaf';
|
|
9
|
+
data: TreeItem;
|
|
10
|
+
id: string;
|
|
11
|
+
groupId: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const useTreeVirtualization: (groupedItems: GroupedItem[], flatItems: TreeItem[], hasSearchValue: boolean, hasGroups: boolean, internalExpandedGroups: string[] | undefined, scrollElementRef: React.RefObject<HTMLDivElement>, overscan: number) => {
|
|
14
|
+
virtualizedItems: VirtualizedItem[];
|
|
15
|
+
virtualizer: import("@tanstack/virtual-core").Virtualizer<any, Element>;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import map from 'lodash/fp/map';
|
|
3
|
+
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
4
|
+
export const useTreeVirtualization = (groupedItems, flatItems, hasSearchValue, hasGroups, internalExpandedGroups, scrollElementRef, overscan) => {
|
|
5
|
+
const virtualizedItems = useMemo(() => {
|
|
6
|
+
// When there's a search value, always show flat items (no groups)
|
|
7
|
+
if (hasSearchValue) {
|
|
8
|
+
return flatItems.map((item) => ({
|
|
9
|
+
type: 'leaf',
|
|
10
|
+
data: item,
|
|
11
|
+
id: item.id,
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
// Virtualize grouped list, when there's no search value and we have groups
|
|
15
|
+
if (hasGroups) {
|
|
16
|
+
const flatList = [];
|
|
17
|
+
map((group) => {
|
|
18
|
+
const isExpanded = internalExpandedGroups?.includes(group.id) ?? false;
|
|
19
|
+
// Add the group header
|
|
20
|
+
flatList.push({
|
|
21
|
+
type: 'group',
|
|
22
|
+
data: group,
|
|
23
|
+
id: group.id,
|
|
24
|
+
isExpanded,
|
|
25
|
+
});
|
|
26
|
+
// Add expanded items
|
|
27
|
+
if (isExpanded) {
|
|
28
|
+
group.items.forEach((item) => {
|
|
29
|
+
flatList.push({
|
|
30
|
+
type: 'leaf',
|
|
31
|
+
data: item,
|
|
32
|
+
id: item.id,
|
|
33
|
+
groupId: group.id,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
})(groupedItems);
|
|
38
|
+
return flatList;
|
|
39
|
+
}
|
|
40
|
+
// Virtualize flat list when no groups are provided initially
|
|
41
|
+
return flatItems.map((item) => ({
|
|
42
|
+
type: 'leaf',
|
|
43
|
+
data: item,
|
|
44
|
+
id: item.id,
|
|
45
|
+
}));
|
|
46
|
+
}, [groupedItems, flatItems, hasSearchValue, hasGroups, internalExpandedGroups]);
|
|
47
|
+
const virtualizer = useVirtualizer({
|
|
48
|
+
count: virtualizedItems.length,
|
|
49
|
+
// getScrollElement: () => scrollElementRef.current,
|
|
50
|
+
getScrollElement: () => {
|
|
51
|
+
// For SmoothScrollbars, we need to get the actual scroll container
|
|
52
|
+
if (scrollElementRef.current) {
|
|
53
|
+
// SmoothScrollbars exposes the scroll container through its view
|
|
54
|
+
const scrollbarsInstance = scrollElementRef.current;
|
|
55
|
+
// Access the internal scroll container
|
|
56
|
+
// This depends on how react-custom-scrollbars-2 exposes its internals
|
|
57
|
+
return scrollbarsInstance?.view;
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
},
|
|
61
|
+
estimateSize: () => 41, // typical single line height without line-break
|
|
62
|
+
measureElement: element => {
|
|
63
|
+
// This will measure the actual rendered height for more accuracy
|
|
64
|
+
return element?.children[0].clientHeight ?? 41;
|
|
65
|
+
},
|
|
66
|
+
overscan, // Render 10 extra items above and below visible area
|
|
67
|
+
// Add this to enable more aggressive remeasurement
|
|
68
|
+
lanes: 1,
|
|
69
|
+
});
|
|
70
|
+
return { virtualizedItems, virtualizer };
|
|
71
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type SortDirectionType } from '../../utils/SortUtils';
|
|
3
|
+
export type BarListRow<T> = T & {
|
|
4
|
+
key?: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
value: number;
|
|
7
|
+
name: string;
|
|
8
|
+
color?: string;
|
|
9
|
+
barColor?: string;
|
|
10
|
+
background?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Props for the BarList component.
|
|
14
|
+
*
|
|
15
|
+
* @template T - The type of the custom data associated with each bar row.
|
|
16
|
+
*/
|
|
17
|
+
type BarListProps<T = unknown> = React.HTMLAttributes<HTMLDivElement> & {
|
|
18
|
+
/**
|
|
19
|
+
* Array of bar row data to be rendered.
|
|
20
|
+
*/
|
|
21
|
+
data: BarListRow<T>[];
|
|
22
|
+
/**
|
|
23
|
+
* Optional function to format the numeric value displayed on the right side of each bar.
|
|
24
|
+
* Can return a string or a React element.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* valueFormatter={(value) => `${value}%`}
|
|
28
|
+
*/
|
|
29
|
+
valueFormatter?: (value: number) => string | React.ReactElement;
|
|
30
|
+
/**
|
|
31
|
+
* A reference value used to calculate relative widths.
|
|
32
|
+
* If not provided, the maximum value in `data` will be used.
|
|
33
|
+
*
|
|
34
|
+
* @default max(data.value)
|
|
35
|
+
*/
|
|
36
|
+
referenceValue?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Whether to animate the bar width transitions using Framer Motion.
|
|
39
|
+
*
|
|
40
|
+
* @default false
|
|
41
|
+
*/
|
|
42
|
+
showAnimation?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Callback fired when a bar is clicked.
|
|
45
|
+
*
|
|
46
|
+
* @param payload - The full data object of the clicked bar.
|
|
47
|
+
*/
|
|
48
|
+
onSelectRow?: (payload: BarListRow<T>) => void;
|
|
49
|
+
/**
|
|
50
|
+
* The sort order for the bars. Options are 'asc', 'desc', or 'none'.
|
|
51
|
+
*
|
|
52
|
+
* @default 'none'
|
|
53
|
+
*/
|
|
54
|
+
sortOrder?: SortDirectionType | 'none';
|
|
55
|
+
/**
|
|
56
|
+
* Height of each bar row in pixels.
|
|
57
|
+
*
|
|
58
|
+
* @default 32
|
|
59
|
+
*/
|
|
60
|
+
rowHeight?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Opacity applied to non-hovered bars (between 0 and 1).
|
|
63
|
+
*
|
|
64
|
+
* @default 0.5
|
|
65
|
+
*/
|
|
66
|
+
opacity?: number;
|
|
67
|
+
/**
|
|
68
|
+
* CSS color string used for the active/progress portion of each bar.
|
|
69
|
+
*
|
|
70
|
+
* @default 'bg-highlight-light'
|
|
71
|
+
*/
|
|
72
|
+
barColor?: string;
|
|
73
|
+
/**
|
|
74
|
+
* CSS color string used for the text labels.
|
|
75
|
+
*
|
|
76
|
+
* @default 'text-color-darker'
|
|
77
|
+
*/
|
|
78
|
+
labelColor?: string;
|
|
79
|
+
/**
|
|
80
|
+
* CSS color string used for the bar background.
|
|
81
|
+
*
|
|
82
|
+
* @default 'bg-transparent'
|
|
83
|
+
*/
|
|
84
|
+
background?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Additional className added to the wrapper element.
|
|
87
|
+
*/
|
|
88
|
+
className?: string;
|
|
89
|
+
};
|
|
90
|
+
declare const BarListInner: {
|
|
91
|
+
<T>(props: BarListProps<T>, forwardedRef: React.ForwardedRef<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
92
|
+
displayName: string;
|
|
93
|
+
};
|
|
94
|
+
declare const BarList: <T>(props: BarListProps<T> & {
|
|
95
|
+
ref?: React.ForwardedRef<HTMLDivElement>;
|
|
96
|
+
}) => ReturnType<typeof BarListInner>;
|
|
97
|
+
export default BarList;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useMemo } from 'react';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import { motion } from 'framer-motion';
|
|
5
|
+
import { SortDirection } from '../../utils/SortUtils';
|
|
6
|
+
import { useSortedBars } from './useSortedBars';
|
|
7
|
+
// Animation variants
|
|
8
|
+
const containerVariants = {
|
|
9
|
+
animate: {
|
|
10
|
+
transition: {
|
|
11
|
+
staggerChildren: 0.1,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
const barVariants = {
|
|
16
|
+
initial: { width: 0 },
|
|
17
|
+
animate: (width) => ({
|
|
18
|
+
width: `${width}%`,
|
|
19
|
+
transition: { duration: 0.8, ease: 'easeOut' },
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
const DEFAULT_ROW_HEIGHT = 25;
|
|
23
|
+
const DEFAULT_OPACITY = 0.5;
|
|
24
|
+
const BarListInner = (props, forwardedRef) => {
|
|
25
|
+
const { data = [], valueFormatter = value => value.toString(), showAnimation = false, onSelectRow, referenceValue, sortOrder = SortDirection.DESCENDING, barColor = 'bg-highlight-light', labelColor = 'text-color-darker', background = 'bg-transparent', rowHeight = DEFAULT_ROW_HEIGHT, opacity = DEFAULT_OPACITY, className = '', ...remainingProps } = props;
|
|
26
|
+
const sortedData = useSortedBars(data, sortOrder, item => item.value);
|
|
27
|
+
const [hoveredIndex, setHoveredIndex] = React.useState(null);
|
|
28
|
+
const widths = useMemo(() => {
|
|
29
|
+
const base = referenceValue ?? Math.max(...sortedData.map(item => item.value), 0);
|
|
30
|
+
return sortedData.map(item => (base === 0 || item.value === 0 ? 0 : Math.max((item.value / base) * 100, 2)));
|
|
31
|
+
}, [sortedData, referenceValue]);
|
|
32
|
+
return (_jsxs("div", { ...remainingProps, ref: forwardedRef, className: classNames('display-flex justify-content-between gap-15', className), children: [_jsx(motion.div, { variants: showAnimation ? containerVariants : undefined, initial: 'initial', animate: 'animate', className: 'width-100pct space-y-5', children: sortedData.map((item, index) => {
|
|
33
|
+
const width = widths[index];
|
|
34
|
+
const itemLabelColor = item.color ?? labelColor;
|
|
35
|
+
const itemBarColor = item.barColor ?? barColor;
|
|
36
|
+
const itemBackground = item.background ?? background;
|
|
37
|
+
return (_jsxs("div", { onMouseEnter: () => setHoveredIndex(index), onMouseLeave: () => setHoveredIndex(null), onClick: () => onSelectRow?.(item), className: classNames('position-relative width-100pct rounded-small', 'transition-all transition-ease-in-out transition-duration-01', itemBackground, onSelectRow && 'cursor-pointer', hoveredIndex === index && 'bg-lightest'), children: [_jsx(motion.div, { custom: width, variants: showAnimation ? barVariants : undefined, className: classNames('display-flex align-items-center rounded-small', 'transition-all transition-ease-in-out transition-duration-01', itemBarColor), style: { height: `${rowHeight}px`, opacity: hoveredIndex === index ? 1 : opacity }, role: 'presentation' }), _jsx("div", { className: 'position-absolute left-0 top-50pct translate-y-50pct display-flex width-100pct padding-left-10', children: item.href ? (_jsx("a", { href: item.href, className: itemLabelColor, target: '_blank', rel: 'noreferrer', onClick: event => event.stopPropagation(), children: item.name })) : (_jsx("div", { className: itemLabelColor, children: item.name })) })] }, item.key ?? item.name));
|
|
38
|
+
}) }), _jsx("div", { className: 'space-y-5', children: sortedData.map(item => (_jsx("div", { className: classNames('display-flex align-items-center justify-content-end'), style: { height: `${rowHeight}px` }, children: _jsx("div", { className: 'text-color-darkest', children: valueFormatter(item.value) }) }, item.key ?? item.name))) })] }));
|
|
39
|
+
};
|
|
40
|
+
BarListInner.displayName = 'BarList';
|
|
41
|
+
const BarList = React.forwardRef(BarListInner);
|
|
42
|
+
export default BarList;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { SortDirection } from '../../utils/SortUtils';
|
|
3
|
+
export function useSortedBars(data, sortOrder, getValue) {
|
|
4
|
+
return useMemo(() => {
|
|
5
|
+
if (sortOrder === 'none') {
|
|
6
|
+
return data;
|
|
7
|
+
}
|
|
8
|
+
return [...data].sort((a, b) => {
|
|
9
|
+
const aVal = getValue(a);
|
|
10
|
+
const bVal = getValue(b);
|
|
11
|
+
return sortOrder === SortDirection.ASCENDING ? aVal - bVal : bVal - aVal;
|
|
12
|
+
});
|
|
13
|
+
}, [data, sortOrder, getValue]);
|
|
14
|
+
}
|
|
@@ -14,7 +14,7 @@ const renderCustomInnerLabel = (dataUnit) => ({ cx, cy, midAngle, innerRadius, o
|
|
|
14
14
|
};
|
|
15
15
|
const PieChart = (props) => {
|
|
16
16
|
const { width, height, innerRadius, outerRadius, data = [], dataKey = 'value', dataUnit = '', nameKey = 'name', color, filled = false, labels = true, innerLabels = false, paddingAngle = 3, legend = _jsx(RechartsLegend, {}), tooltip = true, pieOptions, containerOptions, ...remainingProps } = props;
|
|
17
|
-
// biome-ignore lint/suspicious/noExplicitAny:
|
|
17
|
+
// biome-ignore lint/suspicious/noExplicitAny: unknown type
|
|
18
18
|
const renderLabels = (entry) => `${isFunction(dataKey) ? dataKey(entry) : entry[dataKey]} ${dataUnit}`;
|
|
19
19
|
const pieLabel = labels && (innerLabels ? renderCustomInnerLabel(dataUnit) : renderLabels);
|
|
20
20
|
const tooltipProps = isObject(tooltip) ? tooltip.props : {};
|
|
@@ -136,7 +136,7 @@ const ClearableInput = forwardRef((props, ref) => {
|
|
|
136
136
|
maxLength: hasMask ? undefined : maxLength,
|
|
137
137
|
tabIndex,
|
|
138
138
|
};
|
|
139
|
-
const input = hasMask ? (_jsx(IMaskInput, { ...inputProps,
|
|
139
|
+
const input = hasMask ? (_jsx(IMaskInput, { ...inputProps, inputRef: mergedInternalMaskRef, mask: mask, placeholderChar: maskPlaceholder, onAccept: handleAccept, lazy: !shouldShowMask(), overwrite: true })) : (_jsx("input", { ...inputProps, ref: inputRef || ref }));
|
|
140
140
|
return (_jsxs("div", { className: classes, children: [children && isFunction(children) ? children(inputProps) : input, _jsx("span", { className: clearButtonClassNames, onClick: clearInputValue, children: _jsx("span", { className: 'clearButtonIcon rioglyph rioglyph-remove-sign' }) })] }));
|
|
141
141
|
});
|
|
142
142
|
export default ClearableInput;
|