import { Component, G, One, Render } from "galho";
import { Alias, L } from "galho/orray.js";
import { AnyDic, Dic, Key, Primitive, Task, bool, falsy, float, int, str } from "galho/util.js";
import { Icon, Label, SingleSelectBase, Size, TextInputTp, iSingleSelectBase } from "./galhui.js";
export type Error = Render | G | str;
interface FieldGroup {
    input(key: PropertyKey): Input;
}
/**coisas executadas quando alguma ação acontece dentro do form */
type BotCallback<T extends FieldGroup> = (src: Dic<any>, form: T) => any;
export type Bot<T extends FieldGroup = FieldGroup> = [...src: str[], call: BotCallback<T>];
export declare const enum ErrorType {
    required = "req",
    numberTooBig = "number_too_big",
    numberTooSmall = "number_too_small",
    invalidFormat = "invalid_format",
    textTooLong = "text_too_long",
    textTooShort = "text_too_short",
    isDecimal = "is_decimal",
    isNegative = "is_negative",
    tooOlder = "too_older",
    tooYoung = "too_young",
    moreItems = "more_items",
    lessItems = "less_items",
    unsubmited = "unsubmited"
}
interface EError extends Render {
    tp: ErrorType;
    params?: Dic;
}
export declare const error: (tp: ErrorType, msg?: str, params?: Dic) => EError;
export declare const req: () => EError;
export type Errors = Dic<() => any>;
interface FormEvents extends AnyDic<any[]> {
    input: [Input];
    fill: [data: Dic];
    requestsubmit: [e: SubmitEvent];
    submit: [data: Dic];
    cancel: [];
}
export interface iFormBase {
    /**@default "form" */
    tag?: keyof HTMLElementTagNameMap;
    readOnly?: bool;
    hidden?: Dic;
    bots?: Bot<any>[];
    /**called when input enter/exit off */
    offFN?: (e: G, isOff: bool) => void;
}
/** */
export declare class FormBase<T extends iFormBase = any, Ev extends FormEvents = any> extends Component<T, Ev> implements FieldGroup {
    inputs: Input[];
    constructor(i: T, inputs: (Input | falsy)[]);
    constructor(inputs: (Input | falsy)[]);
    view(): One;
    get isDef(): boolean;
    input<T extends Input>(key: PropertyKey): T;
    errors: AnyDic<Error[]>;
    setErrors(key: PropertyKey, errors?: Error[]): void;
    valid(omit?: bool, focus?: boolean): boolean;
    focus(): this;
    fill(value: Dic, setAsDefault?: bool): this;
    reset(...fields: PropertyKey[]): this;
    /**
     * get value of form
     * @param edited se true only return fields that heve a value
     * @param req se true fields required with default value will be returned too
     */
    data(edited?: bool, req?: bool): Dic<any>;
    formData(edited?: bool, required?: bool): FormData;
}
export declare function dataAsync(form: FormBase, edited?: bool, req?: bool): Promise<Dic<any>>;
export declare const onOffHide: (e: G, isOff: bool) => G<HTMLElement>;
export declare const onOffDisable: (e: G, isOff: bool) => G<HTMLElement>;
/** */
export interface iForm extends iFormBase {
    errorDiv?: G;
    outline?: bool;
    bots?: Bot<Form>[];
    labelSz?: int;
}
export declare class Form extends FormBase<iForm> {
    errDiv: G;
    constructor(i: iForm, inputs: (Input | falsy)[]);
    constructor(inputs: (Input | falsy)[]);
    addInput(input: Input): void;
    view(): G<HTMLElement | HTMLObjectElement | HTMLButtonElement | HTMLMeterElement | HTMLTextAreaElement | HTMLStyleElement | HTMLProgressElement | HTMLTableElement | HTMLEmbedElement | HTMLPreElement | HTMLTableCaptionElement | HTMLMenuElement | HTMLMapElement | HTMLInputElement | HTMLSelectElement | HTMLAnchorElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBodyElement | HTMLBRElement | HTMLCanvasElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDivElement | HTMLDListElement | HTMLFieldSetElement | HTMLFormElement | HTMLHeadingElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLLabelElement | HTMLLegendElement | HTMLLIElement | HTMLLinkElement | HTMLMetaElement | HTMLOListElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLParagraphElement | HTMLPictureElement | HTMLScriptElement | HTMLSlotElement | HTMLSourceElement | HTMLSpanElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTemplateElement | HTMLTimeElement | HTMLTitleElement | HTMLTableRowElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement>;
    setErrors(key: PropertyKey, errors?: Error[]): void;
}
/**modal form */
export declare function mdform<T = Dic>(hd: Label, form: Input[] | FormBase, cb: (dt: Dic, form: FormBase) => Task<T | void>, ok?: G<HTMLButtonElement>, noCancel?: bool, sz?: Size): Promise<T>;
export interface Field {
    name?: PropertyKey;
    info?: str;
    req?: bool;
    outline?: bool;
    text?: Label;
    tip?: any;
    off?: bool;
}
export declare function field(bd: One, i: Field, form?: Form, sz?: number): G<HTMLDivElement>;
export declare function fieldGroup(title: Label, inputs: Input[], form?: Form, sz?: int): G<HTMLFieldSetElement>;
export declare function expand(form: Form, ...main: PropertyKey[]): void;
export declare function valid(e: HTMLFormElement): boolean;
export declare function value(e: HTMLFormElement): Dic<Primitive | Date>;
export interface iInput<V = unknown> extends Field {
    value?: V;
    def?: V;
    submit?(data: Dic): any;
}
export declare abstract class Input<V = unknown, P extends iInput<V> = iInput<V>, Ev extends AnyDic<any[]> = {}> extends Component<P, Ev> {
    #private;
    constructor(p: P);
    get name(): PropertyKey;
    get value(): V;
    set value(v: V);
    fill?(src: AnyDic, setAsDefault?: bool): void;
    get def(): V;
    isDef(value?: V, def?: V): boolean;
    isNull(value?: V): boolean;
    visited?: bool;
    observeVisited(handler: (input: Input) => any): void;
    /**show or hide errors */
    error(state: bool): this;
    invalid(value: V, omit?: bool, focus?: bool): Error[];
    validate(value: V, omit?: bool, focus?: bool): Error[];
    field(form?: Form, sz?: int): G<HTMLElement>;
    submit(this: this, data: AnyDic, edited?: bool, req?: bool): any;
    /**null value used for clear method */
    get null(): V;
}
export interface Input<V, P extends iInput<V>, Ev extends AnyDic<any[]>> {
    form?: FormBase;
}
export interface TextInValidation {
    pattern?: RegExp;
    min?: int;
    max?: int;
}
export interface iTextIn extends iInput<str>, TextInValidation {
    input?: TextInputTp | "ta";
    /**place holder */
    ph?: str;
}
export declare class TextIn extends Input<str, iTextIn, {
    input: [str];
}> {
    view(): G<HTMLTextAreaElement | HTMLInputElement>;
    validate(value: string): Error[];
}
/**text input */
export declare const textIn: (k: str, req?: bool, input?: TextInputTp | "ta") => TextIn;
export interface NumberFmt {
    min?: int;
    max?: int;
    /**open min */
    omin?: int;
    /**open max */
    omax?: int;
    integer?: bool;
}
export type iNumbIn = iInput<int> & NumberFmt & {
    unsigned?: bool;
    unit?: str;
    /**place holder */
    ph?: str;
};
export declare class NumbIn extends Input<float, iNumbIn> {
    view(): G<HTMLSpanElement>;
    validate(value: number): Error[];
    focus(): this;
}
export declare const numbIn: (k: str, req?: bool, text?: str, unit?: str) => NumbIn;
export declare function validateNumber(p: NumberFmt & iInput<int>, value: int): Error[];
export declare const enum CBFmt {
    yesNo = "y",
    checkbox = "c",
    switch = "s"
}
export interface iCheckIn extends iInput<bool> {
    fmt?: CBFmt;
    clear?: bool;
    /**place holder */
    ph?: str;
}
export declare class CheckIn extends Input<bool, iCheckIn> {
    view(): G<HTMLDivElement>;
}
export interface iTimeIn extends iInput<str> {
    min?: str | int;
    max?: str | int;
    /**place holder */
    ph?: str;
}
export declare class TimeIn extends Input<str, iTimeIn> {
    view(): G<HTMLInputElement>;
}
export declare class DateIn extends Input<str, iTimeIn> {
    view(): G<HTMLInputElement>;
    get def(): string;
    fill(src: AnyDic<any>, setAsDefault?: boolean): void;
}
export declare class MonthIn extends Input<str, iTimeIn> {
    view(): G<HTMLInputElement>;
    get def(): string;
    submit(data: AnyDic): void;
}
/**date & time input */
export declare class DTIn extends Input<str, iTimeIn> {
    view(): G<HTMLInputElement>;
}
export type iSelectIn<T extends Dic, K extends keyof T = any> = iInput<T[K]> & iSingleSelectBase<T> & {
    /**menu width will change acord to content */
    fluid?: boolean;
};
export declare class SelectIn<T extends Dic = Dic, K extends keyof T = any> extends Input<T[K], iSelectIn<T, K>, {
    open: [bool];
}> implements SingleSelectBase<K, T> {
    options: L<T, T[K]>;
    get active(): T;
    constructor(i: iSelectIn<T, K>, options?: Alias<T, T[K]>, key?: K);
    get value(): T[K];
    set value(v: T[K]);
    view(): any;
    option(k: T[K]): T;
}
export interface iMobSelect<T = Dic> extends iInput<Key> {
    item?(v: T): any;
}
export declare class MobSelectIn<T = Dic, K extends keyof T = any> extends Input<Key, iMobSelect<T>, {
    open: [bool];
}> {
    private options;
    private okey?;
    constructor(i: iMobSelect<T>, options: Alias<T>, okey?: K);
    view(): G<HTMLSelectElement>;
}
export type RadioOption = [key: Key, text?: any, icon?: Icon];
export interface iRadioIn extends iInput<Key> {
    options?: (RadioOption | str)[];
    src?: str;
    clear?: bool;
    layout?: 'wrap' | 'column';
}
export declare class RadioIn extends Input<Key, iRadioIn> {
    view(): G<HTMLSpanElement>;
}
export interface iChecklistIn extends iInput<Key[]> {
    options?: (RadioOption | str)[];
}
export declare class ChecklistIn extends Input<Key[], iChecklistIn> {
    view(): G<HTMLSpanElement>;
    get def(): any[];
}
interface iPWIn extends iInput<str> {
    /**auto complete */
    auto?: str;
    capitalCase?: int;
    lowerCase?: int;
    spacialDigit?: int;
    /**place holder */
    ph?: str;
}
/**password input */
export declare class PWIn extends Input<str, iPWIn> {
    view(): G<HTMLInputElement>;
    validate(value: string): Error[];
}
export interface iCustomIn<V, O> extends iInput<V> {
    submit?: CustomIn<V, O>["submit"];
    isDef?: CustomIn<V, O>["isDef"];
    validate?: CustomIn<V, O>["validate"];
}
export declare class CustomIn<V = any, O = {}> extends Input<V> {
    view?: (this: CustomIn<V> & O) => One;
    constructor(i: iCustomIn<V, O>, view?: (this: CustomIn<V> & O) => One);
}
interface iCompostIn extends iInput<Dic> {
    sub?: bool | "array";
    bots?: Bot<CompostIn>[];
    labelSz?: int;
}
export declare class CompostIn extends Input<Dic, iCompostIn> implements FieldGroup {
    #private;
    get form(): FormBase<any, any>;
    set form(v: FormBase<any, any>);
    constructor(i: iCompostIn, inputs?: Input<any>[]);
    inputs?: Input<any>[];
    get def(): Dic<any>;
    get value(): Dic;
    set value(v: Dic);
    view(): G;
    fill(value: Dic, setAsDefault?: bool): void;
    validate(_v: Dic, omit: bool, focus?: bool): Error[];
    focus(): this;
    submit(data: Dic, edited: bool, req: bool): void;
    input(key: PropertyKey): Input<any, iInput<any>, {}>;
    isDef(v?: Dic<any>, def?: Dic<any>): boolean;
}
export declare class GroupIn extends CompostIn {
    view(): G;
    field(form?: Form): G<HTMLElement>;
    observeVisited(handler: (input: Input) => any): void;
}
export {};
