Welcome to YumJS

Less is more!

Yum is a small reactive JavaScript library with JQuery like syntax with optional component syntax in 20kb (~10kb gzipped) OR 15kb ( ~7kb gzipped) on a build without draggables.

Yum provides a familiar procedural and/or a component based syntax with low overhead and a slice of delicious reactivity when you need it.


Downloads and Docs

GitHub Repo: Github YumJS

Feel free to download and try one of these minified versions:

Minified Download: Yum.min.js

No Dragging Download: Yum.nodrag-min.js

Documentation - in progress: Docs


A Tasty Demo

Wait ...
Wait ...
drag then drop

Features

  • Simple, easy to learn with familiar syntax.
  • Optional component (rendering) syntax with props and state.
  • A lightweight alternative to JQuery (not all JQuery functions implemented).
  • Tons of utility functions.
  • Ability to observe or subscribe to **any** element for complex reactivity.
  • Small, fast, lightweight and flexible.
  • Built in Drag and Drop/swipe.
  • Open source and extendable with intuitive plugin system.
  • A build tool (node.js) for component based apps! Read about it HERE. Get it ... Yum App Builder.

Usage

Load in your web app like:

<script async src='https://yourdomain.com/js/yum.min.js' ></script>

If you are not loading Yum in a script tag just before the closing body tag then you may want to wrap your executable code in document ready.


<script>

yum(document).ready( function(){

 // do your stuff here

});

</script>


Dragging is built in (yum.min.js)

The code for the Drag Me button above:

// assumes you have an element with an id of dragme

yum('#dragme').drag(false, { contain: '.box' });

Or shorthand to just drag with no containment options:

 yum('#dragme').drg();

Working with Selectors, Nodes or Node Collections

Yum can work with multiple selectors, single elements or collections of elements represented by variables (recommended).

Selectors can be:

  • A comma delimited list of selectors in quotes.
  • A variable holding a reference to an element.
  • An array of elements or a variable representing and array of elements.

Draggables however are accessed via #id or first of a class or singular element.

The reason draggables are declared singularly is because each draggable can be declared as a handle to drag it's parent element. Yum made this singular declaration for draggables part of the internal design. It would be weird to have many handles dragging the same parent and cause mass confusion ...

however,

as you will see, Yum makes it easy to create collections of draggables and swipes too.

// get node collections with JS and pass to Yum
// yum has a shorthand for this too (next)

const buttons = document.querySelectorAll('.button');
for(b of buttons){
yum(b).text('We are buttons');
}

Yum has a shorthand for the above that decreases DOM diving

and promotes re-use by assigning the collection to a variable using Yum's underscore function.

// assign collection to variable for re-use

const buttons = yum('.button')._; 



yum(buttons).text('We are collected buttons.');



// we can make them all draggable too! 

for(b of buttons){
yum(b).drg().text('We are draggable buttons.');
}



// the same as above using each

const drg = function(e){
yum(e).drg();
}
yum(buttons).each(drg);



// * NOTE: If you just want the first element from the collection
// returned by the underscore function you can do:
//(helpful when you want the first of a class found in the DOM)

const buttons = yum('.button')._[0];

// OR

const buttons =  yum('.button').first; 

Not shown here, the _getstack function works in a similar way as the underscore function, more on that later.


Iterate with Each

Use each to iterate over elements of a class or collection. Here we can make them all draggable.



const myFn = function(e){
yum(e).drg();
}

yum('.dragme').each(myFn);

Rename Yum if You Want

You can rename Yum to the familiar $:

window.$ = yum;

$('#dragme').drg();

Other Helpful utilities

Yum has some helpful utilities.

Like find:

yum('.main').find('#dragme').text('found');



// or use an element reference

const dm = document.querySelector('#dragme');

yum('.main').find(dm).text('found');



// pass in optional function parameter 

const fn = function(e){ console.log(e.classList) };

yum('.main').find(dm, fn).text('found');

Additional utilities include: addClass, each, attr, parents, parent, children, and more.....


Subscribe to Elements to Observe then React

Spy / Unspy

Use spy to subscribe to an element or collection and watch for changes (see also component Reactors below) .

Spy is useful for reacting to changes in properties, attributes and other things.

For example: Think about fetching data. The data is fetched and your callback or other function has changed a data-attribute, style, or added children... you can be notified and react to these occurrence if you are subscribed!

// subscribe to all instances of .box, run fn upon changes to attributes

