0.4.16 • Published 5 years ago

vanilly v0.4.16

Weekly downloads
62
License
MIT
Repository
github
Last release
5 years ago

vanilly

Use VanillaJS chained declarative UI, No lifecycle, No state, No diff VDOM.

Gesundheit: UI=fn(state) -> UI=browser(DOM)

npm.io

No React, No Vue, Easy SPA

Compress typeSize
No Gzip5k
Gzip2.5k

Feature:

  • Zero dependencies
  • Freedom, you can use any design mode
  • Fast, no diff VDOM pay expenses
  • Chained declarative UI (Like JSX or Flutter ?)
  • Only element helper functions
  • Easy create css and use BEM in Javascript
  • Support IE 9 (precondition add core.Set polyfill)

Install

Use unpkg:

<script src="https://unpkg.com/vanilly@0.4.12/umd/index.js"></script>

Or use npm:

npm i --save vanilly
# or
yarn add vanilly

Example

Register css:

import $ from 'vanilly';

$.css(`.red-box {background:#f00;}`);

Chain declarative UI:

import $ from 'vanilly';

const box = $('div')
  .$id('box')
  .$text('hello')
  .$class('red-box')
  .$append(
    $('h2').$text(`I'm a title`),
    $('input').$val(`I'm a input`),
    $('button').$text(`I'm a button`),
    $('a').$text(`I'm a <a />`),
  );

// render in dom
document.body.append(box);

Extends any element:

import $ from 'vanilly';

const oldBox = document.getElementById('box');

const box = $(oldBox);
box.$text('hello');

document.body.append(box);

Bind data:

import $ from 'vanilly';
import Observer from 'vanilla-observer';

const obs = Observer({ value: '' });

const inputA = $('input').$on('input', function(e) {
  obs.update(s => (s.value = e.target.value));
});

const inputB = $('input').$on('input', function(e) {
  obs.update(s => (s.value = e.target.value));
});

// Listen obs.update, and when inputA remove auto unListen it
obs.connectElement(inputA, s => {
  inputA.value = s.value;
});

obs.connectElement(inputB, s => {
  inputB.value = s.value;
});

document.body.append(inputA, inputB);

Tutorial

Here have recode React Tutorial: https://reactjs.org/tutorial/tutorial.html

