Adaptive Search Header

A screen header with a visible search input.

Pro component

Requires all-access to use the source code

Apple
Apple
1

Add the following dependencies to your project:

npx expo install react-native-keyboard-controller
2

Edit _layout.tsx

Wrap the _layout.tsx in <KeyboardProvider> with the 2 boolean props of statusBarTranslucent and navigationBarTranslucent

~/app/_layout.tsx
    import '../global.css';
    import 'expo-dev-client';

    import { PortalHost } from '@rn-primitives/portal';
    import { StatusBar } from 'expo-status-bar';
+   import { KeyboardProvider } from 'react-native-keyboard-controller';   
    // YOUR_OTHER_IMPORTS

    import { useColorScheme, useInitialAndroidBarSync } from '~/lib/useColorScheme';
    import { NAV_THEME } from '~/theme';

    export {    
      // Catch any errors thrown by the Layout component.
      ErrorBoundary,
    } from 'expo-router';

    export default function RootLayout() {    
      useInitialAndroidBarSync();
      const { colorScheme, isDarkColorScheme } = useColorScheme();
    
      return (
        <>
          <StatusBar
            key={`root-status-bar-${isDarkColorScheme ? 'light' : 'dark'}`}
            style={isDarkColorScheme ? 'light' : 'dark'}
          />
+         <KeyboardProvider statusBarTranslucent navigationBarTranslucent>
              <NavThemeProvider value={NAV_THEME[colorScheme]}>
                 {/* YOUR_ROOT_NAVIGATOR */}
                 <PortalHost />
              </NavThemeProvider>
+          </KeyboardProvider>
        </>
      );
    }
import { Icon } from '@roninoss/icons';
import { Link } from 'expo-router';
import * as React from 'react';
import { Platform, ScrollView, View } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-controller';
import Animated, { FadeIn, ZoomOut } from 'react-native-reanimated';

import { AdaptiveSearchHeader } from '~/components/nativewindui/AdaptiveSearchHeader';
import { AdaptiveSearchBarRef } from '~/components/nativewindui/AdaptiveSearchHeader/types';
import { Button } from '../~/components/nativewindui/Button';
import { Text } from '~/components/nativewindui/Text';
import { useColorScheme } from '~/lib/useColorScheme';

export default function AdaptiveHeaderScreen() {
  const { colors } = useColorScheme();
  const searchBarRef = React.useRef<AdaptiveSearchBarRef>(null);
  return (
    <>
      <AdaptiveSearchHeader
        iosTitle="Title"
        iosIsLargeTitle={false}
        shadowVisible={false}
        rightView={() => (
          <Button variant="plain" size="icon">
            <Icon size={24} name="account-circle-outline" color={colors.foreground} />
          </Button>
        )}
        searchBar={{
          ref: searchBarRef,
          iosCancelButtonText: 'Abort',
          onChangeText: (text) => {
            console.log(text);
          },
          materialRightView() {
            return (
              <Animated.View entering={FadeIn} exiting={ZoomOut}>
                <Button variant="plain" size="icon">
                  <Icon size={24} name="cog-outline" color={colors.foreground} />
                </Button>
              </Animated.View>
            );
          },
          content: (
            <KeyboardAwareScrollView
              className="ios:bg-background/95"
              contentContainerClassName="flex-1"
              keyboardShouldPersistTaps="always">
              <View className="flex-1 items-center justify-center">
                <Text>Search bar content</Text>
              </View>
            </KeyboardAwareScrollView>
          ),
        }}
      />
      <ScrollView
        contentInsetAdjustmentBehavior="automatic"
        contentContainerClassName="flex-1 py-10 px-4 gap-12">
        <Button
          onPress={() => {
            searchBarRef.current?.focus();
          }}>
          <Text>Focus input</Text>
        </Button>
        {Platform.OS !== 'ios' && (
          <Link href="/" asChild>
            <Button variant="plain">
              <Text>Go home</Text>
            </Button>
          </Link>
        )}
      </ScrollView>
    </>
  );
}
Logo

Unlock All Pro Screens & Components

Elevate your app with powerful, native-feeling components and templates. Build faster with beautiful ready-to-use designs.

Get all-access

Usage

The Adaptive Search Header can only be used with screens that are part of a Stack Navigator.

If your screen is part of a different type of navigation (like a Tab or Drawer Navigator), you’ll need to place that screen inside a Stack Navigator to use the Adaptive Search Header.

For help on how to nest navigators, check out Expo's documentation.

import { AdaptiveSearchHeader } from '~/components/nativewindui/AdaptiveSearchHeader';
 <AdaptiveSearchHeader iosTitle="Adaptive Search Header" />

Props

AdaptiveSearchHeader

PropTypeDefaultDescription
iosIsLargeTitlebooleanfalseWhether the iOS large title style is used.
iosBackButtonMenuEnabledbooleanIf the iOS back button menu is enabled.
iosBackButtonTitlestringThe title of the iOS back button.
iosBackButtonTitleVisiblebooleanWhether the iOS back button title is visible.
iosBackVisiblebooleanWhether the iOS back button is visible.
iosBlurEffect'systemMaterial' | 'none' | HeaderOptions['headerBlurEffect']'systemMaterial'The blur effect used on iOS.
iosTitlestringThe title of the header on iOS.
materialUseSafeAreaTopbooleantrueWhether to use the safe area top on Android.
shadowVisiblebooleanWhether the shadow is visible. iOS requires iosBlurEffect to be set to "none".
leftViewHeaderOptions["headerLeft"]Left view element for the header.
rightViewHeaderOptions["headerRight"]Right view element for the header.
shownbooleanWhether the header is shown.
backgroundColorstringBackground color of the header.
screenScreenOptionsScreen options to apply to the header.
searchBarobjectOptions for the search bar.
searchBar.iosCancelButtonTextstringText for the iOS cancel button in the search bar.
searchBar.iosHideWhenScrollingbooleanWhether the iOS search bar hides when scrolling.
searchBar.iosTintColorstringTint color for the iOS search bar.
searchBar.materialRightViewHeaderOptions["headerRight"]Right view element for the search bar on Android.
searchBar.materialBlurOnSubmitbooleanWhether the search bar blurs on submit for Android.
searchBar.materialOnSubmitEditing((e: NativeSyntheticEvent<TextInputSubmitEditingEventData>) => void)Callback triggered on submit editing for the Android search bar.
searchBar.autoCapitalizeNativeStackNavigationSearchBarOptions["autoCapitalize"]Auto-capitalize behavior for the search bar input.
searchBar.inputTypeNativeStackNavigationSearchBarOptions["inputType"]Input type for the search bar.
searchBar.onBlur() => voidCallback triggered when the search bar loses focus.
searchBar.onCancelButtonPress() => voidCallback triggered when the cancel button is pressed in the search bar.
searchBar.onChangeText(text: string) => voidCallback triggered when the text changes in the search bar.
searchBar.onFocus() => voidCallback triggered when the search bar gains focus.
searchBar.onSearchButtonPress() => voidCallback triggered when the search button is pressed in the search bar.
searchBar.placeholderstringPlaceholder text for the search bar.
searchBar.refReact.RefObject<AdaptiveSearchBarRef>Ref object for the search bar.
searchBar.textColorstringText color for the search bar.
searchBar.contentReact.ReactNodeContent to be rendered inside the search bar.
© Ronin Technologies LLC 2024