Skip to content

Commit 59ac0a2

Browse files
committed
feat: add props excludeItems, excludeSearchItems
1 parent 4ff1be0 commit 59ac0a2

File tree

7 files changed

+118
-10
lines changed

7 files changed

+118
-10
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ yarn add react-native-element-dropdown
8686
| accessibilityLabel | String | No | Set an accessibilityLabel on the view, so that people who use VoiceOver know what element they have selected |
8787
| itemAccessibilityLabelField | String | No | Add this field to the input data. Ex: DATA = [{itemAccessibilityLabelField: '', label: '', value:: ''}]|
8888
| closeModalWhenSelectedItem | Boolean | No | By default, closeModalWhenSelectedItem is set to true. When closeModalWhenSelectedItem is set to false, the Modal won't close when an item is selected. |
89+
| excludeItems | Item[] | No | The array containing the items to be excluded. |
90+
| excludeSearchItems | Item[] | No | The array containing the items to be excluded. |
8991

9092

9193

@@ -143,6 +145,8 @@ yarn add react-native-element-dropdown
143145
| itemTestIDField | String | No | Add this field to the input data. Ex: DATA = [{itemTestIDField: '', label: '', value:: ''}]|
144146
| accessibilityLabel | String | No | Set an accessibilityLabel on the view, so that people who use VoiceOver know what element they have selected |
145147
| itemAccessibilityLabelField | String | No | Add this field to the input data. Ex: DATA = [{itemAccessibilityLabelField: '', label: '', value:: ''}]|
148+
| excludeItems | Item[] | No | The array containing the items to be excluded. |
149+
| excludeSearchItems | Item[] | No | The array containing the items to be excluded. |
146150

147151

148152

example/src/dropdown/Dropdown1.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ const data = [
1515
{ label: 'Item 8', value: '8', search: 'Item 8' },
1616
];
1717

