sag_components 2.0.0-beta305 → 2.0.0-beta307
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/dist/index.esm.js +155 -16
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +155 -16
- package/dist/index.js.map +1 -1
- package/dist/types/components/OverlayDropdown/OverlayDropdown.style.d.ts +2 -0
- package/dist/types/components/SearchInput/SearchInput.stories.d.ts +27 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3806,11 +3806,14 @@ const SearchInput$1 = props => {
|
|
|
3806
3806
|
position = 'left',
|
|
3807
3807
|
iconColor = '#212121',
|
|
3808
3808
|
onTyping = () => {},
|
|
3809
|
+
onClear = () => {},
|
|
3810
|
+
clearTrigger,
|
|
3809
3811
|
className
|
|
3810
3812
|
} = props;
|
|
3811
3813
|
|
|
3812
3814
|
// Use internal state for uncontrolled mode
|
|
3813
3815
|
const [internalValue, setInternalValue] = React$1.useState(defaultValue);
|
|
3816
|
+
const previousValueRef = React$1.useRef(defaultValue);
|
|
3814
3817
|
|
|
3815
3818
|
// Determine if component is controlled
|
|
3816
3819
|
const isControlled = controlledValue !== undefined;
|
|
@@ -3822,12 +3825,33 @@ const SearchInput$1 = props => {
|
|
|
3822
3825
|
setInternalValue(defaultValue);
|
|
3823
3826
|
}
|
|
3824
3827
|
}, [defaultValue, isControlled]);
|
|
3828
|
+
|
|
3829
|
+
// Clear the input when clearTrigger changes (external clear trigger)
|
|
3830
|
+
React$1.useEffect(() => {
|
|
3831
|
+
if (clearTrigger !== undefined) {
|
|
3832
|
+
setInternalValue('');
|
|
3833
|
+
}
|
|
3834
|
+
}, [clearTrigger]);
|
|
3825
3835
|
const handleInputChange = e => {
|
|
3836
|
+
const newValue = e.target.value;
|
|
3837
|
+
|
|
3838
|
+
// Detect native clear button click (value was non-empty, now empty, via input event)
|
|
3839
|
+
if (previousValueRef.current && newValue === '') {
|
|
3840
|
+
onClear();
|
|
3841
|
+
}
|
|
3842
|
+
previousValueRef.current = newValue;
|
|
3826
3843
|
if (!isControlled) {
|
|
3827
|
-
setInternalValue(
|
|
3844
|
+
setInternalValue(newValue);
|
|
3828
3845
|
}
|
|
3829
3846
|
onTyping(e);
|
|
3830
3847
|
};
|
|
3848
|
+
|
|
3849
|
+
// Handle the 'search' event which fires when native clear button is clicked
|
|
3850
|
+
const handleSearch = e => {
|
|
3851
|
+
if (e.target.value === '') {
|
|
3852
|
+
onClear();
|
|
3853
|
+
}
|
|
3854
|
+
};
|
|
3831
3855
|
return /*#__PURE__*/React__default["default"].createElement(TextFieldContainer, {
|
|
3832
3856
|
className: className,
|
|
3833
3857
|
width: width
|
|
@@ -3842,6 +3866,7 @@ const SearchInput$1 = props => {
|
|
|
3842
3866
|
height: height,
|
|
3843
3867
|
placeholder: placeholder,
|
|
3844
3868
|
onChange: handleInputChange,
|
|
3869
|
+
onSearch: handleSearch,
|
|
3845
3870
|
position: position
|
|
3846
3871
|
}));
|
|
3847
3872
|
};
|
|
@@ -37724,8 +37749,16 @@ const SearchInput = styled__default["default"].input`
|
|
|
37724
37749
|
}
|
|
37725
37750
|
`;
|
|
37726
37751
|
const ListWrapper = styled__default["default"].div`
|
|
37727
|
-
max-height: ${props =>
|
|
37728
|
-
|
|
37752
|
+
max-height: ${props => {
|
|
37753
|
+
const maxH = parseInt(props.maxHeight) || 400;
|
|
37754
|
+
const actualH = (props.actualHeight || maxH) + 16;
|
|
37755
|
+
return actualH < maxH ? `${actualH}px` : props.maxHeight;
|
|
37756
|
+
}};
|
|
37757
|
+
overflow-y: ${props => {
|
|
37758
|
+
const maxH = parseInt(props.maxHeight) || 400;
|
|
37759
|
+
const actualH = (props.actualHeight || maxH) + 16;
|
|
37760
|
+
return actualH < maxH ? 'hidden' : 'auto';
|
|
37761
|
+
}};
|
|
37729
37762
|
position: relative;
|
|
37730
37763
|
`;
|
|
37731
37764
|
const CheckboxGroup = styled__default["default"].div`
|
|
@@ -37770,6 +37803,7 @@ const CheckboxLabel = styled__default["default"].label`
|
|
|
37770
37803
|
color: #212121;
|
|
37771
37804
|
cursor: pointer;
|
|
37772
37805
|
flex-shrink: 0;
|
|
37806
|
+
box-sizing: border-box;
|
|
37773
37807
|
|
|
37774
37808
|
&:hover {
|
|
37775
37809
|
background-color: #E6F0F0;
|
|
@@ -37842,7 +37876,7 @@ const FilterPop = props => {
|
|
|
37842
37876
|
selectedAttributes: propSelectedAttributes = {},
|
|
37843
37877
|
showSearch = true,
|
|
37844
37878
|
searchPlaceholder = "Search...",
|
|
37845
|
-
itemHeight =
|
|
37879
|
+
itemHeight = 40,
|
|
37846
37880
|
overscan = 5,
|
|
37847
37881
|
hasActiveFilter = false // NEW: Indicates if this column has an active filter
|
|
37848
37882
|
} = props;
|
|
@@ -37931,16 +37965,18 @@ const FilterPop = props => {
|
|
|
37931
37965
|
offsetY
|
|
37932
37966
|
} = React$1.useMemo(() => {
|
|
37933
37967
|
const containerHeight = parseInt(maxHeight) || 400;
|
|
37934
|
-
const
|
|
37935
|
-
const
|
|
37968
|
+
const gap = 8;
|
|
37969
|
+
const itemWithGap = itemHeight + gap;
|
|
37970
|
+
const startIndex = Math.max(0, Math.floor(scrollTop / itemWithGap) - overscan);
|
|
37971
|
+
const endIndex = Math.min(sortedList.length, Math.ceil((scrollTop + containerHeight) / itemWithGap) + overscan);
|
|
37936
37972
|
const visible = sortedList.slice(startIndex, endIndex).map((item, idx) => ({
|
|
37937
37973
|
...item,
|
|
37938
37974
|
index: startIndex + idx
|
|
37939
37975
|
}));
|
|
37940
37976
|
return {
|
|
37941
37977
|
visibleItems: visible,
|
|
37942
|
-
totalHeight:
|
|
37943
|
-
offsetY: startIndex *
|
|
37978
|
+
totalHeight: sortedList.length * itemHeight + Math.max(0, sortedList.length - 1) * gap,
|
|
37979
|
+
offsetY: startIndex * itemWithGap
|
|
37944
37980
|
};
|
|
37945
37981
|
}, [sortedList, scrollTop, itemHeight, overscan, maxHeight]);
|
|
37946
37982
|
const areAllNonAllItemsSelected = function () {
|
|
@@ -38140,7 +38176,8 @@ const FilterPop = props => {
|
|
|
38140
38176
|
}), /*#__PURE__*/React__default["default"].createElement(ListWrapper, {
|
|
38141
38177
|
ref: scrollContainerRef,
|
|
38142
38178
|
onScroll: handleScroll,
|
|
38143
|
-
maxHeight: maxHeight
|
|
38179
|
+
maxHeight: maxHeight,
|
|
38180
|
+
actualHeight: totalHeight
|
|
38144
38181
|
}, sortedList.length === 1 ? /*#__PURE__*/React__default["default"].createElement(NoResultsMessage, null, "No items match your search") : /*#__PURE__*/React__default["default"].createElement("div", {
|
|
38145
38182
|
style: {
|
|
38146
38183
|
height: `${totalHeight}px`,
|
|
@@ -40992,10 +41029,12 @@ const TableHeader = ({
|
|
|
40992
41029
|
const debouncedFilterState = useDebounce(filterState, debounceDelay);
|
|
40993
41030
|
const iconRefs = React$1.useRef({});
|
|
40994
41031
|
const popupRef = React$1.useRef(null);
|
|
41032
|
+
const prevResetKeyRef = React$1.useRef(resetFiltersKey);
|
|
40995
41033
|
|
|
40996
|
-
// Reset internal state when resetFiltersKey changes
|
|
41034
|
+
// Reset internal state when resetFiltersKey changes (not when columns change)
|
|
40997
41035
|
React$1.useEffect(() => {
|
|
40998
|
-
|
|
41036
|
+
// Only run reset when resetFiltersKey actually changed
|
|
41037
|
+
if (resetFiltersKey !== prevResetKeyRef.current && resetFiltersKey > 0) {
|
|
40999
41038
|
const resetSelections = {};
|
|
41000
41039
|
columns.forEach(column => {
|
|
41001
41040
|
if (column.filter && column.filterOptions) {
|
|
@@ -41017,6 +41056,7 @@ const TableHeader = ({
|
|
|
41017
41056
|
setVisibleFilterPopWrapper(null);
|
|
41018
41057
|
setVisibleSortPopWrapper(null);
|
|
41019
41058
|
}
|
|
41059
|
+
prevResetKeyRef.current = resetFiltersKey;
|
|
41020
41060
|
}, [resetFiltersKey, columns]);
|
|
41021
41061
|
|
|
41022
41062
|
// Track if we've already initialized from saved state
|
|
@@ -57689,6 +57729,21 @@ function ModalDrawer(_ref) {
|
|
|
57689
57729
|
}, "\xD7"), children));
|
|
57690
57730
|
}
|
|
57691
57731
|
|
|
57732
|
+
// Keyframes for rolling/marquee animation
|
|
57733
|
+
const scrollTextAnimation = styled.keyframes`
|
|
57734
|
+
0% {
|
|
57735
|
+
transform: translateX(0);
|
|
57736
|
+
}
|
|
57737
|
+
10% {
|
|
57738
|
+
transform: translateX(0);
|
|
57739
|
+
}
|
|
57740
|
+
90% {
|
|
57741
|
+
transform: translateX(var(--scroll-distance, -30%));
|
|
57742
|
+
}
|
|
57743
|
+
100% {
|
|
57744
|
+
transform: translateX(var(--scroll-distance, -30%));
|
|
57745
|
+
}
|
|
57746
|
+
`;
|
|
57692
57747
|
const scrollableStyles = `
|
|
57693
57748
|
&::-webkit-scrollbar {
|
|
57694
57749
|
height: 8px;
|
|
@@ -57707,6 +57762,9 @@ const scrollableStyles = `
|
|
|
57707
57762
|
`;
|
|
57708
57763
|
const TooltipWrapper = styled__default["default"](Tooltip$2)`
|
|
57709
57764
|
width: 100%;
|
|
57765
|
+
.tooltip-wrapper {
|
|
57766
|
+
width: 100%;
|
|
57767
|
+
}
|
|
57710
57768
|
`;
|
|
57711
57769
|
const DropdownContainer = styled__default["default"].div`
|
|
57712
57770
|
position: relative;
|
|
@@ -57804,6 +57862,41 @@ const Wrapper = styled__default["default"].div`
|
|
|
57804
57862
|
align-items: center;
|
|
57805
57863
|
width: 100%;
|
|
57806
57864
|
`;
|
|
57865
|
+
|
|
57866
|
+
// Wrapper for scrollable truncated text
|
|
57867
|
+
const ScrollableTextWrapper = styled__default["default"].div`
|
|
57868
|
+
flex: 1;
|
|
57869
|
+
display: flex;
|
|
57870
|
+
align-items: center;
|
|
57871
|
+
min-width: 0;
|
|
57872
|
+
overflow: hidden;
|
|
57873
|
+
position: relative;
|
|
57874
|
+
`;
|
|
57875
|
+
|
|
57876
|
+
// Inner text that scrolls when truncated
|
|
57877
|
+
const ScrollableTextInner = styled__default["default"].span`
|
|
57878
|
+
display: inline-block;
|
|
57879
|
+
white-space: nowrap;
|
|
57880
|
+
line-height: 21px;
|
|
57881
|
+
font-family: "Poppins", sans-serif;
|
|
57882
|
+
font-size: 14px;
|
|
57883
|
+
font-weight: 400;
|
|
57884
|
+
color: ${props => props.color || 'inherit'};
|
|
57885
|
+
max-width: 100%;
|
|
57886
|
+
|
|
57887
|
+
/* Default state: show ellipsis */
|
|
57888
|
+
overflow: hidden;
|
|
57889
|
+
text-overflow: ellipsis;
|
|
57890
|
+
|
|
57891
|
+
${props => props.$isTruncated && styled.css`
|
|
57892
|
+
${ScrollableTextWrapper}:hover & {
|
|
57893
|
+
/* On hover: remove ellipsis and start animation */
|
|
57894
|
+
overflow: visible;
|
|
57895
|
+
text-overflow: clip;
|
|
57896
|
+
animation: ${scrollTextAnimation} ${props.$animationDuration || 3}s linear infinite;
|
|
57897
|
+
}
|
|
57898
|
+
`}
|
|
57899
|
+
`;
|
|
57807
57900
|
const TruncatedText = styled__default["default"].span`
|
|
57808
57901
|
flex: 1;
|
|
57809
57902
|
min-width: 0;
|
|
@@ -58120,7 +58213,54 @@ OverlayTemplateDialog.propTypes = {
|
|
|
58120
58213
|
buttonHoverColor: PropTypes.string
|
|
58121
58214
|
};
|
|
58122
58215
|
|
|
58123
|
-
|
|
58216
|
+
// Component for scrolling truncated text on hover
|
|
58217
|
+
const ScrollingText = _ref => {
|
|
58218
|
+
let {
|
|
58219
|
+
children,
|
|
58220
|
+
color
|
|
58221
|
+
} = _ref;
|
|
58222
|
+
const wrapperRef = React$1.useRef(null);
|
|
58223
|
+
const textRef = React$1.useRef(null);
|
|
58224
|
+
const [isTruncated, setIsTruncated] = React$1.useState(false);
|
|
58225
|
+
const [scrollDistance, setScrollDistance] = React$1.useState(0);
|
|
58226
|
+
const [animationDuration, setAnimationDuration] = React$1.useState(3);
|
|
58227
|
+
const checkTruncation = React$1.useCallback(() => {
|
|
58228
|
+
if (wrapperRef.current && textRef.current) {
|
|
58229
|
+
const wrapperWidth = wrapperRef.current.offsetWidth;
|
|
58230
|
+
const textWidth = textRef.current.scrollWidth;
|
|
58231
|
+
const isOverflowing = textWidth > wrapperWidth;
|
|
58232
|
+
setIsTruncated(isOverflowing);
|
|
58233
|
+
if (isOverflowing) {
|
|
58234
|
+
// Calculate how much we need to scroll (extra width + small padding)
|
|
58235
|
+
const extraWidth = textWidth - wrapperWidth + 20;
|
|
58236
|
+
setScrollDistance(-extraWidth);
|
|
58237
|
+
|
|
58238
|
+
// Calculate animation duration based on text length (roughly 50px per second)
|
|
58239
|
+
const duration = Math.max(2, Math.min(8, extraWidth / 50));
|
|
58240
|
+
setAnimationDuration(duration);
|
|
58241
|
+
}
|
|
58242
|
+
}
|
|
58243
|
+
}, []);
|
|
58244
|
+
React$1.useEffect(() => {
|
|
58245
|
+
checkTruncation();
|
|
58246
|
+
|
|
58247
|
+
// Recheck on window resize
|
|
58248
|
+
window.addEventListener('resize', checkTruncation);
|
|
58249
|
+
return () => window.removeEventListener('resize', checkTruncation);
|
|
58250
|
+
}, [children, checkTruncation]);
|
|
58251
|
+
return /*#__PURE__*/React__default["default"].createElement(ScrollableTextWrapper, {
|
|
58252
|
+
ref: wrapperRef
|
|
58253
|
+
}, /*#__PURE__*/React__default["default"].createElement(ScrollableTextInner, {
|
|
58254
|
+
ref: textRef,
|
|
58255
|
+
color: color,
|
|
58256
|
+
$isTruncated: isTruncated,
|
|
58257
|
+
$animationDuration: animationDuration,
|
|
58258
|
+
style: {
|
|
58259
|
+
'--scroll-distance': `${scrollDistance}px`
|
|
58260
|
+
}
|
|
58261
|
+
}, children));
|
|
58262
|
+
};
|
|
58263
|
+
const OverlayDropdown = _ref2 => {
|
|
58124
58264
|
let {
|
|
58125
58265
|
data = [],
|
|
58126
58266
|
value,
|
|
@@ -58146,7 +58286,7 @@ const OverlayDropdown = _ref => {
|
|
|
58146
58286
|
height = "auto",
|
|
58147
58287
|
margin = "8px",
|
|
58148
58288
|
...props
|
|
58149
|
-
} =
|
|
58289
|
+
} = _ref2;
|
|
58150
58290
|
const [open, setOpen] = React$1.useState(false);
|
|
58151
58291
|
const [hoveredText, setHoveredText] = React$1.useState(null);
|
|
58152
58292
|
const [templateDialog, setTemplateDialog] = React$1.useState(null);
|
|
@@ -58433,9 +58573,8 @@ const OverlayDropdown = _ref => {
|
|
|
58433
58573
|
}
|
|
58434
58574
|
}
|
|
58435
58575
|
}
|
|
58436
|
-
}, /*#__PURE__*/React__default["default"].createElement(
|
|
58437
|
-
|
|
58438
|
-
onMouseLeave: () => setHoveredText(null)
|
|
58576
|
+
}, /*#__PURE__*/React__default["default"].createElement(ScrollingText, {
|
|
58577
|
+
color: item.value === value ? '#fff' : '#212121'
|
|
58439
58578
|
}, displayText), iconToShow);
|
|
58440
58579
|
})))), templateDialog && /*#__PURE__*/React__default["default"].createElement(OverlayTemplateDialog, {
|
|
58441
58580
|
open: true,
|