All files / primitive/injector/src settings.js

97.29% Statements 36/37
80% Branches 20/25
100% Functions 17/17
96.77% Lines 30/31

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              3x 8x 22x     1x 3x 2x   1x 9x     3x             1x 9x 18x         9x     9x   1x                   9x 9x 9x 9x                 1x 11x 10x   10x 1x 9x 1x 1x   8x     9x   9x                    
import {Children, cloneElement, isValidElement} from 'react'
import {isFragment} from 'react-is'
 
import cx from 'classnames'
 
import PrimitiveInjector from './index.js'
 
const isUpperCaseChar = char => char.length === 1 && char === char.toUpperCase()
const isFunction = handler => typeof handler === 'function'
const isHandler = propKey => propKey.startsWith('on') && isUpperCaseChar(propKey['on'.length])
 
export const combineHandler =
  (...handlers) =>
  (...args) =>
    handlers.filter(isFunction).forEach(handler => handler(...args))
 
export const combineHandlers = (ownProps, childProps, cHandler = combineHandler) =>
  Object.keys({...ownProps, ...childProps})
    .filter(isHandler)
    .reduce(
      (response, currentKey, index, combinedKeys) => ({
        ...response,
        [currentKey]: cHandler(...[ownProps[currentKey], childProps[currentKey]].filter(isFunction))
      }),
      {}
    )
 
export const combineStyles = (...styles) => {
  const result = styles.reduce((resultingStyle, currentStyle) => {
    return {
      ...resultingStyle,
      ...currentStyle
    }
  }, {})
  return Object.keys(result).length === 0 ? null : result
}
 
export const combineClassNames = (...classNames) => cx(...classNames)
 
export const combineProps = (
  {className: ownClassNames, style: ownStyle = {}, ...ownProps},
  {className: childClassNames, style: childStyle = {}, ...childProps},
  {combineHandlers: cHandlers, combineStyles: cStyles, combineClassNames: cClassNames, combineHandler: cHandler} = {
    combineHandler,
    combineHandlers,
    combineStyles,
    combineClassNames
  }
) => {
  const combinedHandlers = cHandlers(ownProps, childProps, cHandler)
  const style = cStyles(ownStyle, childStyle)
  const className = cClassNames(childClassNames, ownClassNames)
  return {
    ...(className && {className}),
    ...(style && {style}),
    ...ownProps,
    ...childProps,
    ...combinedHandlers
  }
}
 
export const inject = (children, settings = []) =>
  Children.toArray(children).map(child => {
    Iif (!isValidElement(child)) {
      return child
    } else if (isFragment(child)) {
      return cloneElement(child, child?.props, inject(child?.props.children, settings))
    } else if (child?.type === PrimitiveInjector) {
      const {proviso = () => true, combine = combineProps, children, ...otherProps} = child?.props || {}
      return inject(children, [{proviso, combine, props: otherProps}, ...settings])
    } else {
      return cloneElement(
        child,
        settings
          .filter(({proviso}) => proviso(child))
          .reduce((acc, {props, combine}) => {
            return combine(props, acc, {
              combineHandler,
              combineHandlers,
              combineStyles,
              combineClassNames
            })
          }, child?.props)
      )
    }
  })