import type { Fn, Predicate } from "@thi.ng/api";
import type { Attribs, FormAttribs, InputAttribs, InputCheckboxAttribs, InputFileAttribs, InputNumericAttribs, InputRadioAttribs, InputSubmitAttribs, InputTextAttribs, SelectAttribs, StringAttrib, TextAreaAttribs } from "@thi.ng/hiccup-html";
import type { ComponentLike } from "@thi.ng/rdom";
import type { ISubscriber, ISubscription } from "@thi.ng/rstream";
export interface CommonAttribs {
    wrapperAttribs: Partial<Attribs>;
    labelAttribs: Partial<Attribs>;
    descAttribs: Partial<Attribs>;
}
export interface FormItem {
    /**
     * Value/widget type identifier. Used by {@link compileForm} to delegate
     */
    type: string;
    /**
     * Attrib overrides for the actual input element.
     */
    attribs?: Partial<Attribs>;
}
export interface Form {
    type: "form";
    items: FormItem[];
    attribs?: Partial<FormAttribs>;
}
export interface Container extends FormItem {
    type: "container";
    items: FormItem[];
}
export interface Custom extends Pick<FormItem, "type"> {
    type: "custom";
    body: ComponentLike;
}
export interface Group extends FormItem {
    type: "group";
    items: FormItem[];
    label?: StringAttrib | false;
}
export interface Value extends FormItem, Partial<CommonAttribs> {
    id: string;
    name?: string;
    /**
     * If false, no `<label>` element will be generated for this control and the
     * {@link Value.desc} value will be unused.
     */
    label?: StringAttrib | false;
    desc?: any;
    required?: boolean;
    /**
     * If true, no input/change event handlers will be generated and the
     * `readonly` attribute will be set on the input DOM element.
     */
    readonly?: boolean;
    attribs?: Partial<InputAttribs>;
}
export interface HiddenValue extends Omit<FormItem, "attribs"> {
    id?: string;
    name: string;
    value: StringAttrib;
}
export interface WithPresets<T> {
    /**
     * Array of possible preset values.
     */
    list?: T[];
}
export interface Num extends Value, WithPresets<number> {
    type: "num";
    min?: number;
    max?: number;
    placeholder?: StringAttrib;
    size?: number;
    step?: number | "any";
    value?: ISubscription<number, number>;
    attribs?: Partial<InputNumericAttribs>;
}
export interface Range extends Omit<Num, "type" | "placeholder" | "size"> {
    type: "range";
    vlabel?: boolean | number | Fn<number, string>;
}
export interface Str extends Value, WithPresets<string> {
    type: "str";
    min?: number;
    max?: number;
    pattern?: string | RegExp | Predicate<string>;
    placeholder?: StringAttrib;
    size?: number;
    value?: ISubscription<string, string>;
    attribs?: Partial<InputTextAttribs>;
}
export interface Email extends Omit<Str, "type"> {
    type: "email";
    autocomplete?: boolean;
}
export interface Phone extends Omit<Str, "type"> {
    type: "tel";
    autocomplete?: boolean;
}
export interface UrlVal extends Omit<Str, "type"> {
    type: "url";
}
export interface Password extends Omit<Str, "type"> {
    type: "password";
    autocomplete?: boolean;
}
export interface Text extends Value {
    type: "text";
    cols?: number;
    rows?: number;
    placeholder?: StringAttrib;
    value?: ISubscription<string, string>;
    attribs?: Partial<TextAreaAttribs>;
}
export interface Color extends Value, WithPresets<string> {
    type: "color";
    value?: ISubscription<string, string>;
}
export interface DateTime extends Value, WithPresets<string> {
    type: "dateTime";
    min?: string;
    max?: string;
    step?: number;
    value?: ISubscription<string, string>;
}
export interface DateVal extends Omit<DateTime, "type"> {
    type: "date";
}
export interface Time extends Omit<DateTime, "type"> {
    type: "time";
}
export interface Week extends Omit<DateTime, "type" | "list"> {
    type: "week";
}
export interface Month extends Omit<DateTime, "type" | "list"> {
    type: "month";
}
export interface Select<T> extends Value {
    items: (T | SelectItem<T> | SelectItemGroup<T>)[];
    value?: ISubscription<T, T>;
    attribs?: Partial<Omit<SelectAttribs, "multiple">>;
}
export interface SelectItemGroup<T> {
    name: string;
    items: (T | SelectItem<T>)[];
}
export interface SelectItem<T> {
    value: T;
    label?: string;
    desc?: string;
}
export interface SelectStr<T extends string = string> extends Select<T> {
    type: "selectStr";
}
export interface SelectNum<T extends number = number> extends Select<T> {
    type: "selectNum";
}
export interface MultiSelect<T> extends Value {
    items: (T | SelectItem<T> | SelectItemGroup<T>)[];
    value?: ISubscription<T[], T[]>;
    size?: number;
    attribs?: Partial<Omit<SelectAttribs, "multiple">>;
}
export interface MultiSelectStr<T extends string = string> extends MultiSelect<T> {
    type: "multiSelectStr";
}
export interface MultiSelectNum<T extends number = number> extends MultiSelect<T> {
    type: "multiSelectNum";
}
export interface Toggle extends Value {
    type: "toggle";
    value?: ISubscription<boolean, boolean>;
    attribs?: Partial<InputCheckboxAttribs>;
}
export interface Trigger extends Value {
    type: "trigger";
    title: StringAttrib;
    value?: ISubscriber<boolean>;
}
export interface Submit extends Omit<Value, "required" | "readonly"> {
    type: "submit";
    title: StringAttrib;
    value?: ISubscriber<boolean>;
    attribs?: Partial<InputSubmitAttribs>;
}
export interface Reset extends Omit<Value, "required" | "readonly"> {
    type: "submit";
    title: StringAttrib;
    value?: ISubscriber<boolean>;
}
export interface Radio<T> extends Value {
    items: (T | SelectItem<T>)[];
    value?: ISubscription<T, T>;
    attribs?: Partial<InputRadioAttribs>;
}
export interface RadioNum extends Radio<number> {
    type: "radioNum";
}
export interface RadioStr extends Radio<string> {
    type: "radioStr";
}
export interface FileVal extends Value {
    type: "file";
    accept?: string[];
    capture?: InputFileAttribs["capture"];
    value?: ISubscriber<File>;
    attribs?: Partial<InputFileAttribs>;
}
export interface MultiFileVal extends Value {
    type: "multiFile";
    accept?: string[];
    value?: ISubscriber<FileList>;
    attribs?: Partial<InputFileAttribs>;
}
type KnownTypes = Color | Container | DateTime | DateVal | Email | FileVal | Group | Month | MultiFileVal | MultiSelectNum | MultiSelectStr | Num | Password | Phone | Range | SelectNum | SelectStr | Str | Text | Time | Toggle | Trigger | UrlVal | Week;
/**
 * Type specific attribute overrides
 */
