packageDocumentation module import "./Tree.scss" ; import classnames from "classnames" ; import * as React from "react" ; import { CommonProps } from "../utils/Props" ; import { Rectangle } from "../utils/Rectangle" ; public export interface TreeProps extends CommonProps { children ? : React . ReactNode ; onMouseDown ? : React . MouseEventHandler < HTMLDivElement > ; onMouseMove ? : React . MouseEventHandler < HTMLDivElement > ; onMouseUp ? : React . MouseEventHandler < HTMLDivElement > ; onKeyDown ? : React . KeyboardEventHandler < HTMLDivElement > ; onKeyUp ? : React . KeyboardEventHandler < HTMLDivElement > ; } public export class Tree extends React . PureComponent < TreeProps > { private _treeElement : React . RefObject < HTMLDivElement > = React . createRef ( ) ; private get _scrollableContainer ( ) : Element | undefined { if ( ! this . _treeElement . current ) return undefined ; const isScrollable = ( element ) => { const style = window . getComputedStyle ( element ) ; return style . overflow === "auto" || style . overflow === "scroll" || style . overflowY === "auto" || style . overflowY === "scroll" || style . overflowX === "auto" || style . overflowX === "scroll" ; } ; let scrollableContainer = this . _treeElement . current ; while ( scrollableContainer && ! isScrollable ( scrollableContainer ) ) scrollableContainer = ( scrollableContainer . children . length > 0 ) ? scrollableContainer . children [ 0 ] : undefined ; return scrollableContainer ; } public scrollToElement ( element ) { const container = this . _scrollableContainer ; if ( ! container ) return ; if ( ! Element . prototype . scrollTo ) { element . scrollIntoView ( ) ; return ; } const elementBox = element . getBoundingClientRect ( ) ; const elementRange = Rectangle . createXYXY ( elementBox . left , elementBox . top , elementBox . right , elementBox . bottom ) ; const containerBox = container . getBoundingClientRect ( ) ; const containerRange = Rectangle . createXYXY ( containerBox . left - container . scrollLeft , containerBox . top - container . scrollTop , containerBox . right - container . scrollLeft , containerBox . bottom - container . scrollTop ) ; let left ; if ( container . scrollLeft > 0 && elementRange . right <= containerRange . right ) { left = 0 ; } else if ( containerRange . left <= elementRange . left && containerRange . right >= elementRange . right ) { left = container . scrollLeft ; } else { left = elementRange . left - containerRange . left ; } let top ; if ( containerRange . top <= elementRange . top && containerRange . bottom >= elementRange . bottom ) { top = container . scrollTop ; } else { top = elementRange . top - containerRange . top ; } container . scrollTo ( { left , top } ) ; } public getElementsByClassName ( className ) { if ( ! this . _treeElement . current ) return [ ] ; const elems = new Array < Element > ( ) ; const collection = this . _treeElement . current . getElementsByClassName ( className ) ; for ( let i = 0 ; i < collection . length ; ++ i ) elems . push ( collection . item ( i ) ! ) ; return elems ; } public setFocusByClassName ( selector ) { let status = false ; if ( this . _treeElement . current ) { const element = this . _treeElement . current . querySelector ( selector ) as HTMLElement ; if ( element && element . focus ) { element . focus ( ) ; status = true ; } } return status ; } public override render ( ) { const className = classnames ( "core-tree" , this . props . className ) ; return ( < div ref = { this . _treeElement } className = { className } style = { this . props . style } onMouseDown = { this . props . onMouseDown } onMouseMove = { this . props . onMouseMove } onMouseUp = { this . props . onMouseUp } onKeyDown = { this . props . onKeyDown } onKeyUp = { this . props . onKeyUp } role = "tree" tabIndex = { - 1 } > { this . props . children } < /div>); } }