import { CreateHooks } from "./internal/hooks.js"; import { Sheet } from "./css.js"; import { DOMFormElement, DOMFormElements } from "./dom-html.js"; import { SVGProperties } from "./dom-svg.js"; import { InferAttrsFromProps, InferProps, InferPropsWithEvents, SchemaComponentConfig, SchemaRecord } from "./schema.js"; import { VNodeKeyTypes } from "./vnode.js"; export type Nullable = NonNullable | undefined | null; export type PropsNullable = { [I in keyof Data]?: Nullable; }; export interface DOMInternalProperties { shadowDom?: boolean | Partial; staticNode?: boolean; cloneNode?: boolean; key?: any; children?: any; } type DOMCustomTag = Omit & Props; type DOMRefValue = SchemaRecord | ((target: Target) => any); type DOMRef = { ref?: DOMRefValue; }; interface DOMGenericProperties extends DOMInternalProperties { style?: string | Partial | object; class?: string; id?: string; slot?: string; part?: string; is?: string; tabindex?: string | number; role?: string; width?: string | number; height?: string | number; } type DOMCleanKeys = | keyof DOMGenericProperties | `add${string}` | `get${string}` | `set${string}` | `has${string}` | `matches${string}` | `remove${string}` | `replace${string}` | `querySelector${string}` | `offset${string}` | `append${string}` | `request${string}` | `scroll${string}` | `is${string}` | `toggle${string}` | `webkit${string}` | `insert${string}` | `client${string}` | `child${string}` | `${string}_${string}` | `${string}HTML` | `${string}Child` | `${string}Validity` | `${string}Capture` | `${string}ElementSibling` | "classList" | "attributes" | "normalize" | "closest" | "localName" | "contains" | "animate" | "attachShadow" | "outerText" | "attachInternals" | "click" | "tagName" | "focus" | "submit" | "accessKeyLabel" | "elements" | "isContentEditable" | "innerText" | "prepend" | "namespaceURI" | "blur" | "dataset" | "shadowRoot" | keyof Omit; type HTMLTags = HTMLElementTagNameMap; type SVGTags = Omit; type CheckEvent = CurrentEvent extends Event ? True : never; export interface DOMListener extends AddEventListenerOptions { (event: E extends Element ? DOMEvent : E): any; } /** * @todo Rename Handler to Listener */ export type DOMEventHandlerKeys

= { [I in keyof P]-?: NonNullable extends DOMEventHandlerValue ? CheckEvent : P[I] extends { value: DOMEventHandlerValue } ? CheckEvent : never; }[keyof P]; export interface DOMEventHandlerType extends FunctionConstructor {} export interface DOMEventHandlerValue { (event: CurrentEvent): any; } type DOMEventType = { [I in keyof "0" as `on${Type}`]: { type: DOMEventHandlerType; value: DOMEventHandlerValue; }; }; interface DOM$Attrs { [prop: `\$${string}`]: Nullable; } interface DOMUnknown { [prop: string]: any; } type DOMEventTarget = { [I in keyof CurrentEvent]: I extends "currentTarget" ? CurrentTarget : I extends "target" ? Target : CurrentEvent[I]; }; type DOMTarget< Target, CurrentEvent, Targets = Element | Node > = CurrentEvent extends { customTarget: infer EventTarget; } ? DOMTarget, EventTarget> : DOMEventTarget; type DOMGetEventBefore = Value extends DOMEventHandlerValue< infer Event > ? DOMEvent> : null; type DOMEvent = DOMTarget< DOMThis, CurrentEvent >; type DOMEventHandler = Handler extends ( ev: infer CurrentEvent ) => any ? CurrentEvent extends Event ? (ev: DOMEvent) => any : Handler : Handler; type DOMEvents = { [Prop in keyof Target]?: Prop extends `on${string}` ? DOMEventHandler : Target[Prop]; }; type DOMCustomTarget = { customTarget: Target }; export type DOMTag = Props extends null ? PropsNullable< Omit, DOMCleanKeys> & DOMGenericProperties & DOMRef > & DOM$Attrs & DOMUnknown : PropsNullable< Props & Omit, keyof Props | DOMCleanKeys> & DOMGenericProperties & DOMRef > & DOM$Attrs & DOMUnknown; type S = keyof null; export type DOMTags = { [Tag in keyof HTMLTags]: Tag extends keyof HTMLMerge ? DOMTag : DOMTag; }; export type DOMThis = Element extends new ( ...args: any[] ) => infer This ? This : Element; export interface AtomicoElements { host: HTMLElement; } export interface DOMCustomTags { slot: HTMLSlotElement & { onslotchange: (event: Event & DOMCustomTarget) => void; assignNode: ChildNode; }; form: DOMFormElement & { onsubmit: ( event: SubmitEvent & DOMCustomTarget ) => any; onchange: (event: Event & DOMCustomTarget) => any; oninput: (event: Event & DOMCustomTarget) => any; }; input: DOMCustomTag< HTMLInputElement, { min: string | number; max: string | number; step: string | number; value: string | number; } >; } export type JSXElements = DOMTags & DOMTags & DOMTags; export type JSXProxy = { [I in keyof Props]?: I extends `on${string}` ? NonNullable extends DOMEventHandlerValue ? Nullable< ( ev: DOMEventTarget ) => any > : Props[I] : I extends "ref" ? DOMRefValue : Props[I]; }; export type JSXProps = T extends Atomico ? T extends { new (props: infer Props): any } ? Props : DOMTag : T extends keyof JSXElements ? JSXElements[T] : T extends string ? DOMTag : DOMTag>; export type DOMProps = Partial>>; export type AtomicoThisInternal = AtomicoThis & { _props: { [prop: string]: any }; _hooks: ReturnType; _ignoreAttr?: string | null; _umount?: () => void; shadowRoot?: { adoptedStyleSheets: CSSStyleSheet[]; }; constructor: { styles: Sheet[]; form: boolean; }; }; export type AtomicoThis = Props & DOMThis & { update(): Promise; updated: Promise; mounted: Promise; unmounted: Promise; readonly symbolId: unique symbol; }; /** * Type to create a wrapper to instantiate an element with type validation in JSX * @example * ```tsx * const [ Template ] = useSlot< JSX<{value: number} >>(ref); * *