waveterm/frontend/app/view/term/ijson.tsx

118 lines
3.1 KiB
TypeScript
Raw Normal View History

2024-06-14 08:54:04 +02:00
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import * as React from "react";
import Frame from "react-frame-component";
type IJsonNode = {
tag: string;
props?: Record<string, any>;
children?: (IJsonNode | string)[];
};
const TagMap: Record<string, React.ComponentType<{ node: IJsonNode }>> = {};
function convertNodeToTag(node: IJsonNode | string, idx?: number): JSX.Element | string {
if (node == null) {
return null;
}
if (idx == null) {
idx = 0;
}
if (typeof node === "string") {
return node;
}
let key = node.props?.key ?? "child-" + idx;
let TagComp = TagMap[node.tag];
if (!TagComp) {
return <div key={key}>Unknown tag:{node.tag}</div>;
}
return <TagComp key={key} node={node} />;
}
function IJsonHtmlTag({ node }: { node: IJsonNode }) {
let { tag, props, children } = node;
let divProps = {};
if (props != null) {
for (let [key, val] of Object.entries(props)) {
if (key.startsWith("on")) {
divProps[key] = (e: any) => {
console.log("handler", key, val);
};
} else {
divProps[key] = val;
}
}
}
let childrenComps: (string | JSX.Element)[] = [];
if (children != null) {
for (let idx = 0; idx < children.length; idx++) {
let comp = convertNodeToTag(children[idx], idx);
if (comp != null) {
childrenComps.push(comp);
}
}
}
return React.createElement(tag, divProps, childrenComps);
}
TagMap["div"] = IJsonHtmlTag;
TagMap["b"] = IJsonHtmlTag;
TagMap["i"] = IJsonHtmlTag;
TagMap["p"] = IJsonHtmlTag;
TagMap["s"] = IJsonHtmlTag;
TagMap["span"] = IJsonHtmlTag;
TagMap["a"] = IJsonHtmlTag;
TagMap["img"] = IJsonHtmlTag;
TagMap["h1"] = IJsonHtmlTag;
TagMap["h2"] = IJsonHtmlTag;
TagMap["h3"] = IJsonHtmlTag;
TagMap["h4"] = IJsonHtmlTag;
TagMap["h5"] = IJsonHtmlTag;
TagMap["h6"] = IJsonHtmlTag;
TagMap["ul"] = IJsonHtmlTag;
TagMap["ol"] = IJsonHtmlTag;
TagMap["li"] = IJsonHtmlTag;
TagMap["input"] = IJsonHtmlTag;
TagMap["button"] = IJsonHtmlTag;
TagMap["textarea"] = IJsonHtmlTag;
TagMap["select"] = IJsonHtmlTag;
TagMap["option"] = IJsonHtmlTag;
TagMap["form"] = IJsonHtmlTag;
function IJsonView({ rootNode }: { rootNode: IJsonNode }) {
// TODO fix this huge inline style
return (
<div className="ijson">
<Frame>
<style>
{`
*::before, *::after { box-sizing: border-box; }
* { margin: 0; }
body { line-height: 1.2; -webkit-font-smoothing: antialiased; }
img, picture, video, canvas, sgv { display: block; }
input, button, textarea, select { font: inherit; }
body {
display: flex;
flex-direction: column;
width: 100vw;
height: 100vh;
background-color: #000;
color: #fff;
font: normal 15px / normal "Lato", sans-serif;
}
.fixed-font {
normal 12px / normal "Hack", monospace;
}
`}
</style>
{convertNodeToTag(rootNode)}
</Frame>
</div>
);
}
export { IJsonView };