Autocomplete width resize when active/focus
🐛 Bug Report
After updating from Expo 46 to Expo 48. The Autocomplete component no longer behaves at it is before. I checked the ui-kitten dependencies, and still has the same version, so probably due to update of react-native?
from 0.69.9 to 0.71.71

To Reproduce
Steps to reproduce the behavior:
Expected behavior
The focus box should have the same width as before. The component also blinks when you tap on it, it should not blink same as the other components.
Link to runnable example or repository (highly encouraged)
UI Kitten and Eva version
| Package | Version |
|---|---|
| @eva-design/eva | 2.2.0 |
| @ui-kitten/components | 5.3.1 |
Environment information
@rigorcadiz
Hello there!
Please provide code example for more clear understanding and reproducing your problem.
I also see that you use autocomplete in some kind of drawer, right?
Sincerely, UI Kitten team
@bataevvlad
Here is the sample code. I created a basic app to debug this using the following command:
npx create-expo-app MyApp
Here is the App.json
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, View } from 'react-native';
import * as eva from '@eva-design/eva';
import { ApplicationProvider, Layout, Text, Autocomplete, AutocompleteItem } from '@ui-kitten/components';
export default function App() {
return (
<ApplicationProvider {...eva} theme={eva.light}>
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
<View style={{
width: 300, height: 300, borderWidth: 1, padding: 10
}}>
<Autocomplete
placeholder='Place your Text'
>
<AutocompleteItem title='Option 1'/>
<AutocompleteItem title='Option 2'/>
<AutocompleteItem title='Option 3'/>
</Autocomplete>
</View>
</View>
</ApplicationProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
This is my package.json:
{
"name": "myapp",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@eva-design/eva": "^2.2.0",
"@ui-kitten/components": "^5.3.1",
"expo": "~48.0.15",
"expo-status-bar": "~1.4.4",
"react": "^18.0.0",
"react-native": "0.71.7",
"react-native-svg": "^13.9.0"
},
"devDependencies": {
"@babel/core": "^7.20.0"
},
"private": true
}
And I've got the same behavior with the screenshot above.
It used to be working normally before the update.
We have the same problem. In our case, the problem seems to have something to do with the width property. If I set a fixed width to the autocomplete itself, it does all work. Percentage Values don't....
We have the same problem. In our case, the problem seems to have something to do with the width property. If I set a fixed width to the autocomplete itself, it does all work. Percentage Values don't....
Yeah it works with fix width but there is also this other odd behavior that the component blinks/flash when you focus/activate it.. Does it happen on your end too or no?
ok thanks @rigorcadiz we will check it out and come back soon!
Do we have an update here?
@rigorcadiz I can advise you not to switch to a version above 0.71 react-native, the problem is associated with an update modal component of react-native, we are currently thinking about a solution, the fastest way would be to roll back to the old version 0.69 where you worked, I can not yet say how long it will take a fix
@rigorcadiz I can advise you not to switch to a version above 0.71 react-native, the problem is associated with an update modal component of react-native, we are currently thinking about a solution, the fastest way would be to roll back to the old version 0.69 where you worked, I can not yet say how long it will take a fix
Too bad Apple no longer receive the SDK version on that react-native version that is why I was forced to update.
Any updates?
Can someone give me a status update on this bug? Any time indication for the fix? If it takes to long to fix I'll need to find another solution.
@bataevvlad Has this been resolved?
I'm using:
"@eva-design/eva": "^2.2.0",
"@ui-kitten/components": "^5.3.1",
and the issue still exists.
Also ran into this issue and just general inconsistencies when styling the list of autocomplete items. I took a look at the UI-Kitten code and it looks like the issue has to do with the deprecation of UIManager and its methods that measure the position of elements, which the autocomplete and a few other components use quite a bit.
While the UIManager still works, it doesn't look like it's returning values in relation to the window, which makes putting the popover in the correct position and making it the correct size break. While the menu would show up, I could never get it to expand to the full width of the input element, no matter how creative I got with the styling.
I ended up creating a custom autocomplete component for the one instance where I needed it, and figured I'd share it back here in case it helps.
import { useState, useRef } from 'react';
import { View, StylesSheet } from 'react-native';
import { Input, List, ListItem, useTheme } from '@ui-kitten/components';
const colors = ['red', 'blue', 'yellow', 'green'];
const filterColorsByName = (color, query) => color.toLowerCase().includes(query.toLowerCase());
export const CustomAutocomplete = () => {
const theme = useTheme();
const ref = useRef();
const [colorList, setColorList] = useState(colors);
const [colorName, setColorName] = useState('');
const [popoverVisible, setPopoverVisible] = useState(false);
const [popoverPositions, setPopoverPositions] = useState(null);
const onOptionSelect = useCallback(
(color) => () => {
setColorName(color);
setPopoverVisible(false);
},
[colorList]
);
const onChangeText = (query) => {
if (!popoverVisible && query.trim().length > 0) {
setPopoverVisible(true);
}
setColorName(query);
setColorList(colors.filter((color) => filterColorsByName(color, query)));
};
return (
<Layout>
<View
ref={ref}
onLayout={() => {
ref?.current?.measureInWindow((x, y, width, height) => {
setPopoverPositions({ x, y, width, height });
});
}}
>
<Input label="Color" value={colorName} onChangeText={onChangeText} />
</View>
<List
style={[
styles.autocompleteList,
{
display: popoverVisible ? 'flex' : 'none',
borderColor: theme['color-basic-default-border'],
top: popoverPositions?.y,
left: popoverPositions?.x,
width: popoverPositions?.width
}
]}
data={colorList}
renderItem={({ item }) => <ListItem title={item} onPress={onOptionSelect(item)} />}
/>
</Layout>
);
};
const styles = StyleSheet.create({
autocompleteList: {
paddingVertical: 8,
backgroundColor: 'white',
borderWidth: 1,
borderRadius: 4,
position: 'absolute',
zIndex: 1000
}
});
The View wrapping the input with the ref and onLayout methods are the key. I couldn't get it to work with just the Input component and no wrapper. I believe this is because the measureInWindow method is only available for native components.
It's not quite as fancy as the UI-Kitten one without the anchor, but it allowed me to move forward with similar UX. I also ended up adding a debounce for the onChange handler of the Input element to automatically close the popover after 5 seconds of inactivity.
Hope this helps someone!
Thanks for sharing @johnstonbl01!
Seeing as this is still open... A simple fix for me was:
- Wrap the
Autocompletecomponent in a<View> - Give the
Viewaref - Add
style={{ width: ref.current?.offsetWidth }} || 100to theAutocompletecomponent. Number 100 here is an arbitrary fallback and can be changed based on your needs
There is another solution that worked for me using the "onLayout" prop o the View component and keeping the width in a state:
const Component = () => {
const [ width, setWidth] = useState(400)
const handleWidth = (event) => {
const { width } = event.nativeEvent.layout
setWidth(width)
}
return (
<Layout>
<View onLayout={handleWidth}>
<Autocomplete
style={{ width }}
.....>
....
</Autocomplete>
</Layout/>
)
}
Why is this abandoned? To me it seems significant enough to be fixed already...