{
  "version": 3,
  "sources": ["../../../src/input-control/reducer/reducer.ts"],
  "sourcesContent": ["/**\n * External dependencies\n */\n\n/**\n * WordPress dependencies\n */\nimport { useReducer, useLayoutEffect, useRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\n\nimport { initialInputControlState, initialStateReducer } from './state';\nimport * as actions from './actions';\n/**\n * Prepares initialState for the reducer.\n *\n * @param initialState The initial state.\n * @return Prepared initialState for the reducer\n */\nfunction mergeInitialState(initialState = initialInputControlState) {\n  const {\n    value\n  } = initialState;\n  return {\n    ...initialInputControlState,\n    ...initialState,\n    initialValue: value\n  };\n}\n\n/**\n * Creates the base reducer which may be coupled to a specializing reducer.\n * As its final step, for all actions other than CONTROL, the base reducer\n * passes the state and action on through the specializing reducer. The\n * exception for CONTROL actions is because they represent controlled updates\n * from props and no case has yet presented for their specialization.\n *\n * @param composedStateReducers A reducer to specialize state changes.\n * @return The reducer.\n */\nfunction inputControlStateReducer(composedStateReducers) {\n  return (state, action) => {\n    const nextState = {\n      ...state\n    };\n    switch (action.type) {\n      /*\n       * Controlled updates\n       */\n      case actions.CONTROL:\n        nextState.value = action.payload.value;\n        nextState.isDirty = false;\n        nextState._event = undefined;\n        // Returns immediately to avoid invoking additional reducers.\n        return nextState;\n\n      /**\n       * Keyboard events\n       */\n      case actions.PRESS_UP:\n        nextState.isDirty = false;\n        break;\n      case actions.PRESS_DOWN:\n        nextState.isDirty = false;\n        break;\n\n      /**\n       * Drag events\n       */\n      case actions.DRAG_START:\n        nextState.isDragging = true;\n        break;\n      case actions.DRAG_END:\n        nextState.isDragging = false;\n        break;\n\n      /**\n       * Input events\n       */\n      case actions.CHANGE:\n        nextState.error = null;\n        nextState.value = action.payload.value;\n        if (state.isPressEnterToChange) {\n          nextState.isDirty = true;\n        }\n        break;\n      case actions.COMMIT:\n        nextState.value = action.payload.value;\n        nextState.isDirty = false;\n        break;\n      case actions.RESET:\n        nextState.error = null;\n        nextState.isDirty = false;\n        nextState.value = action.payload.value || state.initialValue;\n        break;\n\n      /**\n       * Validation\n       */\n      case actions.INVALIDATE:\n        nextState.error = action.payload.error;\n        break;\n    }\n    nextState._event = action.payload.event;\n\n    /**\n     * Send the nextState + action to the composedReducers via\n     * this \"bridge\" mechanism. This allows external stateReducers\n     * to hook into actions, and modify state if needed.\n     */\n    return composedStateReducers(nextState, action);\n  };\n}\n\n/**\n * A custom hook that connects and external stateReducer with an internal\n * reducer. This hook manages the internal state of InputControl.\n * However, by connecting an external stateReducer function, other\n * components can react to actions as well as modify state before it is\n * applied.\n *\n * This technique uses the \"stateReducer\" design pattern:\n * https://kentcdodds.com/blog/the-state-reducer-pattern/\n *\n * @param stateReducer    An external state reducer.\n * @param initialState    The initial state for the reducer.\n * @param onChangeHandler A handler for the onChange event.\n * @return State, dispatch, and a collection of actions.\n */\nexport function useInputControlStateReducer(stateReducer = initialStateReducer, initialState = initialInputControlState, onChangeHandler) {\n  const [state, dispatch] = useReducer(inputControlStateReducer(stateReducer), mergeInitialState(initialState));\n  const createChangeEvent = type => (nextValue, event) => {\n    dispatch({\n      type,\n      payload: {\n        value: nextValue,\n        event\n      }\n    });\n  };\n  const createKeyEvent = type => event => {\n    dispatch({\n      type,\n      payload: {\n        event\n      }\n    });\n  };\n  const createDragEvent = type => payload => {\n    dispatch({\n      type,\n      payload\n    });\n  };\n\n  /**\n   * Actions for the reducer\n   */\n  const change = createChangeEvent(actions.CHANGE);\n  const invalidate = (error, event) => dispatch({\n    type: actions.INVALIDATE,\n    payload: {\n      error,\n      event\n    }\n  });\n  const reset = createChangeEvent(actions.RESET);\n  const commit = createChangeEvent(actions.COMMIT);\n  const dragStart = createDragEvent(actions.DRAG_START);\n  const drag = createDragEvent(actions.DRAG);\n  const dragEnd = createDragEvent(actions.DRAG_END);\n  const pressUp = createKeyEvent(actions.PRESS_UP);\n  const pressDown = createKeyEvent(actions.PRESS_DOWN);\n  const pressEnter = createKeyEvent(actions.PRESS_ENTER);\n  const currentStateRef = useRef(state);\n  const refPropsRef = useRef({\n    value: initialState.value,\n    onChangeHandler\n  });\n\n  // Freshens refs to props and state so that subsequent effects have access\n  // to their latest values without their changes causing effect runs.\n  useLayoutEffect(() => {\n    currentStateRef.current = state;\n    refPropsRef.current = {\n      value: initialState.value,\n      onChangeHandler\n    };\n  });\n\n  // Propagates the latest state through onChange.\n  useLayoutEffect(() => {\n    if (currentStateRef.current._event !== undefined && state.value !== refPropsRef.current.value && !state.isDirty) {\n      refPropsRef.current.onChangeHandler(state.value ?? '', {\n        event: currentStateRef.current._event\n      });\n    }\n  }, [state.value, state.isDirty]);\n\n  // Updates the state from props.\n  useLayoutEffect(() => {\n    if (initialState.value !== currentStateRef.current.value && !currentStateRef.current.isDirty) {\n      dispatch({\n        type: actions.CONTROL,\n        payload: {\n          value: initialState.value ?? ''\n        }\n      });\n    }\n  }, [initialState.value]);\n  return {\n    change,\n    commit,\n    dispatch,\n    drag,\n    dragEnd,\n    dragStart,\n    invalidate,\n    pressDown,\n    pressEnter,\n    pressUp,\n    reset,\n    state\n  };\n}"],
  "mappings": "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",
  "names": []
}
