import React from 'react'; import styled from 'styled-components'; import { useLocation } from 'react-router-dom'; import type { JSX } from 'react'; import type { ResolvedNavItem, ResolvedNavLinkItem, ResolvedNavGroupItem } from '@redocly/config'; import type { LinkProps } from '@redocly/theme/components/Link/Link'; import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu'; import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem'; import { getPathnameForLocale, withPathPrefix, removeTrailingSlash, } from '@redocly/theme/core/utils'; import { useThemeHooks } from '@redocly/theme/core/hooks'; import { LaunchIcon } from '@redocly/theme/icons/LaunchIcon/LaunchIcon'; import { Link } from '@redocly/theme/components/Link/Link'; import { Dropdown } from '@redocly/theme/components/Dropdown/Dropdown'; import { GenericIcon } from '@redocly/theme/icons/GenericIcon/GenericIcon'; export type NavbarItemProps = { navItem: ResolvedNavItem; className?: string; }; export function NavbarItem({ navItem, className }: NavbarItemProps): JSX.Element | null { const { pathname } = useLocation(); const { useTranslate, useL10nConfig, useTelemetry } = useThemeHooks(); const { translate } = useTranslate(); const { defaultLocale, currentLocale, locales } = useL10nConfig(); const telemetry = useTelemetry(); if (navItem.type !== 'link' && !navItem.items) return null; const item = navItem as ResolvedNavLinkItem; const normalizedPath = (item.link ? removeTrailingSlash(item.link) : item.link) || ''; const pathWithPathPrefix = withPathPrefix( getPathnameForLocale(normalizedPath, defaultLocale, currentLocale, locales), ); const isActive = removeTrailingSlash(pathname) === removeTrailingSlash(pathWithPathPrefix); const itemContent = ( telemetry.sendNavbarMenuItemClickedMessage([{ object: 'menu_item', type: item.type }]) } external={item.external} target={item.target} to={item.link} > {translate(item.labelTranslationKey, item.label)} {item.external ? : null} ); if ((navItem as ResolvedNavGroupItem).items) { const item = navItem as ResolvedNavGroupItem; const groupItems = item.items as ResolvedNavItem[]; const groupItemsComponents = groupItems.map((item, index) => { if (item.type !== 'link' && item.type !== 'separator') return null; return ( {translate(item.labelTranslationKey, item.label)} {item.external ? : null} ); }); return (
{groupItemsComponents}
); } return
{itemContent}
; } const NavbarMenuItemDropdown = styled(Dropdown)` --dropdown-menu-item-separator-font-size: var(--navbar-separator-font-size); --dropdown-menu-item-separator-text-color: var(--navbar-separator-text-color); --dropdown-menu-item-separator-line-height: var(--navbar-separator-line-height); `; const NavbarMenuItem = styled.li` display: inline-block; padding: var(--navbar-item-padding); text-align: center; line-height: var(--navbar-item-line-height); font-weight: var(--navbar-item-font-weight); border-radius: var(--navbar-item-border-radius); border-bottom: ${({ active }) => active ? 'var(--navbar-item-bottom-border-active)' : 'var(--navbar-item-bottom-border)'}; background: ${({ active }) => active && 'var(--navbar-item-bg-color-active)'}; color: ${({ active }) => active ? 'var(--navbar-item-text-color-active)' : 'var(--navbar-text-color)'}; text-decoration: ${({ active }) => active ? 'var(--navbar-item-text-decoration-active)' : 'none'}; &:hover { color: var(--navbar-item-text-color-hover); text-decoration: var(--navbar-item-text-decoration-hover); border-bottom: ${({ active }) => !active && 'var(--navbar-item-bottom-border-hover)'}; background: ${({ active }) => active ? 'var(--navbar-item-bg-color-active)' : 'var(--navbar-item-bg-color-hover)'}; } `; const NavbarLabel = styled.span` cursor: pointer; vertical-align: middle; `; const NavbarIcon = styled(GenericIcon)` --icon-width: var(--navbar-item-icon-width); --icon-height: var(--navbar-item-icon-height); margin-right: var(--navbar-item-icon-margin-right); `; const ExternalLinkIcon = styled(LaunchIcon)` margin-left: 5px; `;