import { type ReactNode } from "react"; import { type GestureResponderEvent } from "react-native"; import { type BreakpointKey, type ColorTokens, type StyleProp, type ViewStyle, type TextStyle } from "../../style/index.js"; import { type IconName } from "../../atoms/icon/icon.js"; import { type Density, type Frame } from "./sidebar.styles.js"; /** The Icon color booleans a nav row's glyph can carry, per active state (the * skin picks foreground (default), `muted`, or brand `primary`). */ export type SidebarIconTint = { primary?: boolean; muted?: boolean; }; export interface SidebarSkin { /** Web paints the accent fill on a pressed (non-active) row; iOS/Android don't. */ pressedFill: boolean; /** iOS dims the row on press; web/Android don't (null). */ pressedOpacity: number | null; /** Android ripple over a pressed row; null on iOS/web. */ ripple: ((t: ColorTokens) => { color: string; borderless: boolean; }) | null; /** * Web-only focus-outline reset for the row Pressables. iOS sets this so the * react-native-web keyboard-focus blue ring (which a real iOS device never * shows on a sidebar nav row) 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. */ focusOutlineReset?: ViewStyle; /** The outer navigation column, per frame. `collapsed` swaps to the rail width; * `shell` (a header/footer is present) drops the inner padding/gap onto the * scroll body and fills the parent height. */ column: (t: ColorTokens, frame: Frame, collapsed: boolean, shell: boolean) => ViewStyle; /** A titled group of nav rows. */ group: ViewStyle; /** The section heading above a pinned group. */ sectionTitle: (t: ColorTokens) => TextStyle; /** The nav-row container (shape + density padding); `collapsed` centers the icon. */ row: (t: ColorTokens, density: Density, collapsed: boolean) => ViewStyle; /** The selected-row highlight fill (null when not active). */ rowFill: (t: ColorTokens, active: boolean) => ViewStyle | null; /** The row label (flex, type, color), per active state + density. */ label: (t: ColorTokens, active: boolean, density: Density) => TextStyle; /** The leading Canvas icon's color booleans, per active state. */ iconTint: (active: boolean) => SidebarIconTint; /** The leading Canvas icon size (px), per platform. */ iconSize: number; /** The panel width when collapsed. */ collapsedWidth: number; /** The header collapse/expand toggle button hit area. */ collapseToggle: (t: ColorTokens) => ViewStyle; /** The collapse toggle glyph size (glyph is `chevronLeft`, muted). */ collapseIconSize: number; /** The pinned header block (holds the brand slot + collapse toggle) + its divider. */ header: (t: ColorTokens, collapsed: boolean) => ViewStyle; /** The pinned footer block + its divider. */ footer: (t: ColorTokens, collapsed: boolean) => ViewStyle; /** The scrolling body wrapper ({ flex: 1 }). */ scroll: ViewStyle; /** The scroll body contentContainer inset + inter-section gap. */ scrollContent: (t: ColorTokens, collapsed: boolean) => ViewStyle; /** The collapsible-section header row layout. */ sectionHeaderRow: (t: ColorTokens) => ViewStyle; /** The collapsible-section header title type (flex, no standalone padding). */ sectionHeaderTitle: (t: ColorTokens) => TextStyle; /** The disclosure chevron glyph at rest (chevronRight iOS/web; chevronDown M3). */ sectionChevronGlyph: "chevronRight" | "chevronDown"; /** Degrees the chevron rotates to when open (90 iOS/web; 180 M3). */ sectionChevronSpinTo: number; /** The disclosure chevron glyph size. */ sectionChevronSize: number; /** The brand dot marking a section that holds the active row. */ activeDot: (t: ColorTokens) => ViewStyle; /** The back-row layout for a drilled-in level of the responsive drawer. */ drillBackRow: (t: ColorTokens) => ViewStyle; /** The back-row title type (the parent section's name). */ drillBackTitle: (t: ColorTokens) => TextStyle; } /** One nav row: a label, an optional leading icon glyph, an optional count. */ export interface SidebarItem { /** * Stable identity for this row, used as its React key so inserting or * reordering rows reconciles by item rather than by position. Falls back to * the row label when omitted, so supply an `id` when two rows can share a * label. Also matched by a string `active` (id first, then label). */ id?: string | number; /** Row label (e.g. "Dashboard"). */ label: string; /** Leading Canvas glyph rendered before the label, named from the kit icon set * (e.g. `"home"`, `"users"`, `"settings"`). Rendered through the `Icon` atom, * tinted per active state. */ icon?: IconName; /** Trailing count rendered as a (e.g. "12"). */ badge?: string; /** Render `badge` in the Badge atom's error status tone (a red status pill with a * leading dot) instead of the default secondary metadata pill, for a count that * reports a problem rather than a volume (e.g. account lockouts). Ignored when the * row carries no `badge`. */ badgeError?: boolean; /** Inert navigation target carried as data (e.g. "/settings"). The Sidebar never * routes; a consumer reads it in `onSelect` (e.g. `router.push(item.href)`). */ href?: string; } /** A titled group of nav rows. */ export interface SidebarSection { /** * Stable identity for this section, used as its React key so inserting or * reordering sections reconciles by section rather than by position. Falls * back to the section title when omitted. Also the section's accordion key. */ id?: string | number; /** Optional muted heading shown above the group. */ title?: string; /** Rows in this group. */ items: SidebarItem[]; /** Leading Canvas glyph for the section, shown as its single button in the * collapsed mini-rail. */ icon?: IconName; /** Render this section as a collapsible accordion group (a pressable header with a * rotating chevron over its rows). Omit for a pinned, always-open section (the * default, and the pre-collapse behavior). */ collapsible?: boolean; /** Initial open state for an uncontrolled `collapsible` section (ignored when * pinned or when `openSections` is controlled; the section owning the active row * auto-opens regardless). */ defaultOpen?: boolean; } export interface SidebarProps { /** Titled sections of nav rows. Use this or the flat `items` array. */ sections?: SidebarSection[]; /** Flat list of nav rows, wrapped into a single untitled section. */ items?: SidebarItem[]; /** The active row (CONTROLLED), by id, by label, or by flat index across all rows. Omit for uncontrolled use. */ active?: string | number; /** Initial active row for uncontrolled use (a bare sidebar moves the highlight on press). */ defaultActive?: string | number; /** Fired with the selected row and its flat index across all sections. */ onSelect?: (item: SidebarItem, index: number, event: GestureResponderEvent) => void; compact?: boolean; bordered?: boolean; floating?: boolean; /** Collapsed to the mini icon-rail (CONTROLLED). Omit for uncontrolled use. */ collapsed?: boolean; /** Initial collapsed state for uncontrolled use (default expanded). */ defaultCollapsed?: boolean; /** Show the collapse/expand toggle in the header slot. */ collapsible?: boolean; /** Fired when the user taps the collapse/expand toggle. */ onToggleCollapse?: () => void; /** Open collapsible sections (CONTROLLED), by section id/title. A single key by * default, an array when `independentSections`. Pair with `onOpenSectionsChange`. */ openSections?: string | string[]; /** Initial open sections for uncontrolled use. */ defaultOpenSections?: string | string[]; /** Fired with the next open sections whenever a section header toggles. */ onOpenSectionsChange?: (value: string | string[]) => void; /** Allow more than one collapsible section open at once (default: one-open-at-a-time). */ independentSections?: boolean; /** Opt in to the responsive rail->drawer behavior. Off by default: a bare sidebar is the * inline rail at every width, byte-identical to before. */ responsive?: boolean; /** The narrow drawer's open state (CONTROLLED). The consumer wires its hamburger to this. */ open?: boolean; /** Initial open state for the uncontrolled narrow drawer (default closed). */ defaultOpen?: boolean; /** Fired when the narrow drawer opens or closes (scrim tap, back, or a leaf selection). */ onOpenChange?: (open: boolean) => void; /** The width at and below which `responsive` switches to the drawer (default `lg` = 1024). */ drawerBreakpoint?: BreakpointKey; /** The narrow drawer panel width in px (default 288). */ drawerWidth?: number; /** Extra bottom padding for the drawer's scrolling content, so its last rows clear persistent * chrome painting over the drawer (e.g. a native bottom tab bar on Android). */ drawerContentInsetBottom?: number; /** Slide the drawer in from the end (right) edge instead of the start (left). */ drawerRight?: boolean; /** Drop the drawer down from the top edge (a top sheet). */ drawerTop?: boolean; /** Raise the drawer up from the bottom edge (a bottom sheet). */ drawerBottom?: boolean; /** Optional top slot (a brand lockup / logo). A render function receives the * collapsed state so it can show a compact mark in the rail. When `header` or * `footer` is set, the panel becomes a pinned header + scrolling body (+ footer). */ header?: ReactNode | ((collapsed: boolean) => ReactNode); /** Optional bottom slot (pinned below the scrolling sections). A render function * receives the collapsed state so it can show a compact (icon-only) footer in the rail. */ footer?: ReactNode | ((collapsed: boolean) => ReactNode); /** E2E hook forwarded to the root element. */ testID?: string; /** Outer layout composition only (width/flex within a parent), never a restyle hook. */ style?: StyleProp; } /** A row's trailing count. Two Badge families: the default secondary metadata pill, * and `badgeError`'s error status pill (`status` is Badge's family switch, `error` * its tone within that family) for a count that reports a problem. Lives here once * so the rail row and the narrow drill-down leaf cannot drift apart. */ export declare function SidebarItemBadge({ item }: { item: SidebarItem; }): import("react").JSX.Element | null; /** Build a Sidebar component from a platform skin. */ export declare function createSidebar(skin: SidebarSkin): (props: SidebarProps) => import("react").JSX.Element; //# sourceMappingURL=sidebar.shared.d.ts.map