<commit_before>import _ from 'lodash'
import cx from 'classnames'
import React, { isValidElement } from 'react'

/**
 * The default CreateFactory mergeExtraProps function.  Merges props and classNames.
 * @param props
 * @param extraProps
 * @returns {{className: *}}
 */
const mergePropsAndClassName = (props, extraProps) => {
  const className = cx(props.className, extraProps.className) // eslint-disable-line react/prop-types
  return { ...props, ...extraProps, className }
}

/**
 * Return a function that produces ReactElements.  Similar to React.createFactory with some extras.
 * If the returned factory is passed a ReactElement it will be cloned.
 * If it passed undefined it will do nothing.
 * @param {function|string} Component A ReactClass or string
 * @param {function} mapValueToProps A function that maps a primitive value to the Component props
 * @param {function} [mergeExtraProps=mergePropsAndClassName]
 * @returns {function}
 */
const createFactory = (Component, mapValueToProps, mergeExtraProps = mergePropsAndClassName) => {
  return function Factory(val, extraProps = {}) {
    // Clone ReactElements
    if (isValidElement(val)) {
      return React.cloneElement(val, mergeExtraProps(val.props, extraProps))
    }

    // Create ReactElements from props objects
    if (_.isPlainObject(val)) {
      return <Component {...mergeExtraProps(val, extraProps)} />
    }

    // Map values to props and create an ReactElement<commit_msg>fix(factories): only merge className if they exists<commit_after>import _ from 'lodash'
import cx from 'classnames'
import React, { isValidElement } from 'react'

/**
 * The default CreateFactory mergeExtraProps function.  Merges props and classNames.
 * @param props
 * @param extraProps
 * @returns {{className: *}}
 */
const mergePropsAndClassName = (props, extraProps) => {
  let className
  if (_.has(props, 'className') || _.has(extraProps.className)) {
    className = cx(props.className, extraProps.className) // eslint-disable-line react/prop-types
  }
  return { ...props, ...extraProps, className }
}

/**
 * Return a function that produces ReactElements.  Similar to React.createFactory with some extras.
 * If the returned factory is passed a ReactElement it will be cloned.
 * If it passed undefined it will do nothing.
 * @param {function|string} Component A ReactClass or string
 * @param {function} mapValueToProps A function that maps a primitive value to the Component props
 * @param {function} [mergeExtraProps=mergePropsAndClassName]
 * @returns {function}
 */
const createFactory = (Component, mapValueToProps, mergeExtraProps = mergePropsAndClassName) => {
  return function Factory(val, extraProps = {}) {
    // Clone ReactElements
    if (isValidElement(val)) {
      return React.cloneElement(val, mergeExtraProps(val.props, extraProps))
    }

    // Create ReactElements from props objects
    if (_.isPlainObject(val)) {
      return <Component {...mergeExtraProps(val, extraProps)} />
    }

    // Map values to props and create an ReactElement
{'fraction_non_alphanumeric': 0.1044825313117996, 'fraction_numerical': 0.0, 'mean_word_length': 4.179180887372014, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '100690', 'n_tokens_mistral': 817, 'n_tokens_neox': 812, 'n_words': 282}