// Type definitions for sandstone/Dropdown

import * as React from "react";
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 { ButtonProps as sandstone_Button_ButtonProps } from "@enact/sandstone/Button";
import { ContextualPopupDecoratorProps as sandstone_ContextualPopupDecorator_ContextualPopupDecoratorProps } from "@enact/sandstone/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 DropdownBaseProps
  extends Omit<
    Merge<
      sandstone_Button_ButtonProps,
      sandstone_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, making it 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;
  /**
   * Text displayed in the Dropdown when nothing is selected.
   *
   * The placeholder will be replaced by the selected item.
   */
  placeholder?: string;
  /**
   * Index of the selected item.
   */
  selected?: number;
  /**
   * The size of the Dropdown's    component.
   */
  size?: "large" | "small";
  /**
   * Primary title text of the Dropdown.
   */
  title?: string;
  /**
   * Width of the Dropdown.
   */
  width?: "huge" | "large" | "x-large" | "medium" | "small" | "tiny" | number;
}
/**
 * A stateless Dropdown component.
 */

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

export interface DropdownDecoratorProps
  extends Merge<
    Merge<ui_Changeable_ChangeableProps, ui_Toggleable_ToggleableProps>,
    spotlight_SpotlightContainerDecorator_SpotlightContainerDecoratorProps
  > {
  /**
   * Displays the items.
   */
  open?: boolean;
  /**
   * Index of the selected item.
   */
  selected?: number;
  /**
   * The initial selected index when  `selected`  is not defined.
   */
  defaultSelected?: number;
}
export function DropdownDecorator<P>(
  Component: React.ComponentType<P> | string,
): React.ComponentType<P & DropdownDecoratorProps>;

export interface DropdownProps extends DropdownBaseProps {}
/**
 * A Sandstone 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;
