import { XIN_PATH, XIN_VALUE, XIN_SET, XIN_OBSERVE, XIN_BIND } from './metadata'; import { XinStyleRule } from './css-types'; export type AnyFunction = (...args: any[]) => any | Promise; export type XinScalar = string | boolean | number | symbol | AnyFunction; export type XinArray = any[]; export interface XinObject { [key: string | number | symbol]: any; } export type XinProxyTarget = XinObject | XinArray; export type XinValue = XinObject | XinArray | XinScalar | null | undefined; type ProxyObserveFunc = ((path: string) => void); type ProxyBindFunc = (element: T, binding: XinBinding, options?: XinObject) => VoidFunction; export interface XinProps { [XIN_PATH]: string; [XIN_VALUE]: T; [XIN_SET]: (value: T) => T; [XIN_OBSERVE]: ProxyObserveFunc; [XIN_BIND]: ProxyBindFunc; } export type BoxedProxy = T extends Array ? Array> : T extends Function ? T & XinProps : T extends object ? { [K in keyof T]: BoxedProxy; } : T extends string ? String & XinProps : T extends number ? Number & XinProps : T extends boolean ? Boolean & XinProps : T; export type Unboxed = T extends String ? string : T extends Number ? number : T extends Boolean ? boolean : T; export type XinProxy = T extends Array ? Array> : T extends Function ? T : T extends object ? { [K in keyof T]: T[K] extends object ? XinProxy : T[K]; } : T; export type XinProxyObject = XinProps & { [key: string]: XinProxyObject | XinProxyArray | XinObject | XinArray | XinScalar; }; export type XinProxyArray = XinProps<[]> & { [key: string]: XinProxyObject; } & (XinProxyObject[] | XinScalar[]); export type XinTouchableType = string | XinProxy | BoxedProxy | String | Number | Boolean; export type EventType = keyof HTMLElementEventMap; export type XinEventHandler = ((evt: T & { target: E; }) => void) | ((evt: T & { target: E; }) => Promise) | string; export type XinBindingShortcut = XinTouchableType | XinBindingSpec; type _BooleanFunction = () => boolean; type _PathTestFunction = (path: string) => boolean | symbol; export type PathTestFunction = _BooleanFunction | _PathTestFunction; type OptionalSymbol = symbol | undefined; type _CallbackFunction = (() => void) | (() => OptionalSymbol); type _PathCallbackFunction = ((path: string) => void) | ((path: string) => OptionalSymbol); export type ObserverCallbackFunction = _PathCallbackFunction | _CallbackFunction; export interface XinBindingSpec { value: XinTouchableType | any; [key: string]: any; } export type XinBindingSetter = (element: T, value: any, options?: XinObject) => void; export type XinBindingGetter = (element: T, options?: XinObject) => any; export interface XinBinding { toDOM?: XinBindingSetter; fromDOM?: XinBindingGetter; } export interface XinInlineBinding { value: XinTouchableType; binding: XinBinding | XinBindingSetter | string; } export interface ElementProps { onClick?: XinEventHandler; onMousedown?: XinEventHandler; onMouseenter?: XinEventHandler; onMouseleave?: XinEventHandler; onMouseup?: XinEventHandler; onTouchstart?: XinEventHandler; onTouchmove?: XinEventHandler; onTouchend?: XinEventHandler; onTouchcancel?: XinEventHandler; onDragstart?: XinEventHandler; onDragover?: XinEventHandler; onDragend?: XinEventHandler; onDragenter?: XinEventHandler; onDragleave?: XinEventHandler; onInput?: XinEventHandler; onChange?: XinEventHandler; onSubmit?: XinEventHandler; onKeydown?: XinEventHandler; onKeyup?: XinEventHandler; bind?: XinInlineBinding; bindValue?: XinBindingShortcut; bindText?: XinBindingShortcut; bindList?: XinBindingShortcut; bindEnabled?: XinBindingShortcut; bindDisabled?: XinBindingShortcut; style?: XinStyleRule; class?: string; apply?: (element: Element) => void | Promise; [key: string]: any; } export interface StringMap { [key: string]: any; } export interface PartsMap { [key: string]: Element; } export type ValueElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement; export type ElementPart = Element | DocumentFragment | ElementProps | string | number; export type HTMLElementCreator = (...contents: ElementPart[]) => T; export type FragmentCreator = (...contents: ElementPart[]) => DocumentFragment; export type ElementCreator = (...contents: ElementPart[]) => T; export type ContentPart = Element | DocumentFragment | string; export type ContentType = ContentPart | ContentPart[]; export {};