import { type ComponentType, type ReactNode } from "react"; import { type ColorTokens, type StyleProp, type ViewStyle, type TextStyle } from "../../style/index.js"; import { type DropdownProps } from "../../atoms/dropdown/dropdown.js"; import { type Surface } from "./navbars.styles.js"; export interface NavbarSkin { /** iOS/web dim a pressed link; Android uses a ripple instead (null). */ pressedOpacity: number | null; /** Android ripple over a pressed link; null on iOS/web. */ ripple: ((t: ColorTokens) => { color: string; borderless: boolean; }) | null; /** * Web-only focus-outline reset for the link Pressable. iOS sets this so the * react-native-web keyboard-focus blue ring (which a real iOS toolbar bar-button * item never shows) is suppressed, leaving the press dim as the only feedback. * Undefined on web/Android, which keep their own focus treatment. No-op * natively, where `outlineStyle`/`outlineWidth` are not real CSS. Mirrors * pagination/input/textarea's focus reset. */ focusOutlineReset?: ViewStyle; /** The bar row: height, padding, and flex layout. */ bar: (t: ColorTokens) => ViewStyle; /** The token-driven background fill (follows the scheme/glass surface). */ surface: (t: ColorTokens) => ViewStyle; /** The surface-axis treatment (hairline / outline / floating card). */ surfaceContainer: (t: ColorTokens, surface: Surface) => ViewStyle; /** The left cluster row (brand + links). */ leftGroup: (t: ColorTokens) => ViewStyle; /** The brand wordmark type. */ brand: (t: ColorTokens) => TextStyle; /** The links row. */ linksRow: (t: ColorTokens) => ViewStyle; /** A nav link tile (padding + active fill). */ linkTile: (t: ColorTokens, active: boolean) => ViewStyle; /** A nav link label (weight + active/inactive color). */ linkLabel: (t: ColorTokens, active: boolean) => TextStyle; /** The right cluster row (action + avatar). */ rightGroup: (t: ColorTokens) => ViewStyle; } export interface NavbarProps { /** Brand or product name shown at the left, in a semibold face. */ brand?: string; /** * A brand ELEMENT for the left cluster (a logo mark, a workspace switcher). * It LEADS the cluster, so passing it beside `brand` renders the mark first and * keeps the wordmark beside it; passing it alone makes the mark the whole brand. * It takes the left cluster's own gap, so it needs no wrapper. */ brandContent?: ReactNode; /** * Ordered navigation link labels rendered in the middle row. Omit it (or pass an * empty array) for a bar with no middle nav: neither the links row nor the * narrow menu button that stands in for it renders. */ links?: string[]; /** Index of the active link (CONTROLLED; its label reads in the foreground color). Omit for uncontrolled use. */ active?: number; /** Initial active link for uncontrolled use (a bare navbar moves the active link on press). */ defaultActive?: number; /** * Free-form trailing controls for the right cluster: a ghost search button, icon * buttons, a notification dropdown, an account menu. They LEAD the cluster, ahead * of the built-in `actionLabel` button and `avatar`, and take the cluster's own * gap, so they need no wrapper. Keep them few and compact: the bar is a fixed * height and the slot is rendered as given at every width. */ actions?: ReactNode; /** Optional primary action; renders a