react-core-ts 2.0.13 → 2.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import { FieldErrors, UseFormRegister } from 'react-hook-form';
2
3
 
3
4
  export type ValueProps = {
@@ -99,6 +100,10 @@ export interface AutoSuggestionInputProps {
99
100
  autoRefreshMainDropdown?: boolean;
100
101
  singleSelectIcon?: any;
101
102
  autoTabSelectAll?: boolean; // auto select all when tab is selected
103
+ moreOptionTab?: React.ReactNode; // custom component to render in the last tab (checkbox, radio, icon, etc.)
104
+ moreOptionTabLabel?: string; // label for the more options tab (default: "More Options")
105
+ moreOptionTabIcon?: React.ReactNode; // icon to display in the more options tab
106
+ onMoreOptionChange?: (values?: any) => void; // separate callback for moreOptionValues
102
107
  }
103
108
  export interface IconsProps {
104
109
  name: any;
@@ -24,9 +24,12 @@ const DropdownFilterTabs = forwardRef<
24
24
  AutoSuggestionInputProps & {
25
25
  dropdownRef?: React.RefObject<HTMLDivElement>;
26
26
  open?: boolean;
27
- applyTabFilter?: () => void;
27
+ applyTabFilter?: (moreOptionValues?: any) => void;
28
28
  onToolClose?: () => void;
29
-
29
+ moreOptionTab?: React.ReactNode;
30
+ moreOptionTabLabel?: string;
31
+ moreOptionTabIcon?: React.ReactNode;
32
+ onMoreOptionChange?: (values?: any) => void;
30
33
  }
31
34
  >(
32
35
  (
@@ -85,7 +88,11 @@ const DropdownFilterTabs = forwardRef<
85
88
  dropdownRef,
86
89
  open = false,
87
90
  applyTabFilter,
88
- onToolClose
91
+ onToolClose,
92
+ moreOptionTab,
93
+ moreOptionTabLabel = 'More Options',
94
+ moreOptionTabIcon,
95
+ onMoreOptionChange
89
96
  },
90
97
  ref
91
98
  ) => {
@@ -129,7 +136,7 @@ const DropdownFilterTabs = forwardRef<
129
136
  const [isKeyboardOpen, setIsKeyboardOpen] = useState(false);
130
137
 
131
138
  // Filter selected items based on current active tab
132
- const currentTabId = tab.length > 0 ? tab[activeTab].id : undefined;
139
+ const currentTabId = tab.length > 0 && activeTab < tab.length ? tab[activeTab].id : undefined;
133
140
  const filteredSelectedItems = useMemo(() => {
134
141
  return selectedItems.filter(item => item.tabId === currentTabId);
135
142
  }, [selectedItems, currentTabId]);
@@ -139,6 +146,10 @@ const DropdownFilterTabs = forwardRef<
139
146
  setDropOpen(open);
140
147
  }, [open]);
141
148
 
149
+ useEffect(() => {
150
+ setActiveTab(currentTab);
151
+ }, [currentTab]);
152
+
142
153
  const adjustDropdownPosition = () => {
143
154
  if (dropdownRef?.current) {
144
155
  const inputRect = dropdownRef?.current?.getBoundingClientRect();
@@ -731,13 +742,15 @@ const DropdownFilterTabs = forwardRef<
731
742
  }, [selectedItems, tab]);
732
743
 
733
744
  const getTabItems = useCallback(() => {
745
+ const allTabs = moreOptionTab ? [...tab, { id: 'more-options', label: moreOptionTabLabel }] : tab;
734
746
  return (
735
747
  <ul
736
748
  className="qbs-flex qbs-flex-wrap qbs-w-full qbs-tab qbs-mb-2 -qbs-mt-2"
737
749
  ref={tabRef}
738
750
  >
739
- {tab.map((item: TabPops, idx: number) => {
740
- const hasSelectedItems = hasSelectedItemsInTab(idx);
751
+ {allTabs.map((item: TabPops, idx: number) => {
752
+ const isMoreOptionsTab = item.id === 'more-options';
753
+ const hasSelectedItems = isMoreOptionsTab ? false : hasSelectedItemsInTab(idx);
741
754
  return (
742
755
  <li
743
756
  className={`qbs-flex-1 qbs-tab-items ${hasSelectedItems ? 'qbs-tab-has-selected-items' : ''}`}
@@ -747,17 +760,28 @@ const DropdownFilterTabs = forwardRef<
747
760
  className={`qbs-inline-block qbs-tab-item qbs-text-sm qbs-cursor-pointer qbs-w-full qbs-text-center qbs-p-1 qbs-border-b-2 ${activeTab === idx ? 'qbs-tab-active-item' : ''
748
761
  }`}
749
762
  onClick={() => {
750
- handleTabClick(idx);
763
+ if (isMoreOptionsTab) {
764
+ setActiveTab(idx);
765
+ } else {
766
+ handleTabClick(idx);
767
+ }
751
768
  }}
752
769
  >
753
- {item.label}
770
+ <span className="qbs-flex qbs-items-center qbs-justify-center qbs-gap-1">
771
+ {isMoreOptionsTab && moreOptionTabIcon && (
772
+ <span className="qbs-inline-flex qbs-items-center">
773
+ {moreOptionTabIcon}
774
+ </span>
775
+ )}
776
+ {item.label}
777
+ </span>
754
778
  </span>
755
779
  </li>
756
780
  );
757
781
  })}
758
782
  </ul>
759
783
  );
760
- }, [tab, hasSelectedItemsInTab, activeTab, handleTabClick]);
784
+ }, [tab, hasSelectedItemsInTab, activeTab, handleTabClick, moreOptionTab, moreOptionTabLabel, moreOptionTabIcon]);
761
785
 
762
786
  const handleSelectAll = useCallback(() => {
763
787
  if (isMultiple) {
@@ -827,9 +851,9 @@ const DropdownFilterTabs = forwardRef<
827
851
  }
828
852
  };
829
853
 
830
- const handleApplySelected = () => {
854
+ const handleApplySelected = (values?: any) => {
831
855
  setDropOpen(false);
832
- applyTabFilter?.();
856
+ applyTabFilter?.(values);
833
857
  };
834
858
 
835
859
  useEffect(() => {
@@ -880,9 +904,25 @@ const DropdownFilterTabs = forwardRef<
880
904
  {!viewMode && (
881
905
  <>
882
906
  <>{tab.length > 0 && getTabItems()}</>
907
+ {moreOptionTab && activeTab === tab.length && (
908
+ <div
909
+ style={{ position: 'relative' }}
910
+ className={`qbs-autocomplete-moreoption-container`}
911
+ >
912
+ {React.isValidElement(moreOptionTab)
913
+ ? React.cloneElement(moreOptionTab as React.ReactElement<any>, {
914
+ onApply: (values?: any) => handleApplySelected(values),
915
+ onValueChange: (values?: any) => {
916
+ onMoreOptionChange?.(values);
917
+ },
918
+ } as any)
919
+ : moreOptionTab}
920
+ </div>
921
+ )}
883
922
  {type === 'auto_suggestion' &&
884
923
  !expandable &&
885
- tabInlineSearch && (
924
+ tabInlineSearch &&
925
+ activeTab !== (moreOptionTab ? tab.length : tab.length - 1) && (
886
926
  <div
887
927
  style={{ position: 'relative' }}
888
928
  className="react-core-ts-search-container qbs-autocomplete-selected-suggestions-outer"
@@ -923,52 +963,54 @@ const DropdownFilterTabs = forwardRef<
923
963
  </>
924
964
  )}
925
965
 
926
- {filteredData?.length > 0 && enableSelectAll && isMultiple && (
927
- <div
928
- id="select-all"
929
- className={`qbs-select-all-link qbs-cursor-pointer qbs-text-xs`}
930
- onClick={handleSelectAll}
931
- >
932
- <div
933
- className={`qbs-autocomplete-listitem-container qbs-autocomplete-checkbox-container`}
934
- >
935
- <div className="qbs-autocomplete-checkbox">
936
- <input
937
- type="checkbox"
938
- checked={selectAll}
939
- id={`qbs-checkbox-all`}
940
- />
941
- <label htmlFor={`qbs-checkbox-all`}>
942
- <svg
943
- width="8"
944
- height="6"
945
- viewBox="0 0 8 6"
946
- fill="none"
947
- xmlns="http://www.w3.org/2000/svg"
948
- >
949
- <path
950
- d="M0 3.21739L2.89883 6L8 1.06994L6.89494 0L2.89883 3.86768L1.09728 2.14745L0 3.21739Z"
951
- fill="white"
966
+ {activeTab !== (moreOptionTab ? tab.length : tab.length - 1) && (
967
+ <>
968
+ {filteredData?.length > 0 && enableSelectAll && isMultiple && (
969
+ <div
970
+ id="select-all"
971
+ className={`qbs-select-all-link qbs-cursor-pointer qbs-text-xs`}
972
+ onClick={handleSelectAll}
973
+ >
974
+ <div
975
+ className={`qbs-autocomplete-listitem-container qbs-autocomplete-checkbox-container`}
976
+ >
977
+ <div className="qbs-autocomplete-checkbox">
978
+ <input
979
+ type="checkbox"
980
+ checked={selectAll}
981
+ id={`qbs-checkbox-all`}
952
982
  />
953
- </svg>
954
- </label>
955
- </div>
956
- <div className={`qbs-autocomplete-suggestions-item`}>
957
- Select All
983
+ <label htmlFor={`qbs-checkbox-all`}>
984
+ <svg
985
+ width="8"
986
+ height="6"
987
+ viewBox="0 0 8 6"
988
+ fill="none"
989
+ xmlns="http://www.w3.org/2000/svg"
990
+ >
991
+ <path
992
+ d="M0 3.21739L2.89883 6L8 1.06994L6.89494 0L2.89883 3.86768L1.09728 2.14745L0 3.21739Z"
993
+ fill="white"
994
+ />
995
+ </svg>
996
+ </label>
997
+ </div>
998
+ <div className={`qbs-autocomplete-suggestions-item`}>
999
+ Select All
1000
+ </div>
1001
+ </div>
958
1002
  </div>
959
- </div>
960
- </div>
961
- )}
1003
+ )}
962
1004
 
963
- <div
964
- className={`qbs-autocomplete-suggestions-sub qbs-autocomplete-selected-suggestions-outer ${viewMode ? 'hidden' : ''
965
- }`}
966
- ref={itemsRef}
967
- style={{
968
- maxHeight: `${selHeight}px`,
969
- minHeight: `${selHeight}px`,
970
- }}
971
- >
1005
+ <div
1006
+ className={`qbs-autocomplete-suggestions-sub qbs-autocomplete-selected-suggestions-outer ${viewMode ? 'hidden' : ''
1007
+ }`}
1008
+ ref={itemsRef}
1009
+ style={{
1010
+ maxHeight: `${selHeight}px`,
1011
+ minHeight: `${selHeight}px`,
1012
+ }}
1013
+ >
972
1014
  {filteredData?.length > 0 ? (
973
1015
  filteredData.map((suggestion: ValueProps, idx: number) => (
974
1016
  <DropdownList
@@ -1023,7 +1065,9 @@ const DropdownFilterTabs = forwardRef<
1023
1065
  <p style={{ margin: 2 }}>Load More</p>
1024
1066
  </div>
1025
1067
  )}
1026
- </div>
1068
+ </div>
1069
+ </>
1070
+ )}
1027
1071
  <>
1028
1072
  {countOnly && filteredSelectedItems?.length > 0 && (
1029
1073
  <>
package/src/index.tsx CHANGED
@@ -19,4 +19,4 @@ export { deepEqual } from './utilities/deepEqual';
19
19
  export { default as ExpandableToolTip } from './utilities/expandableTootltip';
20
20
  export { default as ToolTip } from './utilities/tooltip';
21
21
  export { default as ModernAutoCompleteDropdown } from './ReactAutoCompleteDropdown';
22
- export { default as ReactAutoCompleteTableView } from './ReactAutoCompleteTableView';
22
+ export { default as ModernAutoCompleteTableView } from './ReactAutoCompleteTableView';