sag_components 2.0.0-beta194 → 2.0.0-beta196

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 CHANGED
@@ -3772,7 +3772,7 @@ const TextFieldInput = styled.input`
3772
3772
  }
3773
3773
  `;
3774
3774
 
3775
- const SearchInput = props => {
3775
+ const SearchInput$1 = props => {
3776
3776
  const {
3777
3777
  value,
3778
3778
  placeholder = 'Search',
@@ -3917,7 +3917,7 @@ const ActionsWrapper = styled.div`
3917
3917
  gap: 10px;
3918
3918
  width: 100%;
3919
3919
  `;
3920
- const SearchInputWrap = styled(SearchInput)`
3920
+ const SearchInputWrap = styled(SearchInput$1)`
3921
3921
  margin-left: auto;
3922
3922
  `;
3923
3923
 
@@ -10579,24 +10579,23 @@ const QuarterPopupPicker = ({
10579
10579
  };
10580
10580
 
10581
10581
  /* eslint-disable import/no-extraneous-dependencies */
10582
- const QuarterPicker = _ref => {
10583
- let {
10584
- availableQuarters,
10585
- // ["Q1-2024"]
10586
- label,
10587
- onChange,
10588
- borderRadius,
10589
- required,
10590
- width,
10591
- height,
10592
- placeholder,
10593
- disabled,
10594
- borderColor,
10595
- borderColorFocus,
10596
- textColor,
10597
- selectedValue,
10598
- startYear
10599
- } = _ref;
10582
+ const QuarterPicker = ({
10583
+ availableQuarters,
10584
+ // ["Q1-2024"]
10585
+ label,
10586
+ onChange,
10587
+ borderRadius,
10588
+ required,
10589
+ width,
10590
+ height,
10591
+ placeholder,
10592
+ disabled,
10593
+ borderColor,
10594
+ borderColorFocus,
10595
+ textColor,
10596
+ selectedValue,
10597
+ startYear
10598
+ }) => {
10600
10599
  const [isFocused, setIsFocused] = useState(false);
10601
10600
  const [isOpen, setIsOpen] = useState(false);
10602
10601
  const [value, setValue] = useState('');
@@ -11038,23 +11037,22 @@ const MonthPopupPicker = ({
11038
11037
  };
11039
11038
 
11040
11039
  /* eslint-disable import/no-extraneous-dependencies */
11041
- const MonthPicker = _ref => {
11042
- let {
11043
- availableMonths,
11044
- label,
11045
- onChange,
11046
- borderRadius,
11047
- required,
11048
- width,
11049
- height,
11050
- placeholder,
11051
- disabled,
11052
- borderColor,
11053
- borderColorFocus,
11054
- textColor,
11055
- selectedValue,
11056
- startYear
11057
- } = _ref;
11040
+ const MonthPicker = ({
11041
+ availableMonths,
11042
+ label,
11043
+ onChange,
11044
+ borderRadius,
11045
+ required,
11046
+ width,
11047
+ height,
11048
+ placeholder,
11049
+ disabled,
11050
+ borderColor,
11051
+ borderColorFocus,
11052
+ textColor,
11053
+ selectedValue,
11054
+ startYear
11055
+ }) => {
11058
11056
  const [isFocused, setIsFocused] = useState(false);
11059
11057
  const [isOpen, setIsOpen] = useState(false);
11060
11058
  const [value, setValue] = useState('');
@@ -24165,22 +24163,21 @@ const DeleteIcon = styled.div`
24165
24163
  position: absolute;
24166
24164
  `;
24167
24165
 
24168
- const QuickFilterDropdownSingle = _ref => {
24169
- let {
24170
- label,
24171
- hoverColor,
24172
- options,
24173
- selectedValue,
24174
- placeHolder,
24175
- onChange,
24176
- disabled,
24177
- width,
24178
- error,
24179
- errorMessage,
24180
- xIconShow,
24181
- labelColor,
24182
- showLabelOnTop
24183
- } = _ref;
24166
+ const QuickFilterDropdownSingle = ({
24167
+ label,
24168
+ hoverColor,
24169
+ options,
24170
+ selectedValue,
24171
+ placeHolder,
24172
+ onChange,
24173
+ disabled,
24174
+ width,
24175
+ error,
24176
+ errorMessage,
24177
+ xIconShow,
24178
+ labelColor,
24179
+ showLabelOnTop
24180
+ }) => {
24184
24181
  const [isFocused, setIsFocused] = useState(false);
24185
24182
  const [showOptions, setShowOptions] = useState(false);
24186
24183
  const [inputValue, setInputValue] = useState("");
@@ -24577,24 +24574,23 @@ const IconContainer$2 = styled.div`
24577
24574
  cursor: pointer;
24578
24575
  `;
24579
24576
 
24580
- const QuickFilterDropdownMultiSelection = _ref => {
24581
- let {
24582
- label,
24583
- labelEmptyValue,
24584
- options,
24585
- selectedValue,
24586
- placeHolder,
24587
- onChange,
24588
- required,
24589
- disabled,
24590
- width,
24591
- error,
24592
- errorMessage,
24593
- labelColor,
24594
- xIconShow,
24595
- checkBoxColor,
24596
- showLabelOnTop
24597
- } = _ref;
24577
+ const QuickFilterDropdownMultiSelection = ({
24578
+ label,
24579
+ labelEmptyValue,
24580
+ options,
24581
+ selectedValue,
24582
+ placeHolder,
24583
+ onChange,
24584
+ required,
24585
+ disabled,
24586
+ width,
24587
+ error,
24588
+ errorMessage,
24589
+ labelColor,
24590
+ xIconShow,
24591
+ checkBoxColor,
24592
+ showLabelOnTop
24593
+ }) => {
24598
24594
  const [isFocused, setIsFocused] = useState(false);
24599
24595
  const [showOptions, setShowOptions] = useState(false);
24600
24596
  const [inputValue, setInputValue] = useState('');
@@ -34726,6 +34722,8 @@ const ModalWithOverlay = props => {
34726
34722
  }, children)));
34727
34723
  };
34728
34724
 
34725
+ // src/components/WeeksPicker/WeeksCalendar.styles.js
34726
+
34729
34727
  /* ──────────────────────────────────────────
34730
34728
  COLORS – map to your design-system tokens
34731
34729
  Change only here if the palette shifts
@@ -34737,7 +34735,9 @@ const c = {
34737
34735
  primary: "#016672",
34738
34736
  // apply / highlight
34739
34737
  primaryLight: "#d1e7ea",
34740
- border: "#e0e0e0"
34738
+ border: "#e0e0e0",
34739
+ disabled: "#f5f5f5",
34740
+ disabledText: "#bdbdbd"
34741
34741
  };
34742
34742
 
34743
34743
  /* ───────────────────────── wrapper */
@@ -34777,34 +34777,56 @@ const WeekCell = styled.div`
34777
34777
  text-align: center;
34778
34778
  cursor: pointer;
34779
34779
  color: ${c.textSecondary};
34780
- transition: background 0.15s ease;
34781
- border-radius: 4px;
34780
+ transition: background 0.15s ease, opacity 0.15s ease, color 0.15s ease;
34781
+ border-radius: 4px;
34782
34782
 
34783
+ /* Disabled state - highest priority */
34783
34784
  ${({
34784
- $selected
34785
- }) => $selected && css`
34785
+ $disabled
34786
+ }) => $disabled && css`
34787
+ opacity: 0.3;
34788
+ cursor: not-allowed;
34789
+ background: ${c.disabled} !important;
34790
+ color: ${c.disabledText} !important;
34791
+
34792
+ &:hover {
34793
+ background: ${c.disabled} !important;
34794
+ color: ${c.disabledText} !important;
34795
+ }
34796
+ `}
34786
34797
 
34798
+ /* Selected state - only if not disabled */
34799
+ ${({
34800
+ $selected,
34801
+ $disabled
34802
+ }) => $selected && !$disabled && css`
34787
34803
  background: ${c.primary};
34788
34804
  color: #FFFFFF;
34789
34805
  `}
34790
34806
 
34791
- /* highlight range interior lighter */
34807
+ /* Range middle highlighting - only if not disabled */
34792
34808
  ${({
34793
- $isRangeMiddle
34794
- }) => $isRangeMiddle && css`
34809
+ $isRangeMiddle,
34810
+ $disabled
34811
+ }) => $isRangeMiddle && !$disabled && css`
34795
34812
  background: ${c.primaryLight};
34796
34813
  border-radius: 0px;
34797
34814
  color: ${c.text};
34798
34815
  `}
34799
34816
 
34800
- &:hover {
34801
- background: ${c.primaryLight};
34802
- color: ${c.text};
34803
- }
34817
+ /* Hover state - only if not disabled */
34818
+ ${({
34819
+ $disabled
34820
+ }) => !$disabled && css`
34821
+ &:hover {
34822
+ background: ${c.primaryLight};
34823
+ color: ${c.text};
34824
+ }
34825
+ `}
34826
+
34827
+ /* Typography */
34804
34828
  text-align: center;
34805
34829
  font-feature-settings: "liga" off;
34806
-
34807
- /* Content/P3 Regular */
34808
34830
  font-family: Poppins;
34809
34831
  font-size: 12px;
34810
34832
  font-style: normal;
@@ -34837,15 +34859,20 @@ css`
34837
34859
  }
34838
34860
  `;
34839
34861
 
34862
+ // src/components/WeeksPicker/WeeksCalendar.jsx
34863
+
34840
34864
  /**
34841
34865
  * WeeksCalendar
34842
34866
  * -------------
34843
34867
  * Props
34844
- * • year four-digit year (required)
34845
- * • defaultStartWeek number | null
34846
- * • defaultEndWeek number | null
34847
- * • onApply(start,end) callback, both numbers (inclusive)
34848
- * • onCancel() – callback
34868
+ * • year four-digit year (required)
34869
+ * • defaultStartWeek number | null
34870
+ * • defaultEndWeek number | null
34871
+ * • backgroundColor — string (default: "#066768")
34872
+ * • hoverBackgroundColor — string (default: "#E6F0F0")
34873
+ * • allowedWeekRange — { startWeek: number, endWeek: number } | null
34874
+ * • onApply(start,end) — callback, both numbers (inclusive)
34875
+ * • onCancel() — callback
34849
34876
  */
34850
34877
  const WeeksCalendar = ({
34851
34878
  year,
@@ -34853,6 +34880,8 @@ const WeeksCalendar = ({
34853
34880
  defaultEndWeek = null,
34854
34881
  backgroundColor = "#066768",
34855
34882
  hoverBackgroundColor = "#E6F0F0",
34883
+ allowedWeekRange = null,
34884
+ // New prop for range restriction
34856
34885
  onApply,
34857
34886
  onCancel
34858
34887
  }) => {
@@ -34870,14 +34899,29 @@ const WeeksCalendar = ({
34870
34899
  const hasSelection = startWeek !== null;
34871
34900
  const isRange = hasSelection && endWeek !== null && endWeek !== startWeek;
34872
34901
  const weeks = useMemo(() => [...Array(53)].map((_, i) => i + 1), []);
34902
+
34903
+ // Check if a week is disabled based on allowed range
34904
+ const isWeekDisabled = week => {
34905
+ if (!allowedWeekRange) return false;
34906
+ const {
34907
+ startWeek: allowedStart,
34908
+ endWeek: allowedEnd
34909
+ } = allowedWeekRange;
34910
+ return week < allowedStart || week > allowedEnd;
34911
+ };
34873
34912
  const handleCellClick = week => {
34874
- // first click start
34913
+ // Don't allow selection of disabled weeks
34914
+ if (isWeekDisabled(week)) {
34915
+ return;
34916
+ }
34875
34917
 
34918
+ // first click → start
34876
34919
  if (!hasSelection) {
34877
34920
  setStartWeek(week);
34878
34921
  setEndWeek(null);
34879
34922
  return;
34880
34923
  }
34924
+
34881
34925
  // second click → decide range or single
34882
34926
  if (hasSelection && endWeek === null) {
34883
34927
  // second click on same cell turns it to single selection
@@ -34890,6 +34934,7 @@ const WeeksCalendar = ({
34890
34934
  setStartWeek(week < startWeek ? week : startWeek);
34891
34935
  return;
34892
34936
  }
34937
+
34893
34938
  // any later click resets selection and starts over
34894
34939
  setStartWeek(week);
34895
34940
  setEndWeek(null);
@@ -34905,11 +34950,14 @@ const WeeksCalendar = ({
34905
34950
  columns: 6
34906
34951
  }, weeks.map(wk => {
34907
34952
  const selected = wk === startWeek || isRange && wk >= startWeek && wk <= endWeek;
34953
+ const disabled = isWeekDisabled(wk);
34954
+ const isRangeMiddle = selected && wk !== startWeek && wk !== endWeek;
34908
34955
  return /*#__PURE__*/React$1.createElement(WeekCell, {
34909
34956
  key: wk,
34910
34957
  "data-week": wk,
34911
34958
  $selected: selected,
34912
- $isRangeMiddle: selected && wk !== startWeek && wk !== endWeek,
34959
+ $isRangeMiddle: isRangeMiddle,
34960
+ $disabled: disabled,
34913
34961
  onClick: () => handleCellClick(wk)
34914
34962
  }, wk);
34915
34963
  })), /*#__PURE__*/React$1.createElement(Footer, null, /*#__PURE__*/React$1.createElement(Button$1, {
@@ -34943,6 +34991,12 @@ WeeksCalendar.propTypes = {
34943
34991
  year: PropTypes.number.isRequired,
34944
34992
  defaultStartWeek: PropTypes.number,
34945
34993
  defaultEndWeek: PropTypes.number,
34994
+ backgroundColor: PropTypes.string,
34995
+ hoverBackgroundColor: PropTypes.string,
34996
+ allowedWeekRange: PropTypes.shape({
34997
+ startWeek: PropTypes.number.isRequired,
34998
+ endWeek: PropTypes.number.isRequired
34999
+ }),
34946
35000
  onApply: PropTypes.func.isRequired,
34947
35001
  onCancel: PropTypes.func
34948
35002
  };
@@ -34969,22 +35023,28 @@ const StyledInput$1 = styled.input`
34969
35023
  box-sizing: border-box;
34970
35024
  color: ${props => props.disabled ? '#888' : (props.isFocused || props.value ? props.textColor : '#757575') || '#333'};
34971
35025
  cursor: ${props => props.disabled ? 'not-allowed' : 'text'};
35026
+
35027
+ &:disabled {
35028
+ background-color: #f5f5f5;
35029
+ cursor: not-allowed;
35030
+ }
34972
35031
  `;
34973
35032
  const StyledLabel = styled.label`
34974
35033
  font-size: 14px;
34975
- /* width: ${props => props.isFocused || props.hasValue ? 'auto' : '150px'}; */
34976
35034
  color: ${props => props.disabled ? '#888' : (props.isFocused || props.hasValue ? props.borderColorFocus : '#757575') || '#333'};
34977
35035
  position: absolute;
34978
35036
  top: ${props => props.isFocused || props.hasValue ? '0px' : '50%'};
34979
35037
  left: 15px;
34980
35038
  background-color: ${props => props.isFocused || props.hasValue ? 'white' : 'transparent'};
34981
35039
  transform: translateY(-50%);
34982
- transition: top 0.3s ease, font-size 0.3s ease;
35040
+ transition: top 0.3s ease, font-size 0.3s ease, color 0.3s ease;
34983
35041
  display: flex;
34984
35042
  font-weight: 400;
34985
35043
  align-items: center;
34986
35044
  box-sizing: border-box;
34987
- cursor: pointer;
35045
+ cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
35046
+ padding: 0 4px;
35047
+ z-index: 1;
34988
35048
  `;
34989
35049
  const RequiredIndicator = styled.span`
34990
35050
  color: red;
@@ -35000,9 +35060,13 @@ const OptionsContainer = styled.div`
35000
35060
  z-index: 999;
35001
35061
  ${props => props.showAbove ? `
35002
35062
  bottom: 100%;
35063
+ margin-bottom: 4px;
35003
35064
  ` : `
35004
35065
  top: 100%;
35066
+ margin-top: 4px;
35005
35067
  `}
35068
+ left: 0;
35069
+ right: 0;
35006
35070
  `;
35007
35071
  const InputContainer$1 = styled.div`
35008
35072
  display: flex;
@@ -35015,20 +35079,22 @@ const InputContainer$1 = styled.div`
35015
35079
  width: 100%;
35016
35080
  height: 100%;
35017
35081
  box-sizing: border-box;
35018
- background-color: transparent;
35019
- border: 1px solid ${props => props.disabled ? '#bdbdbd' : props.error ? 'red' : '#B1B1B1'};
35082
+ background-color: ${props => props.disabled ? '#f5f5f5' : 'transparent'};
35083
+ border: 1px solid ${props => props.disabled ? '#bdbdbd' : props.error ? 'red' : '#B1B1B1'};
35020
35084
  font-weight: 400;
35021
35085
  font-size: 14px;
35022
35086
  border-radius: 12px;
35023
35087
  outline: none;
35024
35088
  color: ${props => props.disabled ? '#888' : '#212121'};
35089
+ position: relative;
35090
+ transition: border-color 0.3s ease, background-color 0.3s ease;
35025
35091
 
35026
35092
  &:hover {
35027
35093
  border: 1px solid ${props => props.disabled ? '#bdbdbd' : props.error ? 'red' : props.borderColorFocus || '#212121'};
35028
35094
  cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
35029
35095
  }
35030
35096
 
35031
- &:focus {
35097
+ &:focus-within {
35032
35098
  border: 1px solid ${props => props.disabled ? '#bdbdbd' : props.error ? 'red' : props.borderColorFocus || '#212121'};
35033
35099
  }
35034
35100
  `;
@@ -35038,6 +35104,11 @@ const CalendarDiv = styled.div`
35038
35104
  right: 10px;
35039
35105
  display: flex;
35040
35106
  align-items: center;
35107
+ cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
35108
+
35109
+ svg {
35110
+ transition: fill 0.3s ease;
35111
+ }
35041
35112
  `;
35042
35113
 
35043
35114
  // src/components/WeeksPicker/WeeksPicker.jsx
@@ -35057,7 +35128,11 @@ const WeeksPicker = _ref => {
35057
35128
  height,
35058
35129
  withMarginBottom = true,
35059
35130
  onChange,
35060
- selectedValue
35131
+ selectedValue,
35132
+ // New props for range restriction
35133
+ allowedWeekRange = null,
35134
+ // { startWeek: number, endWeek: number } or null
35135
+ restrictToRange = false // boolean to enable/disable restriction
35061
35136
  } = _ref;
35062
35137
  const [value, setValue] = useState("");
35063
35138
  const inputRef = useRef(null);
@@ -35100,6 +35175,18 @@ const WeeksPicker = _ref => {
35100
35175
  };
35101
35176
  };
35102
35177
 
35178
+ // Validate if selected weeks are within allowed range
35179
+ const validateWeekSelection = (startWeek, endWeek) => {
35180
+ if (!restrictToRange || !allowedWeekRange) {
35181
+ return true;
35182
+ }
35183
+ const {
35184
+ startWeek: allowedStart,
35185
+ endWeek: allowedEnd
35186
+ } = allowedWeekRange;
35187
+ return startWeek >= allowedStart && endWeek <= allowedEnd && startWeek <= endWeek;
35188
+ };
35189
+
35103
35190
  // Get current parsed weeks from value
35104
35191
  const {
35105
35192
  startWeek: currentStartWeek,
@@ -35140,15 +35227,43 @@ const WeeksPicker = _ref => {
35140
35227
  }
35141
35228
  }
35142
35229
  }, [isOpen]);
35230
+
35231
+ // Validate and clear invalid selections when allowedWeekRange changes
35232
+ useEffect(() => {
35233
+ if (restrictToRange && allowedWeekRange && value) {
35234
+ const {
35235
+ startWeek,
35236
+ endWeek
35237
+ } = parseValueToWeeks(value);
35238
+ if (startWeek && endWeek && !validateWeekSelection(startWeek, endWeek)) {
35239
+ // Clear invalid selection
35240
+ setValue("");
35241
+ onChange("");
35242
+ }
35243
+ }
35244
+ }, [allowedWeekRange, restrictToRange]);
35143
35245
  const handleToggle = () => {
35144
35246
  setIsOpen(!isOpen);
35145
35247
  };
35146
35248
  const onChangeEvent = e => {
35147
- onChange(e.target.value);
35148
- setValue(e.target.value);
35249
+ const newValue = e.target.value;
35250
+
35251
+ // If restriction is enabled, validate the manual input
35252
+ if (restrictToRange && allowedWeekRange && newValue) {
35253
+ const {
35254
+ startWeek,
35255
+ endWeek
35256
+ } = parseValueToWeeks(newValue);
35257
+ if (startWeek && endWeek && !validateWeekSelection(startWeek, endWeek)) {
35258
+ // Don't update if selection is outside allowed range
35259
+ return;
35260
+ }
35261
+ }
35262
+ onChange(newValue);
35263
+ setValue(newValue);
35149
35264
  };
35150
35265
  useEffect(() => {
35151
- if (selectedValue) {
35266
+ if (selectedValue !== undefined) {
35152
35267
  setValue(selectedValue);
35153
35268
  }
35154
35269
  }, [selectedValue]);
@@ -35223,8 +35338,17 @@ const WeeksPicker = _ref => {
35223
35338
  defaultStartWeek: currentStartWeek,
35224
35339
  defaultEndWeek: currentEndWeek,
35225
35340
  backgroundColor: borderColorFocus,
35226
- hoverBackgroundColor: hoverColor,
35341
+ hoverBackgroundColor: hoverColor
35342
+ // Pass restriction parameters to WeeksCalendar
35343
+ ,
35344
+ allowedWeekRange: restrictToRange ? allowedWeekRange : null,
35227
35345
  onApply: (start, end) => {
35346
+ // Validate selection before applying
35347
+ if (restrictToRange && allowedWeekRange && !validateWeekSelection(start, end)) {
35348
+ // Show error or prevent selection
35349
+ console.warn('Selected weeks are outside the allowed range');
35350
+ return;
35351
+ }
35228
35352
  const tempValue = end === start ? `Week ${start}` : `Weeks ${start} - ${end}`;
35229
35353
  onChange(tempValue);
35230
35354
  setValue(tempValue);
@@ -35925,9 +36049,9 @@ const ToggleSlider = styled.span`
35925
36049
  }
35926
36050
  `;
35927
36051
 
35928
- /**
35929
- * ToggleSwitch component for on/off states.
35930
- * Supports small/large sizes and disabled state.
36052
+ /**
36053
+ * ToggleSwitch component for on/off states.
36054
+ * Supports small/large sizes and disabled state.
35931
36055
  */
35932
36056
  function ToggleSwitch(_ref) {
35933
36057
  let {
@@ -37335,11 +37459,15 @@ const FilterPopContainer = styled.div`
37335
37459
  font-family: 'Poppins', sans-serif;
37336
37460
  width: ${props => props.width || '300px'};
37337
37461
  height: ${props => props.height || 'auto'};
37462
+ max-height: ${props => props.maxHeight || '400px'};
37338
37463
  padding: 8px;
37339
37464
  color: #212121;
37340
37465
  background-color: #fff;
37341
37466
  border-radius: 4px;
37342
37467
  box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.10);
37468
+ display: flex;
37469
+ flex-direction: column;
37470
+ overflow: hidden;
37343
37471
 
37344
37472
  /* Add this CSS for checkbox styling */
37345
37473
  input[type="checkbox"] {
@@ -37354,52 +37482,133 @@ const Title$5 = styled.h6`
37354
37482
  padding: 4px 12px;
37355
37483
  margin: 0 0 10px;
37356
37484
  text-align: left;
37485
+ flex-shrink: 0;
37486
+ `;
37487
+ const SearchInput = styled.input`
37488
+ width: 100%;
37489
+ padding: 8px 12px;
37490
+ margin: 0 0 12px;
37491
+ font-size: 14px;
37492
+ font-family: 'Poppins', sans-serif;
37493
+ border: 1px solid #e0e0e0;
37494
+ border-radius: 4px;
37495
+ background-color: #fff;
37496
+ color: #212121;
37497
+ flex-shrink: 0;
37498
+ box-sizing: border-box;
37499
+
37500
+ &::placeholder {
37501
+ color: #999;
37502
+ font-style: italic;
37503
+ }
37504
+
37505
+ &:focus {
37506
+ outline: none;
37507
+ border-color: ${props => props.accentColor || '#066768'};
37508
+ box-shadow: 0 0 0 2px ${props => props.accentColor || '#066768'}20;
37509
+ }
37510
+
37511
+ &:hover {
37512
+ border-color: #c0c0c0;
37513
+ }
37357
37514
  `;
37358
37515
  const CheckboxGroup = styled.div`
37359
- display: flex;
37360
- flex-direction: column;
37361
- gap: 8px;
37362
- margin-bottom: 16px;
37516
+ display: flex;
37517
+ flex-direction: column;
37518
+ gap: 8px;
37519
+ margin-bottom: 16px;
37520
+ overflow-y: auto;
37521
+ flex: 1;
37522
+ min-height: 0;
37523
+
37524
+ /* Custom scrollbar styling */
37525
+ &::-webkit-scrollbar {
37526
+ width: 6px;
37527
+ }
37528
+
37529
+ &::-webkit-scrollbar-track {
37530
+ background: #f1f1f1;
37531
+ border-radius: 3px;
37532
+ }
37533
+
37534
+ &::-webkit-scrollbar-thumb {
37535
+ background: #c1c1c1;
37536
+ border-radius: 3px;
37537
+ }
37538
+
37539
+ &::-webkit-scrollbar-thumb:hover {
37540
+ background: #a8a8a8;
37541
+ }
37542
+
37543
+ /* For Firefox */
37544
+ scrollbar-width: thin;
37545
+ scrollbar-color: #c1c1c1 #f1f1f1;
37363
37546
  `;
37364
37547
  const CheckboxLabel = styled.label`
37365
- display: flex;
37366
- align-items: center;
37367
- gap: 8px;
37368
- padding: 8px 12px;
37369
- font-size: 14px;
37370
- font-weight: 400;
37371
- color: #212121;
37372
- cursor: pointer;
37373
-
37374
- &:hover {
37375
- background-color: #E6F0F0;
37376
- }
37377
-
37378
- > span {
37379
- width: ${props => props.width};
37380
- white-space: nowrap;
37381
- overflow: hidden;
37382
- text-overflow: ellipsis;
37383
- }
37548
+ display: flex;
37549
+ align-items: center;
37550
+ gap: 8px;
37551
+ padding: 8px 12px;
37552
+ font-size: 14px;
37553
+ font-weight: 400;
37554
+ color: #212121;
37555
+ cursor: pointer;
37556
+ flex-shrink: 0;
37557
+
37558
+ &:hover {
37559
+ background-color: #E6F0F0;
37560
+ }
37561
+
37562
+ > span {
37563
+ width: ${props => props.width};
37564
+ white-space: nowrap;
37565
+ overflow: hidden;
37566
+ text-overflow: ellipsis;
37567
+ }
37568
+ `;
37569
+ const NoResultsMessage = styled.div`
37570
+ padding: 16px 12px;
37571
+ text-align: center;
37572
+ color: #999;
37573
+ font-size: 14px;
37574
+ font-style: italic;
37384
37575
  `;
37385
37576
  const ButtonWrapper$2 = styled.div`
37386
37577
  text-align: right;
37578
+ flex-shrink: 0;
37579
+ padding-top: 8px;
37580
+ border-top: 1px solid #e0e0e0;
37581
+ display: flex;
37582
+ justify-content: flex-end;
37583
+ align-items: center;
37387
37584
  `;
37388
37585
  const ResetButton$1 = styled.button`
37389
37586
  font-size: 14px;
37390
37587
  font-weight: 400;
37391
- padding: 2px 8px;
37588
+ padding: 4px 8px;
37392
37589
  background-color: transparent;
37393
37590
  border: none;
37394
37591
  cursor: pointer;
37592
+ border-radius: 3px;
37593
+
37594
+ &:hover {
37595
+ background-color: #f0f0f0;
37596
+ color: #066768;
37597
+ }
37395
37598
 
37396
- &:hover {
37397
- // color: #066768;
37398
- }
37399
-
37400
- &:active {
37401
- // color: #066768;
37402
- }
37599
+ &:active {
37600
+ color: #066768;
37601
+ }
37602
+
37603
+ &:disabled {
37604
+ color: #ccc;
37605
+ cursor: not-allowed;
37606
+
37607
+ &:hover {
37608
+ background-color: transparent;
37609
+ color: #ccc;
37610
+ }
37611
+ }
37403
37612
  `;
37404
37613
 
37405
37614
  const FilterPop = props => {
@@ -37407,15 +37616,22 @@ const FilterPop = props => {
37407
37616
  menuName = '',
37408
37617
  width = 'auto',
37409
37618
  height = 'auto',
37619
+ maxHeight = '400px',
37410
37620
  list = [],
37411
37621
  color = '#007bff',
37412
37622
  onCheck = () => {},
37413
37623
  onReset = () => {},
37414
37624
  doubleColumn = false,
37415
37625
  isAsc = true,
37416
- selectedAttributes: propSelectedAttributes = {} // Receive from parent
37626
+ selectedAttributes: propSelectedAttributes = {},
37627
+ showSearch = true,
37628
+ // New prop to enable/disable search
37629
+ searchPlaceholder = 'Search...' // New prop for search placeholder
37417
37630
  } = props;
37418
37631
 
37632
+ // State for search term
37633
+ const [searchTerm, setSearchTerm] = useState('');
37634
+
37419
37635
  // Add hardcoded "Select All" as first item
37420
37636
  const fullList = [{
37421
37637
  value: 'All',
@@ -37439,18 +37655,49 @@ const FilterPop = props => {
37439
37655
  return fullList.filter(item => item.value !== 'All');
37440
37656
  };
37441
37657
 
37442
- // Helper function to check if all non-"All" items are selected
37658
+ // Filter items based on search term
37659
+ const filteredList = useMemo(() => {
37660
+ if (!searchTerm.trim()) {
37661
+ return fullList;
37662
+ }
37663
+ const searchLower = searchTerm.toLowerCase().trim();
37664
+ const filteredNonAllItems = fullList.filter(item => {
37665
+ if (item.value === 'All') return false; // Don't filter out "Select All" in search
37666
+ return item.label.toLowerCase().includes(searchLower);
37667
+ });
37668
+
37669
+ // Always include "Select All" at the top when searching
37670
+ return [fullList.find(item => item.value === 'All'), ...filteredNonAllItems];
37671
+ }, [fullList, searchTerm]);
37672
+
37673
+ // Sort the filtered list based on the `isAsc` prop, keeping 'All' as the first option
37674
+ const sortedList = useMemo(() => {
37675
+ return [...filteredList.filter(item => item.value === 'All'), ...filteredList.filter(item => item.value !== 'All').sort((a, b) => {
37676
+ return isAsc ? a.label.localeCompare(b.label) : b.label.localeCompare(a.label);
37677
+ })];
37678
+ }, [filteredList, isAsc]);
37679
+
37680
+ // Helper functions for "Select All" logic based on ALL items (not just filtered)
37443
37681
  const areAllNonAllItemsSelected = function () {
37444
37682
  let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37445
37683
  const nonAllItems = getNonAllItems();
37446
37684
  return nonAllItems.every(item => attributes[item.value]);
37447
37685
  };
37448
37686
 
37449
- // Helper function to check if any non-"All" items are selected
37450
- const areAnyNonAllItemsSelected = function () {
37687
+ // Helper functions for visible filtered items
37688
+ const getVisibleNonAllItems = () => {
37689
+ return sortedList.filter(item => item.value !== 'All');
37690
+ };
37691
+ const areAllVisibleItemsSelected = function () {
37451
37692
  let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37452
- const nonAllItems = getNonAllItems();
37453
- return nonAllItems.some(item => attributes[item.value]);
37693
+ const visibleItems = getVisibleNonAllItems();
37694
+ if (visibleItems.length === 0) return false;
37695
+ return visibleItems.every(item => attributes[item.value]);
37696
+ };
37697
+ const areAnyVisibleItemsSelected = function () {
37698
+ let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37699
+ const visibleItems = getVisibleNonAllItems();
37700
+ return visibleItems.some(item => attributes[item.value]);
37454
37701
  };
37455
37702
 
37456
37703
  // New helper function to create the efficient data structure
@@ -37474,14 +37721,12 @@ const FilterPop = props => {
37474
37721
  isSelectAll: false
37475
37722
  };
37476
37723
  } else if (mostSelected) {
37477
- // More items selected than unselected - use exclude approach
37478
37724
  return {
37479
37725
  excluded: unselectedItems.map(item => item.value),
37480
37726
  included: [],
37481
37727
  isSelectAll: true
37482
37728
  };
37483
37729
  } else {
37484
- // Fewer items selected than unselected - use include approach
37485
37730
  return {
37486
37731
  excluded: [],
37487
37732
  included: selectedItems.map(item => item.value),
@@ -37491,47 +37736,50 @@ const FilterPop = props => {
37491
37736
  };
37492
37737
  const handleCheckboxChange = attribute => {
37493
37738
  if (attribute === 'All') {
37494
- // If "Select All" is clicked - determine new state based on current "Select All" state
37495
- const currentSelectAllState = selectedAttributes.All || false;
37496
- const newState = !currentSelectAllState;
37497
- const updatedAttributes = {};
37739
+ // "Select All" behavior - affects ALL visible filtered items
37740
+ const visibleNonAllItems = getVisibleNonAllItems();
37741
+ const allVisibleSelected = areAllVisibleItemsSelected();
37498
37742
 
37499
- // Set all items to the same state as "Select All"
37500
- fullList.forEach(item => {
37501
- updatedAttributes[item.value] = newState;
37743
+ // Toggle all visible items
37744
+ const updatedAttributes = {
37745
+ ...selectedAttributes
37746
+ };
37747
+ visibleNonAllItems.forEach(item => {
37748
+ updatedAttributes[item.value] = !allVisibleSelected;
37502
37749
  });
37503
37750
 
37504
- // Call onCheck callback with new efficient structure
37751
+ // Update "Select All" state based on all items (not just visible)
37752
+ updatedAttributes.All = areAllNonAllItemsSelected(updatedAttributes);
37505
37753
  const filterData = createFilterData(updatedAttributes);
37506
37754
  onCheck({
37507
37755
  changedItem: attribute,
37508
37756
  filterData: filterData,
37509
- allItems: updatedAttributes // Keep for backward compatibility if needed
37757
+ allItems: updatedAttributes
37510
37758
  });
37511
37759
  } else {
37512
- // If any other item is clicked
37760
+ // Individual item clicked
37513
37761
  const updatedAttributes = {
37514
37762
  ...selectedAttributes,
37515
37763
  [attribute]: !selectedAttributes[attribute]
37516
37764
  };
37517
37765
 
37518
- // Call onCheck callback with new efficient structure
37766
+ // Update "Select All" state based on all items
37767
+ updatedAttributes.All = areAllNonAllItemsSelected(updatedAttributes);
37519
37768
  const filterData = createFilterData(updatedAttributes);
37520
37769
  onCheck({
37521
37770
  changedItem: attribute,
37522
37771
  filterData: filterData,
37523
- allItems: updatedAttributes // Keep for backward compatibility if needed
37772
+ allItems: updatedAttributes
37524
37773
  });
37525
37774
  }
37526
37775
  };
37527
37776
  const handleReset = () => {
37777
+ // Clear search when resetting
37778
+ setSearchTerm('');
37779
+
37528
37780
  // Reset to the original default state (all selected)
37529
37781
  const resetState = createInitialState();
37530
-
37531
- // Call the onReset callback
37532
37782
  onReset();
37533
-
37534
- // Also call onCheck to notify parent of the reset with new efficient structure
37535
37783
  const filterData = createFilterData(resetState);
37536
37784
  onCheck({
37537
37785
  changedItem: 'reset',
@@ -37540,17 +37788,24 @@ const FilterPop = props => {
37540
37788
  });
37541
37789
  };
37542
37790
 
37543
- // Function to determine checkbox state for "Select All"
37791
+ // Function to determine checkbox state for "Select All" based on visible items
37544
37792
  const getSelectAllCheckboxProps = () => {
37545
- const allSelected = areAllNonAllItemsSelected();
37546
- const anySelected = areAnyNonAllItemsSelected();
37547
- const noneSelected = !anySelected;
37548
- if (allSelected) {
37793
+ const visibleItems = getVisibleNonAllItems();
37794
+ if (visibleItems.length === 0) {
37795
+ return {
37796
+ checked: false,
37797
+ indeterminate: false
37798
+ };
37799
+ }
37800
+ const allVisibleSelected = areAllVisibleItemsSelected();
37801
+ const anyVisibleSelected = areAnyVisibleItemsSelected();
37802
+ const noneVisibleSelected = !anyVisibleSelected;
37803
+ if (allVisibleSelected) {
37549
37804
  return {
37550
37805
  checked: true,
37551
37806
  indeterminate: false
37552
37807
  };
37553
- } else if (noneSelected) {
37808
+ } else if (noneVisibleSelected) {
37554
37809
  return {
37555
37810
  checked: false,
37556
37811
  indeterminate: false
@@ -37563,38 +37818,50 @@ const FilterPop = props => {
37563
37818
  }
37564
37819
  };
37565
37820
 
37566
- // Sort the list based on the `isAsc` prop, keeping 'All' as the first option
37567
- const sortedList = [...fullList.filter(item => item.value === 'All'), ...fullList.filter(item => item.value !== 'All').sort((a, b) => {
37568
- return isAsc ? a.label.localeCompare(b.label) : b.label.localeCompare(a.label);
37569
- })];
37821
+ // Handle search input change
37822
+ const handleSearchChange = e => {
37823
+ setSearchTerm(e.target.value);
37824
+ };
37825
+
37826
+ // Clear search
37827
+ const clearSearch = () => {
37828
+ setSearchTerm('');
37829
+ };
37570
37830
  return /*#__PURE__*/React$1.createElement(FilterPopContainer, {
37571
37831
  width: width,
37572
37832
  height: height,
37573
- accentColor: color // Pass color as prop to styled component
37574
- }, /*#__PURE__*/React$1.createElement(Title$5, null, menuName), /*#__PURE__*/React$1.createElement(CheckboxGroup, {
37833
+ maxHeight: maxHeight,
37834
+ accentColor: color
37835
+ }, /*#__PURE__*/React$1.createElement(Title$5, null, menuName), showSearch && /*#__PURE__*/React$1.createElement(SearchInput, {
37836
+ type: "text",
37837
+ placeholder: searchPlaceholder,
37838
+ value: searchTerm,
37839
+ onChange: handleSearchChange,
37840
+ accentColor: color
37841
+ }), /*#__PURE__*/React$1.createElement(CheckboxGroup, {
37575
37842
  style: {
37576
37843
  display: doubleColumn ? 'grid' : 'flex',
37577
37844
  gridTemplateColumns: doubleColumn ? '1fr 1fr' : 'none',
37578
37845
  gap: '8px'
37579
37846
  }
37580
- }, sortedList.map(item => {
37847
+ }, sortedList.length === 1 ?
37848
+ /*#__PURE__*/
37849
+ // Only "Select All" is visible
37850
+ React$1.createElement(NoResultsMessage, null, "No items match your search") : sortedList.map(item => {
37581
37851
  const isSelectAll = item.value === 'All';
37582
37852
  const checkboxProps = isSelectAll ? getSelectAllCheckboxProps() : {};
37583
37853
  const isChecked = isSelectAll ? checkboxProps.checked : selectedAttributes[item.value] || false;
37584
37854
  return /*#__PURE__*/React$1.createElement(CheckboxLabel, {
37585
37855
  width: !doubleColumn ?? width,
37586
- key: `${item.value}-${JSON.stringify(selectedAttributes)}`
37856
+ key: `${item.value}-${JSON.stringify(selectedAttributes)}-${searchTerm}`
37587
37857
  }, /*#__PURE__*/React$1.createElement("input", {
37588
37858
  type: "checkbox",
37589
37859
  checked: isChecked,
37590
37860
  ref: el => {
37591
37861
  if (el) {
37592
- // Handle indeterminate for Select All FIRST
37593
37862
  if (isSelectAll) {
37594
37863
  el.indeterminate = checkboxProps.indeterminate;
37595
37864
  }
37596
-
37597
- // FORCE DOM SYNC - manually set DOM state to match React state
37598
37865
  if (el.checked !== isChecked) {
37599
37866
  el.checked = isChecked;
37600
37867
  }
@@ -37604,7 +37871,12 @@ const FilterPop = props => {
37604
37871
  handleCheckboxChange(item.value);
37605
37872
  }
37606
37873
  }), /*#__PURE__*/React$1.createElement("span", null, item.label));
37607
- })), /*#__PURE__*/React$1.createElement(ButtonWrapper$2, null, /*#__PURE__*/React$1.createElement(ResetButton$1, {
37874
+ })), /*#__PURE__*/React$1.createElement(ButtonWrapper$2, null, showSearch && searchTerm && /*#__PURE__*/React$1.createElement(ResetButton$1, {
37875
+ onClick: clearSearch,
37876
+ style: {
37877
+ marginRight: '8px'
37878
+ }
37879
+ }, "Clear Search"), /*#__PURE__*/React$1.createElement(ResetButton$1, {
37608
37880
  onClick: handleReset,
37609
37881
  disabled: areAllNonAllItemsSelected() && selectedAttributes.All
37610
37882
  }, "Reset")));
@@ -55305,5 +55577,5 @@ const Tag = props => {
55305
55577
  }, /*#__PURE__*/React$1.createElement("span", null, text || template?.text));
55306
55578
  };
55307
55579
 
55308
- export { AdvancedThresholds, Analytics, AreaChart, BannerEventBoxList, BarChart, BarChartTwoRows, BarChartWithAreaChart, BarChartsByWeeks, BatteryChart, BreakdownPanel, BrushChart, BubbleChart, Budgets, Build, Button$1 as Button, Campaigns, CheckBox, CollapseData, CollapseHeader, ContainerTable, Coupons, CustomerSegments, Dashboard, DialogOverlay$1 as DialogOverlay, DoubleBarSingleLine, DoublePanelDataRow, DownloadProgress, DropdownNew, EventDetailsCard, EventList, Execute, FilterPanel, FilterPop, GroupBuilder, Heatmap, IconButton$1 as IconButton, Input$2 as Input, InsightsCarousel, ItemManagerPanel, ItemsStores, LinkButton, LinnerDataBox, MarketShareDescription, MenuRoute, MessageBox, ModalDrawer, ModalWithOverlay, OneColumnContainer, OverlayDropdown, PerformanceAnalyticsLegend, PieChart, PopupCharts, PreTestWhatIf, QuickFilter, QuickFilterCards, RangePicker, RangePop, ReportTable, RulesEngine, SampleRunEngine, SearchInput, SingleBarLineCharts, SortPop, TabMenu, Table, Tag, ToasterMessageBox, ToggleSwitch, Tooltip$2 as Tooltip, TopToggleList, TotalDoughnutChart, TotalHorizontalCharts, Track, TwoBarCharts, WeeksPicker };
55580
+ export { AdvancedThresholds, Analytics, AreaChart, BannerEventBoxList, BarChart, BarChartTwoRows, BarChartWithAreaChart, BarChartsByWeeks, BatteryChart, BreakdownPanel, BrushChart, BubbleChart, Budgets, Build, Button$1 as Button, Campaigns, CheckBox, CollapseData, CollapseHeader, ContainerTable, Coupons, CustomerSegments, Dashboard, DialogOverlay$1 as DialogOverlay, DoubleBarSingleLine, DoublePanelDataRow, DownloadProgress, DropdownNew, EventDetailsCard, EventList, Execute, FilterPanel, FilterPop, GroupBuilder, Heatmap, IconButton$1 as IconButton, Input$2 as Input, InsightsCarousel, ItemManagerPanel, ItemsStores, LinkButton, LinnerDataBox, MarketShareDescription, MenuRoute, MessageBox, ModalDrawer, ModalWithOverlay, OneColumnContainer, OverlayDropdown, PerformanceAnalyticsLegend, PieChart, PopupCharts, PreTestWhatIf, QuickFilter, QuickFilterCards, RangePicker, RangePop, ReportTable, RulesEngine, SampleRunEngine, SearchInput$1 as SearchInput, SingleBarLineCharts, SortPop, TabMenu, Table, Tag, ToasterMessageBox, ToggleSwitch, Tooltip$2 as Tooltip, TopToggleList, TotalDoughnutChart, TotalHorizontalCharts, Track, TwoBarCharts, WeeksPicker };
55309
55581
  //# sourceMappingURL=index.esm.js.map