diff --git a/src/lib/_misc/_utils.ts b/src/lib/_misc/_utils.ts new file mode 100644 index 0000000..6ceabdf --- /dev/null +++ b/src/lib/_misc/_utils.ts @@ -0,0 +1,48 @@ +export type EventHandlers = Pick< + Input, + { + [K in keyof Input]: K extends `on${infer A}` + ? keyof Input & `on${A}` + : never; + }[keyof Input] +>; + +export type ExtractMap< + Obj extends Record, + Key extends Exclude = never, +> = Obj['*'][keyof Obj['*']] & + (Obj[Key] extends never ? '' : Obj[Key][keyof Obj[Key]]); + +export type ExtractString< + Obj extends Record, + Key extends keyof Obj, +> = Obj[Key][keyof Obj[Key]]; + +export type HTMLElementsMap = Record< + '*' | keyof HTMLElementTagNameMap, + readonly string[] +>; + +export type IfThen = (() => T extends A + ? 1 + : 2) extends () => T extends B ? 1 : 2 + ? Then + : Else; + +export type WritableProps = { + [Prop in keyof Obj]: IfThen< + { + [K in Prop]: Obj[Prop]; + }, + { -readonly [K in Prop]: Obj[Prop] }, + Prop + >; +}[keyof Obj]; + +export type FunctionProps = { + [Prop in keyof Obj]: Obj[Prop] extends Function ? Prop : never; +}[keyof Obj]; + +export type EventProps = { + [K in keyof Obj]: K extends `on${infer A}` ? keyof Obj & `on${A}` : never; +}[keyof Obj]; diff --git a/src/lib/_misc/html-element-attributes.ts b/src/lib/_misc/html-element-attributes.ts new file mode 100644 index 0000000..079746d --- /dev/null +++ b/src/lib/_misc/html-element-attributes.ts @@ -0,0 +1,152 @@ +import { HTMLElementsMap } from '../types/_utils'; + +const htmlElementAttributes: HTMLElementsMap = { + '*': [ + 'accesskey', + 'autocapitalize', + 'autofocus', + 'class', + 'contenteditable', + 'data-*', + 'dir', + 'draggable', + 'enterkeyhint', + 'hidden', + 'id', + 'inputmode', + 'is', + 'itemid', + 'itemprop', + 'itemref', + 'itemscope', + 'itemtype', + 'lang', + 'nonce', + 'part', + 'slot', + 'spellcheck', + 'style', + 'tabindex', + 'title', + 'translate', + ], + a: [], + abbr: [], + address: [], + area: [], + article: [], + aside: [], + audio: [], + b: [], + base: [], + bdi: [], + bdo: [], + blockquote: [], + body: [], + br: [], + button: [], + canvas: [], + caption: [], + cite: [], + code: [], + col: [], + colgroup: [], + data: [], + datalist: [], + dd: [], + del: [], + details: [], + dfn: [], + dialog: [], + dir: [], + div: [], + dl: [], + dt: [], + em: [], + embed: [], + fieldset: [], + figcaption: [], + figure: [], + font: [], + footer: [], + form: [], + frame: [], + frameset: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + head: [], + header: [], + hgroup: [], + hr: [], + html: [], + i: [], + iframe: [], + img: [], + input: [], + ins: [], + kbd: [], + label: [], + legend: [], + li: [], + link: [], + main: [], + map: [], + mark: [], + marquee: [], + menu: [], + meta: [], + meter: [], + nav: [], + noscript: [], + object: [], + ol: [], + optgroup: [], + option: [], + output: [], + p: [], + param: [], + picture: [], + pre: [], + progress: [], + q: [], + rp: [], + rt: [], + ruby: [], + s: [], + samp: [], + script: [], + section: [], + select: [], + slot: [], + small: [], + source: [], + span: [], + strong: [], + style: [], + sub: [], + summary: [], + sup: [], + table: [], + tbody: [], + td: [], + template: [], + textarea: [], + tfoot: [], + th: [], + thead: [], + time: [], + title: [], + tr: [], + track: [], + u: [], + ul: [], + var: [], + video: [], + wbr: [], +} as const; + +export default htmlElementAttributes; diff --git a/src/lib/_misc/html-element-events.ts b/src/lib/_misc/html-element-events.ts new file mode 100644 index 0000000..1e0bc16 --- /dev/null +++ b/src/lib/_misc/html-element-events.ts @@ -0,0 +1,207 @@ +import { + EventHandlers, + ExtractMap, + ExtractString, + HTMLElementsMap, +} from '../types/_utils'; + +type SpecificEventHandlers = Exclude< + keyof EventHandlers, + typeof htmlElementAttributes['*'][keyof typeof htmlElementAttributes['*']] +>; + +type input = Exclude< + keyof EventHandlers, + typeof htmlElementAttributes['*'][keyof typeof htmlElementAttributes['*']] +>; + +const htmlElementAttributes = { + '*': [ + 'onauxclick', + 'onbeforematch', + 'onblur', + 'oncancel', + 'oncanplay', + 'oncanplaythrough', + 'onchange', + 'onclick', + 'onclose', + 'oncontextlost', + 'oncontextmenu', + 'oncontextrestored', + 'oncopy', + 'oncuechange', + 'oncut', + 'ondblclick', + 'ondrag', + 'ondragend', + 'ondragenter', + 'ondragleave', + 'ondragover', + 'ondragstart', + 'ondrop', + 'ondurationchange', + 'onemptied', + 'onended', + 'onerror', + 'onfocus', + 'onformdata', + 'oninput', + 'oninvalid', + 'onkeydown', + 'onkeypress', + 'onkeyup', + 'onload', + 'onloadeddata', + 'onloadedmetadata', + 'onloadstart', + 'onmousedown', + 'onmouseenter', + 'onmouseleave', + 'onmousemove', + 'onmouseout', + 'onmouseover', + 'onmouseup', + 'onpaste', + 'onpause', + 'onplay', + 'onplaying', + 'onprogress', + 'onratechange', + 'onreset', + 'onresize', + 'onscroll', + 'onsecuritypolicyviolation', + 'onseeked', + 'onseeking', + 'onselect', + 'onslotchange', + 'onstalled', + 'onsubmit', + 'onsuspend', + 'ontimeupdate', + 'ontoggle', + 'onvolumechange', + 'onwaiting', + 'onwheel', + ], + a: [], + abbr: [], + address: [], + area: [], + article: [], + aside: [], + audio: [], + b: [], + base: [], + bdi: [], + bdo: [], + blockquote: [], + body: [], + br: [], + button: [], + canvas: [], + caption: [], + cite: [], + code: [], + col: [], + colgroup: [], + data: [], + datalist: [], + dd: [], + del: [], + details: [], + dfn: [], + dialog: [], + dir: [], + div: [], + dl: [], + dt: [], + em: [], + embed: [], + fieldset: [], + figcaption: [], + figure: [], + font: [], + footer: [], + form: [], + frame: [], + frameset: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + head: [], + header: [], + hgroup: [], + hr: [], + html: [], + i: [], + iframe: [], + img: [], + input: [], + ins: [], + kbd: [], + label: [], + legend: [], + li: [], + link: [], + main: [], + map: [], + mark: [], + marquee: [], + menu: [], + meta: [], + meter: [], + nav: [], + noscript: [], + object: [], + ol: [], + optgroup: [], + option: [], + output: [], + p: [], + param: [], + picture: [], + pre: [], + progress: [], + q: [], + rp: [], + rt: [], + ruby: [], + s: [], + samp: [], + script: [], + section: [], + select: [], + slot: [], + small: [], + source: [], + span: [], + strong: [], + style: [], + sub: [], + summary: [], + sup: [], + table: [], + tbody: [], + td: [], + template: [], + textarea: [], + tfoot: [], + th: [], + thead: [], + time: [], + title: [], + tr: [], + track: [], + u: [], + ul: [], + var: [], + video: [], + wbr: [], +} as const; + +export default htmlElementAttributes; diff --git a/src/lib/_misc/html-elements-map.ts b/src/lib/_misc/html-elements-map.ts new file mode 100644 index 0000000..8d9c8e9 --- /dev/null +++ b/src/lib/_misc/html-elements-map.ts @@ -0,0 +1,124 @@ +import { HTMLElementsMap } from '../types/_utils'; + +const htmlElementsMap: HTMLElementsMap = { + '*': [], + a: [], + abbr: [], + address: [], + area: [], + article: [], + aside: [], + audio: [], + b: [], + base: [], + bdi: [], + bdo: [], + blockquote: [], + body: [], + br: [], + button: [], + canvas: [], + caption: [], + cite: [], + code: [], + col: [], + colgroup: [], + data: [], + datalist: [], + dd: [], + del: [], + details: [], + dfn: [], + dialog: [], + dir: [], + div: [], + dl: [], + dt: [], + em: [], + embed: [], + fieldset: [], + figcaption: [], + figure: [], + font: [], + footer: [], + form: [], + frame: [], + frameset: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + head: [], + header: [], + hgroup: [], + hr: [], + html: [], + i: [], + iframe: [], + img: [], + input: [], + ins: [], + kbd: [], + label: [], + legend: [], + li: [], + link: [], + main: [], + map: [], + mark: [], + marquee: [], + menu: [], + meta: [], + meter: [], + nav: [], + noscript: [], + object: [], + ol: [], + optgroup: [], + option: [], + output: [], + p: [], + param: [], + picture: [], + pre: [], + progress: [], + q: [], + rp: [], + rt: [], + ruby: [], + s: [], + samp: [], + script: [], + section: [], + select: [], + slot: [], + small: [], + source: [], + span: [], + strong: [], + style: [], + sub: [], + summary: [], + sup: [], + table: [], + tbody: [], + td: [], + template: [], + textarea: [], + tfoot: [], + th: [], + thead: [], + time: [], + title: [], + tr: [], + track: [], + u: [], + ul: [], + var: [], + video: [], + wbr: [], +} as const; + +export default htmlElementsMap; diff --git a/src/lib/_misc/mutable-elements.ts b/src/lib/_misc/mutable-elements.ts new file mode 100644 index 0000000..3b29211 --- /dev/null +++ b/src/lib/_misc/mutable-elements.ts @@ -0,0 +1,192 @@ +import propProcessors from '../propProcessors'; +import { FunctionProps, WritableProps } from './_utils'; + +type Processors = ReturnType; +type ProcessorTypes = { + [Key in keyof Processors]: Parameters[0]; +}; + +type ExtractedHTMLProps = Pick< + E, + Exclude, FunctionProps | keyof Processors> +> & + ProcessorTypes & + GlobalEventHandlers; + +type Element = ExtractedHTMLProps; +type AnchorElement = ExtractedHTMLProps; +type AreaElement = ExtractedHTMLProps; +type AudioElement = ExtractedHTMLProps; +type BaseElement = ExtractedHTMLProps; +type QuoteElement = ExtractedHTMLProps; +type BodyElement = ExtractedHTMLProps; +type BRElement = ExtractedHTMLProps; +type CanvasElement = ExtractedHTMLProps; +type ButtonElement = ExtractedHTMLProps; +type TableCaptionElement = ExtractedHTMLProps; +type TableColElement = ExtractedHTMLProps; +type DataElement = ExtractedHTMLProps; +type DataListElement = ExtractedHTMLProps; +type ModElement = ExtractedHTMLProps; +type DetailsElement = ExtractedHTMLProps; +type DivElement = ExtractedHTMLProps; +type DListElement = ExtractedHTMLProps; +type EmbedElement = ExtractedHTMLProps; +type FieldSetElement = ExtractedHTMLProps; +type FormElement = ExtractedHTMLProps; +type HeadingElement = ExtractedHTMLProps; +type HeadElement = ExtractedHTMLProps; +type HRElement = ExtractedHTMLProps; +type IFrameElement = ExtractedHTMLProps; +type ImageElement = ExtractedHTMLProps; +type InputElement = ExtractedHTMLProps; +type LabelElement = ExtractedHTMLProps; +type LegendElement = ExtractedHTMLProps; +type ListItemElement = ExtractedHTMLProps; +type LinkElement = ExtractedHTMLProps; +type MapElement = ExtractedHTMLProps; +type MenuElement = ExtractedHTMLProps; +type MetaElement = ExtractedHTMLProps; +type MeterElement = ExtractedHTMLProps; +type ObjectElement = ExtractedHTMLProps; +type OListElement = ExtractedHTMLProps; +type OptGroupElement = ExtractedHTMLProps; +type OptionElement = ExtractedHTMLProps; +type OutputElement = ExtractedHTMLProps; +type ParagraphElement = ExtractedHTMLProps; +type ParamElement = ExtractedHTMLProps; +type PictureElement = ExtractedHTMLProps; +type PreElement = ExtractedHTMLProps; +type ProgressElement = ExtractedHTMLProps; +type ScriptElement = ExtractedHTMLProps; +type SelectElement = ExtractedHTMLProps; +type SlotElement = ExtractedHTMLProps; +type SourceElement = ExtractedHTMLProps; +type SpanElement = ExtractedHTMLProps; +type StyleElement = ExtractedHTMLProps; +type TableElement = ExtractedHTMLProps; +type TableSectionElement = ExtractedHTMLProps; +type TableCellElement = ExtractedHTMLProps; +type TemplateElement = ExtractedHTMLProps; +type TextAreaElement = ExtractedHTMLProps; +type TimeElement = ExtractedHTMLProps; +type TitleElement = ExtractedHTMLProps; +type TableRowElement = ExtractedHTMLProps; +type TrackElement = ExtractedHTMLProps; +type UListElement = ExtractedHTMLProps; +type VideoElement = ExtractedHTMLProps; + +type MutableElements = { + a: AnchorElement; + abbr: Element; + address: Element; + area: AreaElement; + article: Element; + aside: Element; + audio: AudioElement; + b: Element; + base: BaseElement; + bdi: Element; + bdo: Element; + blockquote: QuoteElement; + body: BodyElement; + br: BRElement; + button: ButtonElement; + canvas: CanvasElement; + caption: TableCaptionElement; + cite: Element; + code: Element; + col: TableColElement; + colgroup: TableColElement; + data: DataElement; + datalist: DataListElement; + dd: Element; + del: ModElement; + details: DetailsElement; + dfn: Element; + div: DivElement; + dl: DListElement; + dt: Element; + em: Element; + embed: EmbedElement; + fieldset: FieldSetElement; + figcaption: Element; + figure: Element; + footer: Element; + form: FormElement; + h1: HeadingElement; + h2: HeadingElement; + h3: HeadingElement; + h4: HeadingElement; + h5: HeadingElement; + h6: HeadingElement; + head: HeadElement; + header: Element; + hgroup: Element; + hr: HRElement; + i: Element; + iframe: IFrameElement; + img: ImageElement; + input: InputElement; + ins: ModElement; + kbd: Element; + label: LabelElement; + legend: LegendElement; + li: ListItemElement; + link: LinkElement; + main: Element; + map: MapElement; + mark: Element; + menu: MenuElement; + meta: MetaElement; + meter: MeterElement; + nav: Element; + noscript: Element; + object: ObjectElement; + ol: OListElement; + optgroup: OptGroupElement; + option: OptionElement; + output: OutputElement; + p: ParagraphElement; + param: ParamElement; + picture: PictureElement; + pre: PreElement; + progress: ProgressElement; + q: QuoteElement; + rp: Element; + rt: Element; + ruby: Element; + s: Element; + samp: Element; + script: ScriptElement; + section: Element; + select: SelectElement; + slot: SlotElement; + small: Element; + source: SourceElement; + span: SpanElement; + strong: Element; + style: StyleElement; + sub: Element; + summary: Element; + sup: Element; + table: TableElement; + tbody: TableSectionElement; + td: TableCellElement; + template: TemplateElement; + textarea: TextAreaElement; + tfoot: TableSectionElement; + th: TableCellElement; + thead: TableSectionElement; + time: TimeElement; + title: TitleElement; + tr: TableRowElement; + track: TrackElement; + u: Element; + ul: UListElement; + var: Element; + video: VideoElement; + wbr: Element; +}; + +export default MutableElements; diff --git a/src/lib/_misc/props.ts b/src/lib/_misc/props.ts new file mode 100644 index 0000000..4ead016 --- /dev/null +++ b/src/lib/_misc/props.ts @@ -0,0 +1,35 @@ +import { MaybeMutable } from '@mutablejs/core'; +import propProcessors from '../propProcessors'; +import { WritableProps } from './_utils'; + +type Processors = ReturnType; +type ProcessorTypes = { + [Key in keyof Processors]?: MaybeMutable[0]>; +}; + +type FunctionProps = { + [Prop in keyof HTMLElementTagNameMap[Tag]]: HTMLElementTagNameMap[Tag][Prop] extends Function + ? Prop + : never; +}[keyof HTMLElementTagNameMap[Tag]]; + +type EventProps = { + [K in keyof HTMLElementTagNameMap[Tag]]: K extends `on${infer A}` + ? keyof HTMLElementTagNameMap[Tag] & `on${A}` + : never; +}[keyof HTMLElementTagNameMap[Tag]]; + +type _WritableProps = Exclude< + WritableProps, + Exclude, EventProps> +>; + +type HTMLElementProps = { + [Tag in keyof HTMLElementTagNameMap]: { + [Prop in _WritableProps]?: MaybeMutable< + HTMLElementTagNameMap[Tag][Prop] + >; + } & ProcessorTypes; +}; + +export default HTMLElementProps; diff --git a/src/lib/_misc/tb-discarded.ts b/src/lib/_misc/tb-discarded.ts new file mode 100644 index 0000000..2608ac1 --- /dev/null +++ b/src/lib/_misc/tb-discarded.ts @@ -0,0 +1,66 @@ +const ElementEventHandlers = { + '*': [ + 'onabort', + 'onautocomplete', + 'onautocompleteerror', + 'onblur', + 'oncancel', + 'oncanplay', + 'oncanplaythrough', + 'onchange', + 'onclick', + 'onclose', + 'oncontextmenu', + 'oncuechange', + 'ondblclick', + 'ondrag', + 'ondragend', + 'ondragenter', + 'ondragleave', + 'ondragover', + 'ondragstart', + 'ondrop', + 'ondurationchange', + 'onemptied', + 'onended', + 'onerror', + 'onfocus', + 'oninput', + 'oninvalid', + 'onkeydown', + 'onkeypress', + 'onkeyup', + 'onload', + 'onloadeddata', + 'onloadedmetadata', + 'onloadstart', + 'onmousedown', + 'onmouseenter', + 'onmouseleave', + 'onmousemove', + 'onmouseout', + 'onmouseover', + 'onmouseup', + 'onmousewheel', + 'onpause', + 'onplay', + 'onplaying', + 'onprogress', + 'onratechange', + 'onreset', + 'onresize', + 'onscroll', + 'onseeked', + 'onseeking', + 'onselect', + 'onshow', + 'onsort', + 'onstalled', + 'onsubmit', + 'onsuspend', + 'ontimeupdate', + 'ontoggle', + 'onvolumechange', + 'onwaiting', + ], +} as const;