text: import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  
  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; }
  
  /**
   * External dependencies
   */
  import { isEmpty } from 'lodash';
  /**
   * WordPress dependencies
   */
  
  import { useReducer } from '@wordpress/element';
  
  var initialStateReducer = function initialStateReducer(state) {
    return state;
  };
  
  var initialInputControlState = {
    _event: {},
    error: null,
    initialValue: '',
    isDirty: false,
    isDragEnabled: false,
    isDragging: false,
    isPressEnterToChange: false,
    value: ''
  };
  var actionTypes = {
    CHANGE: 'CHANGE',
    COMMIT: 'COMMIT',
    DRAG_END: 'DRAG_END',
    DRAG_START: 'DRAG_START',
    DRAG: 'DRAG',
    INVALIDATE: 'INVALIDATE',
    PRESS_DOWN: 'PRESS_DOWN',
    PRESS_ENTER: 'PRESS_ENTER',
    PRESS_UP: 'PRESS_UP',
    RESET: 'RESET',
    UPDATE: 'UPDATE'
  };
  export var inputControlActionTypes = actionTypes;
  /**
   * Prepares initialState for the reducer.
   *
   * @param {Object} initialState The initial state.
   * @return {Object} Prepared initialState for the reducer
   */
  
  function mergeInitialState() {
    var initialState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialInputControlState;
    var value = initialState.value;
    return _objectSpread({}, initialInputControlState, {}, initialState, {
      initialValue: value
    });
  }
  /**
   * Composes multiple stateReducers into a single stateReducer, building
   * the pipeline to control the flow for state and actions.
   *
   * @param  {...Function} fns State reducers.
   * @return {Function} The single composed stateReducer.
   */
  
  
  export var composeStateReducers = function composeStateReducers() {
    for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) {
      fns[_key] = arguments[_key];
    }
  
    return function () {
      for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        args[_key2] = arguments[_key2];
      }
  
      return fns.reduceRight(function (state, fn) {
        var fnState = fn.apply(void 0, args);
        return isEmpty(fnState) ? state : _objectSpread({}, state, {}, fnState);
      }, {});
    };
  };
  /**
   * Creates a reducer that opens the channel for external state subscription
   * and modification.
   *
   * This technique uses the "stateReducer" design pattern:
   * https://kentcdodds.com/blog/the-state-reducer-pattern/
   *
   * @param {Function} composedStateReducers A custom reducer that can subscribe and modify state.
   * @return {Function} The reducer.
   */
  
  function inputControlStateReducer(composedStateReducers) {
    return function (state, action) {
      var nextState = _objectSpread({}, state);
  
      var type = action.type,
          payload = action.payload;
  
      switch (type) {
        /**
         * Keyboard events
         */
        case actionTypes.PRESS_UP:
          nextState.isDirty = false;
          break;
  
        case actionTypes.PRESS_DOWN:
          nextState.isDirty = false;
          break;
  
        /**
         * Drag events
         */
  
        case actionTypes.DRAG_START:
          nextState.isDragging = true;
          break;
  
        case actionTypes.DRAG_END:
          nextState.isDragging = false;
          break;
  
        /**
         * Input events
         */
  
        case actionTypes.CHANGE:
          nextState.error = null;
          nextState.value = payload.value;
  
          if (state.isPressEnterToChange) {
            nextState.isDirty = true;
          }
  
          break;
  
        case actionTypes.COMMIT:
          nextState.value = payload.value;
          nextState.isDirty = false;
          break;
  
        case actionTypes.RESET:
          nextState.error = null;
          nextState.isDirty = false;
          nextState.value = payload.value || state.initialValue;
          break;
  
        case actionTypes.UPDATE:
          if (payload.value !== state.value) {
            nextState.value = payload.value;
            nextState.isDirty = false;
          }
  
          break;
  
        /**
         * Validation
         */
  
        case actionTypes.INVALIDATE:
          nextState.error = payload.error;
          break;
      }
  
      if (payload.event) {
        nextState._event = payload.event;
      }
      /**
       * Send the nextState + action to the composedReducers via
       * this "bridge" mechanism. This allows external stateReducers
       * to hook into actions, and modify state if needed.
       */
  
  
      return composedStateReducers(nextState, action);
    };
  }
  /**
   * A custom hook that connects and external stateReducer with an internal
   * reducer. This hook manages the internal state of InputControl.
   * However, by connecting an external stateReducer function, other
   * components can react to actions as well as modify state before it is
   * applied.
   *
   * This technique uses the "stateReducer" design pattern:
   * https://kentcdodds.com/blog/the-state-reducer-pattern/
   *
   * @param {Function} stateReducer An external state reducer.
   * @param {Object} initialState The initial state for the reducer.
   * @return {Object} State, dispatch, and a collection of actions.
   */
  
  
  export function useInputControlStateReducer() {
    var stateReducer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialStateReducer;
    var initialState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : initialInputControlState;
  
    var _useReducer = useReducer(inputControlStateReducer(stateReducer), mergeInitialState(initialState)),
        _useReducer2 = _slicedToArray(_useReducer, 2),
        state = _useReducer2[0],
        dispatch = _useReducer2[1];
  
    var createChangeEvent = function createChangeEvent(type) {
      return function (nextValue, event) {
        /**
         * Persist allows for the (Synthetic) event to be used outside of
         * this function call.
         * https://reactjs.org/docs/events.html#event-pooling
         */
        if (event && event.persist) {
          event.persist();
        }
  
        dispatch({
          type: type,
          payload: {
            value: nextValue,
            event: event
          }
        });
      };
    };
  
    var createKeyEvent = function createKeyEvent(type) {
      return function (event) {
        /**
         * Persist allows for the (Synthetic) event to be used outside of
         * this function call.
         * https://reactjs.org/docs/events.html#event-pooling
         */
        if (event && event.persist) {
          event.persist();
        }
  
        dispatch({
          type: type,
          payload: {
            event: event
          }
        });
      };
    };
  
    var createDragEvent = function createDragEvent(type) {
      return function (dragProps) {
        dispatch({
          type: type,
          payload: dragProps
        });
      };
    };
    /**
     * Actions for the reducer
     */
  
  
    var change = createChangeEvent(actionTypes.CHANGE);
    var inValidate = createChangeEvent(actionTypes.INVALIDATE);
    var reset = createChangeEvent(actionTypes.RESET);
    var commit = createChangeEvent(actionTypes.COMMIT);
    var update = createChangeEvent(actionTypes.UPDATE);
    var dragStart = createDragEvent(actionTypes.DRAG_START);
    var drag = createDragEvent(actionTypes.DRAG);
    var dragEnd = createDragEvent(actionTypes.DRAG_END);
    var pressUp = createKeyEvent(actionTypes.PRESS_UP);
    var pressDown = createKeyEvent(actionTypes.PRESS_DOWN);
    var pressEnter = createKeyEvent(actionTypes.PRESS_ENTER);
    return {
      change: change,
      commit: commit,
      dispatch: dispatch,
      drag: drag,
      dragEnd: dragEnd,
      dragStart: dragStart,
      inValidate: inValidate,
      pressDown: pressDown,
      pressEnter: pressEnter,
      pressUp: pressUp,
      reset: reset,
      state: state,
      update: update
    };
  }
  //# sourceMappingURL=state.js.map