All files Controlled.tsx

100% Statements 37/37
96.15% Branches 25/26
100% Functions 4/4
100% Lines 35/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 1182x 2x                       2x 2x                                     2x 20x 40x 20x 40x 40x 20x 20x 40x 20x 40x 40x 20x 40x 40x   20x 20x 20x   20x   2x 1x 1x           20x 5x     20x 3x   3x 3x       20x   20x                                                                             2x  
import 'focus-options-polyfill'
import React, {
  CSSProperties,
  FC,
  ReactNode,
  ReactType,
  RefObject,
  StrictMode,
  memo,
  useCallback,
  useRef,
  useState
} from 'react'
import ControlledActivated from './ControlledActivated'
import './styles.css'
 
interface Props {
  children: ReactNode
  closeText?: string
  isZoomed: boolean
  onZoomChange?: (value: boolean) => void
  openText?: string
  overlayBgColorEnd?: string
  overlayBgColorStart?: string
  portalEl?: HTMLElement
  scrollableEl?: HTMLElement | Window
  transitionDuration?: number
  wrapElement?: ReactType
  wrapStyle?: CSSProperties
  zoomMargin?: number
  zoomZindex?: number
}
 
const Controlled: FC<Props> = ({
  children,
  closeText = 'Unzoom image',
  isZoomed: isActive,
  overlayBgColorEnd = 'rgba(255, 255, 255, 0.95)',
  overlayBgColorStart = 'rgba(255, 255, 255, 0)',
  portalEl,
  onZoomChange,
  openText = 'Zoom image',
  scrollableEl,
  transitionDuration = 300,
  wrapElement: WrapElement = 'div',
  wrapStyle,
  zoomMargin = 0,
  zoomZindex = 2147483647
}: Props) => {
  const [isChildLoaded, setIsChildLoaded] = useState<boolean>(false)
  const wrapRef = useRef<HTMLElement>(null)
  const btnRef = useRef<HTMLButtonElement>(null)
 
  const handleClickTrigger = useCallback(
    e => {
      if (!isActive && onZoomChange) {
        e.preventDefault()
        onZoomChange(true)
      }
    },
    [isActive, onZoomChange]
  )
 
  const handleChildLoad = useCallback(() => {
    setIsChildLoaded(true)
  }, [])
 
  const handleChildUnload = useCallback(() => {
    setIsChildLoaded(false)
 
    Eif (btnRef.current) {
      btnRef.current.focus({ preventScroll: true })
    }
  }, [])
 
  const wrapType = isChildLoaded ? 'hidden' : 'visible'
 
  return (
    <StrictMode>
      <WrapElement
        data-rmiz-wrap={wrapType}
        ref={wrapRef as RefObject<HTMLElement>}
        style={wrapStyle}
      >
        {children}
        <button
          aria-label={openText}
          data-rmiz-btn-open
          onClick={handleClickTrigger}
          ref={btnRef}
          type="button"
        />
        {typeof window !== 'undefined' && (
          <ControlledActivated
            closeText={closeText}
            isActive={isActive}
            onLoad={handleChildLoad}
            onUnload={handleChildUnload}
            onZoomChange={onZoomChange}
            overlayBgColorEnd={overlayBgColorEnd}
            overlayBgColorStart={overlayBgColorStart}
            parentRef={wrapRef}
            portalEl={portalEl}
            scrollableEl={scrollableEl}
            transitionDuration={transitionDuration}
            zoomMargin={zoomMargin}
            zoomZindex={zoomZindex}
          >
            {children}
          </ControlledActivated>
        )}
      </WrapElement>
    </StrictMode>
  )
}
 
export default memo(Controlled)