// Type definitions for agate/Button

import { ButtonBaseProps as ui_Button_ButtonBaseProps } from "@enact/ui/Button";
import * as React from "react";
import { ButtonDecoratorProps as ui_Button_ButtonDecoratorProps } from "@enact/ui/Button";
import { SpottableProps as spotlight_Spottable_SpottableProps } from "@enact/spotlight/Spottable";
import { SkinnableProps as agate_Skinnable_SkinnableProps } from "@enact/agate/Skinnable";

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 ButtonBaseProps extends ui_Button_ButtonBaseProps {
  /**
   * Animate when this component renders.
   */
  animateOnRender?: boolean;
  /**
   * The delay before the button is animated, in milliseconds.
   */
  animationDelay?: number;
  /**
   * The background opacity of this button.
   *
   * Valid values are:
   * *  `'opaque'` ,
   * *  `'lightOpaque'` , and
   * *  `'transparent'` .
   */
  backgroundOpacity?: "opaque" | "lightOpaque" | "transparent";
  /**
   * A small message overlaid onto the button.
   */
  badge?: number | string;
  /**
   * A custom color for the badge element.
   *
   * This prop is only visible if the  `badge`  prop is also set.
   */
  badgeColor?: string;
  /**
 * Customizes the component by mapping the supplied collection of CSS class names to the
corresponding internal elements and states of this component.
 * 
 * The following classes are supported:
 * *  `button`  - The root class name
 * *  `bg`  - The background node of the button
 * *  `selected`  - Applied to a  `selected`  button
 * *  `small`  - Applied to a button specifying a  `size`  of  `'small'`
 */
  css?: object;
  /**
 * Provides a way to call special interface attention to this button. It will be "featured"
in some way by the theme's visual rules.  This property only has an effect when
 `backgroundOpacity`  is "opaque".
 */
  highlighted?: boolean;
  /**
   * Specifies on which side ( `'before'`  or  `'after'` ) of the text the icon appears.
   */
  iconPosition?: "before" | "after";
  /**
 * The position of this button in relation to other buttons.
 * 
 * To create a collection of buttons that appear as one entity: buttons that butt up against
each other. Specify where the button is in the arrangement: 'left', 'center', or 'right'.
This prop is not recommended for use on a lonely button with no other buttons nearby.
Not specifying this optional prop leaves the button behaving normally.
 */
  joinedPosition?: "left" | "center" | "right";
  /**
   * Boolean controlling whether this component should enforce the "minimum width" rules.
   */
  minWidth?: boolean;
  /**
 * Provides a way to call special interface attention to this button. It will be "featured"
in some way by the theme's visual rules.
 */
  selected?: boolean;
  /**
   * The size of the button.
   */
  size?: "smallest" | "small" | "large" | "huge";
  /**
   * The amount of sprite "cells" in the src image of the  `icon`  being supplied. This prop has no effect without  `icon` .
   */
  spriteCount?: number;
  /**
   * The button type.
   *
   * Grid buttons are intended to be grouped with other related buttons.
   */
  type?: "grid" | "standard";
}
/**
 * A button component.
 * 
 * This component is most often not used directly but may be composed within another component as it
is within  Button  .
 */

export class ButtonBase extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, ButtonBaseProps>
> {}

export interface ButtonDecoratorProps
  extends Merge<
    Merge<ui_Button_ButtonDecoratorProps, spotlight_Spottable_SpottableProps>,
    agate_Skinnable_SkinnableProps
  > {}
export function ButtonDecorator<P>(
  Component: React.ComponentType<P> | string
): React.ComponentType<P & ButtonDecoratorProps>;

export interface ButtonProps
  extends Merge<ButtonBaseProps, ButtonDecoratorProps> {}
/**
 * A button component, ready to use in Agate applications.
 * 
 * Usage:
 * ```
<Button
  backgroundOpacity="transparent"
>
  Press me!
</Button>
```
 */

export class Button extends React.Component<
  Merge<React.HTMLProps<HTMLElement>, ButtonProps>
> {}

export default Button;
