custom-elements-ts 0.0.16 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,168 +1,191 @@
1
- # custom-elements-ts
2
-
3
- [![Coverage Status](https://coveralls.io/repos/github/geocine/custom-elements-ts/badge.svg?branch=master)](https://coveralls.io/github/geocine/custom-elements-ts?branch=master)
4
- [![Build Status](https://travis-ci.org/geocine/custom-elements-ts.svg?branch=master)](https://travis-ci.org/geocine/custom-elements-ts)
5
- [![npm version](https://badge.fury.io/js/custom-elements-ts.svg)](https://www.npmjs.com/package/custom-elements-ts)
6
- [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
-
8
-
9
- Create native custom elements using Typescript without using any third party libraries.
10
-
11
- ```
12
- npm install custom-elements-ts
13
- ```
14
-
15
- ## Usage
16
-
17
- ```ts
18
- import { CustomElement } from 'custom-elements-ts';
19
-
20
- @CustomElement({
21
- tag: 'counter-element',
22
- templateUrl: 'counter-element.html',
23
- styleUrl: 'counter-element.scss'
24
- })
25
- export class CounterElement extends HTMLElement {
26
- // code as you would when creating a native HTMLElement
27
- // full source code is at demo/counter
28
- }
29
- ```
30
-
31
- ```html
32
- <!--index.html-->
33
- <counter-element></counter-element>
34
- <script src="counter.umd.js"></script>
35
- ```
36
-
37
- ## Decorators
38
-
39
- | Decorator | Target | Parameters | Description |
40
- |-------------|----------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
41
- | @Prop() | property | - | custom attribute/properties, reflects primitive properties to attributes |
42
- | @Toggle() | property | - | boolean attribute/properties, it is based on the presence of the attribute but also works with "true" and "false" |
43
- | @Dispatch() | property | (event?) | used to declare a CustomEvent which you could dispatch using the `.emit` method of its type `DispatchEmitter`. The `event` parameter is used to set the name of the `CustomEvent` |
44
- | @Watch() | method | (property) | triggers the method when a `property` is changed |
45
- | @Listen() | method | (event, selector?) | listens to an `event` on the `host` element or on the `selector` if specified |
46
-
47
- ### @Prop()
48
- ```ts
49
- import { CustomElement, Prop } from 'custom-elements-ts';
50
-
51
- @CustomElement({
52
- tag: 'todo-list',
53
- ...
54
- })
55
- export class TodoList extends HTMLElement {
56
- @Prop() color: string;
57
- @Prop() list: TodoItem[];
58
- }
59
- ```
60
- Since `color` is a primitive type of `string` it can be accessed via attributes and properties
61
- ```ts
62
- const element = document.querySelector('todo-list');
63
- // accessing value via attribute
64
- const attrValue = element.getAttribute('color');
65
- // setting value via attribute
66
- element.setAttribute('color', 'red');
67
-
68
- // accessing value via property
69
- const propertyValue = element.color;
70
- // setting via property
71
- element.color = 'red';
72
- ```
73
-
74
- On the other hand `list` is a rich data type (objects or arrays) can only be accessed/set via property
75
-
76
- ### @Toggle()
77
- Toggle attributes work the same way as HTML boolean attributes as defined by [W3C](http://www.w3.org/TR/2008/WD-html5-20080610/semantics.html#boolean) for the most part. We changed a few things to overcome confusion. Check the table below for reference:
78
-
79
- | Markup | `disabled` | Description |
80
- |-------------------------------|------------|----------------------------------------------------------------------|
81
- | `<c-input />` | false | Follows W3C standard |
82
- | `<c-input disabled/>` | true | Follows W3C standard |
83
- | `<c-input disabled="true"/>` | true | Follows W3C standard |
84
- | `<c-input disabled="asd"/>` | false | `false` since `asd` does not evaluate to a valid boolean |
85
- | `<c-input disabled="false"/>` | false | `false` since the boolean `false` converted to a string is `"false"` |
86
- | `<c-input disabled="true"/>` | true | `true` since the boolean `true` converted to a string is `"true"` |
87
-
88
- ### @Dispatch()
89
-
90
- **Creating a custom event**
91
-
92
- ```ts
93
- import { CustomElement, Dispatch, DispatchEmitter } from 'custom-elements-ts';
94
-
95
- ...
96
- export class TodoList extends HTMLElement {
97
- // Creating a CustomEvent
98
- // custom event name will be `on.change`
99
- @Dispatch() onChange: DispatchEmitter;
100
-
101
- // Creating a CustomEvent with custom name `ce.select`
102
- @Dispatch('ce.select') onSelect: DispatchEmitter;
103
- }
104
- ```
105
- **Triggering the custom event** from the example above:
106
-
107
- ```ts
108
- triggerOnChange() {
109
- // adding more data to the event object
110
- this.onChange.emit({detail: 'event changed'});
111
- this.onSelect.emit({detail: 'select triggered'});
112
- }
113
- ```
114
- ### @Watch()
115
-
116
- ```ts
117
- import { CustomElement, Dispatch, Prop } from 'custom-elements-ts';
118
-
119
- ...
120
- export class TodoList extends HTMLElement {
121
- @Prop() color: string;
122
-
123
- @Watch('color')
124
- colorChanged() {
125
- // trigger when color property color changes
126
- // either via property or attribute
127
- }
128
- }
129
- ```
130
-
131
- ### @Listen()
132
-
133
- Listen has parameters `event` and `selector`. `Event` is any valid javascript event. `Selector` is anything that works with [querySelector()](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
134
-
135
- ```ts
136
- import { CustomElement, Dispatch, Prop } from 'custom-elements-ts';
137
-
138
- ...
139
- export class TodoList extends HTMLElement {
140
- @Listen('click')
141
- elementClicked() {
142
- // triggers when the element is clicked
143
- }
144
-
145
- @Listen('click','a')
146
- anchorClicked() {
147
- // triggers when an `a` inside the element is clicked
148
- }
149
- }
150
- ```
151
-
152
- ## Setup
153
-
154
- ### Running the demos
155
-
156
- ```
157
- npm start <element-name>
158
- ```
159
-
160
- ### Building the demo
161
-
162
- ```
163
- npm run build <element-name>
164
- ```
165
- If you want to create a minified bundle
166
- ```
167
- npm run build -- <element-name> --prod
168
- ```
1
+ # custom-elements-ts
2
+
3
+ [![Coverage Status](https://coveralls.io/repos/github/geocine/custom-elements-ts/badge.svg?branch=master)](https://coveralls.io/github/geocine/custom-elements-ts?branch=master)
4
+ ![CI](https://github.com/geocine/custom-elements-ts/actions/workflows/ci.yml/badge.svg)
5
+ [![npm version](https://badge.fury.io/js/custom-elements-ts.svg)](https://www.npmjs.com/package/custom-elements-ts)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+
8
+
9
+ Create native custom elements using Typescript without using any third party libraries.
10
+
11
+ ```
12
+ npm install custom-elements-ts
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { CustomElement } from 'custom-elements-ts';
19
+
20
+ @CustomElement({
21
+ tag: 'counter-element',
22
+ templateUrl: 'counter-element.html',
23
+ styleUrl: 'counter-element.scss'
24
+ })
25
+ export class CounterElement extends HTMLElement {
26
+ // code as you would when creating a native HTMLElement
27
+ // full source code is at demo/counter
28
+ }
29
+ ```
30
+
31
+ ```html
32
+ <!--index.html-->
33
+ <counter-element></counter-element>
34
+ <script src="counter.umd.js"></script>
35
+ ```
36
+
37
+ ## Decorators
38
+
39
+ | Decorator | Target | Parameters | Description |
40
+ |-------------|----------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
41
+ | @Prop() | property | - | custom attribute/properties, reflects primitive properties (string, number, boolean) to attributes |
42
+ | @Toggle() | property | - | boolean attribute/properties, it is based on the presence of the attribute but also works with "true" and "false" |
43
+ | @Dispatch() | property | (event?) | used to declare a CustomEvent which you could dispatch using the `.emit` method of its type `DispatchEmitter`. The `event` parameter is used to set the name of the `CustomEvent` |
44
+ | @Watch() | method | (property) | triggers the method when a `property` is changed |
45
+ | @Listen() | method | (event, selector?) | listens to an `event` on the `host` element or on the `selector` if specified |
46
+
47
+ ### @Prop()
48
+ ```ts
49
+ import { CustomElement, Prop } from 'custom-elements-ts';
50
+
51
+ @CustomElement({
52
+ tag: 'todo-list',
53
+ ...
54
+ })
55
+ export class TodoList extends HTMLElement {
56
+ @Prop() color: string;
57
+ @Prop() list: TodoItem[];
58
+ }
59
+ ```
60
+ Since `color` is a primitive type of `string` it can be accessed via attributes and properties
61
+ ```ts
62
+ const element = document.querySelector('todo-list');
63
+ // accessing value via attribute
64
+ const attrValue = element.getAttribute('color');
65
+ // setting value via attribute
66
+ element.setAttribute('color', 'red');
67
+
68
+ // accessing value via property
69
+ const propertyValue = element.color;
70
+ // setting via property
71
+ element.color = 'red';
72
+ ```
73
+
74
+ On the other hand `list` is a rich data type (objects or arrays), and functions/classes can only be accessed/set via property and are not reflected as attributes.
75
+
76
+ ```ts
77
+ // Functions and classes are not reflected to attributes
78
+ @Prop() onChange: (detail: any) => void;
79
+ @Prop() itemConstructor: { new(...args: any[]): any };
80
+
81
+ element.onChange = () => {};
82
+ // not reflected as attribute
83
+ console.log(element.getAttribute('on-change')); // null
84
+
85
+ class Foo {}
86
+ element.itemConstructor = Foo;
87
+ // not reflected as attribute
88
+ console.log(element.getAttribute('item-ctor')); // null
89
+ ```
90
+
91
+ ### @Toggle()
92
+ Toggle attributes work the same way as HTML boolean attributes as defined by [W3C](http://www.w3.org/TR/2008/WD-html5-20080610/semantics.html#boolean) for the most part. We changed a few things to overcome confusion. Check the table below for reference:
93
+
94
+ | Markup | `disabled` | Description |
95
+ |-------------------------------|------------|----------------------------------------------------------------------|
96
+ | `<c-input />` | false | Follows W3C standard |
97
+ | `<c-input disabled/>` | true | Follows W3C standard |
98
+ | `<c-input disabled="true"/>` | true | Follows W3C standard |
99
+ | `<c-input disabled="asd"/>` | false | `false` since `asd` does not evaluate to a valid boolean |
100
+ | `<c-input disabled="false"/>` | false | `false` since the boolean `false` converted to a string is `"false"` |
101
+ | `<c-input disabled="true"/>` | true | `true` since the boolean `true` converted to a string is `"true"` |
102
+
103
+ ### @Dispatch()
104
+
105
+ **Creating a custom event**
106
+
107
+ ```ts
108
+ import { CustomElement, Dispatch, DispatchEmitter } from 'custom-elements-ts';
109
+
110
+ ...
111
+ export class TodoList extends HTMLElement {
112
+ // Creating a CustomEvent
113
+ // custom event name will be `on.change`
114
+ @Dispatch() onChange: DispatchEmitter;
115
+
116
+ // Creating a CustomEvent with custom name `ce.select`
117
+ @Dispatch('ce.select') onSelect: DispatchEmitter;
118
+ }
119
+ ```
120
+ **Triggering the custom event** from the example above:
121
+
122
+ ```ts
123
+ triggerOnChange() {
124
+ // adding more data to the event object
125
+ this.onChange.emit({detail: 'event changed'});
126
+ this.onSelect.emit({detail: 'select triggered'});
127
+ }
128
+ ```
129
+ ### @Watch()
130
+
131
+ ```ts
132
+ import { CustomElement, Dispatch, Prop } from 'custom-elements-ts';
133
+
134
+ ...
135
+ export class TodoList extends HTMLElement {
136
+ @Prop() color: string;
137
+
138
+ @Watch('color')
139
+ colorChanged() {
140
+ // trigger when color property color changes
141
+ // either via property or attribute
142
+ }
143
+ }
144
+ ```
145
+
146
+ ### @Listen()
147
+
148
+ Listen has parameters `event` and `selector`. `Event` is any valid javascript event. `Selector` is anything that works with [querySelector()](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
149
+
150
+ ```ts
151
+ import { CustomElement, Dispatch, Prop } from 'custom-elements-ts';
152
+
153
+ ...
154
+ export class TodoList extends HTMLElement {
155
+ @Listen('click')
156
+ elementClicked() {
157
+ // triggers when the element is clicked
158
+ }
159
+
160
+ @Listen('click','a')
161
+ anchorClicked() {
162
+ // triggers when an `a` inside the element is clicked
163
+ }
164
+ }
165
+ ```
166
+
167
+ ## Setup
168
+
169
+ ### Running the demos
170
+
171
+ ```
172
+ npm start <element-name>
173
+ ```
174
+
175
+ ### Building the demo
176
+
177
+ ```
178
+ npm run build <element-name>
179
+ ```
180
+ If you want to create a minified bundle
181
+ ```
182
+ npm run build -- <element-name> --prod
183
+ ```
184
+
185
+ ### Building the library (publish artifacts)
186
+
187
+ Builds the library from `src/index.ts` into `dist/` (UMD + ESM builds with typings):
188
+
189
+ ```
190
+ npm run bundle
191
+ ```