import React, { FC, useContext, useEffect, useRef, useState } from 'react'; import classNames from 'classnames'; import { EllipsisOutlined } from '@ant-design/icons'; import Collapsible from '../../../collapsible'; import { Item, ItemProps } from '../Item'; import { ConfigContext } from '../../../config-provider'; function noop() {} const noWindowMatches: MediaQueryList = { media: '', addListener: noop, removeListener: noop, matches: false, onchange: noop, addEventListener: noop, removeEventListener: noop, dispatchEvent: () => true, }; function navigationBarCollapsed() { return typeof window === 'undefined' ? noWindowMatches : window.matchMedia(`(max-width: 768px)`); } export interface SectionProps { items: ItemProps[]; icon?: React.ReactNode; title?: string; fill?: boolean; rollup?: { after: number; view: string; hide: string; activePath: string; }; action?: { icon: React.ReactNode; onClick(): void; }; separator?: boolean; } export const Section: FC = ({ title, fill, action, items, rollup, separator }) => { const { getPrefixCls } = useContext(ConfigContext); const prefixCls = getPrefixCls('navigation'); const [expanded, setExpanded] = useState(false); const animationFrame = useRef(null); const handleClick = (onClick: ItemProps['onClick'], hasSubNavItems: boolean) => () => { if (onClick) { onClick(); } if (animationFrame.current) { cancelAnimationFrame(animationFrame.current); } if (!hasSubNavItems || !navigationBarCollapsed().matches) { animationFrame.current = requestAnimationFrame(() => setExpanded(false)); } }; useEffect(() => () => { if (animationFrame.current) { cancelAnimationFrame(animationFrame.current); } }); const className = classNames({ [`${prefixCls}-section`]: true, [`${prefixCls}-section-with-separator`]: separator, [`${prefixCls}-section-fill`]: fill, }); const actionMarkup = action && ( ); const sectionHeadingMarkup = title && (
  • {title} {actionMarkup}
  • ); const itemsMarkup = items.map(item => { const { onClick, name, subNavigationItems, ...rest } = item; const hasSubNavItems = subNavigationItems != null && subNavigationItems.length > 0; return ( ); }); const toggleClassName = classNames([`${prefixCls}-item`, `${prefixCls}-rollup-toggle`]); const toggleRollup = rollup && items.length > rollup.after && (
    ); const activeItemIndex = items.findIndex((item: ItemProps) => { if (!rollup) { return false; } return ( rollup.activePath === item.path || (item.path && rollup.activePath.startsWith(item.path)) || (item.subNavigationItems ? item.subNavigationItems.some(({ path: itemUrl }) => rollup.activePath.startsWith(itemUrl)) : false) ); }); const sectionItems = rollup ? itemsMarkup.slice(0, rollup.after) : itemsMarkup; const additionalItems = rollup ? itemsMarkup.slice(rollup.after) : []; if (rollup && activeItemIndex !== -1 && activeItemIndex > rollup.after - 1) { sectionItems.push(...additionalItems.splice(activeItemIndex - rollup.after, 1)); } const activeItemsMarkup = rollup && additionalItems.length > 0 && (
    • {additionalItems}
    {toggleRollup}
  • ); return (
      {sectionHeadingMarkup} {sectionItems} {activeItemsMarkup}
    ); };