import type { ReactNode } from "react"; import type { GestureResponderEvent } from "react-native"; import type { SVGIconElement } from "../primitives/Icon"; import { SegmentedItem, type SegmentedItemProps, } from "../selection/SegmentedItem"; import { useNavBarContext } from "./NavBarContext"; export interface NavBarItemProps { /** * Destination, matched against the NavBar's value to mark the item current. * Renders a real `` on web (native ignores it); expo Router's * `` injects it, so it does not have to be written twice. */ href?: string; label: string; icon?: SVGIconElement; /** * Replaces `icon` while the item is hovered, focused or pressed, and for as * long as it is the current destination — a duotone twin of `icon`, usually. */ activeIcon?: SVGIconElement; /** Accent tinting `activeIcon`, so the glyph changes color as well as weight. */ activeAccent?: SegmentedItemProps["activeAccent"]; disabled?: boolean; /** * Handles the press instead of the group's `onValueChange` — this is what * `` injects. A NavBar whose items carry `onPress` must be * controlled: its internal value never updates. A handler that navigates on * web must call `event.preventDefault()`, as routers do. */ onPress?: SegmentedItemProps["onPress"]; } export function NavBarItem({ href, label, icon, activeIcon, activeAccent, disabled, onPress, }: NavBarItemProps): ReactNode { const { value: currentValue, onSelect, disabled: navBarDisabled, orientation, stretch, variant, } = useNavBarContext(); const selected = href !== undefined && currentValue === href; const isDisabled = disabled === true || navBarDisabled === true; // Routing is the app's job, through the group's onValueChange or an item // onPress, so the anchor must not navigate on its own. const selectHref = href === undefined ? undefined : (event: GestureResponderEvent) => { event.preventDefault(); onSelect(href); }; return ( ); }