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.js CHANGED
@@ -3782,7 +3782,7 @@ const TextFieldInput = styled__default["default"].input`
3782
3782
  }
3783
3783
  `;
3784
3784
 
3785
- const SearchInput = props => {
3785
+ const SearchInput$1 = props => {
3786
3786
  const {
3787
3787
  value,
3788
3788
  placeholder = 'Search',
@@ -3927,7 +3927,7 @@ const ActionsWrapper = styled__default["default"].div`
3927
3927
  gap: 10px;
3928
3928
  width: 100%;
3929
3929
  `;
3930
- const SearchInputWrap = styled__default["default"](SearchInput)`
3930
+ const SearchInputWrap = styled__default["default"](SearchInput$1)`
3931
3931
  margin-left: auto;
3932
3932
  `;
3933
3933
 
@@ -10589,24 +10589,23 @@ const QuarterPopupPicker = ({
10589
10589
  };
10590
10590
 
10591
10591
  /* eslint-disable import/no-extraneous-dependencies */
10592
- const QuarterPicker = _ref => {
10593
- let {
10594
- availableQuarters,
10595
- // ["Q1-2024"]
10596
- label,
10597
- onChange,
10598
- borderRadius,
10599
- required,
10600
- width,
10601
- height,
10602
- placeholder,
10603
- disabled,
10604
- borderColor,
10605
- borderColorFocus,
10606
- textColor,
10607
- selectedValue,
10608
- startYear
10609
- } = _ref;
10592
+ const QuarterPicker = ({
10593
+ availableQuarters,
10594
+ // ["Q1-2024"]
10595
+ label,
10596
+ onChange,
10597
+ borderRadius,
10598
+ required,
10599
+ width,
10600
+ height,
10601
+ placeholder,
10602
+ disabled,
10603
+ borderColor,
10604
+ borderColorFocus,
10605
+ textColor,
10606
+ selectedValue,
10607
+ startYear
10608
+ }) => {
10610
10609
  const [isFocused, setIsFocused] = React$1.useState(false);
10611
10610
  const [isOpen, setIsOpen] = React$1.useState(false);
10612
10611
  const [value, setValue] = React$1.useState('');
@@ -11048,23 +11047,22 @@ const MonthPopupPicker = ({
11048
11047
  };
11049
11048
 
11050
11049
  /* eslint-disable import/no-extraneous-dependencies */
11051
- const MonthPicker = _ref => {
11052
- let {
11053
- availableMonths,
11054
- label,
11055
- onChange,
11056
- borderRadius,
11057
- required,
11058
- width,
11059
- height,
11060
- placeholder,
11061
- disabled,
11062
- borderColor,
11063
- borderColorFocus,
11064
- textColor,
11065
- selectedValue,
11066
- startYear
11067
- } = _ref;
11050
+ const MonthPicker = ({
11051
+ availableMonths,
11052
+ label,
11053
+ onChange,
11054
+ borderRadius,
11055
+ required,
11056
+ width,
11057
+ height,
11058
+ placeholder,
11059
+ disabled,
11060
+ borderColor,
11061
+ borderColorFocus,
11062
+ textColor,
11063
+ selectedValue,
11064
+ startYear
11065
+ }) => {
11068
11066
  const [isFocused, setIsFocused] = React$1.useState(false);
11069
11067
  const [isOpen, setIsOpen] = React$1.useState(false);
11070
11068
  const [value, setValue] = React$1.useState('');
@@ -24175,22 +24173,21 @@ const DeleteIcon = styled__default["default"].div`
24175
24173
  position: absolute;
24176
24174
  `;
24177
24175
 
24178
- const QuickFilterDropdownSingle = _ref => {
24179
- let {
24180
- label,
24181
- hoverColor,
24182
- options,
24183
- selectedValue,
24184
- placeHolder,
24185
- onChange,
24186
- disabled,
24187
- width,
24188
- error,
24189
- errorMessage,
24190
- xIconShow,
24191
- labelColor,
24192
- showLabelOnTop
24193
- } = _ref;
24176
+ const QuickFilterDropdownSingle = ({
24177
+ label,
24178
+ hoverColor,
24179
+ options,
24180
+ selectedValue,
24181
+ placeHolder,
24182
+ onChange,
24183
+ disabled,
24184
+ width,
24185
+ error,
24186
+ errorMessage,
24187
+ xIconShow,
24188
+ labelColor,
24189
+ showLabelOnTop
24190
+ }) => {
24194
24191
  const [isFocused, setIsFocused] = React$1.useState(false);
24195
24192
  const [showOptions, setShowOptions] = React$1.useState(false);
24196
24193
  const [inputValue, setInputValue] = React$1.useState("");
@@ -24587,24 +24584,23 @@ const IconContainer$2 = styled__default["default"].div`
24587
24584
  cursor: pointer;
24588
24585
  `;
24589
24586
 
24590
- const QuickFilterDropdownMultiSelection = _ref => {
24591
- let {
24592
- label,
24593
- labelEmptyValue,
24594
- options,
24595
- selectedValue,
24596
- placeHolder,
24597
- onChange,
24598
- required,
24599
- disabled,
24600
- width,
24601
- error,
24602
- errorMessage,
24603
- labelColor,
24604
- xIconShow,
24605
- checkBoxColor,
24606
- showLabelOnTop
24607
- } = _ref;
24587
+ const QuickFilterDropdownMultiSelection = ({
24588
+ label,
24589
+ labelEmptyValue,
24590
+ options,
24591
+ selectedValue,
24592
+ placeHolder,
24593
+ onChange,
24594
+ required,
24595
+ disabled,
24596
+ width,
24597
+ error,
24598
+ errorMessage,
24599
+ labelColor,
24600
+ xIconShow,
24601
+ checkBoxColor,
24602
+ showLabelOnTop
24603
+ }) => {
24608
24604
  const [isFocused, setIsFocused] = React$1.useState(false);
24609
24605
  const [showOptions, setShowOptions] = React$1.useState(false);
24610
24606
  const [inputValue, setInputValue] = React$1.useState('');
@@ -34736,6 +34732,8 @@ const ModalWithOverlay = props => {
34736
34732
  }, children)));
34737
34733
  };
34738
34734
 
34735
+ // src/components/WeeksPicker/WeeksCalendar.styles.js
34736
+
34739
34737
  /* ──────────────────────────────────────────
34740
34738
  COLORS – map to your design-system tokens
34741
34739
  Change only here if the palette shifts
@@ -34747,7 +34745,9 @@ const c = {
34747
34745
  primary: "#016672",
34748
34746
  // apply / highlight
34749
34747
  primaryLight: "#d1e7ea",
34750
- border: "#e0e0e0"
34748
+ border: "#e0e0e0",
34749
+ disabled: "#f5f5f5",
34750
+ disabledText: "#bdbdbd"
34751
34751
  };
34752
34752
 
34753
34753
  /* ───────────────────────── wrapper */
@@ -34787,34 +34787,56 @@ const WeekCell = styled__default["default"].div`
34787
34787
  text-align: center;
34788
34788
  cursor: pointer;
34789
34789
  color: ${c.textSecondary};
34790
- transition: background 0.15s ease;
34791
- border-radius: 4px;
34790
+ transition: background 0.15s ease, opacity 0.15s ease, color 0.15s ease;
34791
+ border-radius: 4px;
34792
34792
 
34793
+ /* Disabled state - highest priority */
34793
34794
  ${({
34794
- $selected
34795
- }) => $selected && styled.css`
34795
+ $disabled
34796
+ }) => $disabled && styled.css`
34797
+ opacity: 0.3;
34798
+ cursor: not-allowed;
34799
+ background: ${c.disabled} !important;
34800
+ color: ${c.disabledText} !important;
34801
+
34802
+ &:hover {
34803
+ background: ${c.disabled} !important;
34804
+ color: ${c.disabledText} !important;
34805
+ }
34806
+ `}
34796
34807
 
34808
+ /* Selected state - only if not disabled */
34809
+ ${({
34810
+ $selected,
34811
+ $disabled
34812
+ }) => $selected && !$disabled && styled.css`
34797
34813
  background: ${c.primary};
34798
34814
  color: #FFFFFF;
34799
34815
  `}
34800
34816
 
34801
- /* highlight range interior lighter */
34817
+ /* Range middle highlighting - only if not disabled */
34802
34818
  ${({
34803
- $isRangeMiddle
34804
- }) => $isRangeMiddle && styled.css`
34819
+ $isRangeMiddle,
34820
+ $disabled
34821
+ }) => $isRangeMiddle && !$disabled && styled.css`
34805
34822
  background: ${c.primaryLight};
34806
34823
  border-radius: 0px;
34807
34824
  color: ${c.text};
34808
34825
  `}
34809
34826
 
34810
- &:hover {
34811
- background: ${c.primaryLight};
34812
- color: ${c.text};
34813
- }
34827
+ /* Hover state - only if not disabled */
34828
+ ${({
34829
+ $disabled
34830
+ }) => !$disabled && styled.css`
34831
+ &:hover {
34832
+ background: ${c.primaryLight};
34833
+ color: ${c.text};
34834
+ }
34835
+ `}
34836
+
34837
+ /* Typography */
34814
34838
  text-align: center;
34815
34839
  font-feature-settings: "liga" off;
34816
-
34817
- /* Content/P3 Regular */
34818
34840
  font-family: Poppins;
34819
34841
  font-size: 12px;
34820
34842
  font-style: normal;
@@ -34847,15 +34869,20 @@ styled.css`
34847
34869
  }
34848
34870
  `;
34849
34871
 
34872
+ // src/components/WeeksPicker/WeeksCalendar.jsx
34873
+
34850
34874
  /**
34851
34875
  * WeeksCalendar
34852
34876
  * -------------
34853
34877
  * Props
34854
- * • year four-digit year (required)
34855
- * • defaultStartWeek number | null
34856
- * • defaultEndWeek number | null
34857
- * • onApply(start,end) callback, both numbers (inclusive)
34858
- * • onCancel() – callback
34878
+ * • year four-digit year (required)
34879
+ * • defaultStartWeek number | null
34880
+ * • defaultEndWeek number | null
34881
+ * • backgroundColor — string (default: "#066768")
34882
+ * • hoverBackgroundColor — string (default: "#E6F0F0")
34883
+ * • allowedWeekRange — { startWeek: number, endWeek: number } | null
34884
+ * • onApply(start,end) — callback, both numbers (inclusive)
34885
+ * • onCancel() — callback
34859
34886
  */
34860
34887
  const WeeksCalendar = ({
34861
34888
  year,
@@ -34863,6 +34890,8 @@ const WeeksCalendar = ({
34863
34890
  defaultEndWeek = null,
34864
34891
  backgroundColor = "#066768",
34865
34892
  hoverBackgroundColor = "#E6F0F0",
34893
+ allowedWeekRange = null,
34894
+ // New prop for range restriction
34866
34895
  onApply,
34867
34896
  onCancel
34868
34897
  }) => {
@@ -34880,14 +34909,29 @@ const WeeksCalendar = ({
34880
34909
  const hasSelection = startWeek !== null;
34881
34910
  const isRange = hasSelection && endWeek !== null && endWeek !== startWeek;
34882
34911
  const weeks = React$1.useMemo(() => [...Array(53)].map((_, i) => i + 1), []);
34912
+
34913
+ // Check if a week is disabled based on allowed range
34914
+ const isWeekDisabled = week => {
34915
+ if (!allowedWeekRange) return false;
34916
+ const {
34917
+ startWeek: allowedStart,
34918
+ endWeek: allowedEnd
34919
+ } = allowedWeekRange;
34920
+ return week < allowedStart || week > allowedEnd;
34921
+ };
34883
34922
  const handleCellClick = week => {
34884
- // first click start
34923
+ // Don't allow selection of disabled weeks
34924
+ if (isWeekDisabled(week)) {
34925
+ return;
34926
+ }
34885
34927
 
34928
+ // first click → start
34886
34929
  if (!hasSelection) {
34887
34930
  setStartWeek(week);
34888
34931
  setEndWeek(null);
34889
34932
  return;
34890
34933
  }
34934
+
34891
34935
  // second click → decide range or single
34892
34936
  if (hasSelection && endWeek === null) {
34893
34937
  // second click on same cell turns it to single selection
@@ -34900,6 +34944,7 @@ const WeeksCalendar = ({
34900
34944
  setStartWeek(week < startWeek ? week : startWeek);
34901
34945
  return;
34902
34946
  }
34947
+
34903
34948
  // any later click resets selection and starts over
34904
34949
  setStartWeek(week);
34905
34950
  setEndWeek(null);
@@ -34915,11 +34960,14 @@ const WeeksCalendar = ({
34915
34960
  columns: 6
34916
34961
  }, weeks.map(wk => {
34917
34962
  const selected = wk === startWeek || isRange && wk >= startWeek && wk <= endWeek;
34963
+ const disabled = isWeekDisabled(wk);
34964
+ const isRangeMiddle = selected && wk !== startWeek && wk !== endWeek;
34918
34965
  return /*#__PURE__*/React__default["default"].createElement(WeekCell, {
34919
34966
  key: wk,
34920
34967
  "data-week": wk,
34921
34968
  $selected: selected,
34922
- $isRangeMiddle: selected && wk !== startWeek && wk !== endWeek,
34969
+ $isRangeMiddle: isRangeMiddle,
34970
+ $disabled: disabled,
34923
34971
  onClick: () => handleCellClick(wk)
34924
34972
  }, wk);
34925
34973
  })), /*#__PURE__*/React__default["default"].createElement(Footer, null, /*#__PURE__*/React__default["default"].createElement(Button$1, {
@@ -34953,6 +35001,12 @@ WeeksCalendar.propTypes = {
34953
35001
  year: PropTypes.number.isRequired,
34954
35002
  defaultStartWeek: PropTypes.number,
34955
35003
  defaultEndWeek: PropTypes.number,
35004
+ backgroundColor: PropTypes.string,
35005
+ hoverBackgroundColor: PropTypes.string,
35006
+ allowedWeekRange: PropTypes.shape({
35007
+ startWeek: PropTypes.number.isRequired,
35008
+ endWeek: PropTypes.number.isRequired
35009
+ }),
34956
35010
  onApply: PropTypes.func.isRequired,
34957
35011
  onCancel: PropTypes.func
34958
35012
  };
@@ -34979,22 +35033,28 @@ const StyledInput$1 = styled__default["default"].input`
34979
35033
  box-sizing: border-box;
34980
35034
  color: ${props => props.disabled ? '#888' : (props.isFocused || props.value ? props.textColor : '#757575') || '#333'};
34981
35035
  cursor: ${props => props.disabled ? 'not-allowed' : 'text'};
35036
+
35037
+ &:disabled {
35038
+ background-color: #f5f5f5;
35039
+ cursor: not-allowed;
35040
+ }
34982
35041
  `;
34983
35042
  const StyledLabel = styled__default["default"].label`
34984
35043
  font-size: 14px;
34985
- /* width: ${props => props.isFocused || props.hasValue ? 'auto' : '150px'}; */
34986
35044
  color: ${props => props.disabled ? '#888' : (props.isFocused || props.hasValue ? props.borderColorFocus : '#757575') || '#333'};
34987
35045
  position: absolute;
34988
35046
  top: ${props => props.isFocused || props.hasValue ? '0px' : '50%'};
34989
35047
  left: 15px;
34990
35048
  background-color: ${props => props.isFocused || props.hasValue ? 'white' : 'transparent'};
34991
35049
  transform: translateY(-50%);
34992
- transition: top 0.3s ease, font-size 0.3s ease;
35050
+ transition: top 0.3s ease, font-size 0.3s ease, color 0.3s ease;
34993
35051
  display: flex;
34994
35052
  font-weight: 400;
34995
35053
  align-items: center;
34996
35054
  box-sizing: border-box;
34997
- cursor: pointer;
35055
+ cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
35056
+ padding: 0 4px;
35057
+ z-index: 1;
34998
35058
  `;
34999
35059
  const RequiredIndicator = styled__default["default"].span`
35000
35060
  color: red;
@@ -35010,9 +35070,13 @@ const OptionsContainer = styled__default["default"].div`
35010
35070
  z-index: 999;
35011
35071
  ${props => props.showAbove ? `
35012
35072
  bottom: 100%;
35073
+ margin-bottom: 4px;
35013
35074
  ` : `
35014
35075
  top: 100%;
35076
+ margin-top: 4px;
35015
35077
  `}
35078
+ left: 0;
35079
+ right: 0;
35016
35080
  `;
35017
35081
  const InputContainer$1 = styled__default["default"].div`
35018
35082
  display: flex;
@@ -35025,20 +35089,22 @@ const InputContainer$1 = styled__default["default"].div`
35025
35089
  width: 100%;
35026
35090
  height: 100%;
35027
35091
  box-sizing: border-box;
35028
- background-color: transparent;
35029
- border: 1px solid ${props => props.disabled ? '#bdbdbd' : props.error ? 'red' : '#B1B1B1'};
35092
+ background-color: ${props => props.disabled ? '#f5f5f5' : 'transparent'};
35093
+ border: 1px solid ${props => props.disabled ? '#bdbdbd' : props.error ? 'red' : '#B1B1B1'};
35030
35094
  font-weight: 400;
35031
35095
  font-size: 14px;
35032
35096
  border-radius: 12px;
35033
35097
  outline: none;
35034
35098
  color: ${props => props.disabled ? '#888' : '#212121'};
35099
+ position: relative;
35100
+ transition: border-color 0.3s ease, background-color 0.3s ease;
35035
35101
 
35036
35102
  &:hover {
35037
35103
  border: 1px solid ${props => props.disabled ? '#bdbdbd' : props.error ? 'red' : props.borderColorFocus || '#212121'};
35038
35104
  cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
35039
35105
  }
35040
35106
 
35041
- &:focus {
35107
+ &:focus-within {
35042
35108
  border: 1px solid ${props => props.disabled ? '#bdbdbd' : props.error ? 'red' : props.borderColorFocus || '#212121'};
35043
35109
  }
35044
35110
  `;
@@ -35048,6 +35114,11 @@ const CalendarDiv = styled__default["default"].div`
35048
35114
  right: 10px;
35049
35115
  display: flex;
35050
35116
  align-items: center;
35117
+ cursor: ${props => props.disabled ? 'not-allowed' : 'pointer'};
35118
+
35119
+ svg {
35120
+ transition: fill 0.3s ease;
35121
+ }
35051
35122
  `;
35052
35123
 
35053
35124
  // src/components/WeeksPicker/WeeksPicker.jsx
@@ -35067,7 +35138,11 @@ const WeeksPicker = _ref => {
35067
35138
  height,
35068
35139
  withMarginBottom = true,
35069
35140
  onChange,
35070
- selectedValue
35141
+ selectedValue,
35142
+ // New props for range restriction
35143
+ allowedWeekRange = null,
35144
+ // { startWeek: number, endWeek: number } or null
35145
+ restrictToRange = false // boolean to enable/disable restriction
35071
35146
  } = _ref;
35072
35147
  const [value, setValue] = React$1.useState("");
35073
35148
  const inputRef = React$1.useRef(null);
@@ -35110,6 +35185,18 @@ const WeeksPicker = _ref => {
35110
35185
  };
35111
35186
  };
35112
35187
 
35188
+ // Validate if selected weeks are within allowed range
35189
+ const validateWeekSelection = (startWeek, endWeek) => {
35190
+ if (!restrictToRange || !allowedWeekRange) {
35191
+ return true;
35192
+ }
35193
+ const {
35194
+ startWeek: allowedStart,
35195
+ endWeek: allowedEnd
35196
+ } = allowedWeekRange;
35197
+ return startWeek >= allowedStart && endWeek <= allowedEnd && startWeek <= endWeek;
35198
+ };
35199
+
35113
35200
  // Get current parsed weeks from value
35114
35201
  const {
35115
35202
  startWeek: currentStartWeek,
@@ -35150,15 +35237,43 @@ const WeeksPicker = _ref => {
35150
35237
  }
35151
35238
  }
35152
35239
  }, [isOpen]);
35240
+
35241
+ // Validate and clear invalid selections when allowedWeekRange changes
35242
+ React$1.useEffect(() => {
35243
+ if (restrictToRange && allowedWeekRange && value) {
35244
+ const {
35245
+ startWeek,
35246
+ endWeek
35247
+ } = parseValueToWeeks(value);
35248
+ if (startWeek && endWeek && !validateWeekSelection(startWeek, endWeek)) {
35249
+ // Clear invalid selection
35250
+ setValue("");
35251
+ onChange("");
35252
+ }
35253
+ }
35254
+ }, [allowedWeekRange, restrictToRange]);
35153
35255
  const handleToggle = () => {
35154
35256
  setIsOpen(!isOpen);
35155
35257
  };
35156
35258
  const onChangeEvent = e => {
35157
- onChange(e.target.value);
35158
- setValue(e.target.value);
35259
+ const newValue = e.target.value;
35260
+
35261
+ // If restriction is enabled, validate the manual input
35262
+ if (restrictToRange && allowedWeekRange && newValue) {
35263
+ const {
35264
+ startWeek,
35265
+ endWeek
35266
+ } = parseValueToWeeks(newValue);
35267
+ if (startWeek && endWeek && !validateWeekSelection(startWeek, endWeek)) {
35268
+ // Don't update if selection is outside allowed range
35269
+ return;
35270
+ }
35271
+ }
35272
+ onChange(newValue);
35273
+ setValue(newValue);
35159
35274
  };
35160
35275
  React$1.useEffect(() => {
35161
- if (selectedValue) {
35276
+ if (selectedValue !== undefined) {
35162
35277
  setValue(selectedValue);
35163
35278
  }
35164
35279
  }, [selectedValue]);
@@ -35233,8 +35348,17 @@ const WeeksPicker = _ref => {
35233
35348
  defaultStartWeek: currentStartWeek,
35234
35349
  defaultEndWeek: currentEndWeek,
35235
35350
  backgroundColor: borderColorFocus,
35236
- hoverBackgroundColor: hoverColor,
35351
+ hoverBackgroundColor: hoverColor
35352
+ // Pass restriction parameters to WeeksCalendar
35353
+ ,
35354
+ allowedWeekRange: restrictToRange ? allowedWeekRange : null,
35237
35355
  onApply: (start, end) => {
35356
+ // Validate selection before applying
35357
+ if (restrictToRange && allowedWeekRange && !validateWeekSelection(start, end)) {
35358
+ // Show error or prevent selection
35359
+ console.warn('Selected weeks are outside the allowed range');
35360
+ return;
35361
+ }
35238
35362
  const tempValue = end === start ? `Week ${start}` : `Weeks ${start} - ${end}`;
35239
35363
  onChange(tempValue);
35240
35364
  setValue(tempValue);
@@ -35935,9 +36059,9 @@ const ToggleSlider = styled__default["default"].span`
35935
36059
  }
35936
36060
  `;
35937
36061
 
35938
- /**
35939
- * ToggleSwitch component for on/off states.
35940
- * Supports small/large sizes and disabled state.
36062
+ /**
36063
+ * ToggleSwitch component for on/off states.
36064
+ * Supports small/large sizes and disabled state.
35941
36065
  */
35942
36066
  function ToggleSwitch(_ref) {
35943
36067
  let {
@@ -37345,11 +37469,15 @@ const FilterPopContainer = styled__default["default"].div`
37345
37469
  font-family: 'Poppins', sans-serif;
37346
37470
  width: ${props => props.width || '300px'};
37347
37471
  height: ${props => props.height || 'auto'};
37472
+ max-height: ${props => props.maxHeight || '400px'};
37348
37473
  padding: 8px;
37349
37474
  color: #212121;
37350
37475
  background-color: #fff;
37351
37476
  border-radius: 4px;
37352
37477
  box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.10);
37478
+ display: flex;
37479
+ flex-direction: column;
37480
+ overflow: hidden;
37353
37481
 
37354
37482
  /* Add this CSS for checkbox styling */
37355
37483
  input[type="checkbox"] {
@@ -37364,52 +37492,133 @@ const Title$5 = styled__default["default"].h6`
37364
37492
  padding: 4px 12px;
37365
37493
  margin: 0 0 10px;
37366
37494
  text-align: left;
37495
+ flex-shrink: 0;
37496
+ `;
37497
+ const SearchInput = styled__default["default"].input`
37498
+ width: 100%;
37499
+ padding: 8px 12px;
37500
+ margin: 0 0 12px;
37501
+ font-size: 14px;
37502
+ font-family: 'Poppins', sans-serif;
37503
+ border: 1px solid #e0e0e0;
37504
+ border-radius: 4px;
37505
+ background-color: #fff;
37506
+ color: #212121;
37507
+ flex-shrink: 0;
37508
+ box-sizing: border-box;
37509
+
37510
+ &::placeholder {
37511
+ color: #999;
37512
+ font-style: italic;
37513
+ }
37514
+
37515
+ &:focus {
37516
+ outline: none;
37517
+ border-color: ${props => props.accentColor || '#066768'};
37518
+ box-shadow: 0 0 0 2px ${props => props.accentColor || '#066768'}20;
37519
+ }
37520
+
37521
+ &:hover {
37522
+ border-color: #c0c0c0;
37523
+ }
37367
37524
  `;
37368
37525
  const CheckboxGroup = styled__default["default"].div`
37369
- display: flex;
37370
- flex-direction: column;
37371
- gap: 8px;
37372
- margin-bottom: 16px;
37526
+ display: flex;
37527
+ flex-direction: column;
37528
+ gap: 8px;
37529
+ margin-bottom: 16px;
37530
+ overflow-y: auto;
37531
+ flex: 1;
37532
+ min-height: 0;
37533
+
37534
+ /* Custom scrollbar styling */
37535
+ &::-webkit-scrollbar {
37536
+ width: 6px;
37537
+ }
37538
+
37539
+ &::-webkit-scrollbar-track {
37540
+ background: #f1f1f1;
37541
+ border-radius: 3px;
37542
+ }
37543
+
37544
+ &::-webkit-scrollbar-thumb {
37545
+ background: #c1c1c1;
37546
+ border-radius: 3px;
37547
+ }
37548
+
37549
+ &::-webkit-scrollbar-thumb:hover {
37550
+ background: #a8a8a8;
37551
+ }
37552
+
37553
+ /* For Firefox */
37554
+ scrollbar-width: thin;
37555
+ scrollbar-color: #c1c1c1 #f1f1f1;
37373
37556
  `;
37374
37557
  const CheckboxLabel = styled__default["default"].label`
37375
- display: flex;
37376
- align-items: center;
37377
- gap: 8px;
37378
- padding: 8px 12px;
37379
- font-size: 14px;
37380
- font-weight: 400;
37381
- color: #212121;
37382
- cursor: pointer;
37383
-
37384
- &:hover {
37385
- background-color: #E6F0F0;
37386
- }
37387
-
37388
- > span {
37389
- width: ${props => props.width};
37390
- white-space: nowrap;
37391
- overflow: hidden;
37392
- text-overflow: ellipsis;
37393
- }
37558
+ display: flex;
37559
+ align-items: center;
37560
+ gap: 8px;
37561
+ padding: 8px 12px;
37562
+ font-size: 14px;
37563
+ font-weight: 400;
37564
+ color: #212121;
37565
+ cursor: pointer;
37566
+ flex-shrink: 0;
37567
+
37568
+ &:hover {
37569
+ background-color: #E6F0F0;
37570
+ }
37571
+
37572
+ > span {
37573
+ width: ${props => props.width};
37574
+ white-space: nowrap;
37575
+ overflow: hidden;
37576
+ text-overflow: ellipsis;
37577
+ }
37578
+ `;
37579
+ const NoResultsMessage = styled__default["default"].div`
37580
+ padding: 16px 12px;
37581
+ text-align: center;
37582
+ color: #999;
37583
+ font-size: 14px;
37584
+ font-style: italic;
37394
37585
  `;
37395
37586
  const ButtonWrapper$2 = styled__default["default"].div`
37396
37587
  text-align: right;
37588
+ flex-shrink: 0;
37589
+ padding-top: 8px;
37590
+ border-top: 1px solid #e0e0e0;
37591
+ display: flex;
37592
+ justify-content: flex-end;
37593
+ align-items: center;
37397
37594
  `;
37398
37595
  const ResetButton$1 = styled__default["default"].button`
37399
37596
  font-size: 14px;
37400
37597
  font-weight: 400;
37401
- padding: 2px 8px;
37598
+ padding: 4px 8px;
37402
37599
  background-color: transparent;
37403
37600
  border: none;
37404
37601
  cursor: pointer;
37602
+ border-radius: 3px;
37603
+
37604
+ &:hover {
37605
+ background-color: #f0f0f0;
37606
+ color: #066768;
37607
+ }
37405
37608
 
37406
- &:hover {
37407
- // color: #066768;
37408
- }
37409
-
37410
- &:active {
37411
- // color: #066768;
37412
- }
37609
+ &:active {
37610
+ color: #066768;
37611
+ }
37612
+
37613
+ &:disabled {
37614
+ color: #ccc;
37615
+ cursor: not-allowed;
37616
+
37617
+ &:hover {
37618
+ background-color: transparent;
37619
+ color: #ccc;
37620
+ }
37621
+ }
37413
37622
  `;
37414
37623
 
37415
37624
  const FilterPop = props => {
@@ -37417,15 +37626,22 @@ const FilterPop = props => {
37417
37626
  menuName = '',
37418
37627
  width = 'auto',
37419
37628
  height = 'auto',
37629
+ maxHeight = '400px',
37420
37630
  list = [],
37421
37631
  color = '#007bff',
37422
37632
  onCheck = () => {},
37423
37633
  onReset = () => {},
37424
37634
  doubleColumn = false,
37425
37635
  isAsc = true,
37426
- selectedAttributes: propSelectedAttributes = {} // Receive from parent
37636
+ selectedAttributes: propSelectedAttributes = {},
37637
+ showSearch = true,
37638
+ // New prop to enable/disable search
37639
+ searchPlaceholder = 'Search...' // New prop for search placeholder
37427
37640
  } = props;
37428
37641
 
37642
+ // State for search term
37643
+ const [searchTerm, setSearchTerm] = React$1.useState('');
37644
+
37429
37645
  // Add hardcoded "Select All" as first item
37430
37646
  const fullList = [{
37431
37647
  value: 'All',
@@ -37449,18 +37665,49 @@ const FilterPop = props => {
37449
37665
  return fullList.filter(item => item.value !== 'All');
37450
37666
  };
37451
37667
 
37452
- // Helper function to check if all non-"All" items are selected
37668
+ // Filter items based on search term
37669
+ const filteredList = React$1.useMemo(() => {
37670
+ if (!searchTerm.trim()) {
37671
+ return fullList;
37672
+ }
37673
+ const searchLower = searchTerm.toLowerCase().trim();
37674
+ const filteredNonAllItems = fullList.filter(item => {
37675
+ if (item.value === 'All') return false; // Don't filter out "Select All" in search
37676
+ return item.label.toLowerCase().includes(searchLower);
37677
+ });
37678
+
37679
+ // Always include "Select All" at the top when searching
37680
+ return [fullList.find(item => item.value === 'All'), ...filteredNonAllItems];
37681
+ }, [fullList, searchTerm]);
37682
+
37683
+ // Sort the filtered list based on the `isAsc` prop, keeping 'All' as the first option
37684
+ const sortedList = React$1.useMemo(() => {
37685
+ return [...filteredList.filter(item => item.value === 'All'), ...filteredList.filter(item => item.value !== 'All').sort((a, b) => {
37686
+ return isAsc ? a.label.localeCompare(b.label) : b.label.localeCompare(a.label);
37687
+ })];
37688
+ }, [filteredList, isAsc]);
37689
+
37690
+ // Helper functions for "Select All" logic based on ALL items (not just filtered)
37453
37691
  const areAllNonAllItemsSelected = function () {
37454
37692
  let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37455
37693
  const nonAllItems = getNonAllItems();
37456
37694
  return nonAllItems.every(item => attributes[item.value]);
37457
37695
  };
37458
37696
 
37459
- // Helper function to check if any non-"All" items are selected
37460
- const areAnyNonAllItemsSelected = function () {
37697
+ // Helper functions for visible filtered items
37698
+ const getVisibleNonAllItems = () => {
37699
+ return sortedList.filter(item => item.value !== 'All');
37700
+ };
37701
+ const areAllVisibleItemsSelected = function () {
37461
37702
  let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37462
- const nonAllItems = getNonAllItems();
37463
- return nonAllItems.some(item => attributes[item.value]);
37703
+ const visibleItems = getVisibleNonAllItems();
37704
+ if (visibleItems.length === 0) return false;
37705
+ return visibleItems.every(item => attributes[item.value]);
37706
+ };
37707
+ const areAnyVisibleItemsSelected = function () {
37708
+ let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : selectedAttributes;
37709
+ const visibleItems = getVisibleNonAllItems();
37710
+ return visibleItems.some(item => attributes[item.value]);
37464
37711
  };
37465
37712
 
37466
37713
  // New helper function to create the efficient data structure
@@ -37484,14 +37731,12 @@ const FilterPop = props => {
37484
37731
  isSelectAll: false
37485
37732
  };
37486
37733
  } else if (mostSelected) {
37487
- // More items selected than unselected - use exclude approach
37488
37734
  return {
37489
37735
  excluded: unselectedItems.map(item => item.value),
37490
37736
  included: [],
37491
37737
  isSelectAll: true
37492
37738
  };
37493
37739
  } else {
37494
- // Fewer items selected than unselected - use include approach
37495
37740
  return {
37496
37741
  excluded: [],
37497
37742
  included: selectedItems.map(item => item.value),
@@ -37501,47 +37746,50 @@ const FilterPop = props => {
37501
37746
  };
37502
37747
  const handleCheckboxChange = attribute => {
37503
37748
  if (attribute === 'All') {
37504
- // If "Select All" is clicked - determine new state based on current "Select All" state
37505
- const currentSelectAllState = selectedAttributes.All || false;
37506
- const newState = !currentSelectAllState;
37507
- const updatedAttributes = {};
37749
+ // "Select All" behavior - affects ALL visible filtered items
37750
+ const visibleNonAllItems = getVisibleNonAllItems();
37751
+ const allVisibleSelected = areAllVisibleItemsSelected();
37508
37752
 
37509
- // Set all items to the same state as "Select All"
37510
- fullList.forEach(item => {
37511
- updatedAttributes[item.value] = newState;
37753
+ // Toggle all visible items
37754
+ const updatedAttributes = {
37755
+ ...selectedAttributes
37756
+ };
37757
+ visibleNonAllItems.forEach(item => {
37758
+ updatedAttributes[item.value] = !allVisibleSelected;
37512
37759
  });
37513
37760
 
37514
- // Call onCheck callback with new efficient structure
37761
+ // Update "Select All" state based on all items (not just visible)
37762
+ updatedAttributes.All = areAllNonAllItemsSelected(updatedAttributes);
37515
37763
  const filterData = createFilterData(updatedAttributes);
37516
37764
  onCheck({
37517
37765
  changedItem: attribute,
37518
37766
  filterData: filterData,
37519
- allItems: updatedAttributes // Keep for backward compatibility if needed
37767
+ allItems: updatedAttributes
37520
37768
  });
37521
37769
  } else {
37522
- // If any other item is clicked
37770
+ // Individual item clicked
37523
37771
  const updatedAttributes = {
37524
37772
  ...selectedAttributes,
37525
37773
  [attribute]: !selectedAttributes[attribute]
37526
37774
  };
37527
37775
 
37528
- // Call onCheck callback with new efficient structure
37776
+ // Update "Select All" state based on all items
37777
+ updatedAttributes.All = areAllNonAllItemsSelected(updatedAttributes);
37529
37778
  const filterData = createFilterData(updatedAttributes);
37530
37779
  onCheck({
37531
37780
  changedItem: attribute,
37532
37781
  filterData: filterData,
37533
- allItems: updatedAttributes // Keep for backward compatibility if needed
37782
+ allItems: updatedAttributes
37534
37783
  });
37535
37784
  }
37536
37785
  };
37537
37786
  const handleReset = () => {
37787
+ // Clear search when resetting
37788
+ setSearchTerm('');
37789
+
37538
37790
  // Reset to the original default state (all selected)
37539
37791
  const resetState = createInitialState();
37540
-
37541
- // Call the onReset callback
37542
37792
  onReset();
37543
-
37544
- // Also call onCheck to notify parent of the reset with new efficient structure
37545
37793
  const filterData = createFilterData(resetState);
37546
37794
  onCheck({
37547
37795
  changedItem: 'reset',
@@ -37550,17 +37798,24 @@ const FilterPop = props => {
37550
37798
  });
37551
37799
  };
37552
37800
 
37553
- // Function to determine checkbox state for "Select All"
37801
+ // Function to determine checkbox state for "Select All" based on visible items
37554
37802
  const getSelectAllCheckboxProps = () => {
37555
- const allSelected = areAllNonAllItemsSelected();
37556
- const anySelected = areAnyNonAllItemsSelected();
37557
- const noneSelected = !anySelected;
37558
- if (allSelected) {
37803
+ const visibleItems = getVisibleNonAllItems();
37804
+ if (visibleItems.length === 0) {
37805
+ return {
37806
+ checked: false,
37807
+ indeterminate: false
37808
+ };
37809
+ }
37810
+ const allVisibleSelected = areAllVisibleItemsSelected();
37811
+ const anyVisibleSelected = areAnyVisibleItemsSelected();
37812
+ const noneVisibleSelected = !anyVisibleSelected;
37813
+ if (allVisibleSelected) {
37559
37814
  return {
37560
37815
  checked: true,
37561
37816
  indeterminate: false
37562
37817
  };
37563
- } else if (noneSelected) {
37818
+ } else if (noneVisibleSelected) {
37564
37819
  return {
37565
37820
  checked: false,
37566
37821
  indeterminate: false
@@ -37573,38 +37828,50 @@ const FilterPop = props => {
37573
37828
  }
37574
37829
  };
37575
37830
 
37576
- // Sort the list based on the `isAsc` prop, keeping 'All' as the first option
37577
- const sortedList = [...fullList.filter(item => item.value === 'All'), ...fullList.filter(item => item.value !== 'All').sort((a, b) => {
37578
- return isAsc ? a.label.localeCompare(b.label) : b.label.localeCompare(a.label);
37579
- })];
37831
+ // Handle search input change
37832
+ const handleSearchChange = e => {
37833
+ setSearchTerm(e.target.value);
37834
+ };
37835
+
37836
+ // Clear search
37837
+ const clearSearch = () => {
37838
+ setSearchTerm('');
37839
+ };
37580
37840
  return /*#__PURE__*/React__default["default"].createElement(FilterPopContainer, {
37581
37841
  width: width,
37582
37842
  height: height,
37583
- accentColor: color // Pass color as prop to styled component
37584
- }, /*#__PURE__*/React__default["default"].createElement(Title$5, null, menuName), /*#__PURE__*/React__default["default"].createElement(CheckboxGroup, {
37843
+ maxHeight: maxHeight,
37844
+ accentColor: color
37845
+ }, /*#__PURE__*/React__default["default"].createElement(Title$5, null, menuName), showSearch && /*#__PURE__*/React__default["default"].createElement(SearchInput, {
37846
+ type: "text",
37847
+ placeholder: searchPlaceholder,
37848
+ value: searchTerm,
37849
+ onChange: handleSearchChange,
37850
+ accentColor: color
37851
+ }), /*#__PURE__*/React__default["default"].createElement(CheckboxGroup, {
37585
37852
  style: {
37586
37853
  display: doubleColumn ? 'grid' : 'flex',
37587
37854
  gridTemplateColumns: doubleColumn ? '1fr 1fr' : 'none',
37588
37855
  gap: '8px'
37589
37856
  }
37590
- }, sortedList.map(item => {
37857
+ }, sortedList.length === 1 ?
37858
+ /*#__PURE__*/
37859
+ // Only "Select All" is visible
37860
+ React__default["default"].createElement(NoResultsMessage, null, "No items match your search") : sortedList.map(item => {
37591
37861
  const isSelectAll = item.value === 'All';
37592
37862
  const checkboxProps = isSelectAll ? getSelectAllCheckboxProps() : {};
37593
37863
  const isChecked = isSelectAll ? checkboxProps.checked : selectedAttributes[item.value] || false;
37594
37864
  return /*#__PURE__*/React__default["default"].createElement(CheckboxLabel, {
37595
37865
  width: !doubleColumn ?? width,
37596
- key: `${item.value}-${JSON.stringify(selectedAttributes)}`
37866
+ key: `${item.value}-${JSON.stringify(selectedAttributes)}-${searchTerm}`
37597
37867
  }, /*#__PURE__*/React__default["default"].createElement("input", {
37598
37868
  type: "checkbox",
37599
37869
  checked: isChecked,
37600
37870
  ref: el => {
37601
37871
  if (el) {
37602
- // Handle indeterminate for Select All FIRST
37603
37872
  if (isSelectAll) {
37604
37873
  el.indeterminate = checkboxProps.indeterminate;
37605
37874
  }
37606
-
37607
- // FORCE DOM SYNC - manually set DOM state to match React state
37608
37875
  if (el.checked !== isChecked) {
37609
37876
  el.checked = isChecked;
37610
37877
  }
@@ -37614,7 +37881,12 @@ const FilterPop = props => {
37614
37881
  handleCheckboxChange(item.value);
37615
37882
  }
37616
37883
  }), /*#__PURE__*/React__default["default"].createElement("span", null, item.label));
37617
- })), /*#__PURE__*/React__default["default"].createElement(ButtonWrapper$2, null, /*#__PURE__*/React__default["default"].createElement(ResetButton$1, {
37884
+ })), /*#__PURE__*/React__default["default"].createElement(ButtonWrapper$2, null, showSearch && searchTerm && /*#__PURE__*/React__default["default"].createElement(ResetButton$1, {
37885
+ onClick: clearSearch,
37886
+ style: {
37887
+ marginRight: '8px'
37888
+ }
37889
+ }, "Clear Search"), /*#__PURE__*/React__default["default"].createElement(ResetButton$1, {
37618
37890
  onClick: handleReset,
37619
37891
  disabled: areAllNonAllItemsSelected() && selectedAttributes.All
37620
37892
  }, "Reset")));
@@ -55375,7 +55647,7 @@ exports.RangePop = RangePop;
55375
55647
  exports.ReportTable = ReportTable;
55376
55648
  exports.RulesEngine = RulesEngine;
55377
55649
  exports.SampleRunEngine = SampleRunEngine;
55378
- exports.SearchInput = SearchInput;
55650
+ exports.SearchInput = SearchInput$1;
55379
55651
  exports.SingleBarLineCharts = SingleBarLineCharts;
55380
55652
  exports.SortPop = SortPop;
55381
55653
  exports.TabMenu = TabMenu;