import _pt from "prop-types";
var _excluded = ["component", "render", "inputRef"];

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; }

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 _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 _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; }

import FormLabel from '../FormLabel/FormLabel';
import React, { useEffect, useRef } from 'react';
import useFormLabel from '../FormLabel/useFormLabel';
/**
 * <FormControl> is an internal component used form components (i.e <TextField>, <Dropdown>, <DateField>, <MonthPicker>)
 * It contains logic shared across form components, handling form labels, errors, id generation, and other shared props
 * <FormControl> is also exported for advanced design system use cases, where the internal component can be leveraged to build custom form components
 * As an internal component, it's subject to more breaking changes. Exercise caution using <FormControl> outside of those special cases
 */

export var FormControl = function FormControl(props) {
  var focusRef = useRef(); // TODO: Make a hook out of this
  // Automatically set focus on field input element when `focusTrigger` prop is used

  useEffect(function () {
    if (props.focusTrigger && focusRef.current) {
      focusRef.current.focus();
    }
  }, [focusRef, props.focusTrigger]);

  var component = props.component,
      render = props.render,
      inputRef = props.inputRef,
      remainingProps = _objectWithoutProperties(props, _excluded);

  var ComponentType = component;
  var wrapperIsFieldset = ComponentType === 'fieldset';

  var _useFormLabel = useFormLabel(_objectSpread(_objectSpread({}, remainingProps), {}, {
    wrapperIsFieldset: wrapperIsFieldset
  })),
      labelProps = _useFormLabel.labelProps,
      fieldProps = _useFormLabel.fieldProps,
      wrapperProps = _useFormLabel.wrapperProps,
      bottomError = _useFormLabel.bottomError;

  function setRef(el) {
    focusRef.current = el;

    if (inputRef) {
      inputRef(el);
    }
  } // Field input props handled by <FormControl>
  // TODO: Move `setRef` logic into <TextField> and <Select>
  // TODO: Simplify `id` props by using a singular `fieldId` prop, and a consistent id naming convention
  // TODO: Use React Context to provide shared form props like `errorPlacement`, `inversed`, `fieldId`


  var fieldInputProps = _objectSpread(_objectSpread({}, fieldProps), {}, {
    labelId: labelProps.id,
    setRef: setRef
  });

  return /*#__PURE__*/React.createElement(ComponentType, wrapperProps, /*#__PURE__*/React.createElement(FormLabel, labelProps), render(fieldInputProps), bottomError);
};
FormControl.propTypes = {
  /**
     * Additional classes to be added to the field container.
     */
  className: _pt.string,

  /**
     * The HTML element used to render the container
     */
  component: _pt.oneOf(['div', 'fieldset']).isRequired,

  /**
     * A unique ID to be used for the error message. If one isn't provided, a unique ID will be generated.
     */
  errorId: _pt.string,
  errorMessage: _pt.node,

  /**
     * Additional classes to be added to the error message
     */
  errorMessageClassName: _pt.string,

  /**
     * Location of the error message relative to the field input
     */
  errorPlacement: _pt.oneOf(['top', 'bottom']),

  /**
     * Used to focus the field input on `componentDidMount()`
     */
  focusTrigger: _pt.bool,

  /**
     * Additional hint text to display
     */
  hint: _pt.node,

  /**
     * A unique ID to be used for the field input. If one isn't provided, a unique ID will be generated.
     */
  id: _pt.string,

  /**
     * Access a reference to the field input
     */
  inputRef: _pt.func,

  /**
     * Applies the "inverse" UI theme
     */
  inversed: _pt.bool,

  /**
     * Label for the field.
     */
  label: _pt.node.isRequired,

  /**
     * Additional classes to be added to the field label
     */
  labelClassName: _pt.string,

  /**
     * The root HTML element used to render the field label
     */
  labelComponent: _pt.oneOf(['label', 'legend']).isRequired,

  /**
     * A unique `id` to be used on the field label. If one isn't provided, a unique ID will be generated.
     */
  labelId: _pt.string,

  /**
     * Text showing the requirement ("Required", "Optional", etc.). See [Required and Optional Fields]({{root}}/guidelines/forms/#required-and-optional-fields).
     */
  requirementLabel: _pt.node,

  /**
     * A function that returns a field input element to accept render props
     */
  render: _pt.func.isRequired
};
export var FormControlPropKeys = ['className', 'component', 'errorId', 'errorMessage', 'errorMessageClassName', 'errorPlacement', 'focusTrigger', 'hint', 'id', 'inputRef', 'inversed', 'label', 'labelClassName', 'labelComponent', 'labelId', 'requirementLabel', 'render'];
export default FormControl;