// Type definitions for agate/Dropdown

import { ChangeableProps as ui_Changeable_ChangeableProps } from "@enact/ui/Changeable";
import { ToggleableProps as ui_Toggleable_ToggleableProps } from "@enact/ui/Toggleable";
import { SpotlightContainerDecoratorProps as spotlight_SpotlightContainerDecorator_SpotlightContainerDecoratorProps } from "@enact/spotlight/SpotlightContainerDecorator";
import { SkinnableProps as agate_Skinnable_SkinnableProps } from "@enact/agate/Skinnable";
import * as React from "react";
import { ButtonProps as agate_Button_ButtonProps } from "@enact/agate/Button";
import { ContextualPopupDecoratorProps as agate_ContextualPopupDecorator_ContextualPopupDecoratorProps } from "@enact/agate/ContextualPopupDecorator";

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 DropdownListBaseProps {
  /**
   * The selections for Dropdown
   */
  children?:
    | string[]
    | {
        key: number | string;
        children: string | React.ComponentType;
        [propName: string]: any;
      }[];
  /**
   * Placement of the Dropdown List.
   */
  direction?: string;
  /**
   * Called when an item is selected.
   */
  onSelect?: Function;
  /**
   * Callback function that will receive the scroller's scrollTo() method
   */
  scrollTo?: Function;
  /**
   * Index of the selected item.
   */
  selected?: number;
  /**
   * The current skin for this component.
   */
  skin?: string;
  /**
   * The width of DropdownList.
   */
  width?: "smallest" | "small" | "medium" | "large" | "x-large" | "huge";
}
/**
 * A stateless DropdownList component.
 */

export class DropdownListBase extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, DropdownListBaseProps>
> {}

export interface DropdownButtonBaseProps {
  /**
   * The icon displayed on the dropdown button.
   */
  icon?: string;
  /**
   * The current skin for this component.
   */
  skin?: string;
}
/**
 * A stateless Dropdown Button component.
 */

export class DropdownButtonBase extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, DropdownButtonBaseProps>
> {}

export interface DropdownBaseProps
  extends Omit<
    Merge<
      agate_Button_ButtonProps,
      agate_ContextualPopupDecorator_ContextualPopupDecoratorProps
    >,
    "popupComponent"
  > {
  /**
   * The "aria-label" for the Dropdown.
   */
  "aria-label"?: string;
  /**
 * Items to be displayed in the  `Dropdown`  when  `open` .
 * 
 * Takes either an array of strings or an array of objects. When strings, the values will be
used in the generated components as the readable text. When objects, the properties will
be passed onto an  `Item`  component;  `children`  as well as a unique  `key`  properties are
required.
 */
  children?:
    | string[]
    | {
        key: number | string;
        children: string | React.ComponentType;
        [propName: string]: any;
      }[];
  /**
   * Placement of the Dropdown.
   */
  direction?: "above" | "below";
  /**
   * Disables Dropdown and becomes non-interactive.
   */
  disabled?: boolean;
  /**
   * Called when the Dropdown is closing.
   */
  onClose?: Function;
  /**
   * Called when the Dropdown is opening.
   */
  onOpen?: Function;
  /**
   * Called when an item is selected.
   *
   * The event payload will be an object with the following members:
   * *  `data`  - The value for the option as received in the  `children`  prop
   * *  `selected`  - Number representing the selected option, 0 indexed
   */
  onSelect?: Function;
  /**
   * Displays the items.
   */
  open?: boolean;
  /**
   * Index of the selected item.
   */
  selected?: number;
  /**
   * The current skin for this component.
   */
  skin?: string;
  /**
   * Text displayed in the Dropdown when nothing is selected.
   *
   * The title will be replaced with the selected item, if set.
   */
  title?: string;
  /**
   * Width of the Dropdown.
   */
  width?: "smallest" | "small" | "medium" | "large" | "x-large" | "huge";
}
/**
 * A stateless Dropdown component.
 */

export class DropdownBase extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, DropdownBaseProps>
> {}

export interface DropdownDecoratorProps
  extends Merge<
    Merge<
      Merge<ui_Changeable_ChangeableProps, ui_Toggleable_ToggleableProps>,
      spotlight_SpotlightContainerDecorator_SpotlightContainerDecoratorProps
    >,
    agate_Skinnable_SkinnableProps
  > {}
export function DropdownDecorator<P>(
  Component: React.ComponentType<P> | string,
): React.ComponentType<P & DropdownDecoratorProps>;

export interface DropdownProps
  extends Merge<DropdownBaseProps, DropdownDecoratorProps> {}
/**
 * An Agate Dropdown component.
 * 
 * By default,  `Dropdown`  maintains the state of its  `selected`  property. Supply the
 `defaultSelected`  property to control its initial value. If you wish to directly control updates
to the component, supply a value to  `selected`  at creation time and update it in response to
 `onSelect`  events.
 */

export class Dropdown extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, DropdownProps>
> {}

export default Dropdown;
