Small, powerfull fast and minimalistic front end web framework - less than 2kB gzipped
It transpiles given in component method object into native javascript code so it is very fast and almost no execution overhead on framework itself.
- Keep it smaller than 2kB
- Not overbloat it with features
- Keep it simple to try, learn and understand
- [TODO] Make separate version for developers with all possible debugging capabilities (no limit on size)
- [TODO] Make Reven bundler and minifier
Framework introduces two methods on HTMLElement class for accessing attributes (attribSet, attribGet) and you should use them instead of native ones (setAttribute, getAttribute) when accessing programatically attributes.
const element = document.createElement('div');
element.attribSet('class', 'someStyle') // sets single attribute
element.attribSet({ // setts multiple attributes
class: 'someStyle',
name: 'someElement'
})
const class = element.attribGet('class'); //gets single attribute
const attributes = element.attribGet({ //gats given attributes
class: true,
name: true
})
const allAttributes = element.attribGet(); // gets all defined in component attributes
Every template
element in HTML document containing attribute 'id' should hold component description.
<template id="main-page">
<!-- place your html code here -->
<!-- every element with attribute 'id' set will be available as variable with same name to component methods -->
<script>
// placing script with component definition is optional and necesarry if you need to define certain behavior of component
component({
storage: false,
methods: {
},
listen: [
],
attributes: {
/* your attributes here */
},
lifecycle: {
/* lifecycle events here */
},
emits: {
/* define here list of events that this comopnent emits */
}
})
</script>
<style>
/* place your styles here, they will be available only to that component */
/* use CSS variables if necesarry */
</style>
</template>
<!-- when all components are defined place 'raven' method with name of main component to execute -->
<script>raven('main-page')</script>
Setting this property to 'true' makes component actually an state storage, element itself will be invisible. You can use events and attributes to manage communication between components
Defines local comopnent methods (they are not public, available only as variables to given component). Example:
methods: {
hello: () => console.log('hello')
}
Assigns methods that will act as event listeners to given by name elements
listen: [
[{buttonClicked: 'click'}, ()=>{
console.log('Button clicked')
}],
[{this: 'click'}, ()=>{
console.log('Component clicked')
}],
[{this: ['blur', 'mouseover']}, ()=>{
console.log('Component mouseover or blur')
}],
]
Defines component attributes. Simple way:
attributes: {
title: (newValue, oldValue) => { // string type of attribute
return newValue; // value returned here will be available as oldValue with next run
},
counter: [(newValue, oldValue) => { // non string type of attribute (object, array, boolean...)
return newValue; // value returned here will be available as oldValue with next run
}],
}
With setters and getters:
attributes: {
title: {
set: (newValue, oldValue) => { // string type of attribute
return newValue; // that value will be also passed to getter in next run
},
get: (value) => { // string type of attribute
return value;
}
},
counter: [{ // non string type of attribute (object, array, boolean...)
set: (newValue, oldValue) => { // string type of attribute
return newValue; // that value will be also passed to getter in next run
},
get: (value) => { // string type of attribute
return value;
}
}],
}
With setters, getters and initializers:
attributes: {
title: {
init: () => { let sharedValue = 'some title:'; }, // init is required to be an arrow function w/o arguments
set: (newValue, oldValue) => { // string type of attribute
console.log(sharedValue);
return newValue; // that value will be also passed to getter in next run
},
get: (value) => { // string type of attribute
console.log(sharedValue);
return value;
}
},
counter: [{ // non string type of attribute (object, array, boolean...)
init: () => { let sharedValue = 10; },
set: (newValue, oldValue) => { // string type of attribute
console.log(sharedValue);
return newValue; // that value will be also passed to getter in next run
},
get: (value) => { // string type of attribute
console.log(sharedValue);
return value;
}
}],
}
lifecycle: {
init: () => {console.log('init')}, // init is required to be an arrow function w/o arguments
// all variables consts and let will be available to all component methods
append: () => {console.log('append')},
remove: () => {console.log('remove')},
move: () => {console.log('move')}
}
Defines events that component emits, these events can be used then by executing 'emit.nameofevent'
emits: {
titleChanged: true, // true is a short for {bubbles:true,composed:true}
submitPerformed: {
bubbles:true,
composed:true
}
}
Feel free to drop a line of code, post a bug or feature request and so on.