Skip to main content

Header with a Search Bar

A Header with a menu button, a tappable search bar that opens the app's search, and the merchant's menuItems as icons on the right - a common layout for shopping apps.

Settings panel​

The search bar's placeholder and what happens when it's tapped are both configurable. menuItems is added automatically for headers, so it isn't declared here:

configurationSchema.json
[
{ "type": "text", "name": "searchPlaceholder", "label": "Search placeholder" },
{ "type": "action-select", "name": "searchAction", "label": "Search action" }
]
data.json
{
"searchPlaceholder": "Search products"
}

Example​

index.tsx
import React from 'react';
import { Actionable, Flexbox, Icon, Text, useAppDrawer } from '@evlop/native-components';
import { CustomBlock } from '@evlop/shopify';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

const SearchHeader: CustomBlock.Header = ({ data = {} }) => {
const appDrawer = useAppDrawer();
const insets = useSafeAreaInsets();
const menuItems = Array.isArray(data.menuItems) ? data.menuItems : [];

return (
<Flexbox
backgroundColor="header-background"
flexDirection="row"
alignItems="center"
gap={12}
paddingTop={insets.top + 8}
paddingBottom={8}
paddingLeft={insets.left + 16}
paddingRight={insets.right + 16}
>
<Icon
icon="material-community-icons:menu"
size={26}
color="header-tint"
onPress={() => {
if (appDrawer.isAvailable()) appDrawer.toggleDrawer();
}}
/>

<Actionable action={data.searchAction} style={{ flex: 1 }}>
<Flexbox flexDirection="row" alignItems="center" gap={8} height={40} px={12} borderRadius={20} bg="gray-100">
<Icon icon="material-community-icons:magnify" size={20} color="gray-500" />
<Text color="gray-500" numberOfLines={1}>
{data.searchPlaceholder || 'Search'}
</Text>
</Flexbox>
</Actionable>

{menuItems.map((item, index) => (
<Actionable key={`${item.label || 'menu-item'}-${index}`} action={item.action}>
<Icon icon={item.icon} size={24} color="header-tint" />
</Actionable>
))}
</Flexbox>
);
};

export default SearchHeader;

How it works​

  • The search bar is just a styled Actionable. It looks like an input, but tapping it runs data.searchAction - the merchant picks the app's search page (or any other action) in the settings panel, so there's no text input or search logic to build.
  • flex: 1 on the search bar makes it fill the space between the menu button and the menu item icons, whatever the screen width or number of icons.
  • useAppDrawer() opens the Drawer Menu from the menu button, and useSafeAreaInsets() keeps the header clear of the status bar and notch - both as on the Header page.
  • Theme colors. header-background and header-tint follow the app's header colors, so the header matches the rest of the app's theme.