UNPKG

@travetto/email-inky

Version:

Email Inky templating module

92 lines (76 loc) 2.92 kB
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;