Skip to content

spuckhafte/SpuckJs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

82 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SPUCKJS

SpuckJs is a Js library which converts pure Js Objects into DOM elements.
Each object of class Spuck is a Virtual element which you can put in the DOM.

NEW DETAILED DOCUMENTATION

https://spuckjs.netlify.app/

EXAMPLES

Example 1

index.html

<head>
  <script src='https://cdn.jsdelivr.net/gh/spuckhafte/[email protected]/Spuck.js'></script>
  <script src='index.js' defer></script>
</head>
<body>
  <div id='app'></div>
</body>

index.js

// initialize the element
const Heading = new Spuck({ type: 'h1', parent: '#app', class: 'heading', id: 'heading' })

// Define properties of "Heading", i.e, "text" and "css"
Heading.prop = {
  text: "SpuckJs",
  css: { // normal css properties, following camel case (margin-inline -> marginInline)
    textAlign: 'center'
  }
}
Heading.make(); // it render and mounts the element to the dom


const NameInput = new Spuck({ type: 'input', parent: '#app', class: 'name', id: 'inp' })
NameInput.render(); // makes an element (does not put it in the dom)

const setValue = NameInput.$state('value', '') // state of the element, returns a function to update it

NameInput.prop = {
  value: '$-value', // refer to the state named "value" by using $- as prefix 
  css: {
    width: '20rem', height: '3rem', backgroundColor: 'black',
    outline: 'none', border: 'none', color: 'white',
    fontSize: '1.5rem', fontWeight: 'bold',
  }
}
NameInput.attr = { autofocus: 'true', autocomplete: 'off' }

// define events on an element and assign callbacks to them
NameInput.events = {
  keyup: e => setValue(e.target.value) // change the "value" state when someone types
}
NameInput.make('re'); // remake(update) the rendered element


const NameDisplay = new Spuck({ type: 'h2', parent: '#app', id: 'display' })
NameDisplay.render();

NameInput.init.pseudoChildren = [NameDisplay] 
/* 
    set NameDis as pseudoChild of NameInp to pass down state of the Parent (input el)
    to its children (only NameDisplay in this case). Now NameDisplay can access these
    states as pseudo-states by using $$- as prefix, eg. $$-someStateOfParent.
*/
NameInput.render('re');

const setColor = NameDisplay.$state('color', 'red'); // this state will manage the color of the text

NameDisplay.prop = { 
    text: '$$-value', // use the "value" state of NameInp (pseudo-parent)
    css: { cursor: 'pointer', color: '$-color', width: 'fit-content' } 
}
NameDisplay.events = { click: () => setColor(color => color === 'red' ? 'blue' : 'red') }
NameDisplay.make('re');

Result:

form-state

Example 2:

SpuckJs - state managed

const Input = new Spuck({ type: 'input', parent: '#app' }).render();
const setValue = Input.$state('value', '');
Input.attr = { value: '$-value', autofocus: 'true' };
Input.events = { input: e => setValue(e.target.value) };
Input.make('re');
const Display = new Spuck({ type: 'h4', parent: '#app' }).render();
Input.init.pseudoChildren = [Display];
Input.render('re');
const setColor = Display.$state('color', 'red');
Display.prop = { text: '$$-value', css: { color: '$-color', cursor: 'pointer', userSelect: 'none' } };
Display.events = { click: () => setColor(color => color === 'blue' ? 'red' : 'blue') };
Display.make('re');

SpuckJs - no state

const Input = new Spuck({ type: 'input', parent: '#app' }, {}, {}, { autofocus: 'true' }).render();
const Display = new Spuck({ type: 'h4', parent: '#app' }).render();
Display.prop = { text: '', css: { color: 'red', userSelect: 'none' } }
Display.events = { click: () => {
   Display.prop.css.color = Display.prop.css.color === 'blue' ? 'red' : 'blue'; 
   Display.render('re');
}};
Input.events = { input: e => {
  Display.prop.text = e.target.value; 
  Display.render('re') 
}};
[Input, Display].forEach(i => i.make('re'));

comparison

Example 3:

SpuckJs - state managed

const Parent = new Spuck({ type: 'div', parent: '#app' }).render();
const setBg = Parent.$state('color', 'red');
Parent.prop = { css: { width: '50px', height:'50px', background: '$-color', cursor: 'pointer', marginBlock: '2em' } };
Parent.events = { click: () => setBg('#'+Math.floor(Math.random()*16777215).toString(16)) };
Parent.make('re');
for (i=1; i <= 3; i++) {
    const Child = new Spuck({ type: 'div', parent: '#app', id: `${i}` }).render();
    Parent.init.pseudoChildren = Parent.init.pseudoChildren ? [...Parent.init.pseudoChildren, Child] : [Child];
    Parent.render('re');
    Child.prop = { css: { width: '50px', height: '50px', background: '$$-color', marginBlock: '2px' } };
    Child.make('re')
}

VanillaJs - no state

let Parent = document.createElement('div');
Object.assign(Parent.style, { width: '50px',height: '50px',background: 'red',cursor: 'pointer',marginBlock: '2em' });
let children = [];
for (i=1; i<=3; i++) {
    let Child = document.createElement('div')
    Object.assign(Child.style, { width: '50px', height: '50px', background: 'red', marginBlock: '2px' })
    children.push(Child)
}
Parent.addEventListener('click', () => {
    let color = '#'+Math.floor(Math.random()*16777215).toString(16)
    Object.assign(Parent.style, { background: color })
    children.forEach(child => child.style.background = color);
})
document.querySelector('#app').appendChild(Parent)
children.forEach(el => document.querySelector('#app').appendChild(el))

state