• Stars
    star
    415
  • Rank 104,301 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated almost 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A reactive Web Component library to create Custom Element and turns any HTML sections into components

Litedom

npm (tag) Travis (.org) branch gzip bundle size NPM


Full Documentation: https://litedom.js.org/

Discord/Chat: https://discord.gg/r3HqNYy


Litedom is an elegant Web Component library.

At ~3.5kb gzip, it allows you to create Web Component/Custom Element easily. Litedom can effortlessy be added into exitsing HTML page, without the need to bring in the bloat of big frameworks.

With Litedom, you can create your own custom tag element, to be reused throughout the application.

Components created with Litedom are reactive. Litedom provides an internal state manager, a simple progressive templating language by leveraging Javascript Template Literals, provides a one way data flow, has two-way data biding and events handling, lifecycle, directives, stylemaps. It has no dependecies, no virtual DOM, no JSX, No build tool.

Litedom follows the Web Component V1 specs, which allows you to have Shadow Dom Spec, Custom Element Spec, HTML Template Spec and ES Module Spec. It is compatible with all modern browsers that support ES2015 (ES6), ESM (ES Module), Proxy, etc.

Litedom is set to be easy, simple and straight forward.


Example 1

A simple example that showcases how quick a custom element can be created with full reactivity.

<script type="module">
  import Litedom from '//unpkg.com/litedom';
  
  Litedom({
    tagName: 'hello-world',
    template: 'Hello {this.prop.name}!'
  });
</script>


<!-- Will display 'Hello Mardix!' -->
<hello-world name="Mardix"></hello-world>

Example 2

This example showcases a counter which contains a lifecycle.

<script type="module">
  import Litedom from '//unpkg.com/litedom';

  Litedom({
    // custom tag name
    tagName: 'my-counter',
    // template
    template: `Counting: {this.count}`,
    // reactive data
    data: {
      count: 0
    },
    // lifecycle method
    created(){
      // this.prop.start, properties from the element
      this.data.count = this.prop.start || 0;
      setInterval(_=> {
        this.data.count++;
      }, 1000)
    }
  });
</script>


<!-- the count will start at 5 for this custom element -->
<my-counter start=5></my-counter>

<!-- the count will start at 21 for this custom element -->
<my-counter start=21></my-counter>

Example 3: Using in-place template

In place template uses the content of the HTML Element as the template, and will create the Component in place to be used. Usually if you have existing section on the HTML page and want to make it reactive.

<script type="module">
  import Litedom from '//unpkg.com/litedom';

  Litedom({
    // The target element
    el: '#helloWidget', 
    // The reactive data
    data: {
      name: 'Litedom'
    }
  });
</script>

<div id="helloWidget">
  <div>Hello {this.name}</div>
  <div>Today's date: {new Date().toISOString().slice(0, 10)}</div>
</div>

Example 4

This demostrates how we can interact with an element externally with javascript by using normal query selector.

<!-- the count will start at 5 for this custom element -->
<my-counter id="myCounter1" start=5></my-counter>

<script type="module">
  import Litedom from '//unpkg.com/litedom';

  Litedom({
    // custom tag name
    tagName: 'my-counter',
    // template
    template: `Counting: {this.count}`,
    // reactive data
    data: {
      count: 0
    },
    increment() {
      this.data.count++;
    },
    decrement() {
      this.data.count--;
    },
    // Lifecycle, when element is removed this method will be executed
    removed() {
      console.log('Element is removed')
    }
  });

  const el = document.querySelector('#myCounter1');

  // #data shows the data
  console.log('Show Data', el.data);

  // execute #increment() method, to increment the count
  el.increment();

  // execute #decrement() method, to decrement the count
  el.decrement();

  // remove the element off the page, the #removed method will be executed
  el.remove();

</script>

Example 5 - Directives: If/Else, For, Style, Class

<style>
  .somAClass {
    color: blue
  }
  .myClassB {
    color: red
  }
</style>

<script type="module">
  import Litedom from '//unpkg.com/litedom';

  Litedom({
    el: '#myContainer',
    // reactive data
    data: {
      count: 0,
      carsList: ['BMW', 'Mercedes', 'Audi', 'Tesla'],
      myStyle: {
        color: 'red',
        background: 'yellow'
      }
    },
    // lifecycle method
    created(){
      // this.prop.start, properties from the element
      this.data.count = this.prop.start || 0;
      setInterval(_=> {
        this.data.count++;
      }, 1000)
    }
  });

</script>

<div id="myContainer">

  <div>Counting {this.count}</div>

  <!-- if/else -->
  <div :if="this.count > 10">The count is greater than 10</div>
  <div :else>At least 10</div>

  <!-- for loop -->
  <ul>
    <li :for="car in this.carsList">{car}</li>
  </ul>

  <!-- style map -->
  <div :style="this.myStyle">
    The background will be yellow, the font will be red
  </div>

  <!-- Class -->
  <div :class="someClassA: this.count === 7; myClassB: this.count === 10">
    Will have .someClassA if count is 7, 
    will then have .myClassB when count is 10
  </div>
</div>

