react-native-input-select 1.1.1 → 1.1.2

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.
Files changed (36) hide show
  1. package/lib/commonjs/components/CheckBox/index.js +17 -7
  2. package/lib/commonjs/components/CheckBox/index.js.map +1 -1
  3. package/lib/commonjs/components/Dropdown/Dropdown.js +4 -2
  4. package/lib/commonjs/components/Dropdown/Dropdown.js.map +1 -1
  5. package/lib/commonjs/components/Dropdown/DropdownFlatList.js +29 -4
  6. package/lib/commonjs/components/Dropdown/DropdownFlatList.js.map +1 -1
  7. package/lib/commonjs/components/Dropdown/DropdownSectionList.js +25 -1
  8. package/lib/commonjs/components/Dropdown/DropdownSectionList.js.map +1 -1
  9. package/lib/commonjs/components/Dropdown/DropdownSelectedItemsView.js +41 -9
  10. package/lib/commonjs/components/Dropdown/DropdownSelectedItemsView.js.map +1 -1
  11. package/lib/commonjs/index.js +60 -15
  12. package/lib/commonjs/index.js.map +1 -1
  13. package/lib/module/components/CheckBox/index.js +17 -6
  14. package/lib/module/components/CheckBox/index.js.map +1 -1
  15. package/lib/module/components/Dropdown/Dropdown.js +4 -2
  16. package/lib/module/components/Dropdown/Dropdown.js.map +1 -1
  17. package/lib/module/components/Dropdown/DropdownFlatList.js +27 -4
  18. package/lib/module/components/Dropdown/DropdownFlatList.js.map +1 -1
  19. package/lib/module/components/Dropdown/DropdownSectionList.js +26 -2
  20. package/lib/module/components/Dropdown/DropdownSectionList.js.map +1 -1
  21. package/lib/module/components/Dropdown/DropdownSelectedItemsView.js +42 -10
  22. package/lib/module/components/Dropdown/DropdownSelectedItemsView.js.map +1 -1
  23. package/lib/module/index.js +61 -16
  24. package/lib/module/index.js.map +1 -1
  25. package/lib/typescript/components/CheckBox/index.d.ts +16 -4
  26. package/lib/typescript/components/Dropdown/Dropdown.d.ts +1 -1
  27. package/lib/typescript/components/Dropdown/DropdownFlatList.d.ts +1 -1
  28. package/lib/typescript/components/Dropdown/DropdownSectionList.d.ts +1 -1
  29. package/lib/typescript/components/Dropdown/DropdownSelectedItemsView.d.ts +1 -1
  30. package/package.json +1 -1
  31. package/src/components/CheckBox/index.tsx +17 -6
  32. package/src/components/Dropdown/Dropdown.tsx +3 -0
  33. package/src/components/Dropdown/DropdownFlatList.tsx +24 -1
  34. package/src/components/Dropdown/DropdownSectionList.tsx +27 -1
  35. package/src/components/Dropdown/DropdownSelectedItemsView.tsx +32 -13
  36. package/src/index.tsx +61 -18
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable react-native/no-inline-styles */
2
- import React, { useEffect, useState } from 'react';
2
+ import React, { useEffect, useState, useRef } from 'react';
3
3
  import { SectionList, StyleSheet } from 'react-native';
4
4
  import DropdownListItem from './DropdownListItem';
