import type {
  ClipboardEvent,
  CompositionEvent,
  FocusEvent,
  KeyboardEvent,
} from "react";

export interface KeyboardEvents {
  /** Event called when the value changes (mandatory for controlled components) */
  onKeyUp?: (e: KeyboardEvent) => void;

  /** Event called when the value changes (mandatory for controlled components) */
  onKeyDown?: (e: KeyboardEvent) => void;
}

export interface ClipboardEvents {
  /** Fired when the user initiates a copy action through the browser's user interface. */
  onCopy?: (e: ClipboardEvent) => void;

  /** Fired when the user initiates a cut action through the browser's user interface. */
  onCut?: (e: ClipboardEvent) => void;

  /** Fired when the user initiates a paste action through the browser's user interface. */
  onPaste?: (e: ClipboardEvent) => void;
}

export interface CompositionEvents {
  /** Fired when a text composition system such as an input method editor completes or cancels the current composition session. */
  onCompositionEnd?: (e: CompositionEvent) => void;

  /** Fired when a text composition system such as an input method editor starts a new composition session. */
  onCompositionStart?: (e: CompositionEvent) => void;

  /** Fired when a new character is received in the context of a text composition session controlled by a text composition system such as an input method editor. */
  onCompositionUpdate?: (e: CompositionEvent) => void;
}

export interface FocusEvents {
  /** Fired when an element has lost focus. */
  onBlur?: (e: FocusEvent) => void;

  /** Fired when an element has gained focus. */
  onFocus?: (e: FocusEvent) => void;
}

export interface InputEvents {
  /** Event called when the value changes (mandatory for controlled components) */
  onChange?: (value: string) => void;
}

export type HTMLElementEvent<T extends HTMLElement> = Event & {
  target: T;
};

export interface Validation {
  /** Whether user input is required on the input before form submission. */
  isRequired?: boolean;
  /** Whether the input value is invalid. */
  isInvalid?: boolean;
}