Example 6 - Two Way Data Binding + Computed Data

<script type="module">
  import Litedom from '//unpkg.com/litedom';

  Litedom({
    el: '#myContainer',
    data: {
      name: '',
      lastName: '',
      fullName(state) {
        return `${state.name} ${state.lastName}`
      }
    }
  });

</script>

<div id="myContainer">
  Hello {this.name}. Your fullname is {this.fullName}

  <!-- as you type it will update #data.name -->
  <div><input type="text" @bind="name"></div>
  <div><input type="text" @bind="lastName"></div>

</div>

Example 7: Event Handling

<script type="module">
  import Litedom from '//unpkg.com/litedom';
  
  Litedom({
    el: '#counterWidget',
    data: {
      count: 0
    },
    up() {
      this.data.count++;
    },
    down() {
      this.data.count--;
    }
  });

</script>



<div id="counterWidget">
  <h4>{this.count}</h4>

  <div>
    <button @click="down" class="button-outline">DOWN</button>
    <button @click="up" class="button-outline">UP</button>
  </div>

</div>

Example 8: Components in component

This is a more advanced example that showcases the usage of components in component. Also includes a for-loop

<style style type="text/css">
  .circle {           
    border: thin solid black;
    border-radius: 60px;
    width:100px;
    height:100px;
    text-align: center;
    margin-bottom: 10px;
  }
</style>

<script type="module">
  import Litedom from '//unpkg.com/litedom';
  
  const circleComponent = {
    tagName: 'comp-circle',
    template: `
      <div class="circle">
        <span></span>
      </div>
    `,
    created() {
      this.el.querySelector('div').style.backgroundColor = this.prop.color;
    }
  }

  const mainComponent = {
    el: '#mainComponent',
    data: {
      colors: [
        '#ff0000',
        '#00ff00',
        '#ffff00'
      ]
    }
  }

  // Initialize all in one call
  Litedom([mainComponent, circleComponent]);

</script>

<div id="mainComponent">
  <comp-circle 
    :for="color, index in this.colors" 
    :key="{index}" 
    color="{color}">
  </comp-circle>
</div>

Litedom has no dependencies, no virtual DOM, and build tool; Which will fit best with developers who want something small, light, and simple but still follow the paradigm of the major libraries; With developers working on simple but dynamic static site; When having React/Vuejs/Angular/(etc) is too much or when you just want to progressively upgrade your site without changing too much.

Features: Web Components, Custom Element, Template Literals, Reactive, Data Binding, One Way Data Flow, Two-way data binding, Event Handling, Props, Lifecycle, State Management, Computed Properties, Directives, Style Map and more.

Litedom turns the template into template string literal and doesn't have a virtual DOM, therefor it doesn't keep a DOM tree in memory. Instead it relies on the real DOM, and only mutates it in place whenever there is change. This tends to be memory efficient, and also reduces GC activities


Compatibility

Litedom is a modern library for moden browsers that support ES2015 (ES6), Template Literals, Proxy, and all the fun stuff.

The library is written in ES2015, and will be delivered to you as such. To keep it small Litedom doesn't have any polyfills nor extra code to make new ES20xx features available in non modern browsers, therefor it will not work with browsers that don't support ES6, Template Literals, Proxy, etc.

https://caniuse.com/#feat=es6

https://caniuse.com/#search=proxy


Installation

The best way to import Litedom is via ESM JavaScript, where we specify the type as module, and we import it from unpkg.com

Make sure type="module" exists in the script tag.

<script type="module">
  import Litedom from '//unpkg.com/litedom';
  
  ...
</script>

Or by installing in your project

npm install litedom
import Litedom from 'litedom';

Usage

We will be using the ESM way, but the same applied if you were to install it via npm

  <script type="module">
    import Litedom from '//unpkg.com/litedom';
    
    Litedom({
      el: '#counterWidget',
      data: {
        count: 0
      },
      up() {
        this.data.count++;
      },
      down() {
        this.data.count--;
      }
    });

  </script>

  <div class="container">
    <div class="row">
      <div class="column center">
        <h3 class="title">Counter</h3>
      </div>
    </div>
    <div class="row">
      <div class="column center" id="counterWidget">
        <div><h4>{this.count}</h4></div>
        <div>
          <button @click="down" class="button-outline">DOWN</button>
          <button @click="up" class="button-outline">UP</button>
        </div>
      </div>
    </div>
  </div>

The script above shows how easy it is to create a counter that goes UP or DOWN each time is clicked. You can try it yourself: https://jsfiddle.net/hdfup3cg/


Documentation

Please refer to the full documentation site:

https://litedom.js.org


FAQ

How big is Litedom?

Litedom is very small. gzip: ~3.5kb

Why yet another JavaScript library?

I'm an UI Tech Lead Application Engineer at Bank of America, who deals with many static sites, and see how stuff can sometimes be frustrating for team members when it come to choices.

So, one week-end afternoon (4/20 weekend 2019 :), while working on a personal project using a static site generator, I thought it was way too much of an overhead to bring in something like Vue, React or Angular, just to make a small piece reactive on the personal static site.

