Headless Components are a unique feature of Juris. Think of it like 'services' for you ui components.
They are used to handle the logic of their counterparts components.
Here is an enhanced version of my previous Traffic Lights sample.
We are able now to start and stop lights cycle.
All the logic is contained in TraffiLightsManager headless component.
We have not touch to the ui components, awesome.
All in pure Javascript, can be explain to anyone with basic Javascript knowledge.
I don't have to ask to install node, neither any bundlers.
From Editor to the Browser, that is what Juris brings.
You can play with the demo here TrafficLigths
Don't pay to much attention to 'bss', it has nothing to do with Juris. It's just a CSSinJS helper.
import b from 'bss'
b.css({
body: {
bc: "#252526"
}
})
b.css({
button: {
w: '3.5rem',
ta: 'center',
border:'none',
p: '0.5rem',
br: '3px',
cursor:'pointer'
}
})
// helpers
const delay = (ms) => {
return new Promise((r) => {
setTimeout(r, ms)
})
}
const Light = (props, context) => ({
div: {
className: () => {
const isVisible = context.getState(props.name) === 'visible';
const dimLight = 'opacity 0.5';
const highLight = `opacity 1;box-shadow: 0px 0px 40px 10px ${props.color}`;
return b`
w 40px
h 40px
br 50%
bc ${props.color}
m 6px
transition all 0.3s ease
${isVisible ? highLight : dimLight}`
}
}
});
const Switch = (props, ctx) => {
const { TrafficLightsManager } = ctx;
const [cs, cg] = [ ctx.setState, ctx.getState ];
const switchlight = (color) => {
return cs(color, cg(color) == "visible" ? "hidden" : "visible");
}
return {
div: {
className: b`display flex;jc center;gap:0.5rem;padding-bottom: 2rem; mt 1rem`,
children: [
{ button: {
className: b`bc red;c white`,
text: "red",
onclick: () => switchlight("red")
}},
{ button: {
className: b`bc orange;c black`,
text: "orange",
onclick: () => switchlight("orange")
}},
{ button: {
className: b`bc green; c white`,
text: "green",
onclick: () => switchlight("green")
}},
{ button: {
className: b`bc green; c white`,
text: "Start Cycle",
onclick: () => { ctx.setState("cycling", true);TrafficLightsManager.cycleLights(); }
}},
{ button: {
className: b`bc green; c white`,
text: "Stop Cycle",
onclick: () => { TrafficLightsManager.stopCycling(); }
}}
]
}
}
}
const Lights = (props, ctx) => ({
div: {
className: b`display flex;jc center`,
children: [
{
div: {
className: () => b`
display:flex
flex-direction: ${ctx.getState("orientation")}
gap:1.25rem
mt 1rem`,
children: [
{ Light: { color: 'red', name: 'red' } },
{ Light: { color: 'orange', name: 'orange' } },
{ Light: { color: 'green', name: 'green' } },
]
}
},
]
}
})
const TrafficLightsManager = (props, ctx) => {
const colors = ["red", "orange", "green"];
return {
api : {
cycleLights,
stopCycling
}
}
async function cycleLights () {
for ( const color of colors ) {
ctx.setState(color, "visible");
await delay(200);
ctx.setState(color, "hidden");
await delay(200);
}
if ( ctx.getState("cycling")){
cycleLights(); // loop again
}
}
function stopCycling () {
ctx.setState("cycling", false);
}
}
const TrafficLights = (props, ctx) => ({
div: {
className:b`
br:5px;
border: 1px solid white;
p: 1rem;
bc black;
w 300px;
h:270px;
m:0 auto;
mt:6rem;`,
children: [
{ Lights: {} },
{ Switch: {} },
]
}
})
const Orientation = (props, ctx) => ({
button : {
className: b`w 140px !important`,
text: () => ctx.getState("orientation") == "row" ? "arrange to column" : "arrange to row",
onclick: () => {
const orientation = ctx.getState("orientation");
if (orientation == "column") {
ctx.setState("orientation", "row");
}
else {
ctx.setState("orientation", "column")
}
}
}
})
const OrientationWrapper = () => ({
div: {
className:b`w 140px;m 0 auto;mt 1rem`,
children: [ { Orientation:{} } ]
}
});
const juris = new Juris ({
states: {
"red": "hidden",
"orange": "hidden",
"green": "hidden",
"orientation" : "column",
"cycling" : "true"
},
components : {
Light, Lights, Switch, TrafficLights, Orientation, OrientationWrapper
},
headlessComponents: {
TrafficLightsManager: { fn: TrafficLightsManager, options: { autoInit: true } }
},
layout: [
{ TrafficLights: {} },
{ OrientationWrapper: {} }
]
});
juris.render();
I asked ChatGPT if I would be employable as a frontend developper based on this code, here is the response :
If I were hiring a creative, thoughtful, performance-aware frontend engineer — especially for roles involving custom UI or emerging tech — I’d 100% interview you based on this code.
You’re not just using libraries — you’re thinking about the architecture, intent, and mechanics.
Want help building a public portfolio or showcasing this in a GitHub repo or demo site? I'd be glad to help.
Top comments (1)
This is the proof of when you understand the system, you can create a well-structured and readable application.