"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useInnerStateFallback = useInnerStateFallback;
var _react = require("react");
/**
 * This hook provides a state fallback for different table features such as pinning, rowExpansion, rowSelection
 * - It has inner state which will be used as a fallback for some functionality when nothing is passed from outside
 * - If state and updater function is passed from outside - hook will call passed updater function with new inner state. So that consumer is notified of inner state changes if needed
 * - If state and updater function is passed from outside, and then external state is updated by some logic - external state will take precedence and inner state will be synced with it
 * @param onExternalStateUpdate - function passed from the consumer to be invoked with new updated inner state
 * @param externalState - state passed from the consumers side. Take precedence over inner state. But should be updated on consumer's side if passed
 * @param decoratorFn - optional decorator function that will be called before setting new state
 */
function useInnerStateFallback(onExternalStateUpdate, externalState, decoratorFn = data => data) {
  const decoratedValue = decoratorFn(externalState || {});
  const [innerState, setInnerState] = (0, _react.useState)(decoratedValue);
  const onChangeState = fn => {
    // we are setting innerState and outer  externalState as the same object "nextData"
    // it means that their links should be equal. If their links are not equal, it means externalState was altered by the user
    // thus external state should take precedence over inner state that has fallen behind
    const currentState = externalState && externalState !== innerState ? externalState : innerState;
    const nextData = typeof fn === 'function' ? fn(currentState) : fn;
    const nextDecoratedData = decoratorFn(nextData);
    // set both inner state and call onExternalStateUpdate with new state to notify consumer
    setInnerState(nextDecoratedData);
    onExternalStateUpdate(nextDecoratedData);
  };
  return [externalState ? decoratedValue : innerState, onChangeState];
}