Ship Expo Router screens, seeded stores, and polished UX so auth, shop, checkout, prescriptions, loyalty, family, and account processes work end-to-end offline. Co-authored-by: Cursor <cursoragent@cursor.com>
77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
import type { ReactNode } from "react";
|
|
import { router } from "expo-router";
|
|
import { View } from "react-native";
|
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
import { IconButton } from "@/components/ui/Button";
|
|
import { Text } from "@/components/ui/Text";
|
|
import { colors, gutter } from "@/lib/theme";
|
|
|
|
type Props = {
|
|
title?: string;
|
|
subtitle?: string;
|
|
/** Large left-aligned title, matching the "Explore Products" reference. */
|
|
large?: boolean;
|
|
back?: boolean;
|
|
onBack?: () => void;
|
|
right?: ReactNode;
|
|
background?: string;
|
|
};
|
|
|
|
export function AppHeader({
|
|
title,
|
|
subtitle,
|
|
large,
|
|
back = true,
|
|
onBack,
|
|
right,
|
|
background = "transparent",
|
|
}: Props) {
|
|
const insets = useSafeAreaInsets();
|
|
|
|
return (
|
|
<View
|
|
style={{
|
|
paddingTop: insets.top + 8,
|
|
paddingHorizontal: gutter,
|
|
paddingBottom: large ? 4 : 12,
|
|
backgroundColor: background,
|
|
}}
|
|
>
|
|
<View style={{ flexDirection: "row", alignItems: "center", gap: 12, minHeight: 40 }}>
|
|
{back ? (
|
|
<IconButton
|
|
icon="chevron-back"
|
|
accessibilityLabel="Go back"
|
|
onPress={onBack ?? (() => router.back())}
|
|
/>
|
|
) : null}
|
|
{!large && title ? (
|
|
<Text variant="h2" numberOfLines={1} style={{ flex: 1 }}>
|
|
{title}
|
|
</Text>
|
|
) : (
|
|
<View style={{ flex: 1 }} />
|
|
)}
|
|
{right}
|
|
</View>
|
|
|
|
{large && title ? (
|
|
<View style={{ marginTop: 16, marginBottom: 8 }}>
|
|
<Text variant="h1">{title}</Text>
|
|
{subtitle ? (
|
|
<Text variant="bodySm" color={colors.subtle} style={{ marginTop: 4 }}>
|
|
{subtitle}
|
|
</Text>
|
|
) : null}
|
|
</View>
|
|
) : null}
|
|
|
|
{!large && subtitle ? (
|
|
<Text variant="caption" color={colors.subtle} style={{ marginTop: 2, marginLeft: 52 }}>
|
|
{subtitle}
|
|
</Text>
|
|
) : null}
|
|
</View>
|
|
);
|
|
}
|