Welcome to VibeJS

Vibe is a small component based library for composing user interfaces and building apps or as a general purpose JQuery like library for getting work done.

Get the code for VibeJS from GitHub here: VibeJS

Not sure if Vibe is for you? Hit me up, maybe I can help you decide if Vibe is right for your project.

Contact me: vibejs

Features

  • Small - currently under ~20KB minified.
  • Create self contained components for composing larger components and apps.
  • Optional external access to the component.
  • Rendered components receive built-in methods (the Vibe).
  • Easy familiar syntax with built-in chainable DOM manipulation methods.
  • Pass in external functions or plugin functions to your rendered components.
  • Built-in Drag and Drop.
  • Ability to set up custom observers on rendered components.
  • Convert any element or HTML string to a Vibe'd element.
  • NEW:
  • Lots of goodies like delay, queue, animate and pipe functions.
  • Animate CSS properties, color, background-color, opacity, width, height, left, etc.
  • And more ...

Basic Usage

  • Basic usage for manually adding and using VibeJS to a web page. (see Bundle with Webpack below for alternate method of use with a bundler)

Add Vibe to your page before the closing body tag :


<script src='https://yoururl.com/vibe.min.js'></script>

A basic component function that doesn't do much would look like this:

  • These would go in a script tag or external.js/bundle.js file

const aComponent = () => {

    const template = `<div> {{message}} Hey, I am a component!</div>`;

    return {
    template: template,
    className: 'myComponent',
    }
}

And to render the component to a page that contains an element with an id of 'app' would look like this:


const aRef = $vibe.render(aComponent, {
    to: '#app',
    className: 'renderedComponent',
    
    vdata: {
    message: "Hello Vibe!'
  }

});


// Reactive!
// The vdata object and {{ message }} in the template let you update {{ message }} to new values with:
// ( i.e. from "Hello Vibe!" to "I am Vibed")
aRef.message("I am Vibed");

A Component That Does a Little More

The component above works but doesn't do a whole lot. Let us make another component that does do something (a click event to log a message to the console). Look at the additions in the code and read the code comments:

Make the component with a function (again in a script tag or external.js/bundle.js):


const myComponent = () => {

    const template = `<div>Hey, I am app!</div>`; // Your component's HTML as string template, can pass in variables too;

   // Just an example function (optional)

    const func = function say() {
        console.log('I am app')
    };

    // init runs automatically if it exists

    const init = function init(e) {
    console.log('I am an '+e)
    e.$css('cursor: pointer;').$text('I am new text');  // can chain built-in e.$fns DOM methods!
    };


   // Another function but this time we will pass it in as an event handler

    const click = function click(e) {
        console.log('clicked ' + e.target.tagName ); // target may or may not be "this" if template has nested elements
        this.$fn.func(this); // In an Event "this" refers to the component and you can access $fn.func()
    };


   // A state object (optional, pass in anything you want).
   // After making changes to state, state can be reverted to original saved in component's $origState

    const state = {x:1};


   // Render uses this return object to add these to the component

   return {
        template: template,
        className: 'myComponent',
        init: init,
        fn: {
            func: func
        },
        events: {
            click: click,
        },
        state: state
    }
}

Render the component to a DIV with an id of "app" and save a reference to it as "myRef"

  • In an html file:

// somewhere in your html

<div id='app'> </div>

  • In a script tag after vibe.min.js:

// className, state, events, plugins (like fn of component) etc. can be added here too

const myRef = $vibe.render(myComponent, {
    to: '#app',
    position: 'append',
    className: 'renderedComponent',
});

  • You can render a component as many times as you want using different reference names.
  • Components can render other components too (hint: modules/import/export within components).

The Vibe

You might be wondering what the Vibe is. Components can be completely self contained however, after rendering a component it becomes vibed.

A Vibed component exposes all it's built-in methods. You can interact with the component (inside the component itself or externally) and call these built-in methods using the reference ("myRef" in this case) like:


// Call built-in Vibe functions to change the css and the text etc. (chainable).

myRef.$css('display: inline-block').$text('Hey hey!');


// Call the internal function you declared in the component

myRef.$fn.func();



// Tack on more events with $on

myRef.$on('click', function(){ console.log('my Text is: '+this.$text()) });

Vibe Any Element

You can also Vibe any existing element. Here is how you do that!

  • Use normal JavaScript OR Vibe to select an existing div with a class name ".divname"

const aDiv = document.querySelectorAll('.divname')[0];

// OR select with Vibe

const aDiv = $vibe.select('.divname'); // by default selects first occurrence of .divname. Select all with $vibe.select('.divname', {all: true} );

  • Vibe it via render. (no need to vibe if $vibe.select was used)

const aDivRef = $vibe.render(aDiv); // no need if $vibe.select was used

// Use it!
console.log('div existing text is ' + aDivRef.$text());
aDivRef.$text('I am new text.');

// if $vibe.select was used just do aDiv.$text('I am new text.');

  • * Note that when vibing existing elements, since there is no "component function", properties for className, state, events and plugin (if any) must be passed in via this render object.

Bundle With Webpack