18+
const excludeItem = [
19+
{ label: 'Item 7', value: '7', search: 'Item 7' },
20+
{ label: 'Item 8', value: '8', search: 'Item 8' },
21+
];
22+
1823
const DropdownComponent = () => {
1924
const [value, setValue] = useState<string>();
2025
const [isFocus, setIsFocus] = useState(false);
@@ -40,6 +45,7 @@ const DropdownComponent = () => {
4045
inputSearchStyle={styles.inputSearchStyle}
4146
iconStyle={styles.iconStyle}
4247
data={data}
48+
excludeSearchItems={excludeItem}
4349
autoScroll
4450
search
4551
maxHeight={300}

example/src/dropdown/MultiSelectAll.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ const data = [
1313
{ label: 'Item 8', value: '8' },
1414
];
1515

16+
const excludeItem = [
17+
{ label: 'Item 7', value: '7', search: 'Item 7' },
18+
{ label: 'Item 8', value: '8', search: 'Item 8' },
19+
];
20+
1621
const MultiSelectComponent = () => {
1722
const [selected, setSelected] = useState<string[]>([]);
1823
const ref = useRef(null);
@@ -54,6 +59,7 @@ const MultiSelectComponent = () => {
5459
backgroundColor={'rgba(0,0,0,0.2)'}
5560
search
5661
data={data}
62+
excludeItems={excludeItem}
5763
labelField="label"
5864
valueField="value"
5965
placeholder="Multiselect All"

src/components/Dropdown/index.tsx

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable @typescript-eslint/no-shadow */
12
import _ from 'lodash';
23
import React, {
34
JSXElementConstructor,
@@ -89,6 +90,8 @@ const DropdownComponent: <T>(
8990
itemAccessibilityLabelField,
9091
mode = 'default',
9192
closeModalWhenSelectedItem = true,
93+
excludeItems = [],
94+
excludeSearchItems = [],
9295
} = props;
9396

9497
const ref = useRef<View>(null);
@@ -123,8 +126,25 @@ const DropdownComponent: <T>(
123126
// eslint-disable-next-line react-hooks/exhaustive-deps
124127
}, []);
125128

129+
const excludeData = useCallback(
130+
(data: any[]) => {
131+
if (excludeItems.length > 0) {
132+
const getData = _.differenceWith(
133+
data,
134+
excludeItems,
135+
(obj1, obj2) => _.get(obj1, valueField) === _.get(obj2, valueField)
136+
);
137+
return getData || [];
138+
} else {
139+
return data || [];
140+
}
141+
},
142+
[excludeItems, valueField]
143+
);
144+
126145
useEffect(() => {
127-
setListData([...data]);
146+
const filterData = excludeData(data);
147+
setListData([...filterData]);
128148
if (searchText) {
129149
onSearch(searchText);
130150
}
@@ -277,7 +297,8 @@ const DropdownComponent: <T>(
277297

278298
_measure();
279299
setVisible(!visible);
280-
setListData(data);
300+
const filterData = excludeData(data);
301+
setListData(filterData);
281302

282303
if (!visible) {
283304
if (onFocus) {
@@ -333,12 +354,35 @@ const DropdownComponent: <T>(
333354
const dataSearch = data.filter(
334355
searchQuery ? propSearchFunction : defaultFilterFunction
335356
);
336-
setListData(dataSearch);
357+
358+
if (excludeSearchItems.length > 0 || excludeItems.length > 0) {
359+
const excludeSearchData = _.differenceWith(
360+
dataSearch,
361+
excludeSearchItems,
362+
(obj1, obj2) =>
363+
_.get(obj1, valueField) === _.get(obj2, valueField)
364+
);
365+
366+
const filterData = excludeData(excludeSearchData);
367+
setListData(filterData);
368+
} else {
369+
setListData(dataSearch);
370+
}
337371
} else {
338-
setListData(data);
372+
const filterData = excludeData(data);
373+
setListData(filterData);
339374
}
340375
},
341-
[data, searchField, labelField, searchQuery]
376+
[
377+
data,
378+
searchQuery,
379+
excludeSearchItems,
380+
excludeItems,
381+
searchField,
382+
labelField,
383+
valueField,
384+
excludeData,
385+
]
342386
);
343387

344388
const onSelect = useCallback(

src/components/Dropdown/model.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ export interface DropdownProps<T> {
5555
inverted?: boolean;
5656
mode?: 'default' | 'modal' | 'auto';
5757
closeModalWhenSelectedItem?: boolean;
58+
excludeItems?: T[];
59+
excludeSearchItems?: T[];
5860
onChange: (item: T) => void;
5961
renderLeftIcon?: (visible?: boolean) => JSX.Element | null | undefined;
6062
renderRightIcon?: (visible?: boolean) => JSX.Element | null | undefined;

src/components/MultiSelect/index.tsx

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ const MultiSelectComponent: <T>(
9393
itemAccessibilityLabelField,
9494
visibleSelectedItem = true,
9595
mode = 'default',
96+
excludeItems = [],
97+
excludeSearchItems = [],
9698
} = props;
9799

98100
const ref = useRef<View>(null);
@@ -127,8 +129,26 @@ const MultiSelectComponent: <T>(
127129
// eslint-disable-next-line react-hooks/exhaustive-deps
128130
}, []);
129131

132+
const excludeData = useCallback(
133+
(data: any[]) => {
134+
if (excludeItems.length > 0) {
135+
const getData = _.differenceWith(
136+
data,
137+
excludeItems,
138+
(obj1, obj2) => _.get(obj1, valueField) === _.get(obj2, valueField)
139+
);
140+
return getData || [];
141+
} else {
142+
return data || [];
143+
}
144+
},
145+
[excludeItems, valueField]
146+
);
147+
130148
useEffect(() => {
131-
setListData([...data]);
149+
const filterData = excludeData(data);
150+
setListData([...filterData]);
151+
132152
if (searchText) {
133153
onSearch(searchText);
134154
}
@@ -244,7 +264,8 @@ const MultiSelectComponent: <T>(
244264

245265
_measure();
246266
setVisible(!visible);
247-
setListData(data);
267+
const filterData = excludeData(data);
268+
setListData(filterData);
248269

249270
if (!visible) {
250271
if (onFocus) {
@@ -299,12 +320,35 @@ const MultiSelectComponent: <T>(
299320
const dataSearch = data.filter(
300321
searchQuery ? propSearchFunction : defaultFilterFunction
301322
);
302-
setListData(dataSearch);
323+
324+
if (excludeSearchItems.length > 0 || excludeItems.length > 0) {
325+
const excludeSearchData = _.differenceWith(
326+
dataSearch,
327+
excludeSearchItems,
328+
(obj1, obj2) =>
329+
_.get(obj1, valueField) === _.get(obj2, valueField)
330+
);
331+
332+
const filterData = excludeData(excludeSearchData);
333+
setListData(filterData);
334+
} else {
335+
setListData(dataSearch);
336+
}
303337
} else {
304-
setListData(data);
338+
const filterData = excludeData(data);
339+
setListData(filterData);
305340
}
306341
},
307-
[data, searchField, labelField, searchQuery]
342+
[
343+
data,
344+
searchQuery,
345+
excludeSearchItems,
346+
excludeItems,
347+
searchField,
348+
labelField,
349+
valueField,
350+
excludeData,
351+
]
308352
);
309353

310354
const onSelect = useCallback(

src/components/MultiSelect/model.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ export interface MultiSelectProps<T> {
5757
itemAccessibilityLabelField?: string;
5858
inverted?: boolean;
5959
mode?: 'default' | 'modal' | 'auto';
60+
excludeItems?: T[];
61+
excludeSearchItems?: T[];
6062
onChange: (value: string[]) => void;
6163
renderLeftIcon?: (visible?: boolean) => JSX.Element | null | undefined;
6264
renderRightIcon?: (visible?: boolean) => JSX.Element | null | undefined;

0 commit comments

Comments
 (0)