##// END OF EJS Templates
Support for Function Components...
cin -
r34:e8012fdf09ae 1.0.0-rc16 default
parent child
Show More
@@ -0,0 +1,32
1 import dom = require("dojo/dom-construct");
2 import attr = require("dojo/dom-attr");
3 import { argumentNotNull } from "@implab/core-amd/safe";
4 import { BuildContextBase } from "./BuildContextBase";
5
6
7 export class FunctionComponentContext extends BuildContextBase<Element> {
8 private _component: (props: any) => Element;
9
10 private _element: Element | undefined;
11
12 constructor(component: (props: any) => Element) {
13 super();
14 argumentNotNull(component, "component");
15
16 this._component = component;
17 }
18
19 _create(attrs: object, children: any[]) {
20 const _attrs: any = attrs || {};
21 _attrs.children = children.map(x => this.getChildDom(x));
22
23 this._element = this._component.call(null, _attrs);
24 }
25
26 _getDomNode() {
27 if (!this._element)
28 throw new Error("The instance of the widget isn't created");
29 return this._element;
30 }
31
32 }
@@ -0,0 +1,13
1 var rjs = require('requirejs');
2
3 rjs.config({
4 baseUrl: '.',
5 nodeRequire: require,
6 packages: [
7 { name: "dojo", location: "../../node_modules/dojo" },
8 { name: "@implab", location: "../../node_modules/@implab" }
9 ]
10 });
11
12
13 rjs(['./plan']); No newline at end of file
@@ -0,0 +1,10
1 import { Baz } from "./mock/Baz";
2
3 console.log("Declare tests");
4
5 const baz = new Baz();
6
7 const data: string[] = [];
8 baz.writeHello(data);
9
10 console.log(data.join("\n"));
@@ -0,0 +1,17
1 import { djclass, djbase } from "../declare";
2
3 interface Super {
4 writeHello(out: string[]): void;
5
6 }
7
8 @djclass
9 export class BarMixin extends djbase<Super>() {
10 writeHello(out: string[]) {
11 out.push("-> Bar");
12
13 super.writeHello(out);
14
15 out.push("<- Bar");
16 }
17 }
@@ -0,0 +1,15
1 import { djbase, djclass } from "../declare";
2 import { FooMixin } from "./FooMixin";
3 import { BarMixin } from "./BarMixin";
4 import { BoxMixin } from "./BoxMixin";
5
6 @djclass
7 export class Baz extends djbase(FooMixin, BarMixin, BoxMixin) {
8 writeHello(out: string[]) {
9 out.push("-> Baz");
10
11 super.writeHello(out);
12
13 out.push("<- Baz");
14 }
15 }
@@ -0,0 +1,16
1 import { djbase, djclass } from "../declare";
2
3 interface Super {
4 writeHello(out: string[]): void;
5 }
6
7 @djclass
8 export class BoxMixin extends djbase<Super>() {
9 writeHello(out: string[]) {
10 out.push("-> Box");
11
12 super.writeHello(out);
13
14 out.push("<- Box");
15 }
16 }
@@ -0,0 +1,16
1 import { djclass, djbase } from "../declare";
2
3 interface Super {
4 writeHello(out: string[]): void;
5 }
6
7 @djclass
8 export class FooMixin extends djbase<Super>() {
9 writeHello(out: string[]) {
10 out.push("-> Foo");
11
12 super.writeHello(out);
13
14 out.push("<- Foo");
15 }
16 } No newline at end of file
@@ -0,0 +1,1
1 import "./DeclareTests"; No newline at end of file
@@ -2,8 +2,9 import { Constructor } from "@implab/cor
2 import { HtmlElementContext } from "./tsx/HtmlElementContext";
2 import { HtmlElementContext } from "./tsx/HtmlElementContext";
3 import { WidgetContext } from "./tsx/WidgetContext";
3 import { WidgetContext } from "./tsx/WidgetContext";
4 import { isWidgetConstructor, BuildContext } from "./tsx/traits";
4 import { isWidgetConstructor, BuildContext } from "./tsx/traits";
5 import { FunctionComponentContext } from "./tsx/FunctionComponentContext";
5
6
6 export function createElement<T extends Constructor>(elementType: string | T, ...args: any[]): BuildContext {
7 export function createElement<T extends Constructor | string | ((props: any) => Element)>(elementType: T, ...args: any[]): BuildContext {
7 if (typeof elementType === "string") {
8 if (typeof elementType === "string") {
8 const ctx = new HtmlElementContext(elementType);
9 const ctx = new HtmlElementContext(elementType);
9 if (args)
10 if (args)
@@ -16,6 +17,12 export function createElement<T extends
16 args.forEach(x => ctx.visitNext(x));
17 args.forEach(x => ctx.visitNext(x));
17
18
18 return ctx;
19 return ctx;
20 } else if (typeof elementType === "function") {
21 const ctx = new FunctionComponentContext(elementType as (props: any) => Element);
22 if (args)
23 args.forEach(x => ctx.visitNext(x));
24
25 return ctx;
19 } else {
26 } else {
20 throw new Error(`The element type '${elementType}' is unsupported`);
27 throw new Error(`The element type '${elementType}' is unsupported`);
21 }
28 }
@@ -4,29 +4,25 import { isPlainObject, isNode, isBuildC
4 import dom = require("dojo/dom-construct");
4 import dom = require("dojo/dom-construct");
5
5
6 export abstract class BuildContextBase<TNode extends Node> implements BuildContext<TNode> {
6 export abstract class BuildContextBase<TNode extends Node> implements BuildContext<TNode> {
7 _attrs = {};
7 private _attrs = {};
8
8
9 _children = new Array();
9 private _children = new Array();
10
10
11 _created: boolean = false;
11 private _created: boolean = false;
12
12
13 visitNext(v: any) {
13 visitNext(v: any) {
14 if (this._created)
15 throw new Error("The Element is already created");
16
14 if (isNull(v))
17 if (isNull(v))
15 return;
18 return;
16
19
17 if (isPlainObject(v)) {
20 if (isPlainObject(v)) {
18
21 mixin(this._attrs, v);
19 if (this._created)
20 this._setAttrs(v);
21 else
22 mixin(this._attrs, v);
23 } else if (v instanceof Array) {
22 } else if (v instanceof Array) {
24 v.forEach(x => this._addChild(x));
23 v.forEach(x => this.visitNext(x));
25 } else {
24 } else {
26 if (this._created)
25 this._children.push(v);
27 this._addChild(v);
28 else
29 this._children.push(v);
30 }
26 }
31 }
27 }
32
28
@@ -68,9 +64,5 export abstract class BuildContextBase<T
68 dom.place(this.getDomNode(), refNode, position);
64 dom.place(this.getDomNode(), refNode, position);
69 }
65 }
70
66
71 abstract _addChild(child: any): void;
72
73 abstract _setAttrs(attrs: object): void;
74
75 abstract _create(attrs: object, children: any[]): void;
67 abstract _create(attrs: object, children: any[]): void;
76 }
68 }
@@ -21,13 +21,6 export class HtmlElementContext extends
21 dom.place(this.getChildDom(child), this._element);
21 dom.place(this.getChildDom(child), this._element);
22 }
22 }
23
23
24 _setAttrs(attrs: object): void {
25 if (!this._element)
26 throw new Error("The HTML element isn't created");
27
28 attr.set(this._element, attrs);
29 }
30
31 _create(attrs: object, children: any[]) {
24 _create(attrs: object, children: any[]) {
32 this._element = dom.create(this.elementType, attrs);
25 this._element = dom.create(this.elementType, attrs);
33
26
@@ -36,12 +36,8 export class WidgetContext extends Build
36 dom.place(this.getChildDom(child), this._instance.containerNode);
36 dom.place(this.getChildDom(child), this._instance.containerNode);
37 }
37 }
38
38
39 _setAttrs(attrs: object): void {
40 this._instance?.set(attrs);
41 }
42
43 _create(attrs: object, children: any[]) {
39 _create(attrs: object, children: any[]) {
44 this._instance = new this.widgetClass(this._attrs);
40 this._instance = new this.widgetClass(attrs);
45 if (children)
41 if (children)
46 children.forEach(x => this._addChild(x));
42 children.forEach(x => this._addChild(x));
47 }
43 }
@@ -4,8 +4,13 declare module "@implab/djx/css!*" {
4 }
4 }
5
5
6 declare namespace JSX {
6 declare namespace JSX {
7 interface IntrinsicElements {
7 interface DjxIntrinsicAttributes {
8 [name: string]: any;
8 class: string;
9 "data-dojo-attach-point": string;
10 "data-dojo-attach-event": string;
11 }
12 type IntrinsicElements = {
13 [name in keyof HTMLElementTagNameMap]: Partial<Omit<HTMLElementTagNameMap[name], "children"> & DjxIntrinsicAttributes>;
9 }
14 }
10 }
15 }
11
16
@@ -19,25 +19,28 interface MyWidgetEvents {
19 @djclass
19 @djclass
20 export class MyWidget extends djbase(DjxWidgetBase as AbstractConstructor<DjxWidgetBase<MyWidgetAttrs, MyWidgetEvents>>) {
20 export class MyWidget extends djbase(DjxWidgetBase as AbstractConstructor<DjxWidgetBase<MyWidgetAttrs, MyWidgetEvents>>) {
21
21
22 @bind({node: "titleNode", type:"innerHTML"})
22 @bind({ node: "titleNode", type: "innerHTML" })
23 title = "";
23 title = "";
24
24
25 @prototype()
25 @prototype()
26 counter = 0;
26 counter = 0;
27
27
28 render() {
28 render() {
29 const Frame = (props: any) => <div>{props.children}</div>;
29 return <div>
30 return <div>
30 <h1 data-dojo-attach-point="titleNode"></h1>
31 <h1 data-dojo-attach-point="titleNode"></h1>
31 <span onclick={() => this._onIncClick()}>[+]</span>
32 <Frame>
32 <span onclick={() => this._onDecClick()}>[-]</span>
33 <span class="up-button" onclick={e => this._onIncClick(e)}>[+]</span>
34 <span class="down-button" onclick={() => this._onDecClick()}>[-]</span>
35 </Frame>
33 </div>;
36 </div>;
34 }
37 }
35
38
36 _onIncClick() {
39 _onIncClick(e: MouseEvent) {
37 this.emit("count-inc", { bubbles: false } );
40 this.emit("count-inc", { bubbles: false });
38 }
41 }
39
42
40 _onDecClick() {
43 _onDecClick() {
41 this.emit("count-dec", { bubbles: false } );
44 this.emit("count-dec", { bubbles: false });
42 }
45 }
43 }
46 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now