The examples above show you how to manually add components via script tags. This section shows you the basics for using a bundler, namely Webpack.

In dist/index.html:


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>App</title>
  </head>
  <body>
      <div id='app'></div>
    <script src="https://cdn.jsdelivr.net/gh/bretgeek/VibeJS@main/vibe.min.js"></script>
    <script src="main.js"></script>
  </body>
</html>

In /src/App.js:


    export const App = () => {

    const template = '<div>I am app!</div>';
    const func = function say() {
        console.log('I am app!')
    };

    const init = function(e) {
    console.log('I am e '+e)
         e.$css('cursor: pointer;');
    }; // can add extras on e too a init time

    const click = function click(e) {
        console.log('clicked ' + e.target.tagName );
        this.$text('I was clicked!')
    };
    const state = {x:1};
    return {
        template: template,
        className: 'webpacked',
        init: init,
        fn: {
            func: func
        },
        events: {
            click: click,
        },
        state: state
    }
}

In /src/index.js:


import {App} from '/src/App.js';

function tip() {console.log('tip') };
const Appref = $vibe.render(App, {
    to: '#app',
    position: 'append',
    plugin: {tip: tip} ,
});
Appref.$plugin.tip();

Bundle it to dist/main.js with:


npx webpack

  • Visit dist/index.html to test!

Components That Render Components

In the previous bundling section you can see how imports are vital for Webpack to work.

If not using Webpack you still may need exports and imports to load in functionality from other files.

Components that render other components work the same way. You must export and import the assets you want to use.

  • If App1 is in in js/App1.js and is prefixed with export like:

export const App1 = () => {

    const template = `I am an App1 component!`;

    return {
    template: template,
    className: 'App1',
    }
}

  • App2 can import and render App1 from a method like init or any other method with:

    import {App1} from '/js/App1.js';

    const App2 = () => {

    const template = `App2 rendered an App1 component!`;

    const init = function init(e) {  // "e" here is $self and you can also pass in $self here.

    // Render App1 to App2
    const App1Ref = $vibe.render(App1, {
    to: e,
    position: 'append',
    });

    // change App1's text to show its working
    App1Ref.$text('App1 component imported to App2');

    };// End init

    return {
    template: template,
    init: init,
    className: 'App2',
    }
}

In the example above App2 imports App1 and renders it via App2's init method. The real power of this comes when rendering components to other components via Events!   Which means you can render new components via click, touch etc. add infinity. Todo list anyone?

Animation example

Below is an example of how animation works in Vibe and is what was used on the logo at the top of the page.


let logo = $vibe.select('.logobox');

logo.$fadeIn({speed: 100});

let offsetLeft = logo.offsetLeft; // get current offsetLeft to use as our value to animate to.

logo.$animate( {
        duration: 1000,
        easing: 'elasticInOut',
        move: {dir: 'left', amt: `${offsetLeft}`},
        });

Calls to $animate() are not put on the queue so that animations can be combined / chained together to create unique effects on the same element. To queue up different squential animations, use $animate from a function passed to $delay.

More examples here soon...

More coming soon...but until then here is a current list of methods that are exposed by Vibe via Vibe's return object: (Not all are chainable but the syntax should be familiar to you if you have ever worked with JQuery)


// Use with $vibe.select() or el.$select() or el.$methodname() from a vibed element (notice the $ on the method of the vibed element).
//  Look at the code to see what these do or contact me for help!
  const obj = {
    fn: fn,
    id: id,
    uuid: uuidv4,
    clone: clone,
    ready: ready,
    get: get,
    post: post,
    css: css,
    left: left,
    isTouch: isTouch,
    rpx: rpx,
    addClass: addClass,
    removeClass: removeClass,
    children: children,
    parents: parents,
    before: before,
    insertBefore: insertBefore,
    insertAfter: insertAfter,
    after: after,
    append: append,
    prepend: prepend,
    select: select,
    attr: attr,
    removeAttr: removeAttr,
    appendTo: appendTo,
    prependTo: prependTo,
    createNode: createNode,
    filterString: filterString,
    dataset: dataset,
    data: data,
    detach: detach,
    render: render,
    addplug: addplug,
    run: run,
    plugin: {},
    doc: document,
    rect: rect,
    mountedTo: false,
    cs: cs,
    ctx: ctx,
    on: on,
    observe: observe,
    observers: {},
    unobserve: unobserve,
    getobservers: getobservers,
    off: removeEvent,
    trigger: trigger,
    html: html,
    text: text,
    pager: pager,
    getState: getState,
    setState: setState,
    isFunction: isFunction,
    isObject: isObject,
    isElement: isElement,
    isArray: isArray,
    isString: isString,
    isNumber: isNumber,
    isInt: isInt,
    getAtPt: getAtPt,
    isTouching: isTouching,
    drag: drag,
    swipe: swipe,
    load: load,
    scroll: scroll,
    show: show,
    hide: hide,
    delay: delay,
    queue: queue,
    fadeIn: fadeIn,
    fadeOut: fadeOut,
    q: [],
    runq: runq,
    isrun: false,
    w: w,
    pipe: pipe,
    stream: [],
    animate: animate,
    each: each,
    stk: [],
  };