feat: provide Fragment component
Adds a new Fragment component that provides the same functionality as React.Fragment. See issue #9 for details. closes issue #9
This commit is contained in:
parent
b112dc2d97
commit
da241efb59
4 changed files with 43 additions and 4 deletions
|
|
@ -44,3 +44,9 @@ export interface Component<P extends object = {}> {
|
|||
}
|
||||
): HTMLElement;
|
||||
}
|
||||
|
||||
export const Fragment: Component<{}> = ({ children }) => ({
|
||||
tag: "#fragment",
|
||||
attributes: {},
|
||||
children: children || [],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
export { HTMLElement, Component } from "./component";
|
||||
export { HTMLElement, Component, Fragment } from "./component";
|
||||
export { UserConfig as Config } from "./config";
|
||||
export { createElement } from "./create-element";
|
||||
export * from "./jsx";
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ const renderElement = (elem: Element): string => {
|
|||
};
|
||||
|
||||
const startTag = (elem: HTMLElement): string => {
|
||||
if (elem.tag === "#fragment") {
|
||||
return "";
|
||||
}
|
||||
|
||||
let output = `<${escapeHtml(elem.tag)}`;
|
||||
|
||||
for (const [attrName, attrValue] of Object.entries(elem.attributes)) {
|
||||
|
|
@ -68,7 +72,12 @@ const startTag = (elem: HTMLElement): string => {
|
|||
return output;
|
||||
};
|
||||
|
||||
const endTag = (elem: HTMLElement): string => `</${escapeHtml(elem.tag)}>`;
|
||||
const endTag = (elem: HTMLElement): string => {
|
||||
if (elem.tag === "#fragment") {
|
||||
return "";
|
||||
}
|
||||
return `</${escapeHtml(elem.tag)}>`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render a complete HTML page from an HTMLElement. Note that the root element
|
||||
|
|
@ -78,7 +87,17 @@ const endTag = (elem: HTMLElement): string => `</${escapeHtml(elem.tag)}>`;
|
|||
*
|
||||
* @return Fully rendered HTML document as a string.
|
||||
*/
|
||||
export const renderPage = (rootElem: HTMLElement): string => {
|
||||
export const renderPage = (rootElem: Element): string => {
|
||||
if (rootElem == undefined) {
|
||||
throw new Error(`root page element cannot be null`);
|
||||
}
|
||||
if (typeof rootElem !== "object" || !("tag" in rootElem)) {
|
||||
throw new Error(
|
||||
`root page element must be a valid HTMLElement, got ${JSON.stringify(
|
||||
rootElem
|
||||
)}`
|
||||
);
|
||||
}
|
||||
if (rootElem.tag.toLowerCase() !== "html") {
|
||||
throw new Error(
|
||||
`attempted to render page with non-HTML root element ${rootElem.tag}`
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Component, createElement } from "../../dist";
|
||||
import { Component, createElement, Fragment } from "../../dist";
|
||||
import { renderPage } from "../../dist/render";
|
||||
import { testSuite } from "../lib";
|
||||
|
||||
|
|
@ -103,4 +103,18 @@ testSuite("renderPage", ({ test, expect }) => {
|
|||
"<!DOCTYPE html><html>There are <div>3 lights</div>!</html>"
|
||||
);
|
||||
});
|
||||
|
||||
test("renders fragment children only", () => {
|
||||
const html = renderPage(
|
||||
<html>
|
||||
<Fragment>
|
||||
<div>test of</div>
|
||||
<div>fragments</div>
|
||||
</Fragment>
|
||||
</html>
|
||||
);
|
||||
expect(html).toEqual(
|
||||
"<!DOCTYPE html><html><div>test of</div><div>fragments</div></html>"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue