├── .github
└── workflows
│ └── blank.yml
├── .gitignore
├── API.md
├── Gulpfile.js
├── README.md
├── demo.html
├── index.browser.js
├── jsdoc.json
├── lib
├── index.js
└── index.spec.js
├── package-lock.json
├── package.json
└── webpack.config.js
/.github/workflows/blank.yml:
--------------------------------------------------------------------------------
1 | name: Unit Tests
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - uses: actions/checkout@v1
11 | - uses: borales/actions-yarn@v2.1.0
12 | with:
13 | cmd: install
14 | - uses: borales/actions-yarn@v2.1.0
15 | with:
16 | cmd: test
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .idea
4 | jblocks.js
5 |
--------------------------------------------------------------------------------
/API.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## jBlocks : object
4 | Methods to define components
5 | using declaration and create new instances.
6 | Also helps to find and destroy components.
7 |
8 | **Kind**: global namespace
9 |
10 | * [jBlocks](#jBlocks) : object
11 | * [.Component](#jBlocks.Component)
12 | * [new Component(node, name, props)](#new_jBlocks.Component_new)
13 | * _instance_
14 | * [.name](#jBlocks.Component+name) : String
15 | * [.node](#jBlocks.Component+node) : HTMLElement
16 | * [.props](#jBlocks.Component+props) : Object
17 | * _static_
18 | * [.on(event, callback)](#jBlocks.Component.on) ⇒ [Component](#jBlocks.Component)
19 | * [.off(event, callback)](#jBlocks.Component.off) ⇒ [Component](#jBlocks.Component)
20 | * [.emit(event, data)](#jBlocks.Component.emit) ⇒ [Component](#jBlocks.Component)
21 | * [.once(event, callback)](#jBlocks.Component.once) ⇒ [Component](#jBlocks.Component)
22 | * [.destroy()](#jBlocks.Component.destroy) ⇒ [Component](#jBlocks.Component)
23 | * [.destroy(node)](#jBlocks.destroy) ⇒ [jBlocks](#jBlocks)
24 | * [.forget(name)](#jBlocks.forget) ⇒ [jBlocks](#jBlocks)
25 | * [.get(node)](#jBlocks.get) ⇒ [Component](#jBlocks.Component)
26 |
27 |
28 |
29 | ### jBlocks.Component
30 | **Kind**: static class of [jBlocks](#jBlocks)
31 |
32 | * [.Component](#jBlocks.Component)
33 | * [new Component(node, name, props)](#new_jBlocks.Component_new)
34 | * _instance_
35 | * [.name](#jBlocks.Component+name) : String
36 | * [.node](#jBlocks.Component+node) : HTMLElement
37 | * [.props](#jBlocks.Component+props) : Object
38 | * _static_
39 | * [.on(event, callback)](#jBlocks.Component.on) ⇒ [Component](#jBlocks.Component)
40 | * [.off(event, callback)](#jBlocks.Component.off) ⇒ [Component](#jBlocks.Component)
41 | * [.emit(event, data)](#jBlocks.Component.emit) ⇒ [Component](#jBlocks.Component)
42 | * [.once(event, callback)](#jBlocks.Component.once) ⇒ [Component](#jBlocks.Component)
43 | * [.destroy()](#jBlocks.Component.destroy) ⇒ [Component](#jBlocks.Component)
44 |
45 |
46 |
47 | #### new Component(node, name, props)
48 |
49 | | Param | Type |
50 | | --- | --- |
51 | | node | HTMLElement |
52 | | name | String |
53 | | props | Object |
54 |
55 |
56 |
57 | #### component.name : String
58 | Name of the components used in decl
59 |
60 | **Kind**: instance property of [Component](#jBlocks.Component)
61 |
62 |
63 | #### component.node : HTMLElement
64 | Node which component is binded with
65 |
66 | **Kind**: instance property of [Component](#jBlocks.Component)
67 |
68 |
69 | #### component.props : Object
70 | Props of the component gained from data-props
71 |
72 | **Kind**: instance property of [Component](#jBlocks.Component)
73 |
74 |
75 | #### Component.on(event, callback) ⇒ [Component](#jBlocks.Component)
76 | Attach an event handler function for the given event
77 |
78 | **Kind**: static method of [Component](#jBlocks.Component)
79 |
80 | | Param | Type |
81 | | --- | --- |
82 | | event | String |
83 | | callback | function |
84 |
85 |
86 |
87 | #### Component.off(event, callback) ⇒ [Component](#jBlocks.Component)
88 | Remove an event handler function for the given event
89 |
90 | **Kind**: static method of [Component](#jBlocks.Component)
91 |
92 | | Param | Type |
93 | | --- | --- |
94 | | event | String |
95 | | callback | function |
96 |
97 |
98 |
99 | #### Component.emit(event, data) ⇒ [Component](#jBlocks.Component)
100 | Execute all handlers attached for the given event
101 |
102 | **Kind**: static method of [Component](#jBlocks.Component)
103 |
104 | | Param | Type |
105 | | --- | --- |
106 | | event | String |
107 | | data | \* |
108 |
109 |
110 |
111 | #### Component.once(event, callback) ⇒ [Component](#jBlocks.Component)
112 | Attach an event handler function for the given event
113 | which will be called only once
114 |
115 | **Kind**: static method of [Component](#jBlocks.Component)
116 |
117 | | Param | Type |
118 | | --- | --- |
119 | | event | String |
120 | | callback | function |
121 |
122 |
123 |
124 | #### Component.destroy() ⇒ [Component](#jBlocks.Component)
125 | Destroy the instance
126 |
127 | **Kind**: static method of [Component](#jBlocks.Component)
128 |
129 |
130 | ### jBlocks.destroy(node) ⇒ [jBlocks](#jBlocks)
131 | Destroy instance binded to the node
132 |
133 | **Kind**: static method of [jBlocks](#jBlocks)
134 |
135 | | Param | Type |
136 | | --- | --- |
137 | | node | HTMLElement |
138 |
139 |
140 |
141 | ### jBlocks.forget(name) ⇒ [jBlocks](#jBlocks)
142 | Remove declaration from cache
143 |
144 | **Kind**: static method of [jBlocks](#jBlocks)
145 |
146 | | Param | Type | Description |
147 | | --- | --- | --- |
148 | | name | String | name of component |
149 |
150 |
151 |
152 | ### jBlocks.get(node) ⇒ [Component](#jBlocks.Component)
153 | Create and return a new instance of component
154 |
155 | **Kind**: static method of [jBlocks](#jBlocks)
156 | **Returns**: [Component](#jBlocks.Component) - a new instance
157 |
158 | | Param | Type |
159 | | --- | --- |
160 | | node | HTMLElement |
161 |
162 |
--------------------------------------------------------------------------------
/Gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var mocha = require('gulp-mocha-phantomjs');
3 |
4 | gulp.task('test', function() {
5 | return gulp
6 | .src('tests/index.html')
7 | .pipe(mocha({reporter: 'nyan'}));
8 | });
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jBlocks
2 |
3 | [](http://badge.fury.io/js/jblocks)
4 | 
5 |
6 | - **[Codepen DEMO](http://codepen.io/vitkarpov/pen/eZReaE?editors=0010)**
7 | - **[Full API Doc created from source](https://github.com/vitkarpov/jblocks/blob/master/API.md)**
8 |
9 | jBlocks helps to create interface components in a functional programming flavour.
10 |
11 | It's build on the following simple rules:
12 |
13 | - declare your components
14 | - set special data-attributes in HTML to bind an instance of the component (will be created in the future) to the node
15 | - interact with components using API, events and other components
16 |
17 | ## Give me an example
18 |
19 | Let we have a simple component.
20 |
21 | Counter with 2 buttons to increase and decrease its value. It could be a lot of independent counters on a page with different initials values.
22 |
23 | At first we need to declare a component in JavaScript and then mark some nodes in HTML using special data-attributes.
24 |
25 | ## Declare a component in JavaScript
26 |
27 | Declare a component:
28 |
29 | ```js
30 | jBlocks.define('counter', {
31 | events: {
32 | 'click .js-inc': 'inc',
33 | 'click .js-dec': 'dec'
34 | },
35 |
36 | methods: {
37 | oninit: function() {
38 | this._currentValue = Number(this.props.initialValue);
39 | },
40 | ondestroy: function() {
41 | this._currentValue = null;
42 | },
43 | /**
44 | * Increases the counter, emits changed event
45 | */
46 | inc: function() {
47 | this._currentValue++;
48 | this.emit('changed', {
49 | value: this._currentValue
50 | });
51 | },
52 | /**
53 | * Decreases the counter, emits changed event
54 | */
55 | dec: function() {
56 | this._currentValue--;
57 | this.emit('changed', {
58 | value: this._currentValue
59 | });
60 | },
61 | /**
62 | * Returns the current value
63 | * @return {Number}
64 | */
65 | getCurrentValue: function() {
66 | return this._currentValue;
67 | }
68 | }
69 | })
70 | ```
71 |
72 | ## Declare a component in HTML
73 |
74 | To make some node as a root node of the component we should set special `data` attributes:
75 |
76 | - `data-component` — name of the given component (`counter` in this case)
77 | - `data-props` — initial properties (`{ "initialValue": 2 }` in this case)
78 |
79 | ```html
80 |
81 |
82 |
83 |
84 | ```
85 |
86 | ## Create instances and interact with them
87 |
88 | After describing all components in declarative way it's time to create an instance and interact with it using API:
89 |
90 | ```js
91 | // somewhere in my program...
92 |
93 | var counter = jBlocks.get(document.querySelector('.js-counter'));
94 |
95 | // use event to react on what happens during lifecycle
96 | counter.on('changed', function() {
97 | console.log('hello, world!');
98 | });
99 |
100 | // ... when user clicks on inc button
101 | // log => 'hello, world!'
102 |
103 | // log => 3, cause the counter has been increased
104 | counter.getCurrentValue();
105 |
106 | // ... then I decided to decrease it using API
107 | counter.dec();
108 |
109 | // log => 2
110 | counter.getCurrentValue();
111 |
112 | // If I remove nodes from DOM instance should be destroyed
113 | counter.destroy();
114 | ```
115 |
116 | ## Usage
117 |
118 | ### CDN
119 |
120 | Include the library:
121 |
122 | ```html
123 |
124 | ```
125 |
126 | :warning: You may use any available version instead of `latest` in the URL above.
127 |
128 | `jBlocks` namespace is now in global scope.
129 |
130 | ### Commonjs
131 |
132 | First of all, get the package using npm:
133 |
134 | ```
135 | npm install jblocks
136 | ```
137 |
138 | After the package ends up in you `node_modules`:
139 |
140 | ```js
141 | var jblocks = require('jblocks');
142 | ```
143 |
144 | You can use the **[full API Doc generated from source](http://vitkarpov.com/jblocks)**.
145 |
146 | Also, feel free to drop me a line — [viktor.s.karpov@gmail.com](mailto:viktor.s.karpov@gmail.com)
147 |
--------------------------------------------------------------------------------
/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | jBlocks demo
8 |
9 |
10 |