boldom
v1.1.0
Published
Scoped html lib (Bold idea)
Downloads
14
Readme
Boldom is a 1kb JS/HTML framework.
NOTE! This is meant for being used in small projects, that would require minimal js usage. And need to be run on server, will not work over file://.
This framework is based on Template Literals, global scope (yes! You heard me, this framework utilizes global window scope) and plain old HTML. I build this as an experiment of an idea of using THE platform to build front end.
Also should mention that this is a runtime framework, no compilation or build process needed.
Installation
To install the stable version:
npm install --save boldom
This assumes you are using npm as your package manager.
If you're not, you can access it on unpkg like so
<script src="https://unpkg.com/boldom"></script>
Altho it's not required, it's nice to import style-scoped
too for scoped css usage
<script src="https://unpkg.com/[email protected]/scoped.min.js"></script>
Browser Compatibility
Every evergreen browser and older ones that support ES6 Template Literals.
Documentation
Here we don't make use Compilers, Bundles, Virtual dom, Hyperscript, State management or any other fancy stuff. We use the platform (tools we are provided already, like plain old HTML for example).
State
State in Boldom is split into 3 different approaches: Local state, Global state and Store.
Local state
It is just a variable that can be changed, so this should be var
or let
.
<script>
var count = 21;
</script>
<h1>${count}</h1>
Remember that calling count
variable in html event attributes will not work as count
is not defined globally. Instead use template variable (${variable}
).
<button
- onclick="alert(count)">
+ onclick="alert(${count})">
Get count
</button>
Global state
It is also just a variable that can be changed, but it should also be rewritable so we should use var
when creating global variables.
<script>
export var count = 21;
</script>
But in this case where count
variable is exported to global scope, we can use it like so.
<button onclick="alert(count)">
Get count
</button>
There's no real functional difference between the approaches. Only that in exported case count
variable is accessible in window
scope and can be overwritten by other value with the same name.
Store
This is state manager that syncs state across multiple components. If one component changes variable, then all components using store are updated.
<script>
store.name = 'John Doe';
</script>
<h1>${store.name}</h1>
Store value can be changed as regular variable with basic assignment operator (=).
Functions
Same export logic applies for functions. Exported functions are accessable from global scope. That is why we can use them.
<script>
var count = 0;
export function increment() {
count += 1;
}
</script>
<h1>${count}</h1>
<button onclick="increment()">+</button>
Style
Styles should work as usual.
<style>
h1 {
color: red;
}
</style>
<h1>Hello World</h1>
But we can also do interesting stuff like changing style using variables. If variable changes, style gets updated too.
<script>
var index = 0;
var colors = ['red', 'green', 'blue'];
setInterval(function () {
index = (index + 1) % colors.length;
}, 1000);
</script>
<style>
h1 {
color: ${colors[index]};
}
</style>
<h1>Hello World</h1>
Now in this example, every second h1 will change it's colors.
Events
Events can be triggered on html tags.
We can also get event object using event
variable.
<button onclick="console.log(event)">Get event</button>
Same applies for current button
element node in this example by using this
variable.
<button onclick="console.log(this)">Get this reference</button>
Example
So what does Boldom component looks like? It's just an html file, stripped down a bit.
counter.html
<script>
var count = 0;
function increment() {
count += 1;
}
function decrement() {
count -= 1;
}
</script>
<style>
h1 {
font-size: ${count + 4}rem;
}
</style>
<h1>${count}</h1>
<button onclick="decrement()" ${count <= 0 && 'disabled' }>-</button>
<button onclick="increment()">+</button>
Ok so we've seen how component looks, but how the hell we can use it ? We just need to inject that component in dom using link
(it must be defined inside body
):
<body>
<link href="./count.html" />
</body>
See examples section for more demos.
Architecture
This is framework taks advantage of global scope and default html functionality. For example html has option to already trigger javascript code from props like onclick
for example this works if you try this in html.
<image src="hello.png" onclick="alert('Hi')"/>
But for it to work, we need functions to be global scope. So we export them to global scope using es6 export
syntax.
export function sayHi() {
console.log('hi');
}
becomes:
window.sayHi = function sayHi() {
console.log('hi');
}
Same happens with all exported variables, not just functions.
So now that there is increment
variable on global scope, we can do this in html:
<button onclick="sayHi()">Say hi</button>
Now that we know why we're making use of global scope, let me quickly show what happens in template engine.
For a while now we have this thing called Template literals. That basically allows us to write multi line strings and use variables inside it like so:
const count = 2;
const template = `
<h1>${count}</h1>
`;
That is basically what happens when boldom is parsing imported html files, that is why we can use that syntax.
And what about updates?
Good question.
We inject Boldom.action()
in every function found in components script
tag. So whenever any function is called in component it triggers update. And it's just simple and small dom patch algo that applies new dom tree to old one (So that buttons/inputs etc. don't lose focus and state and is a bit more faster than innerHTML).
That's all there is to it.
Caveats
- Exported variables and functions used in
<script>
tag should be defined before being used. - Props cannot be passed to component (yet).
Stay In Touch
License
Copyright (c) 2019-present, Marcis (Marcisbee) Bergmanis