All code in 2.8kb, It have: Vanilly, CSS, src/*.ts:

screenshot

Tutorial Demo: vanilly.workos.top

import $ from 'vanilly';
import { calculateWinner } from './utils/calculateWinner';
import './css';

// pure-component
const Square = (val: number | string, onClick: Function) => {
  return $('button')
    .$class('square')
    .$text(val)
    .$on('click', function() {
      const v = onClick(this);
      // Use new data rerender self
      this.$replace(Square(v, onClick));
    });
};

// board, Lifting State up here
const Board = (name: string) => {
  const squares = Array(9).fill(null);
  const status = 'Next player: X';
  let xIsNext = true;

  const handleClick = (i: number) => {
    if (squares[i] || calculateWinner(squares)) {
      return;
    }
    squares[i] = xIsNext ? 'X' : 'O';

    xIsNext = !xIsNext;
    updateGameStatus();
  };

  const renderSquare = (i: number) => {
    return Square('', () => {
      handleClick(i);
      return squares[i];
    });
  };

  const updateGameStatus = () => {
    const winner = calculateWinner(squares);
    let status: string;

    if (winner) {
      status = `Winner: ${winner}`;
    } else {
      status = `Next player: ${xIsNext ? 'X' : 'O'}`;
    }

    game.$query('#status', el => el.$text(status));
  };

  const game = $('div').$append(
    $('div').$text(name),
    $('div')
      .$id('status')
      .$class('status')
      .$text(status),
    $('div')
      .$class('board-row')
      .$append(renderSquare(0), renderSquare(1), renderSquare(2)),
    $('div')
      .$class('board-row')
      .$append(renderSquare(3), renderSquare(4), renderSquare(5)),
    $('div')
      .$class('board-row')
      .$append(renderSquare(6), renderSquare(7), renderSquare(8)),
  );

  return game;
};

// Game application, render some board
const Game = () => {
  return $('div')
    .$class('game')
    .$append(
      $('div')
        .$class('game-board')
        .$append(Board('Game A')),
      $('div')
        .$class('game-board')
        .$append(Board('Game B')),
      $('div')
        .$class('game-board')
        .$append(Board('Game C')),
    );
};

document.body.append(Game());

APIs

Root api

use \$.xxx:

nameparamsdescription
csscss:string; BEM?:stringinsert css in document, and use BEM replace .^
stylesrc:string; onload?:Functioninsert script in document
randomIdnoneCreate random id

Element api

use \$(element).xxx:

nameparamsdescription
\$reffn:(ele: this)=>anyGet element
\$idid:stringSet element.id
\$propsobj:objectSet elementkey = value
\$getPropkey:string; callback:(value:any)=>anyGet elementkey, and callback
\$texttext:stringCreate {text}, and append to element
\$getTextfn:(text:string)=>anyGet \$text created span.textContent
\$valval:anySet element.value
\$htmlhtml:stringSet element.innerHtml
\$queryseletor:string; callback:(node:Element)=>any; unfindable?:()=>anyelement.querySelector and callback, if unfind, callback unfindable
\$queryAllseletor:string; callback:(nodes:Element[])=>anyelement.querySelectorAll and callback
\$beforenewNode:Elementinsert node before element
\$beforeQueryselector:string; newNode:Element; unfindable?:()=>anyelement.querySelector and insert node before element, if unfind, callback unfindable
\$insertposition: 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend', newNode:Elementrun element.insertAdjacentElement
\$append...nodes:any[]element.append some elements
\$childrenfn:(children:Elements)=>anyGet element.children
\$childWithfn:(child:Element, index: number)=>anyForEach element.children
\$parentfn:(node:Element)=>anyGet element.parent
\$attrkey:string, value: anySet or remove element attribute
\$cssTextcssText:stringSet element.style.cssText
\$classcssText:string; BEM?:string;Set element.className, and use BEM replace ^ string
\$classAddcssText:string; BEM?string;Add a class in element classList
\$classRemovecssText:string; BEM?string;Remove a class in element classList
\$classReplacecssText:string; BEM?string;Replace a class in element classList
\$classContainscssText:string; fn:(isHave:boolean)=>any; BEM?string;Get contains a class in element classList
\$styleobj:CSSStyleSet element.style with object
\$checkAppend (slowly)fn :(self:this)=>any; timeOut?:nubmercheck element is append in document with timeOut's time
\$checkRemove (slowly)fn :(self:this)=>any; timeOut?:nubmercheck element is remove in document with timeOut's time
\$replacenode:anyUse node replace self
\$replaceChildnextNode:any, oldNode:anyUse element replace a self child element
\$replaceWithfn: (oldNode:any, index:number)=>anyForEach self children and replace new element
\$ontype:string; listener:(ev:HTMLElementEvent)=>anySet event to element, like element.onclick = fn
\$addEventtype:string; listener:(ev:HTMLElementEvent)=>any; options: boolean | EventListenerOptionsaddEventListener to element
\$removeEventtype:string, listener:(ev:HTMLElementEvent)=>any; options: boolean | EventListenerOptionsremoveEventListener to element

Ecology

All vanilla.js packages can use vanilly

Because vanilly is vanilla.js's helper functions

We created some vanilla.js packages:

You can search other packages in github: https://github.com/search?q=vanilla

npm.io

We have a very large ecosystem :)

0.4.16

5 years ago

0.4.15

5 years ago

0.4.14

5 years ago

0.4.13

5 years ago

0.4.12

5 years ago

0.4.11

5 years ago

0.4.10

5 years ago

0.4.9

5 years ago

0.4.8

5 years ago

0.4.7

5 years ago

0.4.6

5 years ago

0.4.5

5 years ago

0.4.4

5 years ago

0.4.3

5 years ago

0.4.2

5 years ago

0.4.1

5 years ago

0.4.0

5 years ago

0.3.5

5 years ago

0.3.4

5 years ago

0.3.3

5 years ago

0.3.2

5 years ago

0.3.1

5 years ago

0.3.0

5 years ago

0.2.13

5 years ago

0.2.12

5 years ago

0.2.11

5 years ago

0.2.10

5 years ago

0.2.9

5 years ago

0.2.8

5 years ago

0.2.7

5 years ago

0.2.6

5 years ago

0.2.5

5 years ago

0.2.4

5 years ago

0.2.3

5 years ago

0.2.2

5 years ago

0.2.1

5 years ago

0.2.0

5 years ago

0.1.4

5 years ago

0.1.3

5 years ago

0.1.2

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago