Skip to content

Instantly share code, notes, and snippets.

@guiseek
Last active January 18, 2024 16:04
Show Gist options
  • Save guiseek/07d0e195b91d64869411e484161cfe50 to your computer and use it in GitHub Desktop.
Save guiseek/07d0e195b91d64869411e484161cfe50 to your computer and use it in GitHub Desktop.
JSX
declare namespace JSX {
type ElementTagNameMap = HTMLElementTagNameMap &
SVGElementTagNameMap &
MathMLElementTagNameMap;
type Element<K extends keyof ElementTagNameMap = 'div'> = {
[A in keyof ElementTagNameMap[K]]: ElementTagNameMap[K][A];
};
type IntrinsicElements = {
[K in keyof ElementTagNameMap]: Partial<Element<K>>;
};
}
export function factory<K extends keyof JSX.ElementTagNameMap>(
tagOrFn: K | ReturnType<ObjectConstructor> | Function,
props: Partial<HTMLElement>,
...nodes: Node[]
) {
let component;
if (typeof tagOrFn === "string") {
component = document.createElement(tagOrFn);
} else {
try {
component = new tagOrFn(props);
} catch {
component = tagOrFn(props);
}
}
component.append(
...nodes.flatMap((node) =>
typeof node === "string" ? new Text(node) : node
)
);
const attrs = Object.entries(props ?? {});
for (const [attr, value] of attrs) {
if (component.hasOwnProperty(attr)) {
component[attr] = value;
}
}
return component as JSX.Element<K>;
}
export function fragmentFactory() {
return new DocumentFragment();
}
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"jsx": "preserve",
"jsxFactory": "factory",
"jsxFragmentFactory": "fragmentFactory"
},
"include": ["src", "types"]
}
import { defineConfig } from "vite";
export default defineConfig({
esbuild: {
jsxInject: `import { factory, fragmentFactory } from "/src/lib/jsx"`,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment