@teaui/preact
Version:
Preact renderer for TeaUI
297 lines • 9.56 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.run = run;
const preact_1 = require("preact");
const core_1 = require("@teaui/core");
const TextReact_1 = require("./components/TextReact");
function createView(type, props) {
switch (type) {
case 'text':
return new TextReact_1.TextLiteral(String(props.text) ?? '');
case 'br':
case 'tui-br':
return new TextReact_1.TextLiteral('\n');
case 'checkbox':
case 'tui-checkbox':
return new core_1.Checkbox(props);
case 'collapsible-text':
case 'tui-collapsible-text':
return new core_1.CollapsibleText(props);
case 'console':
case 'tui-console':
return new core_1.ConsoleLog(props);
case 'digits':
case 'tui-digits':
return new core_1.Digits(props);
case 'h1':
case 'tui-h1':
return (0, core_1.H1)(props.text ?? '');
case 'h2':
case 'tui-h2':
return (0, core_1.H2)(props.text ?? '');
case 'h3':
case 'tui-h3':
return (0, core_1.H3)(props.text ?? '');
case 'h4':
case 'tui-h4':
return (0, core_1.H4)(props.text ?? '');
case 'h5':
case 'tui-h5':
return (0, core_1.H5)(props.text ?? '');
case 'h6':
case 'tui-h6':
return (0, core_1.H6)(props.text ?? '');
case 'toggle-group':
case 'tui-toggle-group':
return new core_1.ToggleGroup(props);
case 'input':
case 'tui-input':
return new core_1.Input(props);
case 'literal':
case 'tui-literal':
return new TextReact_1.TextLiteral(props.text ?? '');
case 'separator':
case 'tui-separator':
return new core_1.Separator(props);
case 'slider':
case 'tui-slider':
return new core_1.Slider(props);
case 'space':
case 'tui-space':
return new core_1.Space(props);
// case 'Tree':
// return
case 'box':
case 'tui-box':
return new core_1.Box(props);
case 'button':
case 'tui-button':
return new core_1.Button(props);
case 'collapsible':
case 'tui-collapsible':
return new core_1.Collapsible(props);
case 'scrollable':
case 'tui-scrollable':
return new core_1.Scrollable(props);
case 'stack':
case 'tui-stack':
return new core_1.Stack(props);
case 'style':
case 'tui-style':
return new TextReact_1.TextStyle(props);
case 'tui-text':
return new TextReact_1.TextProvider(props);
case 'accordion':
case 'tui-accordion':
return new core_1.Accordion(props);
case 'accordion-section':
case 'tui-accordion-section':
return new core_1.Accordion.Section(props);
case 'drawer':
case 'tui-drawer':
return new core_1.Drawer(props);
case 'tabs':
case 'tui-tabs':
return new core_1.Tabs(props);
case 'tabs-section':
case 'tui-tabs-section':
return new core_1.Tabs.Section(props);
case 'window':
case 'tui-window':
return new core_1.Window(props);
default:
throw Error(`Unknown type ${type}`);
}
}
const defer = Promise.prototype.then.bind(Promise.resolve());
function removeFromTextContainer(container, child) {
// find TextContainer with child in it, and remove
for (const node of container.children) {
if (node instanceof TextReact_1.TextContainer && node.children.includes(child)) {
node.removeChild(child);
if (node.children.length === 0) {
container.removeChild(node);
}
return;
}
}
}
function removeChild(container, child) {
if (child.parent === container) {
container.removeChild(child);
}
else if (child instanceof TextReact_1.TextLiteral || child instanceof TextReact_1.TextStyle) {
removeFromTextContainer(container, child);
}
}
function appendChild(parentInstance, child, before) {
if (parentInstance instanceof TextReact_1.TextStyle &&
(child instanceof TextReact_1.TextLiteral || child instanceof TextReact_1.TextStyle)) {
// do not do the TextContainer song and dance
}
else if (child instanceof TextReact_1.TextLiteral || child instanceof TextReact_1.TextStyle) {
// find the last child (checking 'before')
let lastChild = parentInstance.children.at(-1);
if (before) {
const index = parentInstance.children.indexOf(before);
if (~index) {
lastChild = parentInstance.children.at(index - 1);
}
}
let textContainer;
if (lastChild instanceof TextReact_1.TextContainer) {
textContainer = lastChild;
}
else {
textContainer = new TextReact_1.TextContainer();
parentInstance.add(textContainer);
}
textContainer.add(child);
return;
}
let index = before
? parentInstance.children.indexOf(before)
: -1;
if (index === -1) {
index = undefined;
}
parentInstance.add(child, index);
}
class RendererElement {
renderer;
localName;
parentNode = null;
nextSibling = null;
previousSibling = null;
firstChild = null;
lastChild = null;
props = {};
prevProps;
node;
nodeType = '';
constructor(renderer, localName) {
this.renderer = renderer;
this.localName = localName;
this._commit = this._commit.bind(this);
}
set data(text) {
this.setAttribute('text', String(text));
}
addEventListener(event, func) {
this.setAttribute(`on${event}`, (...args) => this.l[event + false](...args));
}
setAttribute(name, value) {
if (this.node && !this.prevProps) {
this.prevProps = Object.assign({}, this.props);
defer(this._commit);
}
this.props[name] = value;
}
removeAttribute(name) {
delete this.props[name];
}
_attach() {
return (this.node ||= this.renderer.create(this.localName, this.props));
}
_commit() {
const state = this.node;
const prev = this.prevProps;
if (!state || !prev)
return;
this.prevProps = undefined;
this.renderer.update(state, this.props);
}
insertBefore(child, before) {
if (child.parentNode === this)
this.removeChild(child);
if (before) {
const prev = before.previousSibling;
child.previousSibling = prev;
before.previousSibling = child;
if (prev) {
prev.nextSibling = child;
}
if (before == this.firstChild) {
this.firstChild = child;
}
}
else {
const last = this.lastChild;
child.previousSibling = last;
this.lastChild = child;
if (last)
last.nextSibling = child;
if (!this.firstChild)
this.firstChild = child;
}
child.parentNode = this;
child.nextSibling = before ?? null;
this.renderer.insert(this._attach(), child._attach(), before && before._attach());
}
appendChild(child) {
this.insertBefore(child);
}
removeChild(child) {
if (this.firstChild === child)
this.firstChild = child.nextSibling;
if (this.lastChild === child)
this.lastChild = child.previousSibling;
child.parentNode = child.nextSibling = child.previousSibling = null;
if (this.node && child.node) {
this.renderer.remove(this.node, child.node);
}
}
}
function createRendererDom(renderer) {
function createElement(type) {
return new RendererElement(renderer, type);
}
function createElementNS(_, type) {
return new RendererElement(renderer, type);
}
function createTextNode(text) {
const node = createElement('text');
node.props.text = String(text);
return node;
}
function createRoot() {
return createElement('tui-window');
}
return { createElement, createElementNS, createTextNode, createRoot };
}
const dom = createRendererDom({
create(type, props) {
return createView(type, props);
},
insert(parent, node, before) {
if (!(parent instanceof core_1.Container)) {
return;
}
appendChild(parent, node, before);
},
remove(parent, node) {
if (!(parent instanceof core_1.Container)) {
return;
}
removeChild(parent, node);
},
update(node, props) {
if (node instanceof TextReact_1.TextLiteral) {
node.update(props);
node.text = props.text ?? '';
}
else {
node.update(props);
}
},
});
Object.assign(global, { document: {} });
Object.assign(document, dom);
async function run(component) {
const root = dom.createRoot();
(0, preact_1.render)(component, root);
const window = root.node;
const start = await core_1.Screen.start(window);
const [screen, _] = start;
}
//# sourceMappingURL=preact.js.map