({
title,
eyebrow,
size = 'default',
headerRight,
modal,
showBackButton,
onBack,
onTitlePress,
backIcon,
className,
}: Readonly<ScreenHeaderProps>)
| 26 | headerRight?: React.ReactNode; |
| 27 | /** Home, Agents, Quick Chat, and session headers supply context below the title. |
| 28 | * Other callers keep their existing title-only layout when this slot is absent. */ |
| 29 | context?: React.ReactNode; |
| 30 | modal?: boolean; |
| 31 | showBackButton?: boolean; |
| 32 | onBack?: () => void; |
| 33 | /** Keep Back available without history, replacing the current route with this destination. */ |
| 34 | backFallback?: Href; |
| 35 | onTitlePress?: () => void; |
| 36 | /** |
| 37 | * Accessibility label for the pressable title. Defaults to a generic |
| 38 | * "Open menu" so list callers don't have to supply one. Detail screens |
| 39 | * (e.g. session rename) should override with a verb that describes the |
| 40 | * action, not "open menu". |
| 41 | */ |
| 42 | onTitlePressAccessibilityLabel?: string; |
| 43 | backIcon?: 'back' | 'close'; |
| 44 | /** |
| 45 | * Apply the status-bar safe-area inset. Form sheets already clear the |
| 46 | * grabber; passing false leaves vertical padding to `className`. The |
| 47 | * landscape side insets apply regardless, so every caller clears the |
| 48 | * sensor/cutout horizontally. |
| 49 | */ |
| 50 | safeAreaTop?: boolean; |
| 51 | /** Extra classes on the outer header container. Overrides the default `px-4` for screens that need a different horizontal inset. */ |
| 52 | className?: string; |
| 53 | }; |
| 54 | |
| 55 | export function ScreenHeader({ |
| 56 | title, |
| 57 | titleContent, |
| 58 | titleNumberOfLines = 2, |
| 59 | reserveTitleSpace = false, |
| 60 | eyebrow, |
| 61 | reserveEyebrow = false, |
| 62 | size = 'default', |
| 63 | headerRight, |
| 64 | context, |
| 65 | modal, |
| 66 | centerTitle = modal ?? false, |
| 67 | showBackButton, |
| 68 | onBack, |
| 69 | backFallback, |
| 70 | onTitlePress, |
| 71 | onTitlePressAccessibilityLabel, |
| 72 | backIcon, |
| 73 | safeAreaTop = true, |
| 74 | className, |
| 75 | }: Readonly<ScreenHeaderProps>) { |
| 76 | const insets = useSafeAreaInsets(); |
| 77 | const router = useRouter(); |
| 78 | const colors = useThemeColors(); |
| 79 | const { t } = useTranslation(); |
| 80 | const canGoBack = showBackButton ?? (router.canGoBack() || backFallback !== undefined); |
| 81 | |
| 82 | // iOS modals are presented as cards already inset from the status bar |
| 83 | const paddingTop = modal && Platform.OS === 'ios' ? 32 : insets.top + 8; |
| 84 | |
| 85 | // `paddingTop` stays conditional on `safeAreaTop`: a form sheet owns its |
nothing calls this directly
no test coverage detected