export interface TypeAttribs extends Record<KnownTypes["type"], Partial<Attribs>> {
    form: Partial<FormAttribs>;
    /**
     * Attribs for {@link group} label elements
     */
    groupLabel: Partial<Attribs>;
    /**
     * Attribs for the actual {@link radio} `<input>` element
     */
    radio: Partial<InputRadioAttribs>;
    /**
     * Attribs for the outermost {@link radio} group wrapper element (incl. main
     * group label)
     */
    radioWrapper: Partial<Attribs>;
    /**
     * Attribs for the wrapper element only containing the {@link radio} items.
     */
    radioItems: Partial<Attribs>;
    /**
     * Attribs for the wrapper element of a single {@link radio} item (incl.
     * input element and its label)
     */
    radioItem: Partial<Attribs>;
    /**
     * Attribs for a single {@link radio} item's label
     */
    radioItemLabel: Partial<Attribs>;
    /**
     * Attribs for {@link range} label elements
     */
    rangeLabel: Partial<Attribs>;
    /**
     * Attribs for the wrapper element of a single {@link range} widget (incl.
     * input element and optional value label)
     */
    rangeWrapper: Partial<Attribs>;
    [id: string]: Partial<Attribs>;
}
export interface FormOpts extends CommonAttribs {
    /**
     * ID prefix to prepend for all {@link FormItem}s. Needed if the a form is
     * to used in multiple places at the same time.
     */
    prefix: string;
    /**
     * Type specific behavior options.
     */
    behaviors: Partial<BehaviorOpts>;
    /**
     * Type specific attrib overrides
     */
    typeAttribs: Partial<TypeAttribs>;
}
export interface BehaviorOpts {
    /**
     * If false, no label elements will be generated.
     *
     * @defaultValue true
     */
    labels: boolean;
    /**
     * If false, no `value` attributes and event handlers will be generated,
     * even if a `value` option has been specified.
     *
     * @defaultValue true
     */
    values: boolean;
    /**
     * Unless false, {@link range} widgets will emit `oninput` events, if false
     * only `onchange` events.
     *
     * @defaultValue true
     */
    rangeOnInput: boolean;
    /**
     * Unless false, {@link str}-like widgets will emit `oninput` events, if
     * false only `onchange` events.
     *
     * @defaultValue true
     */
    strOnInput: boolean;
    /**
     * Unless false, {@link text} elements will emit `oninput` events, if false
     * only `onchange` events.
     *
     * @defaultValue true
     */
    textOnInput: boolean;
    /**
     * If true, the label for individual radio items will come before the actual
     * input element. By default, the order is reversed.
     *
     * @defaultValue false
     */
    radioLabelBefore: boolean;
    /**
     * Number of fractional digits for range sliders.
     *
     * @defaultValue 2
     */
    rangeLabelFmt: number | Fn<number, string>;
    /**
     * If true, the label for toggle widgets will come before the actual
     * input element. By default, the order is reversed.
     *
     * @defaultValue false
     */
    toggleLabelBefore: boolean;
}
export {};
//# sourceMappingURL=api.d.ts.map