// Type definitions for ui/Changeable

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 ChangeableConfig extends Object {
  /**
   * Configures the prop name to pass the callback to change the value
   */
  change?: string;
  /**
   * Configures the prop name to pass the current value
   */
  prop?: string;
}
export interface ChangeableProps {
  /**
   * Called to notify  `Changeable`  that the value has changed.
   *
   * The event object must contain a property with the same name as the configured  `prop` .
   */
  onChange?: Function;
  /**
   * The value set at construction when the value prop is  `undefined`  or  `null` .
   *
   * This prop is consumed by  `Changeable`  and not passed onto the wrapped component.
   */
  defaultValue?: any;
  /**
 * The current value.
 * 
 * When set at construction, the component is considered "controlled" and will only
update its internal value when updated by new props. If  `undefined` , the component is
"uncontrolled" and  `Changeable`  will manage the value using callbacks defined by its
configuration.
 */
  prop?: any;
  /**
   * Prevents updates to the internal state of  `Changeable` .
   *
   * `disabled`  is forwarded on to the wrapped component.
   */
  disabled?: boolean;
}
export function Changeable<P>(
  config: ChangeableConfig,
  Component: React.ComponentType<P> | string,
): React.ComponentType<P & ChangeableProps>;

export function Changeable<P>(
  Component: React.ComponentType<P> | string,
): React.ComponentType<P & ChangeableProps>;

export default Changeable;
