From 3ea2265d4f1a943698cf91267db3e10faa646fc4 Mon Sep 17 00:00:00 2001
From: rohan km
Date: Tue, 21 Feb 2023 18:49:37 +0530
Subject: [PATCH 1/5] added multiple select with optimisations and updated
readMe
---
README.md | 129 ++++++++++++++-
index.js | 3 +-
src/FlashSelectDropdown.js | 283 +++++++++++++++++++++++++++++++++
src/SelectDropdown.js | 108 ++++++++++---
src/hooks/useSelectDropdown.js | 81 +++++++++-
src/styles.js | 10 ++
yarn.lock | 4 +
7 files changed, 580 insertions(+), 38 deletions(-)
create mode 100644 src/FlashSelectDropdown.js
create mode 100644 yarn.lock
diff --git a/README.md b/README.md
index dded4b8..c7efd51 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,10 @@ yarn add react-native-select-dropdown
+## Optimization
+
+Install `yarn add @shopify/flash-list` then use `` instead of `` for optimised benifits.
+
## Usage
```
@@ -56,6 +60,49 @@ const countries = ["Egypt", "Canada", "Australia", "Ireland"]
/>
```
+#### Multiple Select
+
+```
+const [data,setData]=useState()
+
+ {
+ return (
+
+
+
+ );
+ }}
+ onSelect={async (selectedItem) => {
+ setData(selectedItem);
+ }}
+ buttonTextAfterSelection={"Selected"}
+ rowTextForSelection={(item, index) => {
+ return item.title;
+ }}
+/>;
+
+```
+
### Props
- [`data`](#data)
@@ -128,6 +175,18 @@ const countries = ["Egypt", "Canada", "Australia", "Ireland"]
- [`onChangeSearchInputText`](#onChangeSearchInputText)
+- [`onlyDropdownIcon`](#onlyDropdownIcon)
+
+- [`textNumberOfLines`](#textNumberOfLines)
+
+- [`multipleSelect`](#multipleSelect)
+
+- [`searchKey`](#searchKey)
+
+- [`emptyStyle`](#emptyStyle)
+
+- [`allowSelectAll`](#allowSelectAll)
+
### Methods
- [`reset`](#License)
@@ -151,6 +210,8 @@ array of data that will be represented in dropdown 'can be array of objects
function recieves selected item and its index in data array
+if multipleSelect is true then recives only array of item.
+
| Type | Required |
| -------- | -------- |
| function | Yes |
@@ -171,9 +232,11 @@ default button text when no item is selected
function recieves selected item and its index, this function should return a string that will be represented in button after item is selected
-| Type | Required |
-| -------- | -------------------------------------------------------------------- |
-| function | Yes "unless you customized button using renderCustomizedButtonChild" |
+if multiple select is true then pass the string value
+
+| Type | Required |
+| ------------------ | -------------------------------------------------------------------- |
+| function or string | Yes "unless you customized button using renderCustomizedButtonChild" |
---
@@ -189,7 +252,7 @@ function recieves item and index for each row in dropdown, this function shoud r
### defaultValue
-default selected item in dropdown ( check examples in Demo1)
+default selected item in dropdown ( check examples in Demo1). If multiple select is true then pass the array of selected items.
| Type | Required |
| ---- | -------- |
@@ -199,11 +262,11 @@ default selected item in dropdown ( check examples in Demo1)
### defaultValueByIndex
-default selected item index
+default selected item index. If multipleSelect is true then pass the array of default indices (check Demo2).
-| Type | Required |
-| ------- | -------- |
-| integer | No |
+| Type | Required |
+| ---------------- | -------- |
+| integer or array | No |
---
@@ -399,6 +462,16 @@ style object for selected row text
---
+### emptyStyle
+
+style object for empty list
+
+| Type | Required |
+| ------ | -------- |
+| object | No |
+
+---
+
### renderCustomizedRowChild
function recieves item and its index, this function should return React component as a child for customized row `rowStyle` should be used for parent row view style.
@@ -481,6 +554,46 @@ function returns React component for search input icon
---
+### textNumberOfLines
+
+Drop Down Button Text number of lines (numberOfLines prop for Text)
+
+| Type | Required | default |
+| ------ | -------- | ------- |
+| number | No | 1 |
+
+---
+
+### multipleSelect
+
+Select Multiple values from the Drop down List
+
+| Type | Required | default |
+| ------- | -------- | ------- |
+| boolean | No | false |
+
+---
+
+### searchKey
+
+Searches only the specified keys if the data is object (by default searches all keys)
+
+| Type | Required |
+| ----- | -------- |
+| array | No |
+
+---
+
+### allowSelectAll
+
+Allows user to select all data (works only if multiple select is true)
+
+| Type | Required | default |
+| ------- | -------- | ------- |
+| boolean | No | false |
+
+---
+
### onChangeSearchInputText
function callback when the search input text changes, this will automatically disable the dropdown's internal search to be implemented manually outside the component
diff --git a/index.js b/index.js
index 62d954f..63f041a 100644
--- a/index.js
+++ b/index.js
@@ -1,3 +1,4 @@
import SelectDropdown from './src/SelectDropdown';
+import FlashSelectDropdown from './src/FlashSelectDropdown';
-export default SelectDropdown;
\ No newline at end of file
+export {SelectDropdown, FlashSelectDropdown};
diff --git a/src/FlashSelectDropdown.js b/src/FlashSelectDropdown.js
new file mode 100644
index 0000000..f8eb6c7
--- /dev/null
+++ b/src/FlashSelectDropdown.js
@@ -0,0 +1,283 @@
+import React, {forwardRef, useImperativeHandle, useState} from 'react';
+import {View, Text, TouchableOpacity, FlatList, Switch} from 'react-native';
+import styles from './styles';
+import {isExist} from './helpers/isExist';
+import Input from './components/Input';
+import DropdownOverlay from './components/DropdownOverlay';
+import DropdownModal from './components/DropdownModal';
+import DropdownWindow from './components/DropdownWindow';
+import {useSelectDropdown} from './hooks/useSelectDropdown';
+import {useLayoutDropdown} from './hooks/useLayoutDropdown';
+import {useRefs} from './hooks/useRefs';
+import {FlashList} from '@shopify/flash-list';
+
+const FlashSelectDropdown = (
+ {
+ data /* array */,
+ onSelect /* function */,
+ defaultButtonText /* String */,
+ buttonTextAfterSelection /* function or string */,
+ rowTextForSelection /* function */,
+ defaultValue /* any */,
+ defaultValueByIndex /* integer */,
+ disabled /* boolean */,
+ disableAutoScroll /* boolean */,
+ disabledIndexs /* array of disabled Row index */,
+ onFocus /* function */,
+ onBlur /* function */,
+ onScrollEndReached /* function */,
+ /////////////////////////////
+ buttonStyle /* style object for button */,
+ buttonTextStyle /* style object for button text */,
+ renderCustomizedButtonChild /* function returns React component for customized button */,
+ /////////////////////////////
+ renderDropdownIcon,
+ dropdownIconPosition,
+ statusBarTranslucent,
+ dropdownStyle,
+ dropdownOverlayColor /* string */,
+ /////////////////////////////
+ rowStyle /* style object for row */,
+ rowTextStyle /* style object for row text */,
+ selectedRowStyle /* style object for selected row */,
+ disabledStyle,
+ selectedRowTextStyle /* style object for selected row text */,
+ renderCustomizedRowChild /* function returns React component for customized row */,
+ /////////////////////////////
+ search /* boolean */,
+ searchInputStyle /* style object for search input */,
+ searchInputTxtColor /* text color for search input */,
+ searchInputTxtStyle /* text style for search input */,
+ searchPlaceHolder /* placeholder text for search input */,
+ searchPlaceHolderColor /* text color for search input placeholder */,
+ renderSearchInputLeftIcon /* function returns React component for search input icon */,
+ renderSearchInputRightIcon /* function returns React component for search input icon */,
+ onChangeSearchInputText /* function callback when the search input text changes, this will automatically disable the dropdown's interna search to be implemented manually outside the component */,
+ onlyDropdownIcon = false /*shows only drop down icon and ignores the text */,
+ textNumberOfLines = 1 /*Drop Down Button Text number of lines (numberOfLines prop for Text) */,
+ multipleSelect = false /*Select Multiple values from the Drop down List */,
+ searchKey /*search key if the data is object default searches all */,
+ emptyStyle /*Empty data style */,
+ allowSelectAll = false /*Allows user to select all data (works only if multiple select is true) */,
+ },
+ ref,
+) => {
+ const disabledInternalSearch = !!onChangeSearchInputText;
+ /* ******************* hooks ******************* */
+ const {dropdownButtonRef, dropDownFlatlistRef} = useRefs();
+ const {
+ dataArr, //
+ selectedItem,
+ selectedIndex,
+ selectItem,
+ reset,
+ searchTxt,
+ setSearchTxt,
+ selectAll,
+ toggleSeletAll,
+ } = useSelectDropdown(data, defaultValueByIndex, defaultValue, disabledInternalSearch, multipleSelect, searchKey);
+ const {
+ isVisible, //
+ setIsVisible,
+ buttonLayout,
+ onDropdownButtonLayout,
+ getItemLayout,
+ dropdownWindowStyle,
+ } = useLayoutDropdown(data, dropdownStyle, rowStyle, search);
+ useImperativeHandle(ref, () => ({
+ reset: () => {
+ reset();
+ },
+ openDropdown: () => {
+ openDropdown();
+ },
+ closeDropdown: () => {
+ closeDropdown();
+ },
+ selectIndex: index => {
+ selectItem(index);
+ },
+ }));
+ /* ******************* Methods ******************* */
+ const openDropdown = () => {
+ dropdownButtonRef.current.measure((fx, fy, w, h, px, py) => {
+ onDropdownButtonLayout(w, h, px, py);
+ setIsVisible(true);
+ onFocus && onFocus();
+ });
+ };
+ const closeDropdown = () => {
+ if (multipleSelect) {
+ onSelect && onSelect(selectedItem.map(d => d.item));
+ }
+ setIsVisible(false);
+ setSearchTxt('');
+ onBlur && onBlur();
+ };
+ const onLayout = () => {
+ if (disableAutoScroll) {
+ return;
+ }
+ if (selectedIndex >= 3 && dropDownFlatlistRef) {
+ dropDownFlatlistRef.current.scrollToOffset({
+ offset: rowStyle && rowStyle.height ? rowStyle.height * selectedIndex : 50 * selectedIndex,
+ animated: true,
+ });
+ }
+ };
+ const onSelectItem = (item, index) => {
+ if (multipleSelect) {
+ selectItem(index);
+ toggleSeletAll(false);
+ return;
+ }
+ closeDropdown();
+ onSelect && onSelect(item, index);
+ selectItem(index);
+ };
+ /* ******************** Render Methods ******************** */
+ const renderSearchView = () => {
+ return (
+ search && (
+ {
+ setSearchTxt(txt);
+ disabledInternalSearch && onChangeSearchInputText(txt);
+ }}
+ inputStyle={searchInputStyle}
+ inputTextStyle={searchInputTxtStyle}
+ renderLeft={renderSearchInputLeftIcon}
+ renderRight={renderSearchInputRightIcon}
+ />
+ )
+ );
+ };
+ const renderSelectAll = () => {
+ return (
+ multipleSelect &&
+ allowSelectAll && (
+
+ Select All
+ {
+ toggleSeletAll();
+ }}
+ value={selectAll}
+ />
+
+ )
+ );
+ };
+ const renderFlatlistItem = ({item, index}) => {
+ const isSelected = multipleSelect ? selectedIndex.filter(d => d == index).length > 0 : index == selectedIndex;
+ const disable = disabledIndexs?.includes(index);
+ return (
+ isExist(item) && (
+ onSelectItem(item, index)}>
+ {renderCustomizedRowChild ? (
+
+ {renderCustomizedRowChild(item, index, isSelected, disable)}
+
+ ) : (
+
+ {rowTextForSelection ? rowTextForSelection(item, index) : item.toString()}
+
+ )}
+
+ )
+ );
+ };
+ const renderDropdown = () => {
+ return (
+ isVisible && (
+
+
+
+ {data.length > 0 && (
+
+ {renderSelectAll()}
+ {renderSearchView()}
+
+ )}
+ index.toString()}
+ ref={dropDownFlatlistRef}
+ renderItem={renderFlatlistItem}
+ getItemLayout={getItemLayout}
+ onLayout={onLayout}
+ keyboardShouldPersistTaps="always"
+ onEndReached={() => onScrollEndReached && onScrollEndReached()}
+ onEndReachedThreshold={0.5}
+ ListEmptyComponent={
+
+ List Empty
+
+ }
+ />
+
+
+ )
+ );
+ };
+ ///////////////////////////////////////////////////////
+ return (
+
+ {renderDropdown()}
+ {renderDropdownIcon && renderDropdownIcon(isVisible)}
+ {!onlyDropdownIcon &&
+ (renderCustomizedButtonChild ? (
+
+ {renderCustomizedButtonChild(selectedItem, selectedIndex)}
+
+ ) : (
+
+ {multipleSelect
+ ? selectedItem.length > 0
+ ? buttonTextAfterSelection
+ : defaultButtonText
+ : isExist(selectedItem)
+ ? buttonTextAfterSelection
+ ? buttonTextAfterSelection(selectedItem, selectedIndex)
+ : selectedItem.toString()
+ : defaultButtonText || 'Select an option.'}
+
+ ))}
+
+ );
+};
+
+export default forwardRef((props, ref) => FlashSelectDropdown(props, ref));
diff --git a/src/SelectDropdown.js b/src/SelectDropdown.js
index 4f61bdf..357b403 100644
--- a/src/SelectDropdown.js
+++ b/src/SelectDropdown.js
@@ -1,5 +1,5 @@
-import React, {forwardRef, useImperativeHandle} from 'react';
-import {View, Text, TouchableOpacity, FlatList} from 'react-native';
+import React, {forwardRef, useImperativeHandle, useState} from 'react';
+import {View, Text, TouchableOpacity, FlatList, Switch} from 'react-native';
import styles from './styles';
import {isExist} from './helpers/isExist';
import Input from './components/Input';
@@ -15,7 +15,7 @@ const SelectDropdown = (
data /* array */,
onSelect /* function */,
defaultButtonText /* String */,
- buttonTextAfterSelection /* function */,
+ buttonTextAfterSelection /* function or string */,
rowTextForSelection /* function */,
defaultValue /* any */,
defaultValueByIndex /* integer */,
@@ -39,6 +39,7 @@ const SelectDropdown = (
rowStyle /* style object for row */,
rowTextStyle /* style object for row text */,
selectedRowStyle /* style object for selected row */,
+ disabledStyle,
selectedRowTextStyle /* style object for selected row text */,
renderCustomizedRowChild /* function returns React component for customized row */,
/////////////////////////////
@@ -51,6 +52,12 @@ const SelectDropdown = (
renderSearchInputLeftIcon /* function returns React component for search input icon */,
renderSearchInputRightIcon /* function returns React component for search input icon */,
onChangeSearchInputText /* function callback when the search input text changes, this will automatically disable the dropdown's interna search to be implemented manually outside the component */,
+ onlyDropdownIcon = false /*shows only drop down icon and ignores the text */,
+ textNumberOfLines = 1 /*Drop Down Button Text number of lines (numberOfLines prop for Text) */,
+ multipleSelect = false /*Select Multiple values from the Drop down List */,
+ searchKey /*search key if the data is object default searches all */,
+ emptyStyle /*Empty data style */,
+ allowSelectAll = false /*Allows user to select all data (works only if multiple select is true) */,
},
ref,
) => {
@@ -65,7 +72,9 @@ const SelectDropdown = (
reset,
searchTxt,
setSearchTxt,
- } = useSelectDropdown(data, defaultValueByIndex, defaultValue, disabledInternalSearch);
+ selectAll,
+ toggleSeletAll,
+ } = useSelectDropdown(data, defaultValueByIndex, defaultValue, disabledInternalSearch, multipleSelect, searchKey);
const {
isVisible, //
setIsVisible,
@@ -97,6 +106,9 @@ const SelectDropdown = (
});
};
const closeDropdown = () => {
+ if (multipleSelect) {
+ onSelect && onSelect(selectedItem.map(d => d.item));
+ }
setIsVisible(false);
setSearchTxt('');
onBlur && onBlur();
@@ -113,6 +125,11 @@ const SelectDropdown = (
}
};
const onSelectItem = (item, index) => {
+ if (multipleSelect) {
+ selectItem(index);
+ toggleSeletAll(false);
+ return;
+ }
closeDropdown();
onSelect && onSelect(item, index);
selectItem(index);
@@ -139,17 +156,41 @@ const SelectDropdown = (
)
);
};
+ const renderSelectAll = () => {
+ return (
+ multipleSelect &&
+ allowSelectAll && (
+
+ Select All
+ {
+ toggleSeletAll();
+ }}
+ value={selectAll}
+ />
+
+ )
+ );
+ };
const renderFlatlistItem = ({item, index}) => {
- const isSelected = index == selectedIndex;
+ const isSelected = multipleSelect ? selectedIndex.filter(d => d == index).length > 0 : index == selectedIndex;
+ const disable = disabledIndexs?.includes(index);
return (
isExist(item) && (
onSelectItem(item, index)}>
{renderCustomizedRowChild ? (
- {renderCustomizedRowChild(item, index, isSelected)}
+
+ {renderCustomizedRowChild(item, index, isSelected, disable)}
+
) : (
+ {data.length > 0 && (
+
+ {renderSelectAll()}
+ {renderSearchView()}
+
+ )}
index.toString()}
ref={dropDownFlatlistRef}
renderItem={renderFlatlistItem}
getItemLayout={getItemLayout}
onLayout={onLayout}
- ListHeaderComponent={renderSearchView()}
- stickyHeaderIndices={search && [0]}
keyboardShouldPersistTaps="always"
onEndReached={() => onScrollEndReached && onScrollEndReached()}
onEndReachedThreshold={0.5}
+ ListEmptyComponent={
+
+ List Empty
+
+ }
/>
@@ -197,22 +250,31 @@ const SelectDropdown = (
...styles.dropdownButton,
...(dropdownIconPosition == 'left' ? styles.row : styles.rowRevese),
...buttonStyle,
+ justifyContent: onlyDropdownIcon ? 'center' : 'center',
}}>
{renderDropdown()}
{renderDropdownIcon && renderDropdownIcon(isVisible)}
- {renderCustomizedButtonChild ? (
-
- {renderCustomizedButtonChild(selectedItem, selectedIndex)}
-
- ) : (
-
- {isExist(selectedItem)
- ? buttonTextAfterSelection
- ? buttonTextAfterSelection(selectedItem, selectedIndex)
- : selectedItem.toString()
- : defaultButtonText || 'Select an option.'}
-
- )}
+ {!onlyDropdownIcon &&
+ (renderCustomizedButtonChild ? (
+
+ {renderCustomizedButtonChild(selectedItem, selectedIndex)}
+
+ ) : (
+
+ {multipleSelect
+ ? selectedItem.length > 0
+ ? buttonTextAfterSelection
+ : defaultButtonText
+ : isExist(selectedItem)
+ ? buttonTextAfterSelection
+ ? buttonTextAfterSelection(selectedItem, selectedIndex)
+ : selectedItem.toString()
+ : defaultButtonText || 'Select an option.'}
+
+ ))}
);
};
diff --git a/src/hooks/useSelectDropdown.js b/src/hooks/useSelectDropdown.js
index 879c685..ccea20b 100644
--- a/src/hooks/useSelectDropdown.js
+++ b/src/hooks/useSelectDropdown.js
@@ -3,9 +3,17 @@ import {deepSearchInArr} from '../helpers/deepSearchInArr';
import {findIndexInArr} from '../helpers/findIndexInArr';
import {isExist} from '../helpers/isExist';
-export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disabledInternalSearch) => {
- const [selectedItem, setSelectedItem] = useState(null); // selected item from dropdown
- const [selectedIndex, setSelectedIndex] = useState(-1); // index of selected item from dropdown
+export const useSelectDropdown = (
+ data,
+ defaultValueByIndex,
+ defaultValue,
+ disabledInternalSearch,
+ multipleSelect,
+ searchKey,
+) => {
+ const [selectedItem, setSelectedItem] = useState(multipleSelect ? [] : null); // selected item from dropdown
+ const [selectedIndex, setSelectedIndex] = useState(multipleSelect ? [-1] : -1); // index of selected item from dropdown
+ const [selectAll, setSelectAll] = useState(false); // index of selected item from dropdown
const [searchTxt, setSearchTxt] = useState('');
// data array changes
@@ -19,6 +27,21 @@ export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disab
useEffect(() => {
// defaultValueByIndex may be equals zero
if (isExist(defaultValueByIndex)) {
+ if (multipleSelect) {
+ let tmp = [];
+
+ defaultValueByIndex.map((d, i) => {
+ let exist = isExist(data[d]);
+ if (data && exist) {
+ let index = findIndexInArr(data[d], data);
+ tmp.push({item: data[index], index});
+ }
+ });
+ setSelectedItem(tmp);
+ setSelectedIndex(tmp.map(d => d.index));
+ return;
+ }
+
if (data && isExist(data[defaultValueByIndex])) {
selectItem(defaultValueByIndex);
}
@@ -28,6 +51,20 @@ export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disab
useEffect(() => {
// defaultValue may be equals zero
if (isExist(defaultValue)) {
+ if (multipleSelect) {
+ let tmp = [];
+
+ defaultValue.map((d, i) => {
+ let index = findIndexInArr(d, data);
+ if (data && index >= 0) {
+ tmp.push({item: data[index], index});
+ }
+ });
+ setSelectedItem(tmp);
+ setSelectedIndex(tmp.map(d => d.index));
+ return;
+ }
+
if (data && findIndexInArr(defaultValue, data) >= 0) {
selectItem(findIndexInArr(defaultValue, data));
}
@@ -38,17 +75,47 @@ export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disab
if (disabledInternalSearch) {
return data;
}
- return searchTxt ? deepSearchInArr(searchTxt, data) : data;
+ return searchTxt ? deepSearchInArr(searchTxt, data, searchKey) : data;
}, [data, searchTxt]);
const selectItem = index => {
+ if (multipleSelect) {
+ let tmp = selectedItem;
+ tmp =
+ tmp.filter(d => d?.index == index).length > 0
+ ? tmp.filter(d => d.index !== index)
+ : [...tmp, {item: data[index], index}];
+ setSelectedItem(tmp);
+ setSelectedIndex(tmp.map(d => d.index));
+ return;
+ }
+
setSelectedItem(data[index]);
setSelectedIndex(index);
};
const reset = () => {
- setSelectedItem(null);
- setSelectedIndex(-1);
+ setSelectedItem(multipleSelect ? [] : null);
+ setSelectedIndex(multipleSelect ? [-1] : -1);
+ };
+
+ const toggleSeletAll = (cond = true) => {
+ if (cond) {
+ if (!selectAll) {
+ let tmp = [];
+ data.map((d, i) => {
+ tmp.push({item: d, index: i});
+ });
+ setSelectedItem(tmp);
+ setSelectedIndex(tmp.map(d => d.index));
+ } else {
+ setSelectedItem([]);
+ setSelectedIndex([-1]);
+ }
+ setSelectAll(!selectAll);
+ return;
+ }
+ setSelectAll(false);
};
return {
@@ -59,5 +126,7 @@ export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disab
reset,
searchTxt,
setSearchTxt,
+ selectAll,
+ toggleSeletAll,
};
};
diff --git a/src/styles.js b/src/styles.js
index 4115f96..1ebbd77 100644
--- a/src/styles.js
+++ b/src/styles.js
@@ -49,6 +49,16 @@ const styles = StyleSheet.create({
flex: 1,
overflow: 'hidden',
},
+ allowAllStyle: {
+ justifyContent: 'center',
+ alignItems: 'center',
+ flexDirection: 'row',
+ position: 'absolute',
+ top: 0,
+ right: 0,
+ zIndex: 9999,
+ height: 50,
+ },
});
export default styles;
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..fb57ccd
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,4 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
From a0df3996e4ca0660ce271d1f048eb45949336991 Mon Sep 17 00:00:00 2001
From: rohan km
Date: Tue, 21 Feb 2023 18:59:45 +0530
Subject: [PATCH 2/5] updated readme
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c7efd51..1d319a7 100644
--- a/README.md
+++ b/README.md
@@ -262,7 +262,7 @@ default selected item in dropdown ( check examples in Demo1). If multiple select
### defaultValueByIndex
-default selected item index. If multipleSelect is true then pass the array of default indices (check Demo2).
+default selected item index. If multipleSelect is true then pass the array of default indices.
| Type | Required |
| ---------------- | -------- |
From 2355299dffc4bad104e1d62ebf3f32cdd811fab7 Mon Sep 17 00:00:00 2001
From: rohan km
Date: Tue, 21 Feb 2023 19:09:21 +0530
Subject: [PATCH 3/5] deepSearchInArr updated with searchKey
---
src/helpers/deepSearchInArr.js | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/src/helpers/deepSearchInArr.js b/src/helpers/deepSearchInArr.js
index 39a8f1b..57ae221 100644
--- a/src/helpers/deepSearchInArr.js
+++ b/src/helpers/deepSearchInArr.js
@@ -1,10 +1,24 @@
-const contains = (item, searchTxt) => {
+const decycle = (obj, stack = []) => {
+ if (!obj || typeof obj !== 'object') return obj;
+ if (stack.includes(obj)) return null;
+ if (obj._raw) {
+ return obj._raw;
+ }
+ let s = stack.concat([obj]);
+
+ return Array.isArray(obj)
+ ? obj.map(x => decycle(x, s))
+ : Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, decycle(v, s)]));
+};
+const contains = (item, searchTxt, searchKey) => {
// item is an object
if (typeof item == 'object' && item != null) {
for (let key in item) {
- const value = item[key];
- if (contains(value, searchTxt)) {
- return true;
+ if (searchKey ? searchKey.includes(key) : true) {
+ const value = item[key];
+ if (contains(value, searchTxt)) {
+ return true;
+ }
}
}
}
@@ -19,10 +33,10 @@ const contains = (item, searchTxt) => {
return false;
};
-export const deepSearchInArr = (query, arr) => {
+export const deepSearchInArr = (query, arr, searchKey) => {
let array = [];
for (let i = 0; i <= arr.length - 1; i++) {
- if (contains(arr[i], query)) {
+ if (contains(arr[i], query, searchKey)) {
array.push(arr[i]);
} else {
array.push(null);
From 07bfd04800c7890d9c785eebb2a4c38c42f15375 Mon Sep 17 00:00:00 2001
From: rohan km
Date: Tue, 21 Feb 2023 19:40:29 +0530
Subject: [PATCH 4/5] defauly export SelectDropdown
---
index.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/index.js b/index.js
index 63f041a..1140548 100644
--- a/index.js
+++ b/index.js
@@ -1,4 +1,5 @@
import SelectDropdown from './src/SelectDropdown';
import FlashSelectDropdown from './src/FlashSelectDropdown';
-export {SelectDropdown, FlashSelectDropdown};
+export default SelectDropdown;
+export {FlashSelectDropdown};
From ed65ec8bb76b8864c7dded400ba9a06f29add2f8 Mon Sep 17 00:00:00 2001
From: rohan km
Date: Tue, 21 Feb 2023 20:41:17 +0530
Subject: [PATCH 5/5] added index on select multiple values
---
README.md | 4 ++--
src/FlashSelectDropdown.js | 6 +++++-
src/SelectDropdown.js | 6 +++++-
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 1d319a7..4ba85e9 100644
--- a/README.md
+++ b/README.md
@@ -92,7 +92,7 @@ const [data,setData]=useState()
);
}}
- onSelect={async (selectedItem) => {
+ onSelect={async (selectedItem,index) => {
setData(selectedItem);
}}
buttonTextAfterSelection={"Selected"}
@@ -210,7 +210,7 @@ array of data that will be represented in dropdown 'can be array of objects
function recieves selected item and its index in data array
-if multipleSelect is true then recives only array of item.
+if multipleSelect is true then recives array of items and arrat if selected index.
| Type | Required |
| -------- | -------- |
diff --git a/src/FlashSelectDropdown.js b/src/FlashSelectDropdown.js
index f8eb6c7..63e8987 100644
--- a/src/FlashSelectDropdown.js
+++ b/src/FlashSelectDropdown.js
@@ -108,7 +108,11 @@ const FlashSelectDropdown = (
};
const closeDropdown = () => {
if (multipleSelect) {
- onSelect && onSelect(selectedItem.map(d => d.item));
+ onSelect &&
+ onSelect(
+ selectedItem.map(d => d.item),
+ selectedIndex,
+ );
}
setIsVisible(false);
setSearchTxt('');
diff --git a/src/SelectDropdown.js b/src/SelectDropdown.js
index 357b403..48d1823 100644
--- a/src/SelectDropdown.js
+++ b/src/SelectDropdown.js
@@ -107,7 +107,11 @@ const SelectDropdown = (
};
const closeDropdown = () => {
if (multipleSelect) {
- onSelect && onSelect(selectedItem.map(d => d.item));
+ onSelect &&
+ onSelect(
+ selectedItem.map(d => d.item),
+ selectedIndex,
+ );
}
setIsVisible(false);
setSearchTxt('');