// Type definitions for ui/Button

import { TouchableProps as ui_Touchable_TouchableProps } from "@enact/ui/Touchable";
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 ButtonBaseProps {
  /**
 * Called with a reference to the root component.
 * 
 * When using   , the  `ref`  prop is forwarded to this component
as  `componentRef` .
 */
  componentRef?: object | Function;
  /**
 * 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 component class
 * *  `bg`  - The background node of the button
 * *  `client`  - The content node of the button
 * *  `hasIcon`  - Applied when there is an  `icon`  present
 * *  `icon`  - The icon node, when  `icon`  is set
 * *  `large`  - Applied when  `size`  prop is  `'large'`
 * *  `minWidth`  - Applied when  `minWidth`  prop is  `true`
 * *  `pressed`  - Applied when  `pressed`  prop is  `true`
 * *  `selected`  - Applied when  `selected`  prop is  `true`
 * *  `small`  - Applied when  `size`  prop is  `'small'`
 */
  css?: object;
  /**
   * Applies the  `disabled`  class.
   *
   * When  `true` , the button is shown as disabled.
   */
  disabled?: boolean;
  /**
 * The icon displayed within the Button.
 * 
 * The icon will be displayed before the natural reading order of the text, regardless
of locale. Any string that is valid for its    is
valid here. If  `icon`  is specified as a string and  `iconButton`  is undefined, the icon is
not rendered.
 * 
 * This also supports a custom icon, in the form of a DOM node or a Component,
with the caveat that if you supply a custom icon, you are responsible for sizing and
locale positioning of the custom component.
 * 
 * Setting this to  `true`  means the  `iconComponent`  will be rendered but with empty content.
This may be useful if you've customized the  `iconComponent`  to render the icon content
externally.
 */
  icon?: React.ReactNode | boolean;
  /**
 * The component used to render the   .
 * 
 * This component will receive the  `icon`  class to customize its styling.
If    is not assigned or is false, this component
will not be rendered.
 * 
 * If this is a component rather than an HTML element string, this component will also
receive the  `size`  and  `iconFlip`  (as  `flip` ) properties and should be configured to
handle it.
 */
  iconComponent?: React.ComponentType | React.ReactNode;
  /**
   * Flips the icon.
   */
  iconFlip?: string;
  /**
 * Enforces a minimum width for the component.
 * 
 * Applies the  `minWidth`  CSS class which can be customized by
  .
 */
  minWidth?: boolean;
  /**
 * Indicates the component is depressed.
 * 
 * Applies the  `pressed`  CSS class which can be customized by
  .
 */
  pressed?: boolean;
  /**
 * Indicates the component is selected.
 * 
 * Applies the  `selected`  CSS class which can be customized by
  .
 */
  selected?: boolean;
  /**
 * The size of the button.
 * 
 * Applies the CSS class which can be customized by
  .
 */
  size?: string;
}
/**
 * A basic button component structure without any behaviors applied to it.
 */

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

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

export interface ButtonProps
  extends Omit<Merge<ButtonBaseProps, ButtonDecoratorProps>, "componentRef"> {}
/**
 * A minimally-styled button component with touch support.
 */

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

export default Button;
