BindJS in a lightweight JavaScript framework that uses data binding and fine-grained reactivity for state managment, custom routing system, and conditional rendrening... It's main goal is to let the user write less code, without the cost of performance.
npx rbind my-app
cd my-app
npm iAnd to start it in dev mode:
npm run devimport { router } from "rbind";
router.setup({ "/": App, "/login": Login }); // mount App component to the path "/" and Login to "/login"import html from "rbind";
const { div } = html;
div({ textContent: "Hello World", onclick: () => console.log("Clicked") });
// You can replace "div" by any html elementimport html from "rbind";
const { div, p } = html;
div({ class: "Container" }).add(p({ textContent: "Hello World" }));import { state } from "rbind";
const counter = state(0); // 0 here is the default value
console.log(counter.value); // get the state value
counter.value++; // augment the state valueimport {state},html from "rbind";
const {div} = html
const counter = state(0);
function App() {
return div({
textContent: (w)=>`Counter ${w(counter)}`,
onclick: () => counter.value++,
});
}Conditional rendering is used by passing a function that takes a Watcher and a Condition.
(w, c) => c(() => w(todoList).length > 0) && Footer();Here the w is a function that takes a state to watch for changes in, in this example we watch for changes in the length of todoList.
The c is a function that takes a condition and is used for optimization.
If the length or any other watched property has changed, we resolve the condition, then if the condition has changed we re-render the component in this case the 'Footer'.
import {state}, html from "rbind";
const { div } = html;
const isActive = state(false);
div({
textContent: "Click me!",
className: (w) => (w(isActive) ? "active" : "inactive"),
onclick: () => (isActive.value = !isActive.value),
});
// The className will be "active" when isActive is true, otherwise "inactive"import { list } from "rbind";
const nums = list([1, 2]);
nums.push(3); // list is now [1, 2, 3]
nums.remove(2); // list is now [1, 2] remove the given index from the listimport { list } from "rbind";
const todos = list([
{ title: "Task 1", checked: false },
{ title: "Task 2", checked: true },
]);import html from "rbind";
const { ul, li } = html;
ul().add(
todos.map((item) =>
li({
textContent: item.title,
className: () => (item.checked ? "completed" : ""),
})
)
);const completed = todos.filter((t) => t.checked); // return a filtred list (completed) computed from todos
completed.refine((t) => t.checked); // re-compute the filtered list with the new conditiontodos.push({ title: "Task 3", checked: false });
todos.remove(0); // removes the first item
todos.purge((item) => !item.checked); // clears the unchecked items