import * as React from 'react' ; import { FunctionComponent , useState , useRef } from 'react' ; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ; import { faInfoCircle , faExclamationTriangle } from '@fortawesome/free-solid-svg-icons' ; const realBlur = ( { relatedTarget , currentTarget } ) => { return relatedTarget !== currentTarget && ! ( currentTarget as HTMLElement ) . contains ( relatedTarget as Node ) ; } ; const Switch = ( { onChange , checked } ) => { return < label className = 'switch mb-0' > < input type = 'checkbox' onChange = { ( event ) => onChange ( event . currentTarget . checked ) } checked = { checked } / > < span className = 'slider round' > < /span> < /label>; } ; const DropdownSelection = ( { items , selected , onSelect } ) => { const [ show , setShow ] = useState ( false ) ; return < div className = 'dropdown' onBlur = { ( e ) => realBlur ( e ) && setShow ( false ) } > < button className = 'btn btn-secondary dropdown-toggle' onClick = { ( ) => setShow ( ! show ) } > { items . find ( ( { value } ) => value === selected ) ?. text } < /button> < div className = { 'dropdown-menu ' + ( show ? 'show' : '' ) } > { items . map ( ( { text , value , warning } ) => < a className = 'dropdown-item' href = '#' key = { value } onClick = { ( ) => { setShow ( false ) ; onSelect ( value ) ; } } > { text + ' ' } { warning && < span className = 'float-right tooltip-parent' > < FontAwesomeIcon icon = { faExclamationTriangle } /> < div className = 'tooltip' > < div className = 'tooltip-inner' > { warning } < /div> < /div> < /span>}</a > ) } < /div> < /div>; } ; const SwitchableOption = ( { checked , onChange , text , tooltip , listItem = true , children } ) => { const item = < div className = 'list-group-option' > < Switch checked = { checked } onChange = { onChange } / > < span className = 'ml-2 flex-grow-1' > { text } < /span> { children } { tooltip && < Tooltip text = { tooltip } />} < /div>; return listItem ? < li className = 'list-group-item' > { item } < /li> : item ; } ; const Tooltip = ( { text , children , className } ) => { const [ show , setShow ] = useState ( false ) ; const [ x , setX ] = useState ( 0 ) ; const [ y , setY ] = useState ( 0 ) ; const tooltip = useRef ( null as HTMLDivElement ) ; const tooltipParent = useRef ( null as HTMLSpanElement ) ; return < > < div className = { 'tooltip-dyn ' + ( show ? 'visible' : 'invisible' ) } style = { { left : x , top : y } } ref = { tooltip } > { text } < /div> < span ref = { tooltipParent } onMouseEnter = { ( event ) => { const parentWidth = tooltipParent . current . offsetWidth ; const parentHeight = tooltipParent . current . offsetHeight ; const { top , left } = tooltipParent . current . getBoundingClientRect ( ) ; const childHeight = tooltip . current . offsetHeight ; const childWidth = tooltip . current . offsetWidth ; const rightX = left + parentWidth + 8 ; const rightY = ( top + ( parentHeight / 2 ) ) - ( childHeight / 2 ) ; if ( rightX + childWidth > window . innerWidth ) { setX ( ( left + ( parentWidth / 2 ) ) - ( childWidth / 2 ) ) ; setY ( top - parentHeight - 4 ) ; } else { setX ( rightX ) ; setY ( rightY ) ; } setShow ( true ) ; } } className = { className || '' } onMouseLeave = { ( ) => setShow ( false ) } > { children || < FontAwesomeIcon icon = { faInfoCircle } />} < /span> < />; } ; export { SwitchableOption , DropdownSelection , Tooltip } ; export default SwitchableOption ;