This commit is contained in:
garrettmills
2020-04-08 08:42:39 -05:00
commit f871593191
14 changed files with 720 additions and 0 deletions

57
src/rivets/Component.js Normal file
View File

@@ -0,0 +1,57 @@
import { bindable } from './helpers.js'
// Base class for a Rivets.js component
export default class Component {
/**
* return the HTML selector of the component
* @return {string}
*/
static selector() { return '' }
/**
* return the HTML template of the component
* @return {string}
*/
static template() { return '' }
/**
* Called when the component is initialized
* @param {element} el - the instantiated DOM element
* @param {object} data - the data attributes of the component
* @return {Component}
*/
static initialize(el, data) {
return new this(el, data)
}
/**
* The constructor.
* @param {element} el - the instantiated DOM element
* @param {object} data - the data attributes of the component
*/
constructor(el, data) {
/**
* The DOM element this component is associated with.
* @type {element}
*/
this.element = el
}
/**
* Returns the reference to this component.
* Useful for passing the whole component along.
*/
get self() {
return this
}
/**
* Returns a self-binding proxy wrapper for this class.
* Useful for passing methods to components.
*/
get bind() {
return bindable(this)
}
}

41
src/rivets/Loader.js Normal file
View File

@@ -0,0 +1,41 @@
// Loads the assets/components into the Rivets.js framework
export default class Loader {
constructor({ components }) {
this.components = components
this.state = {}
}
// Prepare the Rivets.js framework by loading component definitions
initialize() {
for ( const key in this.components ) {
if ( !this.components.hasOwnProperty(key) ) continue
const component = this.components[key]
// Register the component class with the rivets framework
rivets.components[component.selector()] = {
template: () => {
return component.template()
},
initialize: (el, data) => {
return new component(el, data)
}
}
}
// Load the custom property binders
this._init_binders()
}
_init_binders() {
// Binds to the CSS background property
rivets.binders.background = (el, value) => {
el.style.background = value;
}
}
// Bind the Rivets.js application to the specified target
bind(target) {
rivets.bind(document.querySelector(target), this.state)
}
}

26
src/rivets/helpers.js Normal file
View File

@@ -0,0 +1,26 @@
// Wraps an object-like thing with a proxy to self-bind top-level functions
const bindable = (base_class) => {
return new Proxy(base_class, {
get(target, property) {
// If we're accessing a function of the item, force-bind it
if ( typeof base_class[property] === 'function' && base_class.hasOwnProperty(property) ) {
return base_class[property].bind(base_class)
}
return base_class[property]
},
set(target, property, value) {
base_class[property] = value
}
})
}
// Async sleeper function
const wait = (ms) => {
return new Promise(resolve => {
setTimeout(resolve, ms)
})
}
export { bindable, wait }