Created
December 10, 2023 06:46
-
-
Save guiseek/61dc21fda6a6400ef3cce3780b00e4b4 to your computer and use it in GitHub Desktop.
TSX
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {ElementType, TagsByType} from '../types' | |
const ns = { | |
html: 'http://www.w3.org/1999/xhtml', | |
svg: 'http://www.w3.org/2000/svg', | |
mathMl: 'http://www.w3.org/1998/Math/MathML', | |
} | |
export function createElement< | |
Type extends ElementType, | |
Tag extends TagsByType<Type> & string | |
>(type: Type, tag: Tag, options?: ElementCreationOptions) { | |
switch (type) { | |
case 'html': | |
return document.createElementNS(ns.html, tag, options) | |
case 'svg': | |
return document.createElementNS(ns.svg, tag, options) | |
case 'mathMl': | |
return document.createElementNS(ns.mathMl, tag, options) | |
default: | |
return document.createElement(tag, options) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Constructor, ElementByTag, ElementFn, Tags} from './types' | |
import {createElement, determineElementType} from './utilities' | |
export const create = <K extends Tags>( | |
tagOrFn: K | ElementFn<K> | Constructor<ElementByTag<K>>, | |
attrs: Partial<ElementByTag<K>>, | |
...nodes: Node[] | |
) => { | |
let component: Element | |
if (typeof tagOrFn === 'string') { | |
const elementType = determineElementType(tagOrFn) | |
component = createElement(elementType, tagOrFn) | |
} else { | |
try { | |
component = new (tagOrFn as Constructor<ElementByTag<K>>)(attrs) | |
} catch { | |
component = (tagOrFn as ElementFn<K>)(attrs) | |
} | |
} | |
component.append( | |
...nodes.flatMap((node) => | |
typeof node === 'string' ? new Text(node) : node | |
) | |
) | |
return Object.assign(component, attrs) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {ElementType} from '../types' | |
import {mathMl} from './math-ml' | |
import {html} from './html' | |
import {svg} from './svg' | |
export function determineElementType(tag: string): ElementType { | |
if (Object.keys(html).includes(tag)) return 'html' | |
if (Object.keys(svg).includes(tag)) return 'svg' | |
if (Object.keys(mathMl).includes(tag)) return 'mathMl' | |
return 'custom' | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const fragment = () => { | |
return new DocumentFragment(); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const html = { | |
a: HTMLAnchorElement, | |
abbr: HTMLElement, | |
address: HTMLElement, | |
area: HTMLAreaElement, | |
article: HTMLElement, | |
aside: HTMLElement, | |
audio: HTMLAudioElement, | |
b: HTMLElement, | |
base: HTMLBaseElement, | |
bdi: HTMLElement, | |
bdo: HTMLElement, | |
blockquote: HTMLQuoteElement, | |
body: HTMLBodyElement, | |
br: HTMLBRElement, | |
button: HTMLButtonElement, | |
canvas: HTMLCanvasElement, | |
caption: HTMLTableCaptionElement, | |
cite: HTMLElement, | |
code: HTMLElement, | |
col: HTMLTableColElement, | |
colgroup: HTMLTableColElement, | |
data: HTMLDataElement, | |
datalist: HTMLDataListElement, | |
dd: HTMLElement, | |
del: HTMLModElement, | |
details: HTMLDetailsElement, | |
dfn: HTMLElement, | |
dialog: HTMLDialogElement, | |
div: HTMLDivElement, | |
dl: HTMLDListElement, | |
dt: HTMLElement, | |
em: HTMLElement, | |
embed: HTMLEmbedElement, | |
fieldset: HTMLFieldSetElement, | |
figcaption: HTMLElement, | |
figure: HTMLElement, | |
footer: HTMLElement, | |
form: HTMLFormElement, | |
h1: HTMLHeadingElement, | |
h2: HTMLHeadingElement, | |
h3: HTMLHeadingElement, | |
h4: HTMLHeadingElement, | |
h5: HTMLHeadingElement, | |
h6: HTMLHeadingElement, | |
head: HTMLHeadElement, | |
header: HTMLElement, | |
hgroup: HTMLElement, | |
hr: HTMLHRElement, | |
html: HTMLHtmlElement, | |
i: HTMLElement, | |
iframe: HTMLIFrameElement, | |
img: HTMLImageElement, | |
input: HTMLInputElement, | |
ins: HTMLModElement, | |
kbd: HTMLElement, | |
label: HTMLLabelElement, | |
legend: HTMLLegendElement, | |
li: HTMLLIElement, | |
link: HTMLLinkElement, | |
main: HTMLElement, | |
map: HTMLMapElement, | |
mark: HTMLElement, | |
menu: HTMLMenuElement, | |
meta: HTMLMetaElement, | |
meter: HTMLMeterElement, | |
nav: HTMLElement, | |
noscript: HTMLElement, | |
object: HTMLObjectElement, | |
ol: HTMLOListElement, | |
optgroup: HTMLOptGroupElement, | |
option: HTMLOptionElement, | |
output: HTMLOutputElement, | |
p: HTMLParagraphElement, | |
picture: HTMLPictureElement, | |
pre: HTMLPreElement, | |
progress: HTMLProgressElement, | |
q: HTMLQuoteElement, | |
rp: HTMLElement, | |
rt: HTMLElement, | |
ruby: HTMLElement, | |
s: HTMLElement, | |
samp: HTMLElement, | |
script: HTMLScriptElement, | |
search: HTMLElement, | |
section: HTMLElement, | |
select: HTMLSelectElement, | |
slot: HTMLSlotElement, | |
small: HTMLElement, | |
source: HTMLSourceElement, | |
span: HTMLSpanElement, | |
strong: HTMLElement, | |
style: HTMLStyleElement, | |
sub: HTMLElement, | |
summary: HTMLElement, | |
sup: HTMLElement, | |
table: HTMLTableElement, | |
tbody: HTMLTableSectionElement, | |
td: HTMLTableCellElement, | |
template: HTMLTemplateElement, | |
textarea: HTMLTextAreaElement, | |
tfoot: HTMLTableSectionElement, | |
th: HTMLTableCellElement, | |
thead: HTMLTableSectionElement, | |
time: HTMLTimeElement, | |
title: HTMLTitleElement, | |
tr: HTMLTableRowElement, | |
track: HTMLTrackElement, | |
u: HTMLElement, | |
ul: HTMLUListElement, | |
var: HTMLElement, | |
video: HTMLVideoElement, | |
wbr: HTMLElement, | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const mathMl = { | |
annotation: MathMLElement, | |
"annotation-xml": MathMLElement, | |
maction: MathMLElement, | |
math: MathMLElement, | |
merror: MathMLElement, | |
mfrac: MathMLElement, | |
mi: MathMLElement, | |
mmultiscripts: MathMLElement, | |
mn: MathMLElement, | |
mo: MathMLElement, | |
mover: MathMLElement, | |
mpadded: MathMLElement, | |
mphantom: MathMLElement, | |
mprescripts: MathMLElement, | |
mroot: MathMLElement, | |
mrow: MathMLElement, | |
ms: MathMLElement, | |
mspace: MathMLElement, | |
msqrt: MathMLElement, | |
mstyle: MathMLElement, | |
msub: MathMLElement, | |
msubsup: MathMLElement, | |
msup: MathMLElement, | |
mtable: MathMLElement, | |
mtd: MathMLElement, | |
mtext: MathMLElement, | |
mtr: MathMLElement, | |
munder: MathMLElement, | |
munderover: MathMLElement, | |
semantics: MathMLElement, | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const svg = { | |
a: SVGAElement, | |
animate: SVGAnimateElement, | |
animateMotion: SVGAnimateMotionElement, | |
animateTransform: SVGAnimateTransformElement, | |
circle: SVGCircleElement, | |
clipPath: SVGClipPathElement, | |
defs: SVGDefsElement, | |
desc: SVGDescElement, | |
ellipse: SVGEllipseElement, | |
feBlend: SVGFEBlendElement, | |
feColorMatrix: SVGFEColorMatrixElement, | |
feComponentTransfer: SVGFEComponentTransferElement, | |
feComposite: SVGFECompositeElement, | |
feConvolveMatrix: SVGFEConvolveMatrixElement, | |
feDiffuseLighting: SVGFEDiffuseLightingElement, | |
feDisplacementMap: SVGFEDisplacementMapElement, | |
feDistantLight: SVGFEDistantLightElement, | |
feDropShadow: SVGFEDropShadowElement, | |
feFlood: SVGFEFloodElement, | |
feFuncA: SVGFEFuncAElement, | |
feFuncB: SVGFEFuncBElement, | |
feFuncG: SVGFEFuncGElement, | |
feFuncR: SVGFEFuncRElement, | |
feGaussianBlur: SVGFEGaussianBlurElement, | |
feImage: SVGFEImageElement, | |
feMerge: SVGFEMergeElement, | |
feMergeNode: SVGFEMergeNodeElement, | |
feMorphology: SVGFEMorphologyElement, | |
feOffset: SVGFEOffsetElement, | |
fePointLight: SVGFEPointLightElement, | |
feSpecularLighting: SVGFESpecularLightingElement, | |
feSpotLight: SVGFESpotLightElement, | |
feTile: SVGFETileElement, | |
feTurbulence: SVGFETurbulenceElement, | |
filter: SVGFilterElement, | |
foreignObject: SVGForeignObjectElement, | |
g: SVGGElement, | |
image: SVGImageElement, | |
line: SVGLineElement, | |
linearGradient: SVGLinearGradientElement, | |
marker: SVGMarkerElement, | |
mask: SVGMaskElement, | |
metadata: SVGMetadataElement, | |
mpath: SVGMPathElement, | |
path: SVGPathElement, | |
pattern: SVGPatternElement, | |
polygon: SVGPolygonElement, | |
polyline: SVGPolylineElement, | |
radialGradient: SVGRadialGradientElement, | |
rect: SVGRectElement, | |
script: SVGScriptElement, | |
set: SVGSetElement, | |
stop: SVGStopElement, | |
style: SVGStyleElement, | |
svg: SVGSVGElement, | |
switch: SVGSwitchElement, | |
symbol: SVGSymbolElement, | |
text: SVGTextElement, | |
textPath: SVGTextPathElement, | |
title: SVGTitleElement, | |
tspan: SVGTSpanElement, | |
use: SVGUseElement, | |
view: SVGViewElement, | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export type HTMLs = HTMLElementTagNameMap | |
export type SVGs = SVGElementTagNameMap | |
export type MathMLs = MathMLElementTagNameMap | |
export type Tags = keyof (HTMLs | SVGs | MathMLs) | |
export type HTMLByTag<K extends keyof HTMLs> = HTMLs[K] | |
export type SVGByTag<K extends keyof SVGs> = SVGs[K] | |
export type MathMLByTag<K extends keyof MathMLs> = MathMLs[K] | |
export type ElementByTag<K extends Tags> = K extends keyof HTMLs | |
? HTMLByTag<K> | |
: K extends keyof SVGs | |
? SVGByTag<K> | |
: K extends keyof MathMLs | |
? MathMLByTag<K> | |
: Element | |
export type ElementFn<K extends Tags> = (props: object) => ElementByTag<K> | |
export type ElementType = 'html' | 'svg' | 'mathMl' | 'custom' | |
export type TagsByType<K extends ElementType> = K extends 'html' | |
? keyof HTMLs | |
: K extends 'svg' | |
? keyof SVGs | |
: K extends keyof MathMLs | |
? keyof MathMLs | |
: keyof Tags | |
export type Constructor<T> = new (...args: any[]) => T |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <reference types="vite/client" /> | |
type HTMLs = HTMLElementTagNameMap; | |
type MathMLs = MathMLElementTagNameMap; | |
type SVGs = SVGElementTagNameMap; | |
type HTMLByTag<K extends keyof HTMLs> = HTMLs[K]; | |
type MathMLByTag<K extends keyof MathMLs> = MathMLs[K]; | |
type SVGByTag<K extends keyof SVGs> = SVGs[K]; | |
declare namespace JSX { | |
type Element = ReturnType<<T>(props: T) => Node>; | |
type IntrinsicElements = { | |
[K in keyof (HTMLs & SVGs & MathMLs)]: K extends keyof HTMLs | |
? Partial<HTMLByTag<K>> | |
: K extends keyof SVGs | |
? Partial<SVGByTag<K>> | |
: K extends keyof MathMLs | |
? Partial<MathMLByTag<K>> | |
: Partial<HTMLByTag<K> | SVGByTag<K> | MathMLByTag<K>>; | |
}; | |
} | |
interface CustomConstructor<K extends keyof HTMLs> | |
extends CustomElementConstructor { | |
new (...params: any[]): HTMLByTag<K>; | |
prototype: HTMLByTag<K>; | |
} | |
declare const root: HTMLDivElement; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment