import * as React from 'react' ; import * as ReactDOM from 'react-dom' ; import { position } from './utils' ; import './styles.scss' ; const Portal = ( { children } ) => { const portalNode = React . useRef ( null ) ; const [ _ , forceUpdate ] = React . useState ( ) ; React . useLayoutEffect ( ( ) => { portalNode . current = document . createElement ( 'portal' ) ; document . body . appendChild ( portalNode . current ) ; forceUpdate ( { } ) ; return ( ) => { if ( portalNode . current ) { document . body . removeChild ( portalNode . current ) ; } } ; } , [ ] ) ; return portalNode . current ? ReactDOM . createPortal ( children , portalNode . current ) : null ; } ; const Popover = ( { children , targetRef } ) => { const popoverRef = React . useRef ( null ) ; const [ styles , setStyles ] = React . useState ( { } ) ; function initPopoverRef ( el ) { if ( ! popoverRef . current ) { popoverRef . current = el ; if ( targetRef . current && popoverRef . current ) { const targetRect = targetRef . current . getBoundingClientRect ( ) ; const popoverRect = popoverRef . current . getBoundingClientRect ( ) ; setStyles ( position ( targetRect , popoverRect ) ) ; } } } return ( < Portal > < div ref = { initPopoverRef } data - popover = "" onClick = { ( e ) => e . stopPropagation ( ) } style = { { position : 'absolute' , ... styles , } } > { children } < /div> < /Portal>); } ; const Define = ( { children } ) => { const [ open , setOpen ] = React . useState ( false ) ; const buttonRef = React . useRef ( ) ; React . useLayoutEffect ( ( ) => { const listener = ( event ) => { if ( event . target !== buttonRef . current ) { setOpen ( false ) ; } } ; window . addEventListener ( 'click' , listener ) ; return ( ) => window . removeEventListener ( 'click' , listener ) ; } , [ ] ) ; return ( < > < button ref = { buttonRef } onClick = { ( ) => setOpen ( ! open ) } className = "as-link" > { children } < /button> { open && ( < Popover targetRef = { buttonRef } > Hooks are a way to compose behavior into components < /Popover>)} < />); } ; export default function App ( ) { return ( < p > Modern React is filled with < Define > Hooks < /Define>. They work with function-components and they give us an ability to use state and other React features similarly to class - based components . < /p>); }