jsxte
Advanced tools
Comparing version 1.0.0 to 1.0.1-canary-624a5d7d6dd32ecde94b298635c9b42d2fcb9052.0
@@ -5,9 +5,9 @@ "use strict"; | ||
const attributeToHtmlTagString = ([key, value]) => { | ||
if (value === undefined || value === true) { | ||
if (value === true) { | ||
return `${key}`; | ||
} | ||
if (value === false) { | ||
if (value === false || value === null || value === undefined) { | ||
return ""; | ||
} | ||
return `${key}="${value?.toString().replace(/"/g, """)}"`; | ||
return `${key}="${value.toString().replace(/"/g, """)}"`; | ||
}; | ||
@@ -14,0 +14,0 @@ exports.attributeToHtmlTagString = attributeToHtmlTagString; |
@@ -1,2 +0,1 @@ | ||
import type { JSXTagElem } from "../../jsx/jsx.types"; | ||
import type { HTMLElementStruct, RendererHTMLAttributes } from "../types"; | ||
@@ -6,5 +5,5 @@ export declare class HTMLElementResolver { | ||
constructor(attributeMap: Record<string, string>); | ||
resolveAttributes(element: JSXTagElem): RendererHTMLAttributes; | ||
resolveChildren(element: JSXTagElem): JSX.Element[]; | ||
resolveElement(element: JSXTagElem): HTMLElementStruct; | ||
resolveAttributes(element: JSXTE.TagElement): RendererHTMLAttributes; | ||
resolveChildren(element: JSXTE.TagElement): JSX.Element[]; | ||
resolveElement(element: JSXTE.TagElement): HTMLElementStruct; | ||
} |
@@ -1,3 +0,2 @@ | ||
import type { JSXTagElem } from "../jsx/jsx.types"; | ||
import type { HTMLElementStruct } from "./types"; | ||
export declare const getHTMLStruct: (element: JSXTagElem, attributeMap: Record<string, string>) => HTMLElementStruct; | ||
export declare const getHTMLStruct: (element: JSXTE.TagElement, attributeMap: Record<string, string>) => HTMLElementStruct; |
@@ -28,3 +28,8 @@ "use strict"; | ||
for (const child of htmlStruct.children) { | ||
results.push((0, exports.jsxElemToHtmlSync)(child, { indent: indent + 2, attributeMap })); | ||
const renderedChild = (0, exports.jsxElemToHtmlSync)(child, { | ||
indent: indent + 2, | ||
attributeMap, | ||
}); | ||
if (renderedChild.length > 0) | ||
results.push(renderedChild); | ||
} | ||
@@ -42,3 +47,8 @@ return results.join("\n"); | ||
for (const child of htmlStruct.children) { | ||
children.push((0, exports.jsxElemToHtmlSync)(child, { indent: indent + 2, attributeMap })); | ||
const renderedChild = (0, exports.jsxElemToHtmlSync)(child, { | ||
indent: indent + 2, | ||
attributeMap, | ||
}); | ||
if (renderedChild.length > 0) | ||
children.push(renderedChild); | ||
} | ||
@@ -67,3 +77,8 @@ return [startTag, ...children, endTag].join("\n"); | ||
for (const child of htmlStruct.children) { | ||
results.push(await (0, exports.jsxElemToHtmlAsync)(child, { indent: indent + 2, attributeMap })); | ||
const renderedChild = await (0, exports.jsxElemToHtmlAsync)(child, { | ||
indent: indent + 2, | ||
attributeMap, | ||
}); | ||
if (renderedChild.length > 0) | ||
results.push(renderedChild); | ||
} | ||
@@ -81,3 +96,8 @@ return results.join("\n"); | ||
for (const child of htmlStruct.children) { | ||
children.push(await (0, exports.jsxElemToHtmlAsync)(child, { indent: indent + 2, attributeMap })); | ||
const renderedChild = await (0, exports.jsxElemToHtmlAsync)(child, { | ||
indent: indent + 2, | ||
attributeMap, | ||
}); | ||
if (renderedChild.length > 0) | ||
children.push(renderedChild); | ||
} | ||
@@ -84,0 +104,0 @@ return [startTag, ...children, endTag].join("\n"); |
import type { Rewrap } from "../html-parser/types"; | ||
export declare type AttributeBool = true | false | "true" | "false"; | ||
export declare type BaseHTMLTagProps = { | ||
children?: JSX.ElementChildren; | ||
accesskey?: string; | ||
class?: string; | ||
contenteditable?: AttributeBool; | ||
dir?: "ltr" | "rtl" | "auto"; | ||
draggable?: AttributeBool | "auto"; | ||
hidden?: AttributeBool; | ||
id?: string; | ||
lang?: string; | ||
onabort?: string; | ||
onafterprint?: string; | ||
onbeforeprint?: string; | ||
onbeforeunload?: string; | ||
onblur?: string; | ||
oncanplay?: string; | ||
oncanplaythrough?: string; | ||
onchange?: string; | ||
onclick?: string; | ||
oncontextmenu?: string; | ||
oncopy?: string; | ||
oncuechange?: string; | ||
oncut?: string; | ||
ondblclick?: string; | ||
ondrag?: string; | ||
ondragend?: string; | ||
ondragenter?: string; | ||
ondragleave?: string; | ||
ondragover?: string; | ||
ondragstart?: string; | ||
ondrop?: string; | ||
ondurationchange?: string; | ||
onemptied?: string; | ||
onended?: string; | ||
onerror?: string; | ||
onfocus?: string; | ||
onhashchange?: string; | ||
oninput?: string; | ||
oninvalid?: string; | ||
onkeydown?: string; | ||
onkeypress?: string; | ||
onkeyup?: string; | ||
onload?: string; | ||
onloadeddata?: string; | ||
onloadedmetadata?: string; | ||
onloadstart?: string; | ||
onmousedown?: string; | ||
onmousemove?: string; | ||
onmouseout?: string; | ||
onmouseover?: string; | ||
onmouseup?: string; | ||
onmousewheel?: string; | ||
onoffline?: string; | ||
ononline?: string; | ||
onpagehide?: string; | ||
onpageshow?: string; | ||
onpaste?: string; | ||
onpause?: string; | ||
onplay?: string; | ||
onplaying?: string; | ||
onpopstate?: string; | ||
onprogress?: string; | ||
onratechange?: string; | ||
onreset?: string; | ||
onresize?: string; | ||
onscroll?: string; | ||
onsearch?: string; | ||
onseeked?: string; | ||
onseeking?: string; | ||
onselect?: string; | ||
onstalled?: string; | ||
onstorage?: string; | ||
onsubmit?: string; | ||
onsuspend?: string; | ||
ontimeupdate?: string; | ||
ontoggle?: string; | ||
onunload?: string; | ||
onvolumechange?: string; | ||
onwaiting?: string; | ||
onwheel?: string; | ||
slot?: string; | ||
spellcheck?: AttributeBool; | ||
style?: string; | ||
tabindex?: string | number; | ||
title?: string; | ||
translate?: "yes" | "no"; | ||
}; | ||
export declare type HTMLProps<T extends object = never> = Rewrap<ExtendBaseProps<[ | ||
T | ||
] extends [never] ? BaseHTMLTagProps : Partial<T> & BaseHTMLTagProps>>; | ||
] extends [never] ? JSXTE.BaseHTMLTagProps : Partial<T> & JSXTE.BaseHTMLTagProps>>; | ||
declare type ExtendBaseProps<P> = { | ||
[K in keyof P]: TJSXExtends.AttributeAcceptedTypes extends { | ||
[K in keyof P]: JSXTE.AttributeAcceptedTypes extends { | ||
[E in K]: infer T; | ||
@@ -99,7 +12,116 @@ } ? T | P[K] : P[K]; | ||
declare global { | ||
namespace TJSXExtends { | ||
namespace JSXTE { | ||
interface AttributeAcceptedTypes { | ||
} | ||
type TagElement = { | ||
type: "tag"; | ||
tag: string | ((props: ElementProps) => Element) | ((props: ElementProps) => Promise<Element>); | ||
props: ElementProps; | ||
}; | ||
type TextNodeElement = { | ||
type: "textNode"; | ||
text: string; | ||
}; | ||
type SyncElement = TagElement | TextNodeElement; | ||
type ElementChildren = JSX.Element | string | number | Array<JSX.Element | string | number | Array<JSX.Element | string | number>>; | ||
type ElementProps = { | ||
children?: ElementChildren; | ||
[k: string]: any; | ||
}; | ||
type PropsWithChildren<P extends object> = P & { | ||
children?: JSXTE.ElementChildren; | ||
}; | ||
type Component<P extends object = {}> = (props: PropsWithChildren<P>) => JSX.Element; | ||
type AsyncComponent<P extends object = {}> = (props: PropsWithChildren<P>) => Promise<JSX.Element>; | ||
interface BaseHTMLTagProps { | ||
children?: ElementChildren; | ||
accesskey?: string; | ||
class?: string; | ||
contenteditable?: AttributeBool; | ||
dir?: "ltr" | "rtl" | "auto"; | ||
draggable?: AttributeBool | "auto"; | ||
hidden?: AttributeBool; | ||
id?: string; | ||
inert?: AttributeBool; | ||
lang?: string; | ||
onabort?: string; | ||
onafterprint?: string; | ||
onbeforeprint?: string; | ||
onbeforeunload?: string; | ||
onblur?: string; | ||
oncanplay?: string; | ||
oncanplaythrough?: string; | ||
onchange?: string; | ||
onclick?: string; | ||
oncontextmenu?: string; | ||
oncopy?: string; | ||
oncuechange?: string; | ||
oncut?: string; | ||
ondblclick?: string; | ||
ondrag?: string; | ||
ondragend?: string; | ||
ondragenter?: string; | ||
ondragleave?: string; | ||
ondragover?: string; | ||
ondragstart?: string; | ||
ondrop?: string; | ||
ondurationchange?: string; | ||
onemptied?: string; | ||
onended?: string; | ||
onerror?: string; | ||
onfocus?: string; | ||
onhashchange?: string; | ||
oninput?: string; | ||
oninvalid?: string; | ||
onkeydown?: string; | ||
onkeypress?: string; | ||
onkeyup?: string; | ||
onload?: string; | ||
onloadeddata?: string; | ||
onloadedmetadata?: string; | ||
onloadstart?: string; | ||
onmousedown?: string; | ||
onmousemove?: string; | ||
onmouseout?: string; | ||
onmouseover?: string; | ||
onmouseup?: string; | ||
onmousewheel?: string; | ||
onoffline?: string; | ||
ononline?: string; | ||
onpagehide?: string; | ||
onpageshow?: string; | ||
onpaste?: string; | ||
onpause?: string; | ||
onplay?: string; | ||
onplaying?: string; | ||
onpopstate?: string; | ||
onprogress?: string; | ||
onratechange?: string; | ||
onreset?: string; | ||
onresize?: string; | ||
onscroll?: string; | ||
onsearch?: string; | ||
onseeked?: string; | ||
onseeking?: string; | ||
onselect?: string; | ||
onstalled?: string; | ||
onstorage?: string; | ||
onsubmit?: string; | ||
onsuspend?: string; | ||
ontimeupdate?: string; | ||
ontoggle?: string; | ||
onunload?: string; | ||
onvolumechange?: string; | ||
onwaiting?: string; | ||
onwheel?: string; | ||
role?: string; | ||
slot?: string; | ||
spellcheck?: AttributeBool; | ||
style?: string; | ||
tabindex?: string | number; | ||
title?: string; | ||
translate?: "yes" | "no"; | ||
} | ||
} | ||
} | ||
export {}; |
declare type CreateElementProps = { | ||
[k: string]: any; | ||
children?: JSX.ElementChildren; | ||
children?: JSXTE.ElementChildren; | ||
}; | ||
@@ -5,0 +5,0 @@ export declare const createElement: (tag: string | ((props: any) => JSX.Element) | ((props: any) => Promise<JSX.Element>), props?: CreateElementProps | undefined, ...children: Array<JSX.Element | string | number | Array<JSX.Element | string | number>>) => JSX.Element; |
@@ -28,3 +28,8 @@ "use strict"; | ||
props.children = props.children.map((child) => { | ||
if (typeof child === "string") { | ||
if (typeof child === "boolean" || | ||
child === null || | ||
child === undefined) { | ||
return { type: "tag", tag: exports.Fragment, props: {} }; | ||
} | ||
else if (typeof child === "string") { | ||
return { type: "textNode", text: child }; | ||
@@ -38,2 +43,7 @@ } | ||
} | ||
else if (typeof props.children === "boolean" || | ||
props.children === null || | ||
props.children === undefined) { | ||
props.children = []; | ||
} | ||
} | ||
@@ -40,0 +50,0 @@ return { |
@@ -48,25 +48,5 @@ import type { HTMLProps } from "./base-html-tag-props"; | ||
import type { VideoTagProps } from "./prop-types/video-jsx-props"; | ||
export declare type JSXTagElem = { | ||
type: "tag"; | ||
tag: string | ((props: JSX.ElementProps) => Element) | ((props: JSX.ElementProps) => Promise<Element>); | ||
props: JSX.ElementProps; | ||
}; | ||
export declare type JSXTextNodeElem = { | ||
type: "textNode"; | ||
text: string; | ||
}; | ||
export declare type JSXSyncElem = JSXTagElem | JSXTextNodeElem; | ||
declare global { | ||
namespace JSX { | ||
type PropsWithChildren<P extends object> = P & { | ||
children?: JSX.ElementChildren; | ||
}; | ||
type Component<P extends object = {}> = (props: PropsWithChildren<P>) => JSX.Element; | ||
type AsyncComponent<P extends object = {}> = (props: PropsWithChildren<P>) => Promise<JSX.Element>; | ||
type ElementChildren = JSX.Element | string | number | Array<JSX.Element | string | number | Array<JSX.Element | string | number>>; | ||
type ElementProps = { | ||
children?: ElementChildren; | ||
[k: string]: any; | ||
}; | ||
type Element = JSXTagElem | JSXTextNodeElem | Promise<JSXTagElem | JSXTextNodeElem>; | ||
type Element = JSXTE.TagElement | JSXTE.TextNodeElement | Promise<JSXTE.TagElement | JSXTE.TextNodeElement>; | ||
type LibraryManagedAttributes<T, PropsWithChildren> = PropsWithChildren; | ||
@@ -73,0 +53,0 @@ interface IntrinsicElements { |
@@ -1,3 +0,2 @@ | ||
import type { JSXTagElem } from "../jsx/jsx.types"; | ||
export declare const resolveElement: (element: JSXTagElem) => { | ||
export declare const resolveElement: (element: JSXTE.TagElement) => { | ||
attributes: { | ||
@@ -4,0 +3,0 @@ [k: string]: any; |
@@ -9,3 +9,3 @@ { | ||
"eslint": "^8.15.0", | ||
"git-hook-tasks": "ncpa0cpl/git-hook-tasks", | ||
"git-hook-tasks": "github:ncpa0cpl/git-hook-tasks", | ||
"husky": "^8.0.1", | ||
@@ -19,6 +19,6 @@ "jest": "^28.1.0", | ||
"name": "jsxte", | ||
"version": "1.0.0", | ||
"version": "1.0.1-canary-624a5d7d6dd32ecde94b298635c9b42d2fcb9052.0", | ||
"main": "./dist/index.js", | ||
"scripts": { | ||
"build": "tsc", | ||
"build": "rm -rf ./dist && tsc -p tsconfig.build.json", | ||
"test:lint": "eslint .", | ||
@@ -25,0 +25,0 @@ "test:tsc": "tsc --noEmit", |
@@ -20,2 +20,4 @@ # JSX Template Engine | ||
(See example configurations [here](./docs/config-examples/)). | ||
Once you are done with that you can start writing your templates and rendering them. | ||
@@ -105,2 +107,45 @@ | ||
## Extending the typings | ||
JSXTE should be able to parse any html attributes you put in, as well as custom web component tags, although you may see type errors if you use anything that is not defined in the library typings. If you wish to use them it is recommended you extend the typings to disable said errors. | ||
### Adding custom web component tags | ||
To add a typing for a custom web component simply add a declare block in one of your project `.ts` or `.tsx` files, like this one: | ||
```tsx | ||
declare global { | ||
namespace JSX { | ||
interface IntrinsicElements { | ||
"my-custom-web-component": { | ||
/* here include the attributes your component can take */ | ||
"data-example-attribute"?: string; | ||
}; | ||
} | ||
} | ||
} | ||
// with it it's possible to use this without type errors: | ||
const MyComponent = () => ( | ||
<my-custom-web-component data-example-attribute="Hello"></my-custom-web-component> | ||
); | ||
``` | ||
### Adding a global html attribute | ||
There is a dictionary of html attributes that are available for every default html tag, that dictionary can be extended like so: | ||
```tsx | ||
declare global { | ||
namespace JSXTE { | ||
interface BaseHTMLTagProps { | ||
"new-attribute"?: string; | ||
} | ||
} | ||
} | ||
// with it it's possible to use this without type errors: | ||
const MyComponent = () => <div new-attribute="Hello"></div>; | ||
``` | ||
## Express JS View Engine | ||
@@ -107,0 +152,0 @@ |
@@ -7,3 +7,3 @@ { | ||
"outDir": "./dist", | ||
"rootDir": "./src", | ||
"rootDirs": ["./src", "./__tests__"], | ||
"downlevelIteration": true, | ||
@@ -15,5 +15,8 @@ "strict": true, | ||
"skipLibCheck": true, | ||
"forceConsistentCasingInFileNames": true | ||
"forceConsistentCasingInFileNames": true, | ||
"jsx": "react", | ||
"jsxFactory": "jsx", | ||
"jsxFragmentFactory": "Fragment" | ||
}, | ||
"include": ["src/**/*"] | ||
"include": ["src/**/*", "__tests__/**/*"] | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
222
65226
150
1399
2
1