feat: support rendering array elements

This commit is contained in:
M. George Hansen 2020-06-02 16:39:44 -07:00
parent 75ed8c6537
commit ed547cc851
Signed by: mgeorgehansen
SSH key fingerprint: SHA256:JlIGiQLPyQ2RHTH3a2oVlb20Xkh9Glr8DUF4YTXHJxM
4 changed files with 35 additions and 14 deletions

View file

@ -26,6 +26,7 @@ export interface HTMLElement {
* All valid types of elements that can be rendered to HTML.
*/
export type Element =
| Element[]
| HTMLElement
| string
| number

View file

@ -28,6 +28,9 @@ const renderElement = (elem: Element): string => {
if (typeof elem === "string") {
return escapeHtml(elem);
}
if (Array.isArray(elem)) {
return elem.map((e) => renderElement(e)).join("");
}
let output = "";
output += startTag(elem);

View file

@ -51,18 +51,6 @@ export const purgeModuleAndDepsFromCache = (modName: string): void => {
export type Flattenable<T> = Array<T | Flattenable<T>>;
const flatDeepRec = <T>(arr: Flattenable<T>, d: number): T[] => {
if (d <= 0) {
return arr.slice() as T[];
}
let acc = [] as T[];
for (const val of arr) {
acc = acc.concat(Array.isArray(val) ? flatDeepRec(arr, d - 1) : val);
}
return acc;
};
/**
* Flatten an arbitrarily-deeply nested array into a flat array.
*
@ -70,4 +58,14 @@ const flatDeepRec = <T>(arr: Flattenable<T>, d: number): T[] => {
*
* @return Flattened array.
*/
export const flatDeep = <T>(arr: Flattenable<T>): T[] => flatDeepRec(arr, 1);
export const flatDeep = <T>(arr: Flattenable<T>): T[] => {
const flattenedArr: T[] = [];
for (const val of arr) {
if (Array.isArray(val)) {
flattenedArr.push(...flatDeep(val));
} else {
flattenedArr.push(val);
}
}
return flattenedArr;
};

View file

@ -3,7 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { createElement } from "../../dist";
import { Component, createElement } from "../../dist";
import { renderPage } from "../../dist/render";
import { testSuite } from "../lib";
@ -67,4 +67,23 @@ testSuite("renderPage", ({ test, expect }) => {
const html = renderPage(<html>There are {nLights} lights!</html>);
expect(html).toEqual("<!DOCTYPE html><html>There are 3 lights!</html>");
});
test("renders spliced arrays", () => {
const Light: Component<{ lightN: number }> = ({ lightN }) => (
<div>{lightN}</div>
);
const lights = [1, 2, 3];
const html = renderPage(
<html>
There are{" "}
{lights.map((lightN) => (
<Light lightN={lightN} />
))}{" "}
lights!
</html>
);
expect(html).toEqual(
"<!DOCTYPE html><html>There are <div>1</div><div>2</div><div>3</div> lights!</html>"
);
});
});