Skip to content

Header

The Header component provides a navigation header with support for left and right action buttons, customizable title, and automatic safe area handling.

import { Header } from '@space-uy/pulsar-ui';
<Header title="My App" />
PropertyTypeRequiredDefault valueDescription
titlestring-The title text to display in the header
leftButtonHeaderButtonProps-Configuration for the left button
rightButtonHeaderButtonProps-Configuration for the right button
styleStyleProp<ViewStyle>-Custom styles for the header container
useInsetsbooleantrueWhether to use safe area insets for top padding
childrenReact.ReactNode-Additional content below the header

Configuration object for header buttons:

PropertyTypeRequiredDefault valueDescription
iconNameIconName-Lucide React Native icon name
onPress() => void-Function called when button is pressed
disabledbooleanfalseWhether the button is disabled
<Header title="Home" />
<Header
title="Profile"
leftButton={{
iconName: 'ArrowLeft',
onPress: () => navigation.goBack(),
}}
/>
<Header
title="Settings"
rightButton={{
iconName: 'Save',
onPress: handleSave,
disabled: !hasChanges,
}}
/>
<Header
title="Edit Profile"
leftButton={{
iconName: 'ArrowLeft',
onPress: () => navigation.goBack(),
}}
rightButton={{
iconName: 'Check',
onPress: handleSave,
disabled: isLoading,
}}
/>
<Header
title="Dashboard"
leftButton={{
iconName: 'Menu',
onPress: () => navigation.openDrawer(),
}}
rightButton={{
iconName: 'Bell',
onPress: () => navigation.navigate('Notifications'),
}}
/>
<Header
title="Messages"
rightButton={{
iconName: 'Plus',
onPress: () => setShowCompose(true),
}}
>
<View style={{ paddingHorizontal: 16, paddingTop: 12 }}>
<Tabs
options={[
{ value: 'all', label: 'All' },
{ value: 'unread', label: 'Unread' },
{ value: 'archived', label: 'Archived' },
]}
selected={selectedTab}
onChange={setSelectedTab}
/>
</View>
</Header>
const [showSearch, setShowSearch] = useState(false);
const [searchQuery, setSearchQuery] = useState('');
<Header
title={showSearch ? 'Search' : 'Contacts'}
leftButton={
showSearch
? {
iconName: 'ArrowLeft',
onPress: () => {
setShowSearch(false);
setSearchQuery('');
},
}
: undefined
}
rightButton={
!showSearch
? {
iconName: 'Search',
onPress: () => setShowSearch(true),
}
: undefined
}
>
{showSearch && (
<View style={{ paddingHorizontal: 16, paddingTop: 12 }}>
<Input
placeholder="Search contacts..."
value={searchQuery}
onChangeText={setSearchQuery}
iconName="Search"
clearable
/>
</View>
)}
</Header>;
<Header
title="Custom Header"
style={{
backgroundColor: colors.primary,
borderBottomWidth: 0,
}}
leftButton={{
iconName: 'ArrowLeft',
onPress: () => navigation.goBack(),
}}
/>
<Header
title="Add Item"
useInsets={false}
leftButton={{
iconName: 'X',
onPress: () => setModalVisible(false),
}}
rightButton={{
iconName: 'Check',
onPress: handleSubmit,
disabled: !isFormValid,
}}
/>
<Header
title="Sync Status"
rightButton={{
iconName: isOnline ? 'Wifi' : 'WifiOff',
onPress: () => showNetworkStatus(),
disabled: false,
}}
>
{!isOnline && (
<View
style={{
backgroundColor: colors.destructive,
paddingVertical: 8,
alignItems: 'center',
}}
>
<Text variant="ps" style={{ color: colors.background }}>
No internet connection
</Text>
</View>
)}
</Header>
<Header
title="Explore"
rightButton={{
iconName: 'Filter',
onPress: () => setShowFilters(true),
}}
>
<View style={{ paddingTop: 16 }}>
<Tabs
options={categories}
selected={selectedCategory}
onChange={setSelectedCategory}
/>
</View>
</Header>
  • The header automatically applies safe area insets for proper spacing on devices with notches
  • Button icons use IconButton component with medium size and transparent variant
  • Title text automatically truncates with ellipsis when too long
  • The header height is fixed at 52px plus safe area insets
  • Border bottom is automatically applied for visual separation
  • Children content adds bottom padding when present
  • All interactions follow theme styling conventions

The header follows a three-column layout:

  • Left slot: 40px width for left button
  • Center slot: Flexible width for title (with margins)
  • Right slot: 40px width for right button

The Header automatically applies theme styling:

  • Background: Uses theme background color
  • Border: Uses theme border color for bottom border
  • Text: Uses h3 typography variant for title
  • Buttons: Use transparent variant with theme colors
<Header
title="Custom Styled"
style={{
backgroundColor: colors.primary,
borderBottomColor: colors.primary,
borderBottomWidth: 2,
}}
/>

The component automatically handles safe area insets:

  • Top padding: Automatically added based on device safe area
  • Disable insets: Use useInsets={false} for modals or custom layouts
  • Manual handling: When disabled, you manage spacing manually
  • The header maintains proper heading hierarchy for screen readers
  • All buttons are fully keyboard accessible
  • Title text is properly announced as a heading
  • Disabled buttons are correctly communicated to assistive technologies
  • Touch targets meet minimum size requirements for accessibility