feat: always focus input when search tab is pressed

This commit is contained in:
Adrian Castro
2024-02-20 20:38:02 +01:00
parent 987d051fee
commit b41f929f6e
3 changed files with 112 additions and 78 deletions

View File

@@ -1,3 +1,4 @@
import { useRef } from "react";
import { Platform, View } from "react-native";
import { Tabs } from "expo-router";
@@ -6,87 +7,102 @@ import Colors from "@movie-web/tailwind-config/colors";
import { MovieWebSvg } from "~/components/Icon";
import SvgTabBarIcon from "~/components/SvgTabBarIcon";
import TabBarIcon from "~/components/TabBarIcon";
import SearchTabContext from "./search/SearchTabContext";
export default function TabLayout() {
// eslint-disable-next-line @typescript-eslint/no-empty-function
const focusSearchInputRef = useRef(() => {});
return (
<Tabs
sceneContainerStyle={{
backgroundColor: Colors.background,
}}
screenOptions={{
headerShown: false,
tabBarActiveTintColor: Colors.primary[100],
tabBarStyle: {
backgroundColor: Colors.secondary[700],
borderTopColor: "transparent",
borderTopRightRadius: 20,
borderTopLeftRadius: 20,
paddingBottom: Platform.select({ ios: 100 }),
height: 80,
},
tabBarItemStyle: {
paddingVertical: 18,
height: 82,
},
tabBarLabelStyle: [
{
marginTop: 2,
<SearchTabContext.Provider value={{ focusSearchInputRef }}>
<Tabs
sceneContainerStyle={{
backgroundColor: Colors.background,
}}
screenListeners={({ route }) => ({
tabPress: () => {
switch (route.name) {
case "search":
focusSearchInputRef.current();
break;
}
},
],
}}
>
<Tabs.Screen
name="index"
options={{
title: "Home",
tabBarIcon: ({ focused }) => (
<TabBarIcon name="home" focused={focused} />
),
})}
screenOptions={{
headerShown: false,
tabBarActiveTintColor: Colors.primary[100],
tabBarStyle: {
backgroundColor: Colors.secondary[700],
borderTopColor: "transparent",
borderTopRightRadius: 20,
borderTopLeftRadius: 20,
paddingBottom: Platform.select({ ios: 100 }),
height: 80,
},
tabBarItemStyle: {
paddingVertical: 18,
height: 82,
},
tabBarLabelStyle: [
{
marginTop: 2,
},
],
}}
/>
<Tabs.Screen
name="downloads"
options={{
title: "Downloads",
tabBarIcon: ({ focused }) => (
<TabBarIcon name="download" focused={focused} />
),
}}
/>
<Tabs.Screen
name="search"
options={{
title: "Search",
tabBarLabel: "",
tabBarIcon: ({ focused }) => (
<View
className={`android:top-2 ios:top-2 flex h-14 w-14 items-center justify-center overflow-hidden rounded-full ${focused ? "bg-primary-300" : "bg-primary-400"} text-center align-middle text-2xl text-white`}
>
<TabBarIcon name="search" color="#FFF" />
</View>
),
}}
/>
<Tabs.Screen
name="movie-web"
options={{
title: "movie-web",
tabBarIcon: ({ focused }) => (
<SvgTabBarIcon focused={focused}>
<MovieWebSvg />
</SvgTabBarIcon>
),
}}
/>
<Tabs.Screen
name="settings"
options={{
title: "Settings",
tabBarIcon: ({ focused }) => (
<TabBarIcon name="cog" focused={focused} />
),
}}
/>
</Tabs>
>
<Tabs.Screen
name="index"
options={{
title: "Home",
tabBarIcon: ({ focused }) => (
<TabBarIcon name="home" focused={focused} />
),
}}
/>
<Tabs.Screen
name="downloads"
options={{
title: "Downloads",
tabBarIcon: ({ focused }) => (
<TabBarIcon name="download" focused={focused} />
),
}}
/>
<Tabs.Screen
name="search"
options={{
title: "Search",
tabBarLabel: "",
tabBarIcon: ({ focused }) => (
<View
className={`android:top-2 ios:top-2 flex h-14 w-14 items-center justify-center overflow-hidden rounded-full ${focused ? "bg-primary-300" : "bg-primary-400"} text-center align-middle text-2xl text-white`}
>
<TabBarIcon name="search" color="#FFF" />
</View>
),
}}
/>
<Tabs.Screen
name="movie-web"
options={{
title: "movie-web",
tabBarIcon: ({ focused }) => (
<SvgTabBarIcon focused={focused}>
<MovieWebSvg />
</SvgTabBarIcon>
),
}}
/>
<Tabs.Screen
name="settings"
options={{
title: "Settings",
tabBarIcon: ({ focused }) => (
<TabBarIcon name="cog" focused={focused} />
),
}}
/>
</Tabs>
</SearchTabContext.Provider>
);
}

View File

@@ -0,0 +1,8 @@
import React from "react";
const SearchTabContext = React.createContext({
// eslint-disable-next-line @typescript-eslint/no-empty-function
focusSearchInputRef: { current: () => {} },
});
export default SearchTabContext;

View File

@@ -1,10 +1,12 @@
import { useCallback, useRef, useState } from "react";
import { useCallback, useContext, useEffect, useRef, useState } from "react";
import { TextInput, View } from "react-native";
import { useFocusEffect } from "expo-router";
import { FontAwesome5 } from "@expo/vector-icons";
import Colors from "@movie-web/tailwind-config/colors";
import SearchTabContext from "./SearchTabContext";
export default function Searchbar({
onSearchChange,
}: {
@@ -13,6 +15,14 @@ export default function Searchbar({
const [keyword, setKeyword] = useState("");
const inputRef = useRef<TextInput>(null);
const { focusSearchInputRef } = useContext(SearchTabContext);
useEffect(() => {
focusSearchInputRef.current = () => {
inputRef.current?.focus();
};
}, [focusSearchInputRef]);
useFocusEffect(
useCallback(() => {
// When the screen is focused