neweb-components
v0.13.23
Published
NewebComponents - framework, which has 2 goals:
Downloads
6
Readme
NewebComponents
NewebComponents - framework, which has 2 goals:
- The real separating of the design and logic for user-interface.
- Reactive web-components without virtual dom, only with HTML5 DOM specification.
NewebComponents use pure HTML for templating, without data-binding, conditions, cycles and event-handlers.
NewebComponents use RxJs as engine for reactivity.
Install
npm install neweb-components --save
or
yarn add neweb-components
Usage
Simple example :: counter
import { interval } from "rxjs";
import { t } from "rx-template-strings";
import { HtmlComponent, render } from "neweb-components";
// Create new component
const view = new HtmlComponent({
innerHTML: t`Counter: ${interval()}`,
});
// Render into container #root
render(view, document.getElementById("root") as HTMLElement);
Complex example
// index.ts
import { interval } from "rxjs";
import { Component, Document, render } from "neweb-components";
import View from "./view";
// Bind components to real window-object by special class `Document`, for example, window can be from JSDOM
Component.setDocument(new Document({
window,
}));
// Instance of view
const view = new View({
counter: interval(),
});
// Render into container #root
render(view, document.getElementById("root") as HTMLElement);
// template.html
<div>
<div>Counter: <template name="lblCounter"></template></div>
<form name="frmMain">
<div>
<input autocomplete="off" name="txtEmail" type="text" placeholder="Type email" />
<small name="tipsEmail"></small>
</div>
<div>
<input type="submit" value="Save" />
</div>
</form>
<ul name="listEmails">
<li></li>
</ul>
</div>
// view.ts
import { BehaviorSubject } from "rxjs/BehaviorSubject";
import { Subject } from "rxjs/Subject";
import { Component, ElementComponent, InputComponent, List } from "neweb-components";
import template = require("./template.html");
enum EmailErrorType {
None = "",
Required = "Required",
ShouldContainsDog = "Email should contains @",
}
class View extends Component<{
counter: Observable<number>;
}> {
email = new BehaviorSubject("");
emailError = new BehaviorSubject(EmailErrorType.Required);
emails = new BehaviorSubject<string[]>([]);
submit = new Subject<void>();
beforeMount() {
this.subscribe(this.email, (value) => {
if (!value) {
this.emailError.next(EmailErrorType.Required);
} else if (value.indexOf("@") === -1) {
this.emailError.next(EmailErrorType.ShouldContainsDog);
} else {
this.emailError.next(EmailErrorType.None);
}
});
this.addElement("lblCounter", new Text({
value: this.props.counter.pipe(map((v) => v.toString())),
}));
this.addElement("txtEmail", new InputComponent({
value: this.email,
}));
this.addElement("tipsEmail", new ElementComponent({
innerHTML: this.emailError,
}));
this.addElement("frmMain", new ElementComponent({
events: {
submit: (e) => {
e.preventDefault();
if (!this.emailError.getValue()) {
const items = this.emails.getValue();
items.push(this.email.getValue());
this.emails.next(items);
this.email.next("");
}
},
},
}));
this.addElement("listEmails", new List({
items: this.emails,
}));
}
getTemplate() {
return template;
}
}
export default View;
API
Test
npm install
npm test