Skip to content

Commit

Permalink
Added types and typescript example
Browse files Browse the repository at this point in the history
  • Loading branch information
gianluca.frediani committed Mar 11, 2018
1 parent 50b7028 commit 41808e7
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 0 deletions.
91 changes: 91 additions & 0 deletions index.d.ts
@@ -0,0 +1,91 @@
import { bind, hyper, wire, define, Component, WiredTemplateFunction } from "hyperhtml";

interface HyperHTMLElement<T = {}> extends HTMLElement {
onabort(ev: UIEvent): void;
onactivate(ev: UIEvent): void;
onbeforeactivate(ev: UIEvent): void;
onbeforecopy(ev: ClipboardEvent): void;
onbeforecut(ev: ClipboardEvent): void;
onbeforedeactivate(ev: UIEvent): void;
onbeforepaste(ev: ClipboardEvent): void;
onblur(ev: FocusEvent): void;
oncanplay(ev: Event): void;
oncanplaythrough(ev: Event): void;
onchange(ev: Event): void;
onclick(ev: MouseEvent): void;
oncontextmenu(ev: PointerEvent): void;
oncopy(ev: ClipboardEvent): void;
oncuechange(ev: Event): void;
oncut(ev: ClipboardEvent): void;
ondblclick(ev: MouseEvent): void;
ondeactivate(ev: UIEvent): void;
ondrag(ev: DragEvent): void;
ondragend(ev: DragEvent): void;
ondragenter(ev: DragEvent): void;
ondragleave(ev: DragEvent): void;
ondragover(ev: DragEvent): void;
ondragstart(ev: DragEvent): void;
ondrop(ev: DragEvent): void;
ondurationchange(ev: Event): void;
onemptied(ev: Event): void;
onended(ev: MediaStreamErrorEvent): void;
onerror(ev: ErrorEvent): void;
onfocus(ev: FocusEvent): void;
oninput(ev: Event): void;
oninvalid(ev: Event): void;
onkeydown(ev: KeyboardEvent): void;
onkeypress(ev: KeyboardEvent): void;
onkeyup(ev: KeyboardEvent): void;
onload(ev: Event): void;
onloadeddata(ev: Event): void;
onloadedmetadata(ev: Event): void;
onloadstart(ev: Event): void;
onmousedown(ev: MouseEvent): void;
onmouseenter(ev: MouseEvent): void;
onmouseleave(ev: MouseEvent): void;
onmousemove(ev: MouseEvent): void;
onmouseout(ev: MouseEvent): void;
onmouseover(ev: MouseEvent): void;
onmouseup(ev: MouseEvent): void;
onmousewheel(ev: WheelEvent): void;
onmscontentzoom(ev: UIEvent): void;
onmsmanipulationstatechanged(ev: MSManipulationEvent): void;
onpaste(ev: ClipboardEvent): void;
onpause(ev: Event): void;
onplay(ev: Event): void;
onplaying(ev: Event): void;
onprogress(ev: ProgressEvent): void;
onratechange(ev: Event): void;
onreset(ev: Event): void;
onscroll(ev: UIEvent): void;
onseeked(ev: Event): void;
onseeking(ev: Event): void;
onselect(ev: UIEvent): void;
onselectstart(ev: Event): void;
onstalled(ev: Event): void;
onsubmit(ev: Event): void;
onsuspend(ev: Event): void;
ontimeupdate(ev: Event): void;
onvolumechange(ev: Event): void;
onwaiting(ev: Event): void;
}

declare class HyperHTMLElement<T = {}> {
static readonly observedAttributes: string[];
constructor();
created(): void;
attributeChangedCallback(name: string, prev: string, curr: string): void;
html: WiredTemplateFunction;
state: T;
readonly defaultState: T;
render(): void;
setState(state: Partial<T> | ((this: this, state: T) => Partial<T>)): void;
static bind: typeof bind;
static Component: typeof Component;
static intent: typeof define;
static hyper: typeof hyper;
static wire: typeof wire;
static define(name: string): void;
}

export default HyperHTMLElement;
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -5,6 +5,7 @@
"browser": "min.js",
"module": "esm/index.js",
"main": "cjs/index.js",
"types": "index.d.ts",
"scripts": {
"bundle-cjs": "ascjs ./esm ./cjs && sed -i.bak 's/hyperhtml\\/esm/hyperhtml\\/cjs/' cjs/index.js && rm -f cjs/index.js.bak",
"bundle-esm": "rollup --config esm.config.js && npm run fix-esm-export",
Expand Down
82 changes: 82 additions & 0 deletions typescript.md
@@ -0,0 +1,82 @@
# Usage with Typescript
You can import the library and use it with Typescript:

```ts
import HyperHTMLElement from "hyperhtml-element";

class MySimpleElement extends HyperHTMLElement {
render() {
this.html`Hello from my-simple-element!`
}
}

MySimpleElement.define('my-simple-element');
```

You can also define the type of the state using an interface, for have a better auto-complete in your editor. You should also define the observedAttributes that are automaticaly mapped as class attributes. Here's a more complex example:

```ts
import HyperHTMLElement from "hyperhtml-element";

interface MyCustomElementState {
counter: number;
name: string;
}

class MyCustomElement extends HyperHTMLElement<MyCustomElementState> {

// Observed attributes are mapped to class attributes, converted from kebab-case to camelCase
// They should be declared for later use and declared as optional since the user is not forced to use them
name?: string;

static get observedAttributes() {
return ['name'];
}

attributeChangedCallback(attrName: string, prev: string, curr: string) {
if (attrName === 'name') {
this.setState({name: curr});
}
}

get defaultState() {
return {
counter: 0,
name: this.name || ''
};
}

created() {
this.render();
}

oninput(e: KeyboardEvent) {
const value = (e.target as HTMLInputElement).value;
this.setState({name: value});
}

handleIncrement(e: Event) {
this.setState({counter: ++this.state.counter});
}

handleDecrement(e: Event) {
this.setState({counter: --this.state.counter});
}

render() {
this.html`
<strong>Owner:</strong> ${this.state.name}<br />
<strong>Counter:</strong> ${this.state.counter}<br />
<button onclick=${this.handleIncrement}>+</button> <button onclick=${this.handleDecrement}>-</button>
${this.state.counter < 0 ?
HyperHTMLElement.wire()`<div style=${{color: 'red'}}>Warning: negative counter!</div>`
: ''}
<br /><br />
Change Owner name: <input value=${this.state.name} oninput=${this} />
`;
}

}

MyCustomElement.define('my-custom-element');
```

0 comments on commit 41808e7

Please sign in to comment.