import { forwardRef, ReactElement, useId, useState } from 'react'; import classnames from 'classnames'; import { useSideNavigation } from './contexts/SideNavigationProvider'; import icons from './icons/index'; import styles from './SideNavigation.css'; import ItemContent from './SideNavigation/ItemContent'; import TapAreaLink from './TapAreaLink'; import { Indexable } from './zIndex'; export type Props = { /** * When set to 'page' or 'section', it displays the item in "active" state. See the [Accessibility](https://gestalt.pinterest.systems/web/sidenavigation#Accessibility) guidelines to learn more. */ active?: 'page' | 'section'; /** * When supplied, will display a [Badge](https://gestalt.pinterest.systems/web/badge) next to the item's label. See the [Badges](https://gestalt.pinterest.systems/web/sidenavigation#Badge) variant to learn more. */ badge?: { text: string; type?: 'info' | 'error' | 'warning' | 'success' | 'neutral'; }; /** * When supplied, will display a counter. See the [Counter](https://gestalt.pinterest.systems/web/sidenavigation#Counter) variant to learn more. */ counter?: { number: string; accessibilityLabel: string; }; /** * Indicates if row item is disabled and therefore inactive and non-interactive. See [disabled variant](https://gestalt.pinterest.systems/web/sidenavigation#Disabled) to learn more. */ disabled?: boolean; /** * Directs users to the url when item is selected. */ href: string; /** * When supplied, will display Icon. See the [Icon](https://gestalt.pinterest.systems/web/sidenavigation#Icon) variant to learn more. */ icon?: | keyof typeof icons | { __path: string; }; /** * When supplied, will display a notification dot. See the [Notification](https://gestalt.pinterest.systems/web/sidenavigation#Notification) variant to learn more. */ notificationAccessibilityLabel?: string; /** * Callback when the user selects an item using the mouse or keyboard. */ onClick?: (arg1: { event: React.MouseEvent | React.KeyboardEvent; dangerouslyDisableOnNavigation: () => void; }) => void; /** * Provides optional additional information about a row item. See [subtext variant](https://gestalt.pinterest.systems/web/sidenavigation#Subtext) to learn more. */ subtext?: string; /** * Label for the item. */ label: string; /** * The primary action for each item. See the [primary action variant](https://gestalt.pinterest.systems/web/sidenavigation#Primary-action) to learn more. */ primaryAction?: { icon?: 'ellipsis' | 'edit' | 'trash-can'; onClick?: (arg1: { event: React.MouseEvent | React.KeyboardEvent; }) => void; tooltip: { accessibilityLabel?: string; text: string; zIndex?: Indexable; }; dropdownItems?: ReadonlyArray; }; /** * Ref that is forwarded to the underlying `li` element. */ ref?: HTMLLIElement; }; /** * Use [SideNavigation.TopItem](https://gestalt.pinterest.systems/web/sidenavigation#SideNavigation.TopItem) to redirect the user to a different page or section. SideNavigation.TopItem must be used at the top level of SideNavigation. It supports badges, icons, counters, and notifications. */ const SideNavigationTopItemWithForwardRef = forwardRef( function SideNavigationTopItem( { active, href, badge, counter, disabled, icon, label, subtext, primaryAction, notificationAccessibilityLabel, onClick, }: Props, ref, ) { const { collapsed: sideNavigationCollapsed, setSelectedItemId, setOverlayPreview, } = useSideNavigation(); const itemId = useId(); const [compression, setCompression] = useState<'compress' | 'none'>('compress'); const [hovered, setHovered] = useState(false); const [focused, setFocused] = useState(false); return (
  • setFocused(false)} onFocus={() => setFocused(true)} onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)} onTap={({ event, dangerouslyDisableOnNavigation }) => { setSelectedItemId(itemId); onClick?.({ event, dangerouslyDisableOnNavigation }); if (sideNavigationCollapsed) setOverlayPreview(false); }} rounding={2} tapStyle={compression} >
  • ); }, ); SideNavigationTopItemWithForwardRef.displayName = 'SideNavigation.TopItem'; export default SideNavigationTopItemWithForwardRef;