mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
118 lines
3.1 KiB
TypeScript
118 lines
3.1 KiB
TypeScript
// 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 };
|