5
5
  import {
@@ -8,6 +8,7 @@ import {
8
8
  SectionHeaderTitle,
9
9
  } from '../Others';
10
10
  import { extractPropertyFromArray } from '../../utils';
11
+ import { TSectionList } from 'src/types/index.types';
11
12
 
12
13
  const DropdownSectionList = ({
13
14
  options,
@@ -25,6 +26,7 @@ const DropdownSectionList = ({
25
26
  checkboxLabelStyle,
26
27
  checkboxComponentStyles,
27
28
  listComponentStyles,
29
+ listIndex,
28
30
  ...rest
29
31
  }: any) => {
30
32
  const [expandedSections, setExpandedSections] = useState(new Set());
@@ -53,6 +55,24 @@ const DropdownSectionList = ({
53
55
  });
54
56
  };
55
57
 
58
+ /**
59
+ * @description Scroll to item location
60
+ */
61
+
62
+ const sectionlistRef = useRef<SectionList<TSectionList>>(null);
63
+
64
+ const scrollToLocation = (listIndex: any) => {
65
+ sectionlistRef.current?.scrollToLocation({
66
+ sectionIndex: listIndex.sectionIndex,
67
+ animated: true,
68
+ itemIndex: listIndex.itemIndex,
69
+ });
70
+ };
71
+
72
+ useEffect(() => {
73
+ scrollToLocation(listIndex);
74
+ }, [listIndex]);
75
+
56
76
  return (
57
77
  <SectionList
58
78
  sections={options}
@@ -100,6 +120,12 @@ const DropdownSectionList = ({
100
120
  }
101
121
  keyExtractor={(_item, index) => `Options${index}`}
102
122
  stickySectionHeadersEnabled={false}
123
+ ref={sectionlistRef}
124
+ onScrollToIndexFailed={() => {
125
+ setTimeout(() => {
126
+ scrollToLocation(listIndex);
127
+ }, 500);
128
+ }}
103
129
  {...rest}
104
130
  />
105
131
  );
@@ -6,6 +6,7 @@ import {
6
6
  ScrollView,
7
7
  StyleSheet,
8
8
  Image,
9
+ TouchableOpacity,
9
10
  } from 'react-native';
10
11
  import { colors } from '../../styles/colors';
11
12
  import { inputStyles } from '../../styles/input';
@@ -27,6 +28,7 @@ const DropdownSelectedItemsView = ({
27
28
  dropdownErrorStyle,
28
29
  primaryColor,
29
30
  disabled,
31
+ setIndexOfSelectedItem,
30
32
  }: any) => {
31
33
  return (
32
34
  <Pressable
@@ -36,8 +38,7 @@ const DropdownSelectedItemsView = ({
36
38
  ...inputStyles.inputFocusState,
37
39
  borderColor: primaryColor,
38
40
  },
39
- inputStyles.input,
40
- dropdownStyle,
41
+ { ...inputStyles.input, ...dropdownStyle },
41
42
  error && //this must be last
42
43
  error !== '' &&
43
44
  !pressed && {
@@ -57,27 +58,37 @@ const DropdownSelectedItemsView = ({
57
58
  onStartShouldSetResponder={() => true}
58
59
  >
59
60
  {isMultiple ? (
60
- getSelectedItemsLabel()?.map((item: any, i: Number) => (
61
- <Text
61
+ getSelectedItemsLabel()?.map((label: string, i: Number) => (
62
+ <DropdownContent
63
+ onPress={() => {
64
+ handleToggleModal();
65
+ setIndexOfSelectedItem(label); // immediately scrolls to list item with the specified label when modal
66
+ }}
62
67
  key={`react-native-input-select-${Math.random()}-${i}`}
63
68
  style={[
64
69
  styles.selectedItems,
65
70
  { backgroundColor: primaryColor },
66
71
  multipleSelectedItemStyle,
67
72
  ]}
68
- >
69
- {item}
70
- </Text>
73
+ label={label}
74
+ />
71
75
  ))
72
76
  ) : (
73
- <Text style={[styles.blackText, selectedItemStyle]}>
74
- {getSelectedItemsLabel()}
75
- </Text>
77
+ <DropdownContent
78
+ onPress={() => {
79
+ handleToggleModal();
80
+ setIndexOfSelectedItem(getSelectedItemsLabel()); // immediately scrolls to list item with the specified label when modal
81
+ }}
82
+ style={[styles.blackText, selectedItemStyle]}
83
+ label={getSelectedItemsLabel()}
84
+ />
76
85
  )}
77
86
  {!selectedItem && selectedItems?.length === 0 && (
78
- <Text style={[styles.blackText, placeholderStyle]}>
79
- {placeholder ?? 'Select an option'}
80
- </Text>
87
+ <DropdownContent
88
+ onPress={() => handleToggleModal()}
89
+ style={[styles.blackText, placeholderStyle]}
90
+ label={placeholder ?? 'Select an option'}
91
+ />
81
92
  )}
82
93
  </View>
83
94
  </ScrollView>
@@ -90,6 +101,14 @@ const DropdownSelectedItemsView = ({
90
101
  );
91
102
  };
92
103
 
104
+ const DropdownContent = ({ onPress, style, label, ...rest }: any) => {
105
+ return (
106
+ <TouchableOpacity onPress={() => onPress()} {...rest}>
107
+ <Text style={style}>{label}</Text>
108
+ </TouchableOpacity>
109
+ );
110
+ };
111
+
93
112
  const styles = StyleSheet.create({
94
113
  iconStyle: { position: 'absolute', right: 25, top: 25 },
95
114
  selectedItemsContainer: {
package/src/index.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect } from 'react';
1
+ import React, { useState, useEffect, useCallback } from 'react';
2
2
  import { TouchableOpacity, StyleSheet, View } from 'react-native';
3
3
  import Input from './components/Input';
4
4
  import CheckBox from './components/CheckBox';
@@ -62,9 +62,13 @@ export const DropdownSelect: React.FC<DropdownProps> = ({
62
62
  const [newOptions, setNewOptions] = useState<TFlatList | TSectionList>([]);
63
63
  const [open, setOpen] = useState<boolean>(false);
64
64
  const [selectAll, setSelectAll] = useState<boolean>(false);
65
- const [selectedItem, setSelectedItem] = useState<any>(''); //for single selection
66
- const [selectedItems, setSelectedItems] = useState<any[]>([]); //for multiple selection
65
+ const [selectedItem, setSelectedItem] = useState<any>(''); // for single selection
66
+ const [selectedItems, setSelectedItems] = useState<any[]>([]); // for multiple selection
67
67
  const [searchValue, setSearchValue] = useState<string>('');
68
+ const [listIndex, setListIndex] = useState<{
69
+ sectionIndex?: number;
70
+ itemIndex: number;
71
+ }>({ itemIndex: 0 }); // for scrollToIndex in Sectionlist and Flatlist
68
72
 
69
73
  useEffect(() => {
70
74
  if (options) {
@@ -92,11 +96,15 @@ export const DropdownSelect: React.FC<DropdownProps> = ({
92
96
  const ListTypeComponent = isSectionList
93
97
  ? DropdownSectionList
94
98
  : DropdownFlatList;
95
- let modifiedSectionData = extractPropertyFromArray(newOptions, 'data').flat();
96
- let modifiedOptions = isSectionList ? modifiedSectionData : newOptions;
99
+ const modifiedSectionData = extractPropertyFromArray(
100
+ newOptions,
101
+ 'data'
102
+ ).flat();
103
+ const modifiedOptions = isSectionList ? modifiedSectionData : newOptions;
97
104
 
98
105
  const optLabel = optionLabel || DEFAULT_OPTION_LABEL;
99
106
  const optValue = optionValue || DEFAULT_OPTION_VALUE;
107
+ const optionsCopy = JSON.parse(JSON.stringify(options)); //copy of the original options array
100
108
 
101
109
  /*===========================================
102
110
  * Selection handlers
@@ -121,19 +129,7 @@ export const DropdownSelect: React.FC<DropdownProps> = ({
121
129
  } else {
122
130
  selectedValues.push(value);
123
131
  }
124
-
125
- setSelectedItems(selectedValues);
126
132
  onValueChange(selectedValues); //send value to parent
127
-
128
- //select all checkbox should not be checked if the list contains disabled values
129
- if (
130
- modifiedOptions.filter((item: TFlatListItem) => !item.disabled)
131
- .length === selectedValues.length
132
- ) {
133
- setSelectAll(true);
134
- } else {
135
- setSelectAll(false);
136
- }
137
133
  return selectedValues;
138
134
  });
139
135
  };
@@ -159,6 +155,32 @@ export const DropdownSelect: React.FC<DropdownProps> = ({
159
155
  });
160
156
  };
161
157
 
158
+ /*===========================================
159
+ * Handle side effects
160
+ *==========================================*/
161
+ const checkSelectAll = useCallback(
162
+ (selectedValues: any[]) => {
163
+ //if the list contains disabled values, those values will not be selected
164
+ if (
165
+ modifiedOptions.filter((item: TFlatListItem) => !item.disabled)
166
+ .length === selectedValues.length
167
+ ) {
168
+ setSelectAll(true);
169
+ } else {
170
+ setSelectAll(false);
171
+ }
172
+ },
173
+ [modifiedOptions]
174
+ );
175
+
176
+ // anytime the selected items change, check if it is time to set `selectAll` to true
177
+ useEffect(() => {
178
+ if (isMultiple) {
179
+ checkSelectAll(selectedItems);
180
+ }
181
+ return () => {};
182
+ }, [checkSelectAll, isMultiple, selectedItems]);
183
+
162
184
  /*===========================================
163
185
  * Get label handler
164
186
  *==========================================*/
@@ -192,7 +214,6 @@ export const DropdownSelect: React.FC<DropdownProps> = ({
192
214
  const regexFilter = new RegExp(searchText, 'i');
193
215
 
194
216
  //Because Search mutates the initial state, we have to search with a copy of the original array
195
- const optionsCopy = JSON.parse(JSON.stringify(options));
196
217
  const searchResults = isSectionList
197
218
  ? searchSectionList(optionsCopy as TSectionList, regexFilter)
198
219
  : searchFlatList(optionsCopy as TFlatList, regexFilter);
@@ -241,6 +262,7 @@ export const DropdownSelect: React.FC<DropdownProps> = ({
241
262
  setOpen(!open);
242
263
  setSearchValue('');
243
264
  setNewOptions(options);
265
+ setListIndex({ itemIndex: 0, sectionIndex: 0 });
244
266
  };
245
267
 
246
268
  useEffect(() => {
@@ -261,6 +283,25 @@ export const DropdownSelect: React.FC<DropdownProps> = ({
261
283
  ? sectionListMaxLength > 1
262
284
  : newOptions.length > 1;
263
285
 
286
+ /*===========================================
287
+ * setIndexOfSelectedItem - For ScrollToIndex
288
+ *==========================================*/
289
+ const setIndexOfSelectedItem = (selectedLabel: string) => {
290
+ isSectionList
291
+ ? optionsCopy.map((item: TSectionListItem, sectionIndex: number) => {
292
+ item.data?.find((dataItem: TFlatListItem, itemIndex: number) => {
293
+ if (dataItem[optLabel] === selectedLabel) {
294
+ setListIndex({ sectionIndex, itemIndex });
295
+ }
296
+ });
297
+ })
298
+ : optionsCopy?.find((item: TFlatListItem, itemIndex: number) => {
299
+ if (item[optLabel] === selectedLabel) {
300
+ setListIndex({ itemIndex });
301
+ }
302
+ });
303
+ };
304
+
264
305
  return (
265
306
  <>
266
307
  <Dropdown
@@ -286,6 +327,7 @@ export const DropdownSelect: React.FC<DropdownProps> = ({
286
327
  primaryColor={primary}
287
328
  disabled={disabled}
288
329
  placeholderStyle={placeholderStyle}
330
+ setIndexOfSelectedItem={setIndexOfSelectedItem}
289
331
  {...rest}
290
332
  />
291
333
  <CustomModal
@@ -342,6 +384,7 @@ export const DropdownSelect: React.FC<DropdownProps> = ({
342
384
  checkboxStyle={checkboxStyle}
343
385
  checkboxLabelStyle={checkboxLabelStyle}
344
386
  checkboxComponentStyles={checkboxComponentStyles}
387
+ listIndex={listIndex}
345
388
  />
346
389
  </CustomModal>
347
390
  </>