import { APPEARANCE, Button, VIEW } from '@cloud-ru/ds-button'; import { VerticalMenuCloseSVG, VerticalMenuOpenSVG } from '@cloud-ru/ds-icons/interface/product'; import { List, ListProps } from '@cloud-ru/ds-list'; import { extractSupportProps, useUncontrolledProp, WithSupportProps } from '@cloud-ru/ds-utils'; import cn from 'classnames'; import { useCallback, useState } from 'react'; import { TEST_IDS } from '../../constants'; import { SearchContextProvider } from './contexts'; import { useItemsContent, useTopPinnedContent } from './hooks/useItemsCreator'; import { useSearchFilter } from './hooks/useSearchFilter'; import styles from './styles.module.scss'; import { Documentation, HeaderProps, SidebarItem } from './types'; export type PageSidebarProps = WithSupportProps<{ open?: boolean; defaultOpen?: boolean; onOpenChanged?(open: boolean): void; items: SidebarItem[]; footerItems?: SidebarItem[]; header?: HeaderProps; selected?: string | number; onSelect?(id: string | number): void; className?: string; /** Зарезервировано, в текущей реализации не используется. */ documentation?: Documentation; /** Зарезервировано, в текущей реализации не используется. */ pageContainerId?: string; hasSearch?: boolean; collapse?: ListProps['collapse']; }>; function PrivateSideBar({ open: openProp, defaultOpen, onOpenChanged, className, items, footerItems = [], header, selected, onSelect, hasSearch, collapse, // documentation / pageContainerId — зарезервированы, в текущей реализации не используются. // Деструктурируем, чтобы не попадали в otherProps и не ломали extractSupportProps. // eslint-disable-next-line @typescript-eslint/no-unused-vars documentation, // eslint-disable-next-line @typescript-eslint/no-unused-vars pageContainerId, ...otherProps }: PageSidebarProps) { const [open, setOpenState] = useUncontrolledProp(openProp, defaultOpen || true, onOpenChanged); const [hoverOff, setHoverOff] = useState(false); const toggleOpen = useCallback( (newValue: boolean = !open) => { if (newValue === open) { return; } if (!newValue) { /* кнопка сворачивания внутри сайдбара, а он раскрывается по ховеру — после клика на время отключаем ховер, чтобы дать ему свернуться */ setHoverOff(true); setTimeout(() => setHoverOff(false), 300); } setOpenState(newValue); }, [open, setOpenState], ); const { filteredList, searchValue, searchCollapseState } = useSearchFilter(items); const list = useItemsContent(filteredList, onSelect); const footerList = useItemsContent(footerItems); const { pinTop } = useTopPinnedContent(header, hasSearch); return (