/// <reference types="react" />
/**
 * Functions that compare fields of a given State object
 */
export type StateComparers<State> = {
    [key in keyof State]?: (value1: State[key], value2: State[key]) => boolean;
};
export type StateChangeCallback<State> = <StateKey extends keyof State>(event: React.SyntheticEvent | null, field: StateKey, value: State[StateKey], reason: string, state: State) => void;
export type ActionWithContext<Action, ContextValue> = Action & {
    context: ContextValue;
};
/**
 * Parameters of the useControllableReducer hook.
 */
export interface ControllableReducerParameters<State, Action extends ControllableReducerAction, ActionContext = undefined> {
    /**
     * The reducer function.
     *
     * @param state The previous state. If controlledProps are defined, the state will contain the values of the controlledProps.
     * @param action The action to dispatch. The action can be augmented with the `actionContext`.
     * @returns The updated state.
     */
    reducer: (state: State, action: ActionWithContext<Action, ActionContext>) => State;
    /**
     * The controlled props that will override the state items.
     */
    controlledProps?: Partial<State>;
    /**
     * The initial state.
     */
    initialState: State;
    /**
     * Comparers for each state item. If a state item has a corresponding comparer, it will be used to determine if the state has changed.
     * This is taken into consideration when firing the `onStateChange` event.
     * If no comparer is defined, the default equality comparison will be used.
     */
    stateComparers?: StateComparers<State>;
    /**
     * The event handler called whenever a field of the state changes.
     */
    onStateChange?: StateChangeCallback<State>;
    /**
     * Additional properties that will be added to the action.
     */
    actionContext?: ActionContext;
}
export type ControllableReducerAction = {
    /**
     * The type of the action.
     */
    type?: string;
    /**
     * The event that triggered the action.
     */
    event?: React.SyntheticEvent | null;
};
