Skip to content

Commit 46c1f51

Browse files
authored
Merge pull request #146 from onmotion/fix/direction-calculation-with-kb
fix: improve calculateDirection with a keyboard
2 parents 28838db + 05f13f7 commit 46c1f51

File tree

3 files changed

+45
-32
lines changed

3 files changed

+45
-32
lines changed

example/components/ModalExample.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
import React, { memo, useState } from 'react'
2-
import { Button, Modal, SafeAreaView, View } from 'react-native'
2+
import { Button, Dimensions, Modal, SafeAreaView, View } from 'react-native'
33
import { AutocompleteDropdownContextProvider } from 'react-native-autocomplete-dropdown'
44
import { RemoteDataSetExample } from './RemoteDataSetExample'
5+
import { LocalDataSetExample } from './LocalDataSetExample'
56

67
export const ModalExample = memo(() => {
78
const [opened, setOpened] = useState(false)
89
return (
910
<>
1011
<Button onPress={() => setOpened(prev => !prev)} title="Open modal" />
11-
<Modal visible={opened}>
12+
<Modal
13+
visible={opened}
14+
presentationStyle="formSheet"
15+
animationType="slide"
16+
onRequestClose={() => setOpened(false)}>
1217
<SafeAreaView style={{ flex: 1, backgroundColor: 'transparent' }}>
1318
<AutocompleteDropdownContextProvider>
1419
<View style={{ paddingHorizontal: 20, flex: 1, paddingTop: 20 }}>
20+
<LocalDataSetExample />
21+
<View style={{ height: Dimensions.get('screen').height - 300 }} />
1522
<RemoteDataSetExample />
1623
<Button onPress={() => setOpened(false)} title="Close modal" />
1724
</View>

src/index.tsx

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import { NothingFound } from './NothingFound'
3333
import { RightButton } from './RightButton'
3434
import { ScrollViewListItem } from './ScrollViewListItem'
3535
import { AutocompleteDropdownContext, AutocompleteDropdownContextProvider } from './AutocompleteDropdownContext'
36-
import { useKeyboardHeight } from './useKeyboardHeight'
3736
import diacriticless from './diacriticless'
3837
import { theme } from './theme'
3938
import type { IAutocompleteDropdownProps, AutocompleteDropdownItem } from './types'
@@ -99,7 +98,6 @@ export const AutocompleteDropdown = memo<
9998
const initialValueRef = useRef(initialValueProp)
10099
const [dataSet, setDataSet] = useState(dataSetProp)
101100
const matchFromStart = matchFrom === 'start' ? true : false
102-
const kbHeight = useKeyboardHeight()
103101
const {
104102
content,
105103
setContent,
@@ -116,17 +114,28 @@ export const AutocompleteDropdown = memo<
116114
setLoading(loadingProp)
117115
}, [loadingProp])
118116

119-
const calculateDirection = useCallback(async () => {
120-
const [, positionY] = await new Promise<[x: number, y: number, width: number, height: number]>(resolve =>
121-
containerRef.current?.measureInWindow((...rect) => resolve(rect)),
122-
)
117+
const calculateDirection = useCallback(
118+
async ({ waitForKeyboard }: { waitForKeyboard: boolean }) => {
119+
const [, positionY] = await new Promise<[x: number, y: number, width: number, height: number]>(resolve =>
120+
containerRef.current?.measureInWindow((...rect) => resolve(rect)),
121+
)
123122

124-
const screenHeight = Dimensions.get('window').height
125-
setDirection((screenHeight - kbHeight) / 2 > positionY ? 'down' : 'up')
126-
return new Promise<void>(resolve => {
127-
setTimeout(resolve, 1)
128-
})
129-
}, [kbHeight, setDirection])
123+
return new Promise<void>(resolve => {
124+
setTimeout(
125+
() => {
126+
Keyboard.isVisible()
127+
const kbHeight = Keyboard.metrics()?.height || 0
128+
console.log({ kbHeight })
129+
const screenHeight = Dimensions.get('window').height
130+
setDirection((screenHeight - kbHeight) / 2 > positionY ? 'down' : 'up')
131+
resolve()
132+
},
133+
waitForKeyboard ? Platform.select({ ios: 600, android: 150, default: 1 }) : 1, // wait for keyboard to show
134+
)
135+
})
136+
},
137+
[setDirection],
138+
)
130139

131140
const onClearPress = useCallback(() => {
132141
setSearchText('')
@@ -149,23 +158,20 @@ export const AutocompleteDropdown = memo<
149158
inputRef.current?.blur()
150159
}, [])
151160

152-
// useEffect(() => {
153-
// if (kbHeight && !direction) {
154-
// calculateDirection()
155-
// }
156-
// }, [kbHeight, direction])
157-
158-
const open = useCallback(async () => {
159-
if (directionProp) {
160-
setDirection(directionProp)
161-
} else {
162-
await calculateDirection()
163-
}
161+
const open = useCallback(
162+
async ({ focused } = { focused: false }) => {
163+
if (directionProp) {
164+
setDirection(directionProp)
165+
} else {
166+
await calculateDirection({ waitForKeyboard: focused })
167+
}
164168

165-
setTimeout(() => {
166-
setIsOpened(true)
167-
}, 0)
168-
}, [calculateDirection, directionProp, setDirection])
169+
setTimeout(() => {
170+
setIsOpened(true)
171+
}, 0)
172+
},
173+
[calculateDirection, directionProp, setDirection],
174+
)
169175

170176
const toggle = useCallback(() => {
171177
isOpened ? close() : open()
@@ -392,7 +398,7 @@ export const AutocompleteDropdown = memo<
392398
if (typeof onFocusProp === 'function') {
393399
onFocusProp(e)
394400
}
395-
open()
401+
open({ focused: true })
396402
},
397403
[clearOnFocus, onFocusProp, open],
398404
)

src/types/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface IAutocompleteDropdownRef {
1111
clear: () => void
1212
close: () => void
1313
blur: () => void
14-
open: () => Promise<void>
14+
open: (params: { focused: false }) => Promise<void>
1515
setInputText: (text: string) => void
1616
toggle: () => void
1717
setItem: (item: AutocompleteDropdownItem) => void

0 commit comments

Comments
 (0)