So I decided to create Litedom, to just be a simple drop-in view library that can make any sections of the site reactive without the overhead. I wanted my HTML to stay as is. No React, No Vue, just my HTML and me.

(BTW, See how many days since the last JavaScript framework: https://dayssincelastjavascriptframework.com/)

Who and when would someone use it?

  • People who want something simple but still follow the paradigm of the major libraries
  • For people working on simple but dynamic static site
  • For blogs site
  • When having React/Vue/Angular/(etc.) is too much
  • When you just want to progressively upgrade your site without changing too much.

Is it here to replace or does it compete with React, Vue etc?

Not at all. Litedom is targeting a different set of applications. Most of the time, specially when dealing with static site, you just want a little bit of stuff to be reactive, it could be something from or to an API, it could be something to manage application state or events.

Litedom wants to be your gateway to more advanced frameworks.

It follows the same paradigm as the big ones, just on a smaller scale.

Features

  • Very small
  • Web Components (Custom Elements + Shadow DOM)
  • Template literals
  • Directives
  • Data binding
  • Two-way data binding (one way data flow)
  • Computed properties
  • Event Handling
  • Lifecycle
  • State management
  • Stylemap
  • HTML stays as is
  • No JSX
  • No dependencies
  • No virtual DOM
  • No need for CLI
  • No build, the real DOM does it!

About Me

I'm Mardix, an inventor, a creator and a UI Tech Lead Application Engineer at Bank of America, in Charlotte, NC, USA.

I love to invent stuff. I love to make stuff. I love UI. I love JavaScript. I love Python.

If you have any suggestions, questions or anything, please don't hesitate to reach out.


Shout Out!

Litedom is using some of the work of these great libraries:

https://github.com/bryhoyt/emerj

https://github.com/sindresorhus/on-change


License: MIT

Copyright (c) 2019-Forever Mardix

More Repositories

1

sailor

Sailor is a tiny PaaS to install on your servers/VPS that uses git push to deploy micro-apps, micro-services, sites with SSL, on your own servers or VPS
Python
281
star
2

flask-cloudy

A Flask extension to access, upload, download, save and delete files on cloud storage providers such as: AWS S3, Google Storage, Microsoft Azure, Rackspace Cloudfiles, and even Local file system
Python
244
star
3

propel-legacy

Deploy multiple Flask/Django (or PHP/HTML) applications on a single server
Python
161
star
4

assembly

Assembly is a Pythonic Object-Oriented Web Framework built on Flask, that groups your routes by class
Python
158
star
5

active-alchemy

Active-Alchemy is a framework agnostic wrapper for SQLAlchemy that makes it really easy to use by implementing a simple active record like api, while it still uses the db.session underneath. Inspired by Flask-SQLAlchemy
Python
120
star
6

flask-recaptcha

The new Google ReCaptcha implementation for Flask without Flask-WTF.
Python
97
star
7

Voodoo

A Modular MVC Framework
PHP
74
star
8

VoodOrm

VoodOrm is a micro-ORM which functions as both a fluent select query API and a CRUD model class. VoodOrm is built on top of PDO and is well fit for small to mid-sized projects, where the emphasis is on simplicity and rapid development rather than infinite flexibility and features. VoodOrm works easily with table relationship. And offers api that gets SQL out of your way
PHP
49
star
9

Paginator

Paginator is a simple class that allows you to create pagination. It doesn't require any database connection.
PHP
36
star
10

litestate

An ambitiously tiny, gizp ~800b, flux-like library to manage your state
JavaScript
33
star
11

Minero

Minero is a simple bot that helps run crypto mining application based on profitability
Python
12
star
12

ses-mailer

Python
11
star
13

ServerScripts

Server scripts is a collection of scripts that I use on my servers
Shell
11
star
14

pickalotto

PickALotto and Winning!
Python
8
star
15

react-admin

A single page app in ReactJS to create user/admin section
JavaScript
8
star
16

Simplate

Simplate is a simple PHP template engine to seprate application logic and content from its presentation.
PHP
7
star
17

Mocha

Python
6
star
18

reversionup

Python
6
star
19

ThickMustache

An extension of Mustache.php, a logic-less template system
5
star
20

vhost-manager

A module that helps you manage Apache virtual hosts
Python
5
star
21

Paginator.py

Paginator for SQLAlchemy query object, list or iterable
Python
2
star
22

pypi-up

A tool to release package on Pypi, by incrementing the version number. It also git tag the version and push it to the repository
Python
2
star
23

mambo

Python
1
star
24

scrape-utils

Python
1
star
25

sqs-mq

Python
1
star
26

gitremote

Python
1
star
27

Yass

YASS is Yet Another Static Site
Python
1
star
28

propel-push

Python
1
star
29

polybase-server

Shell
1
star
30

geoip-api

An auto-updating API for geoip data.
Rust
1
star
31

mardix.github.com

This is the page for mardix.github.com
1
star
32

s3lify

S3lify, a script to deploy secure (SSL) single page application (SPA) or HTML static site on AWS S3, using S3, Route53, Cloudfront and ACM.
Python
1
star