(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fortawesome/fontawesome-svg-core'), require('prop-types'), require('react')) :
  typeof define === 'function' && define.amd ? define(['exports', '@fortawesome/fontawesome-svg-core', 'prop-types', 'react'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["react-fontawesome"] = {}, global.FontAwesome, global.PropTypes, global.React));
})(this, (function (exports, fontawesomeSvgCore, PropTypes, React) { 'use strict';

  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);

  function ownKeys(object, enumerableOnly) {
    var keys = Object.keys(object);

    if (Object.getOwnPropertySymbols) {
      var symbols = Object.getOwnPropertySymbols(object);
      enumerableOnly && (symbols = symbols.filter(function (sym) {
        return Object.getOwnPropertyDescriptor(object, sym).enumerable;
      })), keys.push.apply(keys, symbols);
    }

    return keys;
  }

  function _objectSpread2(target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = null != arguments[i] ? arguments[i] : {};
      i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
        _defineProperty(target, key, source[key]);
      }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
      });
    }

    return target;
  }

  function _typeof(obj) {
    "@babel/helpers - typeof";

    return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
      return typeof obj;
    } : function (obj) {
      return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
    }, _typeof(obj);
  }

  function _defineProperty(obj, key, value) {
    if (key in obj) {
      Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
      });
    } else {
      obj[key] = value;
    }

    return obj;
  }

  function _objectWithoutPropertiesLoose(source, excluded) {
    if (source == null) return {};
    var target = {};
    var sourceKeys = Object.keys(source);
    var key, i;

    for (i = 0; i < sourceKeys.length; i++) {
      key = sourceKeys[i];
      if (excluded.indexOf(key) >= 0) continue;
      target[key] = source[key];
    }

    return target;
  }

  function _objectWithoutProperties(source, excluded) {
    if (source == null) return {};

    var target = _objectWithoutPropertiesLoose(source, excluded);

    var key, i;

    if (Object.getOwnPropertySymbols) {
      var sourceSymbolKeys = Object.getOwnPropertySymbols(source);

      for (i = 0; i < sourceSymbolKeys.length; i++) {
        key = sourceSymbolKeys[i];
        if (excluded.indexOf(key) >= 0) continue;
        if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
        target[key] = source[key];
      }
    }

    return target;
  }

  function _toConsumableArray(arr) {
    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
  }

  function _arrayWithoutHoles(arr) {
    if (Array.isArray(arr)) return _arrayLikeToArray(arr);
  }

  function _iterableToArray(iter) {
    if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
  }

  function _unsupportedIterableToArray(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _arrayLikeToArray(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(o);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  }

  function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length) len = arr.length;

    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

    return arr2;
  }

  function _nonIterableSpread() {
    throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }

  // Get CSS class list from a props object
  function classList(props) {
    var _classes;

    var beat = props.beat,
        fade = props.fade,
        beatFade = props.beatFade,
        bounce = props.bounce,
        shake = props.shake,
        flash = props.flash,
        spin = props.spin,
        spinPulse = props.spinPulse,
        spinReverse = props.spinReverse,
        pulse = props.pulse,
        fixedWidth = props.fixedWidth,
        inverse = props.inverse,
        border = props.border,
        listItem = props.listItem,
        flip = props.flip,
        size = props.size,
        rotation = props.rotation,
        pull = props.pull; // map of CSS class names to properties

    var classes = (_classes = {
      'fa-beat': beat,
      'fa-fade': fade,
      'fa-beat-fade': beatFade,
      'fa-bounce': bounce,
      'fa-shake': shake,
      'fa-flash': flash,
      'fa-spin': spin,
      'fa-spin-reverse': spinReverse,
      'fa-spin-pulse': spinPulse,
      'fa-pulse': pulse,
      'fa-fw': fixedWidth,
      'fa-inverse': inverse,
      'fa-border': border,
      'fa-li': listItem,
      'fa-flip': flip === true,
      'fa-flip-horizontal': flip === 'horizontal' || flip === 'both',
      'fa-flip-vertical': flip === 'vertical' || flip === 'both'
    }, _defineProperty(_classes, "fa-".concat(size), typeof size !== 'undefined' && size !== null), _defineProperty(_classes, "fa-rotate-".concat(rotation), typeof rotation !== 'undefined' && rotation !== null && rotation !== 0), _defineProperty(_classes, "fa-pull-".concat(pull), typeof pull !== 'undefined' && pull !== null), _defineProperty(_classes, 'fa-swap-opacity', props.swapOpacity), _classes); // map over all the keys in the classes object
    // return an array of the keys where the value for the key is not null

    return Object.keys(classes).map(function (key) {
      return classes[key] ? key : null;
    }).filter(function (key) {
      return key;
    });
  }

  // Camelize taken from humps
  // humps is copyright © 2012+ Dom Christie
  // Released under the MIT license.
  // Performant way to determine if object coerces to a number
  function _isNumerical(obj) {
    obj = obj - 0; // eslint-disable-next-line no-self-compare

    return obj === obj;
  }

  function camelize(string) {
    if (_isNumerical(string)) {
      return string;
    } // eslint-disable-next-line no-useless-escape


    string = string.replace(/[\-_\s]+(.)?/g, function (match, chr) {
      return chr ? chr.toUpperCase() : '';
    }); // Ensure 1st char is always lowercase

    return string.substr(0, 1).toLowerCase() + string.substr(1);
  }

  var _excluded = ["style"];

  function capitalize(val) {
    return val.charAt(0).toUpperCase() + val.slice(1);
  }

  function styleToObject(style) {
    return style.split(';').map(function (s) {
      return s.trim();
    }).filter(function (s) {
      return s;
    }).reduce(function (acc, pair) {
      var i = pair.indexOf(':');
      var prop = camelize(pair.slice(0, i));
      var value = pair.slice(i + 1).trim();
      prop.startsWith('webkit') ? acc[capitalize(prop)] = value : acc[prop] = value;
      return acc;
    }, {});
  }

  function convert(createElement, element) {
    var extraProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

    if (typeof element === 'string') {
      return element;
    }

    var children = (element.children || []).map(function (child) {
      return convert(createElement, child);
    });
    /* eslint-disable dot-notation */

    var mixins = Object.keys(element.attributes || {}).reduce(function (acc, key) {
      var val = element.attributes[key];

      switch (key) {
        case 'class':
          acc.attrs['className'] = val;
          delete element.attributes['class'];
          break;

        case 'style':
          acc.attrs['style'] = styleToObject(val);
          break;

        default:
          if (key.indexOf('aria-') === 0 || key.indexOf('data-') === 0) {
            acc.attrs[key.toLowerCase()] = val;
          } else {
            acc.attrs[camelize(key)] = val;
          }

      }

      return acc;
    }, {
      attrs: {}
    });

    var _extraProps$style = extraProps.style,
        existingStyle = _extraProps$style === void 0 ? {} : _extraProps$style,
        remaining = _objectWithoutProperties(extraProps, _excluded);

    mixins.attrs['style'] = _objectSpread2(_objectSpread2({}, mixins.attrs['style']), existingStyle);
    /* eslint-enable */

    return createElement.apply(void 0, [element.tag, _objectSpread2(_objectSpread2({}, mixins.attrs), remaining)].concat(_toConsumableArray(children)));
  }

  var PRODUCTION = false;

  try {
    PRODUCTION = process.env.NODE_ENV === 'production';
  } catch (e) {}

  function log () {
    if (!PRODUCTION && console && typeof console.error === 'function') {
      var _console;

      (_console = console).error.apply(_console, arguments);
    }
  }

  function normalizeIconArgs(icon) {
    // this has everything that it needs to be rendered which means it was probably imported
    // directly from an icon svg package
    if (icon && _typeof(icon) === 'object' && icon.prefix && icon.iconName && icon.icon) {
      return icon;
    }

    if (fontawesomeSvgCore.parse.icon) {
      return fontawesomeSvgCore.parse.icon(icon);
    } // if the icon is null, there's nothing to do


    if (icon === null) {
      return null;
    } // if the icon is an object and has a prefix and an icon name, return it


    if (icon && _typeof(icon) === 'object' && icon.prefix && icon.iconName) {
      return icon;
    } // if it's an array with length of two


    if (Array.isArray(icon) && icon.length === 2) {
      // use the first item as prefix, second as icon name
      return {
        prefix: icon[0],
        iconName: icon[1]
      };
    } // if it's a string, use it as the icon name


    if (typeof icon === 'string') {
      return {
        prefix: 'fas',
        iconName: icon
      };
    }
  }

  // creates an object with a key of key
  // and a value of value
  // if certain conditions are met
  function objectWithKey(key, value) {
    // if the value is a non-empty array
    // or it's not an array but it is truthy
    // then create the object with the key and the value
    // if not, return an empty array
    return Array.isArray(value) && value.length > 0 || !Array.isArray(value) && value ? _defineProperty({}, key, value) : {};
  }

  var FontAwesomeIcon = /*#__PURE__*/React__default["default"].forwardRef(function (props, ref) {
    var iconArgs = props.icon,
        maskArgs = props.mask,
        symbol = props.symbol,
        className = props.className,
        title = props.title,
        titleId = props.titleId,
        maskId = props.maskId;
    var iconLookup = normalizeIconArgs(iconArgs);
    var classes = objectWithKey('classes', [].concat(_toConsumableArray(classList(props)), _toConsumableArray(className.split(' '))));
    var transform = objectWithKey('transform', typeof props.transform === 'string' ? fontawesomeSvgCore.parse.transform(props.transform) : props.transform);
    var mask = objectWithKey('mask', normalizeIconArgs(maskArgs));
    var renderedIcon = fontawesomeSvgCore.icon(iconLookup, _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, classes), transform), mask), {}, {
      symbol: symbol,
      title: title,
      titleId: titleId,
      maskId: maskId
    }));

    if (!renderedIcon) {
      log('Could not find icon', iconLookup);
      return null;
    }

    var abstract = renderedIcon.abstract;
    var extraProps = {
      ref: ref
    };
    Object.keys(props).forEach(function (key) {
      // eslint-disable-next-line no-prototype-builtins
      if (!FontAwesomeIcon.defaultProps.hasOwnProperty(key)) {
        extraProps[key] = props[key];
      }
    });
    return convertCurry(abstract[0], extraProps);
  });
  FontAwesomeIcon.displayName = 'FontAwesomeIcon';
  FontAwesomeIcon.propTypes = {
    beat: PropTypes__default["default"].bool,
    border: PropTypes__default["default"].bool,
    beatFade: PropTypes__default["default"].bool,
    bounce: PropTypes__default["default"].bool,
    className: PropTypes__default["default"].string,
    fade: PropTypes__default["default"].bool,
    flash: PropTypes__default["default"].bool,
    mask: PropTypes__default["default"].oneOfType([PropTypes__default["default"].object, PropTypes__default["default"].array, PropTypes__default["default"].string]),
    maskId: PropTypes__default["default"].string,
    fixedWidth: PropTypes__default["default"].bool,
    inverse: PropTypes__default["default"].bool,
    flip: PropTypes__default["default"].oneOf([true, false, 'horizontal', 'vertical', 'both']),
    icon: PropTypes__default["default"].oneOfType([PropTypes__default["default"].object, PropTypes__default["default"].array, PropTypes__default["default"].string]),
    listItem: PropTypes__default["default"].bool,
    pull: PropTypes__default["default"].oneOf(['right', 'left']),
    pulse: PropTypes__default["default"].bool,
    rotation: PropTypes__default["default"].oneOf([0, 90, 180, 270]),
    shake: PropTypes__default["default"].bool,
    size: PropTypes__default["default"].oneOf(['2xs', 'xs', 'sm', 'lg', 'xl', '2xl', '1x', '2x', '3x', '4x', '5x', '6x', '7x', '8x', '9x', '10x']),
    spin: PropTypes__default["default"].bool,
    spinPulse: PropTypes__default["default"].bool,
    spinReverse: PropTypes__default["default"].bool,
    symbol: PropTypes__default["default"].oneOfType([PropTypes__default["default"].bool, PropTypes__default["default"].string]),
    title: PropTypes__default["default"].string,
    titleId: PropTypes__default["default"].string,
    transform: PropTypes__default["default"].oneOfType([PropTypes__default["default"].string, PropTypes__default["default"].object]),
    swapOpacity: PropTypes__default["default"].bool
  };
  FontAwesomeIcon.defaultProps = {
    border: false,
    className: '',
    mask: null,
    maskId: null,
    fixedWidth: false,
    inverse: false,
    flip: false,
    icon: null,
    listItem: false,
    pull: null,
    pulse: false,
    rotation: null,
    size: null,
    spin: false,
    spinPulse: false,
    spinReverse: false,
    beat: false,
    fade: false,
    beatFade: false,
    bounce: false,
    shake: false,
    symbol: false,
    title: '',
    titleId: null,
    transform: null,
    swapOpacity: false
  };
  var convertCurry = convert.bind(null, React__default["default"].createElement);

  exports.FontAwesomeIcon = FontAwesomeIcon;

  Object.defineProperty(exports, '__esModule', { value: true });

}));
