Skip to content

Commit 47aa264

Browse files
committed
refactoring to FlatList
1 parent 8eab682 commit 47aa264

File tree

10 files changed

+168
-149
lines changed

10 files changed

+168
-149
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,11 @@ npm run ios
254254
| `suggestionsListTextStyle` | | TextStyle | styles of suggestions list text items |
255255
| `ChevronIconComponent` | | React.Component | Feather chevron icon |
256256
| `ClearIconComponent` | | React.Component | Feather x icon |
257-
| `ScrollViewComponent` | | React.Component name | ScrollView that provide suggestions content |
257+
| ~~ScrollViewComponent~~ | removed in 2.0.0 based on FlatList | React.Component name | ScrollView that provide suggestions content |
258258
| `EmptyResultComponent` | replace the default `<NothingFound>` Component on empty result | React.Component | |
259259
| `emptyResultText` | replace the default "Nothing found" text on empty result | string | "Nothing found" |
260260
| `textInputProps` | text input props | TextInputProps | |
261+
| `flatListProps` | props for \<FlatList/\> component | FlatListProps\<any\> | |
261262

262263
## Troubleshooting
263264

example/components/LocalDataSetExample.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@ import { AutocompleteDropdown } from 'react-native-autocomplete-dropdown'
55
export const LocalDataSetExample = memo(() => {
66
const [selectedItem, setSelectedItem] = useState(null)
77

8+
const dataSet = new Array(450)
9+
.fill({ id: '1', title: 'test' })
10+
.map((item, i) => ({ ...item, id: i.toString(), title: item.title + i }))
11+
812
return (
913
<View>
1014
<AutocompleteDropdown
1115
clearOnFocus={false}
12-
closeOnBlur={true}
16+
closeOnBlur={false}
1317
initialValue={{ id: '2' }} // or just '2'
1418
onSelectItem={setSelectedItem}
15-
dataSet={[
16-
{ id: '1', title: 'Alpha' },
17-
{ id: '2', title: 'Beta' },
18-
{ id: '3', title: 'Gamma' }
19-
]}
19+
dataSet={dataSet}
20+
ItemSeparatorComponent={<View style={{ height: 1, width: '100%', backgroundColor: '#d8e1e6' }} />}
21+
getItemLayout={(data, index) => ({ length: 50, offset: 50 * index, index })}
2022
/>
2123
<Text style={{ color: '#668', fontSize: 13 }}>Selected item: {JSON.stringify(selectedItem)}</Text>
2224
</View>

example/components/RemoteDataSetExample3.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ export const RemoteDataSetExample3 = memo(() => {
102102
containerStyle={{ flexGrow: 1, flexShrink: 1 }}
103103
renderItem={(item, text) => {
104104
console.log(text)
105-
return <Text style={{ color: '#383b42', padding: 15 }}>{item.title}</Text>
105+
return (
106+
<Text style={{ color: '#383b42', padding: 15 }}>
107+
({text}) - {item.title}
108+
</Text>
109+
)
106110
}}
107111
ChevronIconComponent={<Feather name="chevron-down" size={20} color="#383b42" />}
108112
ClearIconComponent={<Feather name="x-circle" size={18} color="#383b42" />}

example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"dependencies": {
1212
"react": "17.0.2",
1313
"react-native": "0.68.1",
14-
"react-native-autocomplete-dropdown": "^1.2.0",
14+
"react-native-autocomplete-dropdown": "^1.2.1",
1515
"react-native-vector-icons": "^9.1.0"
1616
},
1717
"devDependencies": {

example/yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6214,10 +6214,10 @@ react-is@^16.13.1:
62146214
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
62156215
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
62166216

6217-
react-native-autocomplete-dropdown@^1.2.0:
6218-
version "1.2.0"
6219-
resolved "https://registry.yarnpkg.com/react-native-autocomplete-dropdown/-/react-native-autocomplete-dropdown-1.2.0.tgz#fc461e110dfa378b45ce4968a34810eaef51807b"
6220-
integrity sha512-AFGgeFtIfEt9SlaPorFTSuqSERNrdR6ZNpeenH0xURfPfvaMF1GZW7H8u/00Tot8+TUER0nBfoor2eFb8gnIzQ==
6217+
react-native-autocomplete-dropdown@^1.2.1:
6218+
version "1.2.1"
6219+
resolved "https://registry.yarnpkg.com/react-native-autocomplete-dropdown/-/react-native-autocomplete-dropdown-1.2.1.tgz#404701c9797632be43af6a58a2a87168616228e2"
6220+
integrity sha512-g0AtN6MIaFEFtwCm/QwU4sLZ0cmaVgT1kGbjtihGg9uzj0gwnfRSZEBe1Qh1cjXgqjmXPVGJ51BhhGezvSm6fg==
62216221
dependencies:
62226222
lodash.debounce "*"
62236223
prop-types "*"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-autocomplete-dropdown",
3-
"version": "1.2.1",
3+
"version": "2.0.0",
44
"description": "Dropdown Item picker with search and autocomplete (typeahead) functionality for react native",
55
"main": "src/index.js",
66
"typings": "src/index.d.ts",

src/Dropdown.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React, { memo, useMemo } from 'react'
2+
import { StyleSheet, FlatList, View, Keyboard } from 'react-native'
3+
4+
export const Dropdown = memo(
5+
({
6+
position,
7+
direction,
8+
inputHeight,
9+
dataSet,
10+
suggestionsListMaxHeight,
11+
renderItem,
12+
ListEmptyComponent,
13+
...props
14+
}) => {
15+
const ItemSeparatorComponent = useMemo(() => {
16+
return () =>
17+
props.ItemSeparatorComponent ?? <View style={{ height: 1, width: '100%', backgroundColor: '#ddd' }} />
18+
}, [props.ItemSeparatorComponent])
19+
20+
return (
21+
<View
22+
style={{
23+
...styles.listContainer,
24+
position,
25+
...(position === 'relative'
26+
? { marginTop: 5 }
27+
: {
28+
[direction === 'down' ? 'top' : 'bottom']: inputHeight + 5
29+
}),
30+
...props.suggestionsListContainerStyle
31+
}}>
32+
<FlatList
33+
keyboardDismissMode="on-drag"
34+
keyboardShouldPersistTaps="handled"
35+
nestedScrollEnabled={true}
36+
onScrollBeginDrag={Keyboard.dismiss}
37+
data={dataSet}
38+
style={{ maxHeight: suggestionsListMaxHeight }}
39+
renderItem={renderItem}
40+
keyExtractor={item => item.id}
41+
ListEmptyComponent={ListEmptyComponent}
42+
ItemSeparatorComponent={ItemSeparatorComponent}
43+
{...props.flatListProps}
44+
/>
45+
</View>
46+
)
47+
}
48+
)
49+
50+
const styles = StyleSheet.create({
51+
container: {},
52+
listContainer: {
53+
backgroundColor: '#fff',
54+
width: '100%',
55+
zIndex: 9,
56+
borderRadius: 5,
57+
shadowColor: '#00000099',
58+
shadowOffset: {
59+
width: 0,
60+
height: 12
61+
},
62+
shadowOpacity: 0.3,
63+
shadowRadius: 15.46,
64+
65+
elevation: 20
66+
}
67+
})

src/ScrollViewListItem.js

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,42 @@
1-
import React, { memo } from 'react'
1+
import React, { memo, useMemo } from 'react'
22
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'
33

4-
export const ScrollViewListItem = memo(
5-
({ titleHighlighted, titleStart, titleEnd, style, onPress, numberOfLines = 2 }) => {
6-
return (
7-
<TouchableOpacity onPress={onPress}>
8-
<View style={styles.container}>
9-
<Text numberOfLines={numberOfLines}>
10-
<Text numberOfLines={1} style={{ ...styles.text, ...style }}>
11-
{titleStart}
12-
</Text>
13-
<Text numberOfLines={1} style={{ ...styles.text, ...style, fontWeight: 'bold' }}>
14-
{titleHighlighted}
15-
</Text>
16-
<Text numberOfLines={1} style={{ ...styles.text, ...style }}>
17-
{titleEnd}
18-
</Text>
4+
export const ScrollViewListItem = memo(({ highlight, title, style, onPress, numberOfLines = 2 }) => {
5+
const titleParts = useMemo(() => {
6+
let titleHighlighted = ''
7+
let titleStart = title
8+
let titleEnd = ''
9+
10+
if (typeof title === 'string' && title.length > 0 && highlight.length > 0) {
11+
const substrIndex = title.toLowerCase().indexOf(highlight.toLowerCase())
12+
if (substrIndex !== -1) {
13+
titleStart = title.slice(0, substrIndex)
14+
titleHighlighted = title.slice(substrIndex, substrIndex + highlight.length)
15+
titleEnd = title.slice(substrIndex + highlight.length)
16+
}
17+
}
18+
19+
return { titleHighlighted, titleStart, titleEnd }
20+
}, [title, highlight])
21+
22+
return (
23+
<TouchableOpacity onPress={onPress}>
24+
<View style={styles.container}>
25+
<Text numberOfLines={numberOfLines}>
26+
<Text numberOfLines={1} style={{ ...styles.text, ...style }}>
27+
{titleParts.titleStart}
1928
</Text>
20-
</View>
21-
</TouchableOpacity>
22-
)
23-
}
24-
)
29+
<Text numberOfLines={1} style={{ ...styles.text, ...style, fontWeight: 'bold' }}>
30+
{titleParts.titleHighlighted}
31+
</Text>
32+
<Text numberOfLines={1} style={{ ...styles.text, ...style }}>
33+
{titleParts.titleEnd}
34+
</Text>
35+
</Text>
36+
</View>
37+
</TouchableOpacity>
38+
)
39+
})
2540

2641
const styles = StyleSheet.create({
2742
container: {

src/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { FC } from 'react';
2-
import { StyleProp, TextInputProps, TextStyle, ViewStyle } from 'react-native';
2+
import { StyleProp, TextInputProps, TextStyle, ViewStyle, FlatListProps } from 'react-native';
33

44
export type TAutocompleteDropdownItem = {
55
id: string;
@@ -57,11 +57,11 @@ interface AutocompleteDropdownProps {
5757
suggestionsListTextStyle?: StyleProp<TextStyle>;
5858
ChevronIconComponent?: JSX.Element;
5959
ClearIconComponent?: JSX.Element;
60-
ScrollViewComponent?: JSX.Element;
6160
InputComponent?: JSX.Element;
6261
ItemSeparatorComponent?: JSX.Element;
6362
EmptyResultComponent?: JSX.Element;
6463
emptyResultText?: string;
64+
flatListProps?: FlatListProps<any>
6565
}
6666

6767
export const AutocompleteDropdown: FC<AutocompleteDropdownProps>;

0 commit comments

Comments
 (0)