All files / atom/popover/src index.js

70% Statements 7/10
26.66% Branches 4/15
33.33% Functions 1/3
70% Lines 7/10

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 118 119 120 121 122 123 124                                          1x                                 2x 2x 2x         2x                                                                                   1x   1x                                                                    
import {forwardRef, useRef} from 'react'
 
import PropTypes from 'prop-types'
 
import useControlledState from '@s-ui/react-hooks/lib/useControlledState/index.js'
 
import {
  BASE_CLASS,
  CLASS_INNER,
  DEFAULT_DELAY,
  DEFAULT_OFFSET,
  DEFAULT_TRIGGER,
  getClassName,
  PLACEMENTS,
  Popover,
  PREFIX_PLACEMENT,
  TRIGGERS,
  TYPES
} from './config.js'
import PopoverExtendChildren from './PopoverExtendChildren.js'
 
const AtomPopover = forwardRef(
  (
    {
      children,
      closeIcon,
      content: Content,
      onClose,
      onOpen,
      placement = PLACEMENTS.BOTTOM,
      isVisible,
      defaultIsVisible,
      hideArrow = true,
      trigger = DEFAULT_TRIGGER,
      type
    },
    outRef
  ) => {
    const targetRef = useRef()
    const [isVisibleState, setIsVisibleState] = useControlledState(isVisible, defaultIsVisible)
    const handleToggle = ev => {
      setIsVisibleState(!isVisibleState)
      isVisibleState ? typeof onClose === 'function' && onClose(ev) : typeof onOpen === 'function' && onOpen(ev)
    }
 
    return (
      <>
        <PopoverExtendChildren ref={targetRef} onToggle={handleToggle}>
          {children}
        </PopoverExtendChildren>
        <Popover
          trigger={Array.isArray(trigger) ? trigger.join(' ') : trigger}
          isOpen={isVisibleState}
          toggle={handleToggle}
          target={targetRef}
          className={BASE_CLASS}
          popperClassName="popperClassName"
          innerClassName={getClassName({defaultClass: CLASS_INNER, type})}
          arrowClassName={getClassName({
            defaultClass: `${BASE_CLASS}-arrow`,
            type
          })}
          innerRef={outRef}
          hideArrow={hideArrow}
          placementPrefix={PREFIX_PLACEMENT}
          delay={DEFAULT_DELAY}
          placement={placement}
          offset={DEFAULT_OFFSET}
        >
          {({scheduleUpdate: update}) => {
            return (
              <>
                {closeIcon && (
                  <div className={`${BASE_CLASS}-closeIcon`} onClick={handleToggle}>
                    {closeIcon}
                  </div>
                )}
                {typeof Content === 'function' ? <Content update={update} /> : Content}
              </>
            )
          }}
        </Popover>
      </>
    )
  }
)
 
AtomPopover.displayName = 'AtomPopover'
 
AtomPopover.propTypes = {
  /** HTML (component) to be displayed on the Popover */
  content: PropTypes.element.isRequired,
  /** Popover children */
  children: PropTypes.node.isRequired,
  /** initial value for the show pop over */
  defaultIsVisible: PropTypes.bool,
  /** Controlled value for the show pop over */
  isVisible: PropTypes.bool,
  /** Custom close icon  */
  closeIcon: PropTypes.node,
  /** On close callback */
  onClose: PropTypes.func,
  /** On open callback */
  onOpen: PropTypes.func,
  /** Popover position */
  placement: PropTypes.oneOf(Object.values(PLACEMENTS)),
  /** Whether to show arrow or not. */
  hideArrow: PropTypes.bool,
  /** behavior of the popover handler methods fired **/
  trigger: PropTypes.oneOfType([
    PropTypes.oneOf(Object.values(TRIGGERS)),
    PropTypes.arrayOf(PropTypes.oneOf(Object.values(TRIGGERS)))
  ]),
  /** Determine the type of the popover */
  type: PropTypes.oneOfType([
    PropTypes.oneOf(Object.values(TYPES)),
    PropTypes.string // Can even custom your own type
  ])
}
 
export {PLACEMENTS as atomPopoverPositions}
export {TRIGGERS as atomPopoverTriggers}
export default AtomPopover