import React , { Children , useLayoutEffect , useState , useEffect } from 'react' ; import { BreadcrumbLink } from './Link' ; import { Breadcrumb } from '../types' ; export const useCollapse = < E extends HTMLElement > ( listEl , maxWidth = 0 ) => { const [ shouldCollapseList , setShouldCollapseList ] = useState < boolean > ( false ) ; useLayoutEffect ( ( ) => { const listWidth = listEl . current ?. clientWidth || 0 ; setShouldCollapseList ( listWidth > maxWidth ) ; } , [ listEl , maxWidth ] ) ; return { shouldCollapseList } ; } ; const getBreadcrumbLink = ( breadcrumb ) => { return Children . toArray ( breadcrumb . props . children ) . filter ( child => { return React . isValidElement ( child ) && child . type === BreadcrumbLink ; } ) [ 0 ] as React . ReactElement ; } ; const buildCollapsedList = ( list , containerWidth , maxWidth , collapsedList = [ ] ) : Breadcrumb [ ] => { const EXPANDER_WIDTH = 66 ; if ( ! list . length || containerWidth + EXPANDER_WIDTH <= maxWidth ) { return collapsedList ; } const [ firstCrumb , ... restList ] = list ; const updatedCollapsedList = collapsedList . concat ( firstCrumb ) ; const adjustedWidth = containerWidth - firstCrumb . width ; return buildCollapsedList ( restList , adjustedWidth , maxWidth , updatedCollapsedList ) ; } ; export const useBuildCollapsedList = < E extends HTMLElement > ( listEl , children , maxWidth ) => { const [ collapsedItems , setCollapsedItems ] = useState < Breadcrumb [ ] > ( [ ] ) ; useLayoutEffect ( ( ) => { const listItemNodes = listEl . current ? listEl . current . querySelectorAll ( 'li' ) : [ ] ; const containerWidth = listEl . current ? listEl . current . clientWidth : 0 ; const listItems = [ ] ; Children . forEach ( children , ( child , index ) => { if ( ! React . isValidElement ( child ) ) { return ; } const breadcrumbLink = getBreadcrumbLink ( child ) ; const listItemNode = listItemNodes [ index ] ; listItems . push ( { index : index , link : breadcrumbLink ?. props ?. href || '' , text : listItemNode ? listItemNode . innerText : '' , width : listItemNode ? listItemNode . clientWidth : 0 , onAction : breadcrumbLink ?. props ?. onAction , } as Breadcrumb ) ; } ) ; const collapsibleListItems = listItems . slice ( 1 ) ; const collapsedList = buildCollapsedList ( collapsibleListItems , containerWidth , maxWidth ) ; setCollapsedItems ( collapsedList ) ; } , [ maxWidth ] ) ; const collapsedItemIndices = collapsedItems . map ( child => child . index ) ; return { collapsedItems , collapsedItemIndices } ; } ; export const useTruncateTooltip = ( ref ? ) => { const [ isTooltipOpen , setIsTooltipOpen ] = useState ( false ) ; const [ shouldShowTooltip , setShouldShowTooltip ] = useState ( false ) ; useEffect ( ( ) => { if ( ref ?. current ) { setShouldShowTooltip ( ref . current . scrollWidth > ref . current . clientWidth ) ; } } , [ ref ] ) ; const openTooltip = ( event ) => { const { currentTarget } = event ; if ( currentTarget . scrollWidth > currentTarget . clientWidth ) { setIsTooltipOpen ( true ) ; } } ; const closeTooltip = ( ) => { setIsTooltipOpen ( false ) ; } ; const tooltipProps = { role : 'tooltip' , } ; return { isTooltipOpen , openTooltip , closeTooltip , shouldShowTooltip , tooltipProps , } ; } ;