import _extends from "@babel/runtime/helpers/esm/extends";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";

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

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

import React, { forwardRef, useCallback, useRef } from 'react';
import PropTypes from 'prop-types';
import { keyframes } from '@emotion/core';
import { Input as RebassInput } from '@rebass/forms';
import { isFunction, noop } from 'ramda-extension';
import useBlockingEffect from '../hooks/useBlockingEffect';
import { isInputValueEmpty, useSuperFieldContext } from '../SuperField';
import Box from '../Box';
const placeholderHidden = {
  opacity: '0 !important'
};
const placeholderVisible = {
  opacity: 0.5
};

const mergeRefs = refs => value => {
  refs.filter(Boolean).forEach(ref => isFunction(ref) ? ref(value) : ref.current = value);
};

const autofill = keyframes`
	from {}
`; // NOTE: make sure, that contents of `autofill` and `autofillCancel` are not
// the same. Otherwise emotion actually assings both of them same
// animation.name.

const autofillCancel = keyframes`
	from {}
	to: {}
`;

const getBorderColor = ({
  hasError,
  readOnly,
  disabled
}) => {
  if (hasError) {
    return 'danger';
  } else if (disabled || readOnly) {
    return 'muted';
  } else {
    return 'secondary';
  }
};

const Input = /*#__PURE__*/forwardRef((props, ref) => {
  const {
    id,
    isLabelShrank,
    hasError,
    onFill,
    onEmpty,
    onFocus,
    onBlur
  } = useSuperFieldContext();
  const inputRef = useRef();
  const internalInputRef = mergeRefs([inputRef, ref]);

  const {
    value,
    onChange,
    onFocus: onFocusProp = () => {},
    onBlur: onBlurProp = () => {},
    placeholder,
    disabled,
    readOnly
  } = props,
        rest = _objectWithoutProperties(props, ["value", "onChange", "onFocus", "onBlur", "placeholder", "disabled", "readOnly"]);

  const checkDirty = useCallback(value => {
    if (isInputValueEmpty(value)) {
      onEmpty();
    } else {
      onFill();
    }
  }, [onEmpty, onFill]);
  useBlockingEffect(() => {
    checkDirty(value);
  }, [checkDirty, value]);

  const handleAutoFill = event => {
    // Provide a fake value as Chrome might not let you access it for security
    // reasons.
    checkDirty(event.animationName.indexOf(autofillCancel.name) !== -1 ? inputRef.current.value : 'x');
  };

  const handleFocus = event => {
    if (disabled) {
      return;
    }

    onFocus();
    return onFocusProp(event);
  };

  const handleBlur = event => {
    if (disabled) {
      return;
    }

    onBlur();
    return onBlurProp(event);
  };

  const handleChange = disabled ? noop : onChange;
  const fontSize = [2, 4];
  return /*#__PURE__*/React.createElement(Box, {
    sx: {
      position: 'relative',
      '&:before': {
        content: '"\u00a0"',
        display: 'block',
        position: 'absolute',
        bottom: 0,
        left: 0,
        right: 0,
        borderBottomStyle: 'solid',
        borderBottomWidth: '1px',
        borderBottomColor: 'muted',
        pointerEvents: 'none'
      },
      '&:hover:before': {
        borderBottomColor: disabled ? 'muted' : 'gray.2'
      },
      '&:after': {
        content: '"\u00a0"',
        display: 'block',
        position: 'absolute',
        bottom: 0,
        left: 0,
        right: 0,
        borderBottomStyle: 'solid',
        borderBottomWidth: disabled || readOnly ? '1px' : '2px',
        borderBottomColor: getBorderColor(props),
        pointerEvents: 'none',
        transition: 'transform 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms',
        transform: !isLabelShrank && !hasError ? 'scaleX(0)' : ''
      }
    }
  }, /*#__PURE__*/React.createElement(RebassInput, _extends({
    sx: _objectSpread(_objectSpread({
      color: 'inherit',
      border: 'none',
      animationDuration: '50000s',
      '&:not(:-webkit-autofill)': {
        animationName: autofillCancel,
        animationDuration: '50000s'
      },
      '&:-webkit-autofill': {
        animationName: autofill,
        animationDuration: '50000s',
        fontSize
      },
      '&:-webkit-autofill::firstline': {
        fontSize
      },
      WebkitTapHighlightColor: 'transparent',
      '&::placeholder': placeholder,
      '&::WebkitSearchDecoration': {
        // Remove the padding when type=search.
        WebkitAppearance: 'none'
      }
    }, !isLabelShrank ? {
      '&::placeholder': placeholderHidden
    } : {
      '&:placeholder': placeholderVisible
    }), {}, {
      // FF
      '&:invalid': {
        boxShadow: 'none'
      },
      '&:focus': {
        outline: 0
      },
      width: '100%',
      fontSize
    }),
    px: 0,
    id: id,
    onAnimationStart: handleAutoFill,
    value: value,
    onChange: handleChange,
    onFocus: handleFocus,
    onBlur: handleBlur,
    placeholder: placeholder,
    disabled: disabled,
    readOnly: readOnly,
    ref: internalInputRef
  }, rest)));
});
Input.displayName = 'Input';
process.env.NODE_ENV !== "production" ? Input.propTypes = {
  disabled: PropTypes.bool,
  onBlur: PropTypes.func,
  onChange: PropTypes.func,
  onFocus: PropTypes.func,
  placeholder: PropTypes.string,
  readOnly: PropTypes.bool,
  value: PropTypes.any
} : void 0;
export default Input;