AniUI

Header

Navigation header with back button, title, and action slots.

Installation#

npx @aniui/cli add header
Settings
Web preview — components render natively on iOS & Android
import { Header, HeaderLeft, HeaderTitle, HeaderRight, HeaderBackButton } from "@/components/ui/header";
import { Button } from "@/components/ui/button";

export function MyScreen() {
  return (
    <Header>
      <HeaderLeft>
        <HeaderBackButton onPress={() => router.back()} />
      </HeaderLeft>
      <HeaderTitle>Settings</HeaderTitle>
      <HeaderRight>
        <Button size="sm" variant="ghost">Save</Button>
      </HeaderRight>
    </Header>
  );
}

Usage#

app/index.tsx
import { Header, HeaderLeft, HeaderTitle, HeaderRight, HeaderBackButton } from "@/components/ui/header";
import { Button } from "@/components/ui/button";

export function MyScreen() {
  return (
    <Header>
      <HeaderLeft>
        <HeaderBackButton onPress={() => router.back()} />
      </HeaderLeft>
      <HeaderTitle>Settings</HeaderTitle>
      <HeaderRight>
        <Button size="sm" variant="ghost">Save</Button>
      </HeaderRight>
    </Header>
  );
}

Props#

PropTypeDefault
variant
"default" | "transparent" | "primary"
"default"
className
string
-
children
React.ReactNode
-

HeaderLeft#

PropTypeDefault
className
string
-
children
React.ReactNode
-

HeaderTitle#

PropTypeDefault
className
string
-

HeaderRight#

PropTypeDefault
className
string
-
children
React.ReactNode
-

HeaderBackButton#

PropTypeDefault
onPress
() => void
-
label
string
"←"
className
string
-

Accessibility#

  • App header with back button navigation.
  • Back button has accessibilityRole="button" and accessibilityLabel for screen readers.

Source#

components/ui/header.tsx
import React from "react";
import { View, Text, Pressable } from "react-native";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";

const headerVariants = cva("flex-row items-center min-h-14 px-4", {
  variants: {
    variant: {
      default: "bg-background border-b border-border",
      transparent: "bg-transparent",
      primary: "bg-primary",
    },
  },
  defaultVariants: { variant: "default" },
});

export interface HeaderProps
  extends React.ComponentPropsWithoutRef<typeof View>,
    VariantProps<typeof headerVariants> {
  className?: string;
  children?: React.ReactNode;
}

export function Header({ variant, className, children, ...props }: HeaderProps) {
  return (
    <View className={cn(headerVariants({ variant }), className)} {...props}>
      {children}
    </View>
  );
}

export interface HeaderLeftProps extends React.ComponentPropsWithoutRef<typeof View> {
  className?: string;
  children?: React.ReactNode;
}

export function HeaderLeft({ className, children, ...props }: HeaderLeftProps) {
  return <View className={cn("flex-row items-center mr-3", className)} {...props}>{children}</View>;
}

export interface HeaderTitleProps extends React.ComponentPropsWithoutRef<typeof Text> {
  className?: string;
}

export function HeaderTitle({ className, ...props }: HeaderTitleProps) {
  return (
    <Text
      className={cn("flex-1 text-lg font-semibold text-foreground", className)}
      numberOfLines={1}
      {...props}
    />
  );
}

export interface HeaderRightProps extends React.ComponentPropsWithoutRef<typeof View> {
  className?: string;
  children?: React.ReactNode;
}

export function HeaderRight({ className, children, ...props }: HeaderRightProps) {
  return <View className={cn("flex-row items-center ml-3 gap-2", className)} {...props}>{children}</View>;
}

export interface HeaderBackButtonProps extends React.ComponentPropsWithoutRef<typeof Pressable> {
  className?: string;
  label?: string;
  onPress: () => void;
}

export function HeaderBackButton({ className, label = "←", onPress, ...props }: HeaderBackButtonProps) {
  return (
    <Pressable
      onPress={onPress}
      accessible={true}
      accessibilityRole="button"
      accessibilityLabel="Go back"
      className={cn("min-h-12 min-w-12 items-center justify-center", className)}
      {...props}
    >
      <Text className="text-primary text-lg">{label}</Text>
    </Pressable>
  );
}