@travetto/email-inky
Version:
Email Inky templating module
92 lines (76 loc) • 2.92 kB
text/typescript
import { castTo, Class } from '@travetto/runtime';
import { EmailTemplateModule, EmailTemplateLocation } from '@travetto/email';
export type JSXChild = JSXElement | number | bigint | boolean | object | string;
type JSXProps = { children?: JSXChild | JSXChild[] | null, className?: string, id?: string, name?: string, dir?: string };
export type JSXComponentFunction<P extends {} = {}> = (props: P & JSXProps, ...args: unknown[]) => (JSXElement | null);
export const JSXRuntimeTag = Symbol.for('@travetto/email-inky:jsx-runtime');
export class JSXFragmentType { }
let id = 0;
/** Simple JSX Element */
export interface JSXElement<
T extends string | Class | JSXComponentFunction<P> = string | Class | JSXComponentFunction,
P extends {} = {},
> {
[JSXRuntimeTag]?: { id: number };
type: T;
key: string;
props: P & JSXProps;
}
export type ValidHtmlTags =
'strong' | 'em' | 'br' | 'hr' | 'a' |
'li' | 'ul' | 'ol' | 'img' | 'p' |
'h1' | 'h2' | 'h3' | 'h4' | 'small' |
'td' | 'tr' | 'th' | 'table' | 'thead' | 'tbody' |
'span' | 'div' | 'center' | 'title';
type BasicElements = { [K in ValidHtmlTags]: JSX.IntrinsicAttributes };
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX {
interface Element extends JSXElement { }
interface IntrinsicAttributes {
className?: string;
id?: string;
dir?: string;
name?: string;
src?: string | Function;
alt?: string;
href?: string;
title?: string;
height?: string;
target?: string;
width?: string;
style?: string;
align?: string;
valign?: string;
}
interface IntrinsicElements extends BasicElements { }
}
}
let createFrag: Function | undefined = undefined;
export function createElement<T extends string | Class | JSXComponentFunction<P>, P extends {}>(
type: T, props: P & JSXProps
): JSXElement<T, P> {
type = castTo(type === createFrag ? JSXFragmentType : type);
return { [JSXRuntimeTag]: { id: (id += 1) }, type, key: '', props };
}
export function createRootElement<T extends string | Class | JSXComponentFunction<P>, P extends {}>(
type: T, props: P & JSXProps
): JSXElement<T, P> {
const res = createElement(type, props);
Object.assign(res, {
prepare(loc: EmailTemplateLocation): Promise<EmailTemplateModule> {
return import('@travetto/email-inky/src/wrapper').then(v => v.prepare(castTo(res), loc));
}
});
return res;
}
export function createFragment<P extends {}>(props: P & JSXProps): JSXElement<typeof JSXFragmentType, P> {
return createElement(JSXFragmentType, props);
}
export const jsx = createElement;
export const jsxs = createRootElement;
export const Fragment = createFragment;
export function isJSXElement(el: unknown): el is JSXElement {
return el !== undefined && el !== null && typeof el === 'object' && JSXRuntimeTag in el;
}
createFrag = Fragment;