The UI section of the UBuilder framework provides you with five important functions that you can use:
tagrenderTemplaterenderStylesrenderScriptshtml
The tag function is used to create an object representing an
HTML tag. It takes the following arguments:
tag(tagName, props, ...slots)
tagName: The name of the HTML tag.props: An object containing the props or attributes for the
tag.
slots: Additional arguments that can be used for slots
within the tag.
Here's an example:
const Hello = tag('div', { class: 'text-red' }, 'Hello');
The above code will return the following object:
{
"tag": "div",
"props": {
"class": "text-red"
},
"slots": [
"Hello"
]
}
The renderTemplate function converts a tag object into an
HTML string. It takes the tag object as input and returns the
corresponding HTML representation.
const HelloHtml = renderTemplate(Hello);
The above code will generate the following HTML string:
<div class="text-red">Hello</div>
The renderStyles function extracts and combines the styles
from tag objects. It takes the tag object as input and returns a string
containing the CSS styles.
const styles = renderStyles(Hello);
The renderScripts function is used to extract and combine
JavaScript code from tag objects. It is particularly useful when you have
interactive components that require custom JavaScript functionality. The
function takes the tag object as input and returns a string containing the
JavaScript code.
const scriptString = renderScripts(tagObject);
The tagObject parameter represents the tag object containing
the component and its associated JavaScript code. The
renderScripts function scans the tag object for any
properties related to JavaScript code execution, such as
scriptName and script. It then extracts and
combines the JavaScript code into a single string.
When creating a tag object that includes JavaScript code, you can use the following properties:
scriptName: A unique identifier for the JavaScript code
block. This property is not rendered in the template and is used
internally by the framework.
scriptProps: An optional object containing any additional
properties that should be passed to the JavaScript code block. These
properties can be accessed within the script function.
script: A function representing the JavaScript code block.
It takes the element associated with the tag object as the first
argument and can access any additional properties defined in
scriptProps.
Here's an example:
const tagWithScript = tag('div', {
scriptName: 'hello',
scriptProps: { value: 123 },
script(el, props) {
console.log('Hello World', props.value);
}
}, 'Check Console logs');
In this example, the tagWithScript object includes a
JavaScript code block. The scriptName property provides a
unique identifier for this code block. The
scriptProps property defines additional properties that can
be accessed within the script function. Finally, the
script function contains the actual JavaScript code.
renderScripts to Retrieve JavaScript Code
To retrieve the JavaScript code from the tag object, you can call the
renderScripts function, passing the tag object as the
argument:
const scriptString = renderScripts(tagWithScript);
The scriptString variable will then contain a valid
JavaScript code string that you can insert into a
<script> tag in your HTML document. This allows you to
execute the JavaScript code associated with the tag object.
Remember to include the generated scriptString within a
<script> tag in your HTML document to ensure the
JavaScript code is properly executed.
<script>
// Insert the scriptString here
</script>
This way, the JavaScript code associated with the tag object will be executed when the page loads, enabling the desired interactive behavior.
The html function is used to render a tag object directly
into the DOM. It takes the tag object as input and inserts it into the
specified element in the document.
html(element, tagObject);
element: The DOM element where the tag object should be
inserted.
tagObject: The tag object to be rendered.Here is an example for Toggle component which uses all of the provided methods:
import { renderTemplate } from "../src/ui/index.js";
import { renderScripts } from "../src/ui/index.js";
import { tag, html } from "../src/ui/tags.js";
const Toggle = () => {
const toggleButton = tag(
"button",
{
scriptName: "toggle-button",
script(el) {
const contentElement = document.getElementById("toggle-content");
el.addEventListener("click", () => {
if (contentElement.style.display === "none") {
contentElement.style.display = "block";
} else {
contentElement.style.display = "none";
}
});
},
},
"Toggle"
);
const content = tag(
"div",
{
id: "toggle-content",
style: { display: "none" },
},
"Toggleable Content"
);
const scriptString = renderScripts(toggleButton);
const script = tag("script", {}, scriptString);
const page = html({ body: [toggleButton, content, script] });
return renderTemplate(page); // returns html
};
console.log(Toggle());
Here you can see live demo:
Toggle Example
import { tag, renderScripts, renderTemplate, html } from "../src/ui/index.js";
function Counter({ count = 0 }) {
return tag(
"div",
{
scriptName: "u-counter",
scriptProps: { count },
script(el, { count }) {
function $(selector, callback) {
el.querySelectorAll(selector).forEach(el => callback(el))
}
function on(element, event, callback) {
element.addEventListener(event, callback)
}
function attr(element, attribute) {
return element.getAttribute(attribute)
}
setCount(count);
function setCount(newValue) {
count = newValue;
$("[u-count]", el => el.textContent = count);
}
$("[u-action]", (button) => {
on(button, "click", (event) => {
const action = attr(button, "u-action");
if (action === "decrement") {
setCount(count - 1);
} else if (action === "increment") {
setCount(count + 1);
} else {
setCount(0);
}
});
});
},
},
[
tag("h1", {}, ["Value: ", tag("span", { "u-count": true })]),
tag("button", { "u-action": "decrement" }, "Decrement"),
tag("button", { "u-action": "reset" }, "Reset"),
tag("button", { "u-action": "increment" }, "Increment"),
]
);
}
const counter = Counter({ count: 6 });
const counterScript = tag("script", {}, renderScripts(counter));
const counterTemplate = renderTemplate(counter);
const counterHTML = html({
body: [counterTemplate, counterScript],
});
console.log(renderTemplate(counterHTML));
Counter Example