Hybrids
![Build Status](https://travis-ci.org/hybridsjs/hybrids.svg?branch=master)
Hybrids is a toolkit for creating web components using Custom Elements, Template and Shadow DOM specifications. It supposed to create the simplest and the easiest to use API.
Name of the project is taken from hybrid architecture, which is a core concept of the library.
Hybrid Architecture
- Component logic decoupled from custom element prototype
- Full logic encapsulation with public and private access
- Attributes and properties mapping with type reflection
- Normalized lifecycle callbacks
- Easily extendable functionality with plugins
- Helper methods for listen and dispatch events, get children or parent components and more
- Future possibility for server side rendering*
Core Packages
Package | Description |
---|
@hybrids/core | Hybrid custom elements definition and helper methods |
@hybrids/shim | Collection of polyfills for required Web APIs |
@hybrids/debug | Helpful documentation in browser DevTools |
Plugins
Package | Description |
---|
@hybrids/engine | View engine with unidirectional data binding using consistent and predictable micro DSL |
@hybrids/vdom | Middleware for connecting any React-like render library |
@hybrids/store * | State management adapted for Hybrid Custom Elements |
* Not yet implemented
Getting Started
Simple counter component can be defined like this:
class MyCounter {
constructor() {
this.value = 0;
}
count() {
this.value += 1;
}
}
There is no inheritance, no dependency injection or difficult structure - just simple definition. How can we make it
a web component, but still using it's API?
import { define } from '@hybrids/core';
import { engine } from '@hybrids/engine';
class MyCounter {
static get options() {
return {
plugins: [engine],
properties: ['value', 'count']
template: `{{ value }}`
};
}
constructor() {
this.value = 0;
}
count() {
this.value += 1;
}
}
define({ MyCounter });
From now <my-counter>
is fully working custom element:
- It displays current value in Shadow DOM (it uses
@hybrids/engine
plugin) - Value can be set by attribute
<my-counter value="100"></my-counter>
- You can access your element in DOM and set property
myCounter.value = 10
or call myCounter.count()
However, the definition has not changed. There is only one difference - options
static property. This object contains metadata required for connecting logic and custom element.
For example, using engine
plugin is optional and can be easily replaced with vdom
package to use React-like library.
Documentation
Work in progress.
Installation
NPM/Yarn
The best way to use Hybrids is to use package manager and JavaScript bundler (e.g. webpack):
npm install --save @hybrids/core
npm install --save @hybrids/engine
npm install --save @hybrids/vdom
import { define } from '@hybrids/core';
import { engine } from '@hybrids/engine';
Packages are in development mode by default. Remember to create production package with process.env.NODE_ENV
set to production
.
In Browsers
Alternatively you can use built version of Hybrids. Bundle contains core
, engine
and vdom
packages exported in global hybrids
namespace (UMD). All packages has named exports, so you can use all available API like this: hybrids.define
or hybrids.engine
.
Development mode
<script src="https://unpkg.com/hybrids@0.6.1/dist/hybrids.js"></script>
Production mode
<script src="https://unpkg.com/hybrids@0.6.1/dist/hybrids.min.js"></script>
Browser Support
Hybrids supports all evergreen browsers and IE11 with polyfills included where needed. Codebase uses ES2015 APIs, so for IE11 you need also include polyfill for that. The easiest way is to use @hybrids/shim
and core-js
packages at top of your project:
import 'core-js/shim';
import '@hybrids/shim';
...
@hybrids/shim
contains following polyfills: