import classNames from "classnames" ; import * as React from "react" ; import { Boundary } from "../../common/boundary" ; import * as Classes from "../../common/classes" ; import * as Errors from "../../common/errors" ; import { Position } from "../../common/position" ; import { DISPLAYNAME_PREFIX , Props } from "../../common/props" ; import { isElementOfType } from "../../common/utils" ; import { Menu } from "../menu/menu" ; import { MenuItemProps , MenuItem } from "../menu/menuItem" ; import { IPopoverProps , Popover } from "../popover/popover" ; type CollapsibleItem = React . ReactElement < MenuItemProps > ; export type CollapsibleListProps = ICollapsibleListProps ; deprecated export interface ICollapsibleListProps extends Props { /**
     * Element to render as dropdown target with `CLICK` interaction to show collapsed menu.
     */ dropdownTarget : JSX . Element ; /**
     * Props to pass to the dropdown.
     */ dropdownProps ? : IPopoverProps ; /**
     * Callback invoked to render each visible item. The item will be wrapped in an `li` with
     * the optional `visibleItemClassName` prop.
     */ visibleItemRenderer : ( props : MenuItemProps , index : number ) => JSX . Element ; default collapseFrom ? : Boundary ; /**
     * CSS class names to add to `<li>` tags containing each visible item and the dropdown.
     */ visibleItemClassName ? : string ; default visibleItemCount ? : number ; } deprecated export class CollapsibleList extends React . Component < CollapsibleListProps > { public static displayName = `${ DISPLAYNAME_PREFIX }.CollapsibleList` ; public static defaultProps : Partial < CollapsibleListProps > = { collapseFrom : Boundary . START , visibleItemCount : 3 , } ; public render ( ) { const { collapseFrom } = this . props ; const childrenLength = React . Children . count ( this . props . children ) ; const [ visibleChildren , collapsedChildren ] = this . partitionChildren ( ) ; const visibleItems = visibleChildren . map ( ( child , index ) => { const absoluteIndex = collapseFrom === Boundary . START ? childrenLength - 1 - index : index ; return ( < li className = { this . props . visibleItemClassName } key = { absoluteIndex } > { this . props . visibleItemRenderer ( child . props , absoluteIndex ) } < /li>); } ) ; if ( collapseFrom === Boundary . START ) { visibleItems . reverse ( ) ; } let collapsedPopover ; if ( collapsedChildren . length > 0 ) { const position = collapseFrom === Boundary . END ? Position . BOTTOM_RIGHT : Position . BOTTOM_LEFT ; collapsedPopover = ( < li className = { this . props . visibleItemClassName } > < Popover content = { < Menu > { collapsedChildren } < /Menu>} position={position} {...this.props.dropdownProps}> { this . props . dropdownTarget } < /Popover> < /li>); } return ( < ul className = { classNames ( Classes . COLLAPSIBLE_LIST , this . props . className ) } > { collapseFrom === Boundary . START ? collapsedPopover : null } { visibleItems } { collapseFrom === Boundary . END ? collapsedPopover : null } < /ul>); } private partitionChildren ( ) { const childrenArray = React . Children . map ( this . props . children , ( child , index ) => { if ( ! isElementOfType ( child , MenuItem ) ) { throw new Error ( Errors . COLLAPSIBLE_LIST_INVALID_CHILD ) ; } return React . cloneElement ( child as JSX . Element , { key : `visible-${ index }` } ) ; } ) ; if ( childrenArray == null ) { return [ [ ] , [ ] ] ; } if ( this . props . collapseFrom === Boundary . START ) { childrenArray . reverse ( ) ; } const { visibleItemCount } = this . props ; return [ childrenArray . slice ( 0 , visibleItemCount ) , childrenArray . slice ( visibleItemCount ) ] ; } }