// Type definitions for ui/ViewManager

import { ForwardRefProps as ui_ForwardRef_ForwardRefProps } from "@enact/ui/ForwardRef";
import * as React from "react";

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;

export interface ViewManagerBaseProps {
  /**
   * Arranger to control the animation
   */
  arranger?: Arranger;
  /**
   * An object containing properties to be passed to each child.
   */
  childProps?: object;
  /**
   * Views to be managed.
   *
   * May be any renderable component including custom React components or primitive DOM nodes.
   */
  children?: React.ReactNode;
  /**
   * Type of component wrapping the children. May be a DOM node or a custom React component.
   */
  component?: string | React.ComponentType;
  /**
 * Called with a reference to the root component.
 * 
 * When using   , the  `ref`  prop is forwarded to this
component as  `componentRef` .
 */
  componentRef?: object | Function;
  /**
   * Time in milliseconds to complete a transition
   */
  duration?: number;
  /**
   * Index of last visible view.
   *
   * Defaults to the current value of  `index` .
   */
  end?: number;
  /**
 * Time, in milliseconds, to wait after a view has entered to inform it by pass the
 `enteringProp`  as false.
 */
  enteringDelay?: number;
  /**
 * Name of the property to pass to the wrapped view to indicate when it is entering the
viewport.
 * 
 * When  `true` , the view has been created but has not transitioned into place.
When  `false` , the view has finished its transition.
 * 
 * The notification can be delayed by setting  `enteringDelay` . If not set, the view will not
be notified of the change in transition.
 */
  enteringProp?: string;
  /**
   * Index of active view
   */
  index?: number;
  /**
   * Indicates if the transition should be animated
   */
  noAnimation?: boolean;
  /**
   * Called when each view is rendered during initial construction.
   */
  onAppear?: Function;
  /**
   * Called when each view completes its transition into the viewport.
   */
  onEnter?: Function;
  /**
   * Called when each view completes its transition out of the viewport.
   */
  onLeave?: Function;
  /**
   * Called when each view completes its transition within the viewport.
   */
  onStay?: Function;
  /**
   * Called once when all views have completed their transition.
   */
  onTransition?: Function;
  /**
   * Called once before views begin their transition.
   */
  onWillTransition?: Function;
  /**
 * Explicitly sets the transition direction.
 * 
 * If omitted, the direction is determined automatically based on the change of index or a
string comparison of the first child's key.
 */
  reverseTransition?: boolean;
  /**
 * Indicates the current locale uses right-to-left reading order.
 * 
 * `rtl`  is passed to the  `arranger`  in order to alter the animation (e.g. reversing the
horizontal direction).
 */
  rtl?: boolean;
  /**
   * Index of first visible view. Defaults to the current value of  `index` .
   */
  start?: number;
}
/**
 * The base  `ViewManager`  component, without
   applied.
 */

export class ViewManagerBase extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, ViewManagerBaseProps>
> {}

/**
 * A function that generates an animation for a given transition configuration
 */
export interface ArrangerCallback {
  (
    /**
     * Animation configuration object.
     */
    config: object,
  ): any;
}
/**
 * An object with callback functions to arrange views within   .
 */
export interface Arranger {
  /**
 * Returns an array of keyframes describing the animation when
a view is entering the viewport.
 */
  enter: ArrangerCallback /**
 * Returns an array of keyframes describing the animation when
a view is leaving the viewport.
 */;
  leave: ArrangerCallback /**
 * Returns an array of keyframes describing the animation when
a view is remaining in the viewport.
 */;
  stay?: ArrangerCallback;
}
/**
 * A basic arranger factory that must be configured with  `direction`  and optionally an  `amount` .
 */
export function SlideArranger(config: object): Arranger;
/**
 * An arranger that enters from the left and leaves to the right.
 */
export declare const SlideRightArranger: Arranger;
/**
 * An arranger that enters from the right and leaves to the left..
 */
export declare const SlideLeftArranger: Arranger;
/**
 * An arranger that enters from the bottom and leaves to the top..
 */
export declare const SlideTopArranger: Arranger;
/**
 * An arranger that enters from the top and leaves to the bottom..
 */
export declare const SlideBottomArranger: Arranger;

export interface ViewManagerDecoratorProps
  extends ui_ForwardRef_ForwardRefProps {}
export function ViewManagerDecorator<P>(
  Component: React.ComponentType<P> | string,
): React.ComponentType<P & ViewManagerDecoratorProps>;

export interface ViewManagerProps
  extends Omit<
    Merge<ViewManagerBaseProps, ViewManagerDecoratorProps>,
    "componentRef"
  > {}
/**
 * A  `ViewManager`  controls the visibility of a configurable number of views, allowing for them to be
transitioned on and off the viewport.
 */

export class ViewManager extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, ViewManagerProps>
> {}

export default ViewManager;
