import { type AnchorHTMLAttributes, type ComponentPropsWithoutRef, type ReactNode, type RefObject } from 'react';
import * as RadixCollapsible from '@radix-ui/react-collapsible';
import { type SidebarItemMove } from './sidebar-move';
export type { SidebarItemMove } from './sidebar-move';
export type SidebarMode = 'expanded' | 'icon' | 'overlay';
export type SidebarDensity = 'default' | 'compact';
export interface SidebarContextValue {
mode: SidebarMode;
density: SidebarDensity;
/** Transition the sidebar to a new mode from an internal toggle. */
transitionTo?: (next: SidebarMode) => void;
/** The `` element's DOM id, which `SidebarBody` names its scroll area
* with. Not `SidebarItem`'s `navId`, the agent hook. */
navElementId?: string;
/** True while the drawer moves focus itself on opening, so the item it
* lands on opens no tooltip. Internal. */
quietFocusRef?: RefObject;
}
export declare const useSidebar: () => SidebarContextValue;
export { usePersistentState } from '../../hooks/use-persistent-state';
export interface SidebarHandle {
getIsCollapsed: () => boolean;
toggleCollapsed: () => void;
/** True while any foldable section is open. */
getAnySectionOpen: () => boolean;
/** Fold or unfold every foldable section, as SidebarSectionsToggle does. */
setAllSectionsOpen: (open: boolean) => void;
}
export interface SidebarProps extends ComponentPropsWithoutRef<'nav'> {
/** Visual mode. Controlled via `onStateChange`. @default 'expanded' */
state?: SidebarMode;
/** Uncontrolled default mode. @default 'expanded' */
defaultState?: SidebarMode;
/** Fires when the mode changes (user toggle or overlay open/close). */
onStateChange?: (state: SidebarMode) => void;
/** Compact density shrinks inline padding. @default 'default' */
density?: SidebarDensity;
/** Overlay-only: controlled open state. */
open?: boolean;
/** Overlay-only: fires when the dialog opens/closes. */
onOpenChange?: (open: boolean) => void;
/**
* Opt-in drag handle on the inline-end edge (expanded mode only).
* Dragging or arrow keys write the committed width to the
* `--sidebar-modern-expanded-size` custom property on the root;
* Enter / double-click resets to the token default (248px).
* @default false
*/
resizable?: boolean;
/**
* Opt-in moves between sections, by drag and drop or keyboard, reported once
* on drop: apply it and re-render. Items need a `navId`, sections a
* `sectionId`. Off when omitted and in the icon rail.
*/
onMoveItem?: (move: SidebarItemMove) => void;
/**
* One call for SidebarSectionsToggle's fold or unfold of every section,
* with every section's `sectionId`, in place of each section's own
* `onOpenChange`: one write for a host that saves which sections are open.
* Uncontrolled sections still set their own state. Optional.
*/
onSetAllSectionsOpen?: (open: boolean, sectionIds: string[]) => void;
/** Override the nav aria-label. */
'aria-label'?: string;
}
declare const Sidebar: import("react").ForwardRefExoticComponent>;
declare const SidebarHeader: import("react").ForwardRefExoticComponent, HTMLDivElement>, "ref"> & import("react").RefAttributes>;
declare const SidebarBody: import("react").ForwardRefExoticComponent, HTMLDivElement>, "ref"> & import("react").RefAttributes>;
declare const SidebarFooter: import("react").ForwardRefExoticComponent, HTMLDivElement>, "ref"> & import("react").RefAttributes>;
export interface SidebarSectionProps extends ComponentPropsWithoutRef<'div'> {
/** Section label shown in expanded / overlay modes. */
label?: string;
/**
* Optional leading glyph rendered inline with the section label. Stays
* visible in `icon` mode (when the label collapses to `sr-only`) so the
* user still has a visual grouping cue. Decorative — the label carries
* the accessible name, so the icon slot is `aria-hidden`.
*/
icon?: ReactNode;
/**
* Make the label an accordion trigger that collapses its children.
* @default true
*/
collapsible?: boolean;
/** Uncontrolled default open state for the accordion. @default true */
defaultOpen?: boolean;
/** Controlled open state. */
open?: boolean;
/** Fires when the accordion opens / closes. */
onOpenChange?: (open: boolean) => void;
/**
* Stable id for moves (see `Sidebar`'s `onMoveItem`, which reports it as
* `toSectionId`). Items move into and out of a section only when it has one.
*/
sectionId?: string;
/**
* Controls at the end of the heading row, such as a `…` DropdownMenu
* trigger: beside the collapse button, never inside it, and always shown.
* Each control is at least the minimum target. Hidden in the icon rail.
*/
actions?: ReactNode;
/**
* The heading level of a foldable section's label, or `false` for none: the
* section stays a group named by its label, but adds nothing to the page's
* heading outline. `false` suits an app's navigation sidebar. @default 3
*/
headingLevel?: 2 | 3 | 4 | 5 | 6 | false;
}
declare const SidebarSection: import("react").ForwardRefExoticComponent>;
export interface SidebarGroupProps extends ComponentPropsWithoutRef {
/** Visible label for the group trigger. */
label: string;
/** Optional leading icon. */
icon?: ReactNode;
}
declare const SidebarGroup: import("react").ForwardRefExoticComponent>;
export interface SidebarItemProps extends AnchorHTMLAttributes {
/** Mark the item as the current page (`aria-current='page'`). */
isActive?: boolean;
/**
* Stable identifier emitted as `data-nav-id` on the rendered row so an agent
* can locate and activate this nav item without traversing React state.
* Optional — when omitted the row carries no nav id. (See sidebar.agent.ts
* `domHooks.item`.)
*/
navId?: string;
/** Render through Radix `Slot` so a router link can take over. */
asChild?: boolean;
/**
* Whether this item is currently pinned to Favourites. Only consulted
* when `onPinChange` is supplied.
*/
isPinned?: boolean;
/**
* Fires with the new pinned state when the user clicks the star. Passing
* this prop opts the row into the always-on pin affordance — a star
* outline fades in on row hover / focus and fills when pinned. Hidden in
* icon-only mode where there is no room for trailing controls.
*/
onPinChange?: (next: boolean) => void;
/** Accessible label for the pin button. Defaults to the item's `aria-label`. */
pinLabel?: string;
}
declare const SidebarItem: import("react").ForwardRefExoticComponent>;
declare const SidebarItemIcon: import("react").ForwardRefExoticComponent, HTMLSpanElement>, "ref"> & import("react").RefAttributes>;
declare const SidebarItemLabel: import("react").ForwardRefExoticComponent, HTMLSpanElement>, "ref"> & import("react").RefAttributes>;
declare const SidebarItemBadge: import("react").ForwardRefExoticComponent, HTMLSpanElement>, "ref"> & import("react").RefAttributes>;
export interface SidebarWorkspaceSwitcherProps extends ComponentPropsWithoutRef<'button'> {
/** Workspace glyph — square , , or . Required. */
logo: ReactNode;
/** Workspace name. Hidden in icon mode; always the accessible name. */
name: string;
/** Trailing chevron for the dropdown affordance. Defaults to true. */
showChevron?: boolean;
/**
* Visual treatment. `'ghost'` (default) is borderless — transparent at
* rest with a muted hover fill (Linear / Notion style). `'field'` gives it
* the same bordered, `--input`-filled, softly-elevated chrome as a
* co-located `` / ``, so a practice / workspace
* selector stacked directly above the search field reads as a matched pair.
* @default 'ghost'
*/
variant?: 'ghost' | 'field';
}
declare const SidebarWorkspaceSwitcher: import("react").ForwardRefExoticComponent>;
export interface SidebarPrimaryActionProps extends ComponentPropsWithoutRef<'button'> {
icon: ReactNode;
/** Button label — hidden in icon mode, always the accessible name. */
label: string;
/** Optional keyboard shortcut displayed on inline-end in expanded mode. */
shortcut?: string;
/**
* Render through Radix `Slot`, so the one child, an empty router link or
* ``, becomes the action and can open in a new tab. The kit puts
* the icon and label inside it. The ref then points at the link.
*/
asChild?: boolean;
/** Marks a link action as the current page (`aria-current="page"`). */
isActive?: boolean;
/**
* Shown dimmed, and blocks clicks, Enter, Space and middle-click, but stays
* focusable through `aria-disabled`, so the rail tooltip and keyboard users
* still find it. As a link it loses its href, so nothing can open it.
*/
disabled?: boolean;
}
declare const SidebarPrimaryAction: import("react").ForwardRefExoticComponent>;
export interface SidebarHeaderActionProps extends ComponentPropsWithoutRef<'button'> {
/** The glyph. Decorative: `label` names the action. */
icon: ReactNode;
/** The accessible name, also shown as the tooltip in every mode. */
label: string;
/** A keyboard shortcut, announced and shown in the tooltip after the label. */
shortcut?: string;
/**
* Render through Radix `Slot`, so the one child, an empty router link or
* ``, becomes the action. The ref then points at the link.
*/
asChild?: boolean;
/** Marks a link action as the current page (`aria-current="page"`). */
isActive?: boolean;
/**
* Shown dimmed, and blocks clicks, Enter, Space and middle-click, but stays
* focusable through `aria-disabled`. As a link it loses its href.
*/
disabled?: boolean;
}
/**
* An icon button for the sidebar header's tool row, beside the collapse
* button, such as "New dashboard": the collapse trigger's ghost look, icon
* only, named and tooltipped by `label`, at `--min-target-size`. Works in any
* `SidebarHeader`, in every mode.
*/
declare const SidebarHeaderAction: import("react").ForwardRefExoticComponent>;
export type SidebarSectionsToggleProps = Omit;
/**
* Folds or unfolds every foldable `SidebarSection` in its Sidebar, as a tool
* in the header row. While any section is open it collapses them all;
* only when all are folded does it expand them. Hidden with no sections.
* See `Sidebar`'s `onSetAllSectionsOpen` for one batch call.
*/
declare const SidebarSectionsToggle: import("react").ForwardRefExoticComponent>;
/**
* Toggleable star button used to pin / unpin a nav item to the Favorites
* section. Rendered inline alongside a `SidebarItem`'s content — hidden in
* icon mode (pin affordances only make sense when the full row is visible).
*
* Controlled via `isPinned` + `onPinChange`. The consumer owns the list of
* pinned items and mirrors them into ``.
*/
export interface SidebarPinButtonProps extends Omit, 'onChange'> {
/** Whether the associated item is currently pinned. */
isPinned: boolean;
/** Fires with the new pinned state. */
onPinChange?: (next: boolean) => void;
/**
* Accessible label that names what is being pinned — e.g. the item's
* label. Required so screen-readers can tell pin buttons apart.
*/
label: string;
}
declare const SidebarPinButton: import("react").ForwardRefExoticComponent>;
/**
* Renders `` with an
* empty-state prompt when no children are supplied. When `onReorder` is
* provided, children rendered as `` become drag-and-drop
* and keyboard reorderable (Alt+↑ / Alt+↓).
*/
export interface SidebarFavoritesProps extends ComponentPropsWithoutRef<'div'> {
heading?: string;
/** Shown when `children` is empty. */
emptyMessage?: string;
/**
* Called when a favorite item is moved from `from` index to `to` index.
* Providing this opts the section into drag-and-drop + keyboard reorder.
*/
onReorder?: (from: number, to: number) => void;
}
declare const SidebarFavorites: import("react").ForwardRefExoticComponent>;
export interface SidebarFavoriteItemProps extends SidebarItemProps {
/** Zero-based position of this item within its ``. */
index: number;
/**
* Accessible name used by the drag handle and live-region announcements.
* Defaults to the `aria-label` of the underlying `SidebarItem`.
*/
reorderLabel?: string;
}
declare const SidebarFavoriteItem: import("react").ForwardRefExoticComponent>;
export interface SidebarProfilePillProps extends ComponentPropsWithoutRef<'button'> {
/** Avatar or other identifying glyph. Required. */
avatar: ReactNode;
/** User's display name — hidden in icon mode, always the accessible name. */
name: string;
/**
* Secondary line (e.g. selected studio, "Owner", "Admin"). Accepts arbitrary
* JSX so an icon can sit inline with the text. Hidden in icon mode.
*/
subtitle?: ReactNode;
/**
* Plain-text form of the subtitle for the accessible name. Required when
* `subtitle` is not a string; ignored otherwise.
*/
subtitleLabel?: string;
}
declare const SidebarProfilePill: import("react").ForwardRefExoticComponent>;
export interface SidebarCollapseTriggerProps extends ComponentPropsWithoutRef<'button'> {
/** Override the accessible label. Defaults to the i18n collapse/expand string. */
'aria-label'?: string;
}
declare const SidebarCollapseTrigger: import("react").ForwardRefExoticComponent>;
export type SidebarCloseTriggerProps = ComponentPropsWithoutRef<'button'>;
/**
* The phone drawer's close button, placed by the host, for instance in a
* header row beside its actions, so focus order follows what is on screen.
* The drawer then leaves out its own corner button. Nothing outside the
* drawer.
*/
declare const SidebarCloseTrigger: import("react").ForwardRefExoticComponent, HTMLButtonElement>, "ref"> & import("react").RefAttributes>;
export interface SidebarUpgradeChipProps extends AnchorHTMLAttributes {
/**
* Headline (clamped to two lines). In icon mode it becomes the tile's
* accessible name and tooltip; in expanded mode the name comes from the
* visible contents (title + description).
*/
title: string;
/** Supporting copy. Clamped to two lines; hidden in icon mode. */
description?: string;
/** Leading glyph. Defaults to an upgrade arrow. */
icon?: ReactNode;
}
declare const SidebarUpgradeChip: import("react").ForwardRefExoticComponent>;
export { Sidebar, SidebarHeader, SidebarBody, SidebarFooter, SidebarSection, SidebarGroup, SidebarItem, SidebarItemIcon, SidebarItemLabel, SidebarItemBadge, SidebarWorkspaceSwitcher, SidebarPrimaryAction, SidebarFavorites, SidebarFavoriteItem, SidebarPinButton, SidebarProfilePill, SidebarCollapseTrigger, SidebarCloseTrigger, SidebarHeaderAction, SidebarSectionsToggle, SidebarUpgradeChip, };
//# sourceMappingURL=sidebar.d.ts.map