Skip to main content

StackHeader

Stack navigation header with theme-aware styling and responsive layout.

Basic Usage

import { StackHeader } from '@multinaire/ui';

<Stack.Screen
options={{
header: (props) => <StackHeader {...props} />,
}}
/>

Props

PropTypeDefaultDescription
styleContainerStylePropsAdditional styles applied to the container
backTitlestring'Back'Label for the back navigation button (shown on tablet/desktop)
closeTitlestring'Close'Label for the modal close button (shown on tablet/desktop)

Configuration

The header is configured through React Navigation's screen options:

OptionTypeDescription
titlestringHeader title text
headerLeft() => ReactNodeLeft side content
headerRight() => ReactNodeRight side content

Examples

Basic Setup

// In your layout file
import { Stack } from 'expo-router';
import { StackHeader } from '@multinaire/ui';

export default function Layout() {
return (
<Stack
screenOptions={{
header: (props) => <StackHeader {...props} />,
}}
>
<Stack.Screen name="index" options={{ title: 'Home' }} />
<Stack.Screen name="profile" options={{ title: 'Profile' }} />
</Stack>
);
}

With Actions

<Stack.Screen
name="details"
options={{
title: 'Details',
headerRight: () => (
<IconButton icon="Send2" onPress={handleShare} />
),
}}
/>

Custom Left Button

<Stack.Screen
name="modal"
options={{
title: 'Edit Profile',
headerLeft: () => (
<IconButton icon="CloseCircle" onPress={() => navigation.goBack()} />
),
headerRight: () => (
<IconButton icon="TickCircle" onPress={handleSave} />
),
}}
/>

Multiple Right Actions

<Stack.Screen
name="post"
options={{
title: 'Post',
headerRight: () => (
<Container horizontal gap={8}>
<IconButton icon="Archive" onPress={handleSave} />
<IconButton icon="Send2" onPress={handleShare} />
</Container>
),
}}
/>

With Custom Button Labels

<Stack.Screen
name="modal"
options={{
header: (props) => (
<StackHeader {...props} backTitle="Go back" closeTitle="Dismiss" />
),
}}
/>

Using useScreenOptions Hook

import { Stack } from 'expo-router';
import { useScreenOptions } from '@multinaire/ui';

export default function Layout() {
const { screenOptions, title } = useScreenOptions('stack');

return (
<Stack screenOptions={screenOptions()}>
<Stack.Screen name="index" options={{ title: title('Home') }} />
<Stack.Screen
name="details"
options={screenOptions({ animation: 'fade' })}
/>
</Stack>
);
}

Safe area behavior

The header applies a top safe-area inset automatically. The inset is skipped when the parent navigator is a tab or drawer (those navigators own the safe area themselves). Stacks nested inside other stacks still receive the inset.

Built-in testID markers

The following elements always have fixed testID values you can target in tests without any extra configuration:

ElementtestID
Back button"navigation-back"
Close button"navigation-close"

See the Testing guide for the full list of built-in markers across all components.