BasicsConfiguration: Understanding HyptiotesExample: Hooks (DOM API)Example: Observable (DOM API)Example: Hyptiotes x ReactExample: Demo Wrapper (Markup)
Sources
index.js
const hyptiotes = require("hyptiotes"); const { createRoot } = require("react-dom/client"); const configuration = require("./configuration"); const App = require("./app"); hyptiotes.setElementInitializer(configuration.elementInitializer); hyptiotes.setItemHandlers(configuration.itemHandlers); hyptiotes.setAttributeHandlers(configuration.attributeHandlers); hyptiotes.setElementFinalizer(configuration.elementFinalizer); // Cast hyptiotes tree to React tree const reactTree = hyptiotes.castWeb(App); // Append to root element const root = createRoot(document.getElementById("root")); root.render(reactTree);
configuration.js
const React = require("react"); const hyptiotes = require("hyptiotes"); // Hyptiotes configuration to create React trees module.exports = { elementInitializer: hyptiotes.PLUGINS.initiateElementObject, itemHandlers: [ hyptiotes.PLUGINS.skipEmpty, hyptiotes.PLUGINS.textToChild, // modified nested to child, allows functions as tags { test: (item) => Array.isArray(item) && ((typeof item[0] === "string" && item[0][0] === ":") || typeof item[0] === "function"), handler: ({ item, parent, hyptiotes }) => { const nested = hyptiotes.castWeb(item); if (nested) parent.children.push(nested); }, }, ], attributeHandlers: [hyptiotes.PLUGINS.forwardAttribute], elementFinalizer: ({ tag, attributes, children }) => { const component = typeof tag === "string" ? tag.slice(1) // wrap render fn in hyptiotes cast to map returned tree, expose React : (props) => hyptiotes.castWeb(tag(props, React)); return React.createElement(component, attributes, ...children); }, };
app.js
// Don't need to require React since it's exposed in function call // const React = require("react"); const TodoStore = require("../TodoStore"); module.exports = [ ":div", { id: "main-content" }, [":h1", "Hyptiotes To-Do"], [TodoList], [AddTodo], ]; function TodoList(_, { useEffect, useState }) { const [list, setList] = useState(TodoStore.get()); useEffect(() => TodoStore.subscribe((v) => setList(v))); return [ ":ul", ...list.map((todo) => { return [":li", todo]; }), ]; } function AddTodo(_, { useState }) { const [val, setVal] = useState(""); return [ ":div", [ ":input", { value: val, onChange: (e) => { setVal(e.target.value); }, }, ], [ ":button", { onClick: () => { TodoStore.add(val); setVal(""); }, }, "Add", ], ]; }
Full Configuration
{ "elementInitializer": (tag) => ({ tag, attributes: {}, children: [] }), "itemHandlers": [ { "test": (item) => item === null || item === undefined, "handler": () => {} }, { "test": (item) => typeof item === "string", "handler": ({ item, parent }) => { parent.children.push(item); } }, { "test": (item) => Array.isArray(item) && ((typeof item[0] === "string" && item[0][0] === ":") || typeof item[0] === "function"), "handler": ({ item, parent, hyptiotes }) => { const nested = hyptiotes.castWeb(item); if (nested) parent.children.push(nested); } } ], "attributeHandlers": [ { "test": () => true, "handler": ({ key, value, parent }) => { parent.attributes[key] = value; } } ], "elementFinalizer": ({ tag, attributes, children }) => { const component = typeof tag === "string" ? tag.slice(1) // wrap render fn in hyptiotes cast to map returned tree, expose React : (props) => hyptiotes.castWeb(tag(props, React)); return React.createElement(component, attributes, ...children); } }
Example: Hyptiotes x React Rendered