Based on DML, Morphdom and HTL
MVU tries to follow the Model View Update pattern. The idea is to make the view a function of the state only.
MVU can be used directly in the browser, and don't use any external framework, it's plain vanilla Javascript.
Here is an example , you can test it here ChooseColors
const { html, dom, udom, render, svg } = mvu.MVU;
const target = document.getElementById("app")
let state = {
init: true,
red: 255,
green: 128,
blue: 125
}
function Circle(state) {
const strcolor = (state) => `rgb(${state.red},${state.green},${state.blue})`;
let node = (
svg`<svg width="100px" height="100px" fill=${strcolor(state)}>
${svg`<circle cx=50 cy=50 r=50></circle>`}
</svg>`
)
return node
}
function Slider(color, state) {
let slider = dom();
let input = html`
<div>
<div style="display:flex;align-items:center">
<div style="width:50px;text-align:right;margin-right:10px;">
${color.charAt(0).toUpperCase()}
</div>
<div>
<input type="range" min="0" max="255" value=${state[color]}>
</div>
${state[color]}
</div>
</div>`
udom();
input.oninput = function (e) {
let value = e.target.value
state[color] = value;
update(state)
}
return slider
}
function Title () {
let title = html`<h1>A Simple Colors Chooser</h1>`
return title
}
function App(state) {
let app = dom();
html`
${Title()}
<div class='color-chooser'>
<div>${Circle(state)}</div>
<div class="color-slider">
<div>
<div>${Slider("red", state)}</div>
<div>${Slider("green", state)}</div>
<div>${Slider("blue", state)}</div>
</div>
</div>
</div>`
udom();
return app
}
function update(state) {
render(target, App(state))
}
update(state);
Here is the a more compact version : ChooseColors
const { html, dom, udom, render, svg, tags } = mvu.MVU;
const { div, input, span } = tags;
const mcircle = () =>
div('', `width:40px;height:40px;background:red;border-radius:50%`);
const Slider = (min, max, value, libelle) => {
let slider = dom ();
span(libelle);
let eltinput = input("", {type : "range", style:"display:block", max, min, value});
let eltvalue = div(eltinput.value.toString())
udom();
slider.style.display = "flex";
return {
input : eltinput,
value: eltvalue
}
}
function setColor(elt, R, G, B){
console.log(R.input.value)
elt.style.backgroundColor = `rgb(${R.input.value},${G.input.value},${B.input.value})`
};
function App () {
const app = dom ();
const circle = mcircle ();
const [R, G, B] = [
Slider(0, 255, 128, "R"),
Slider(0, 255, 128, "G"),
Slider(0, 255, 128, "B")
];
udom();
[R, G, B].forEach((slider) => {
slider.input.oninput = () => {
circle.style.backgroundColor = `rgb(${R.input.value},${G.input.value},${B.input.value})`;
slider.value.innerText = slider.input.value
}
});
setColor(circle, R, G, B);
return app;
}
render(app, App());