const fn = function(e){console.log('I am subscribed to '+ e.getAttribute('data-spy'));}

yum('.box').spy(fn, 'MyName', { delay: 200, attrs: ['style', 'data-id'] })



// unsubscribe from .box elements or anything being watched starting with MyName

yum().unspy('MyName');



// unsubscribe from only first element being watched with:

yum().unspy('MyName0');



// unspy can be done from within (fn) too.

More on spy later...


Component syntax (optional)

Yum has a flexible (optional) component syntax for creating self contained components.

When used in conjunction with Yum App Builder you can compile your app code to a minified file for your project/app. Read more about that at Build Component based apps with YumJS

Yum's components are are created with functions to be later 'rendered'. They provide the means to container-ize your code without using the shadow DOM. You can make them do what you want, look how you want and make them reactive using all of Yum's other facilities for reactivity.

The syntax for initializing a component with function is similar to libraries like React JS and Preact JS and looks like this:


const App = () => {


const html = `<h1>1</h1>`;

const h = yum(html).first;

yum(h).addClass('hey');

yum(h).on('click', function() {  let num = yum(h).text(); num = Number(num) + 1 ; yum(h).text(num); console.log('num is '+num)} );

// OR

let num = 0;
yum(h).on('click', function(e){ console.log(yum(e.target)._);  num++;  e.target.atom.state = num; console.log('data is '+ e.target.data); console.log('sub is '+e.target.subscriber); yum(e.target).text(e.target.data+1) });

return h;
}


// Render the App to the body element (or wherever).

yum()._render(App, 'body', { pos: 'append', state: 'state', initState: 'hey',  });



The same component function as above but with comments explaining each item:


const App = () => {

// Create some html using template strings

const html = `<h1>1</h1>`;



// Use yum to create a virtual occurance of the html above assign to variable 'h'

const h = yum(html).first;


// Add a class to 'h' element (obtional)

yum(h).addClass('hey')


// get current text of 'h' and use the state hooks to update the number in 'h'

yum(h).on('click', function() {  let num = yum(h).text(); num = Number(num) + 1 ; yum(h).text(num); console.log('num is '+num)} );

// The variable you return here must resolve to HTML.
// Above, I used yum to create it so I could add self contained events onto 
// it but you could just return straight HTML here too. 

return h;
}


// Render the App to the body element (or wherever).
// Optional 3rd parameter can be an object where pos =  ['append, after, before, prepend'],
// reactor = [ true, false], state = reactor element ['state' or some other string].
// initState = this is for when an element is reacting to itself and will cause 'h.react' function to run
// if it exists see below 

yum()._render(App, 'body', { pos: 'append', state: 'state', initState: 'hey',  });


// If the component element ('h'  in the example above), has a function attached to it like 
// h.react function(){ }; then this component can react to itself. When initState option exists
// h.react function will auto run upon load.


// A sample h.react function here with all the things that are exposed from the reactor doing something

h.react = function(reactor){
console.log(`${reactor.name} reacted with ${reactor.data} `);
console.log(`${reactor.data} `);
yum(reactor.subscriber).text(reactor.data)
};


// Also,  suppose the the component element ('h') had a click event define before the App return like:

yum(h).on('click', function(e){ console.log(yum(e.target)._);  num++;  e.target.atom.state = num; console.log('data is '+ e.target.data); });


Creating components using functions/yum()._render() lets you compose apps with many self contained components. You can get as creative as you want and use all Yum functions inside them then render them anywhere.

State

Yum updates component state a little differently than other libraries. It uses Reactors, which are just properties that are assigned to an element. Reactors are assigned either manually using Reactor() / ReactTo() functions or automatically when rendering a component.

When a components has an el.react function like 'h.react' above, it will become reactive to itself (for updating it's own state);



// When a component is reacting to another component's Reactor (or even itself),
// you can use the result of the atom.state data directly (instead of from the h.react function which also works) using e.target.data.

// The result of the h.reactor fiddling the bits of h.atom.state will be contained in e.target.data. This is how you can update a components state!



let num = 0;

yum(h).on('click', function(e){ console.log(yum(e.target)._);  num++;  e.target.atom.state = num; console.log('data is '+ e.target.data); yum(e.target).text(e.target.data+1) });


More Here Soon

More docs and demos are currently being written and will be here soon.

If you are interested in this project, have questions, find it useful or just need someone to talk to, please contact me.