##// END OF EJS Templates
Corrected tsx typings
cin -
r41:3b6c4159c66c v1.0.0 default
parent child
Show More
@@ -44,7 +44,7 configureTsMain {
44 44 configureTsTest {
45 45 compilerOptions {
46 46 typeRoots = []
47 types = ["requirejs", sources.main.output.typingsDir.get().toString()+"/legacy" ]
47 types = ["requirejs", sources.main.output.typingsDir.get().toString() ]
48 48 }
49 49 }
50 50
@@ -1,3 +1,198
1 1 # @implab/djx
2 2
3 TODO No newline at end of file
3 ## SYNOPSIS
4
5 ```tsx
6 import { djbase, djclass, bind, prototype, AbstractConstructor } from "@implab/djx/declare";
7
8 import { DjxWidgetBase } from "@implab/djx/tsx/DjxWidgetBase";
9 import { createElement } from "@implab/djx/tsx";
10
11 interface MyWidgetAttrs {
12 title: string;
13
14 counter: number;
15 }
16
17 interface MyWidgetEvents {
18 "count-inc": Event;
19
20 "count-dec": Event;
21 }
22
23
24 @djclass
25 export class MyWidget extends djbase(
26 DjxWidgetBase as AbstractConstructor<DjxWidgetBase<MyWidgetAttrs, MyWidgetEvents>>
27 ) {
28
29 @bind({ node: "titleNode", type: "innerHTML" })
30 title = "";
31
32 @prototype()
33 counter = 0;
34
35 render() {
36 const Frame = (props: any) => <div>{props.children}</div>;
37 return <div
38 className="myWidget"
39 tabIndex={3}
40 style={ alignContent: "center", border: "1px solid" }
41 >
42 <h1 data-dojo-attach-point="titleNode"></h1>
43 <Frame>
44 <span class="up-button" onclick={e => this._onIncClick(e)}>[+]</span>
45 <span class="down-button" onclick={() => this._onDecClick()}>[-]</span>
46 </Frame>
47 </div>;
48 }
49
50 _onIncClick(e: MouseEvent) {
51 this.emit("count-inc", { bubbles: false });
52 }
53
54 _onDecClick() {
55 this.emit("count-dec", { bubbles: false });
56 }
57 }
58
59 ```
60
61 ## DESCRIPTION
62
63 This package provides you with tools to glue your good-fellow dojo with modern
64 techniques of building the webapp. The core concept is built around widgets and
65 using .tsx to write it. Here some features:
66
67 * `djbase()`, `@djaclass` - traits to declare your classes with `dojo/_base/declare`
68 * `@implab/djx/tsx` - traits to build the rendering of your widgets with tsx
69 * `DjxWidgetBase` - abstract class which supports tsx markup and
70 `data-dojo-attach-*` attributes.
71 * `@bind(...)` - annotations provides an easy way of using standard dojo widget
72 attribute bindings.
73
74 ### djbase, @djclass
75
76 These two traits provides convenient way of using `dojo/_base/declare` in Typescript
77 for declaring your classes.
78
79 `djbase(...constructors)` - this method accepts a list of constructors in its
80 parameters and returns the **fake** base type which then can be used to derive
81 your own class. This allows you to provide the Typescript with the correct
82 information about the base type and even use `super`!. The only one caveat of
83 this approach is that you **MUST** decorate your class with `@djclass` annotation.
84
85 Consider the following example:
86
87 ```ts
88 import { djbase, djclass } from "@implab/djx/declare";
89 import { FooMixin } from "./FooMixin";
90 import { BarMixin } from "./BarMixin";
91 import { BoxMixin } from "./BoxMixin";
92
93 @djclass
94 export class Baz extends djbase(FooMixin, BarMixin, BoxMixin) {
95 writeHello(out: string[]) {
96 out.push("-> Baz");
97
98 super.writeHello(out);
99
100 out.push("<- Baz");
101 }
102 }
103
104 ```
105
106 All mixins are declared like the one below:
107
108 ```ts
109 import { djclass, djbase } from "@implab/djx/declare";
110
111 interface Super {
112 writeHello(out: string[]): void;
113
114 }
115
116 @djclass
117 export class BarMixin extends djbase<Super>() {
118 writeHello(out: string[]) {
119 out.push("-> Bar");
120
121 super.writeHello(out);
122
123 out.push("<- Bar");
124 }
125 }
126 ```
127
128 finally create an instance and call the `writeHello` method
129
130 ```ts
131 const baz = new Baz();
132
133 const data: string[] = [];
134 baz.writeHello(data);
135
136 console.log(data.join("\n"));
137
138 ```
139
140 you will get the following output:
141
142 ```text
143 -> Baz
144 -> Box
145 -> Bar
146 -> Foo
147 <- Foo
148 <- Bar
149 <- Box
150 <- Baz
151 ```
152
153 Let's take a closer look to the `Baz` declaration it uses `djbase` to derive
154 from three mixins and the class is decorated with `@djclass` to accomplish the
155 declaration and make a real constructor.
156
157 To allow an access to the next sibling method (in terms of multiple inheritance)
158 Dojo provides `this.inherited(arguments)` method but this approach leads to the
159 problem with 'strict' mode of ES5 and eliminates the type information about a
160 calling method. This library solves the problem calling inherited/next method by
161 utilizing `super` keyword. Under the hood there are proxy methods generated in
162 the prototype of the declared class which make calls to `this.inherited(...)`
163 method. This technique is compatible with 'strict' mode.
164
165 Mixins are declared the similar, they are also may have the base types although
166 the most common case is declaring the mixin without any base classes. To allow
167 the mixin to access the next method you should declare the interface with
168 desired methods and use the special form of `djbase<Super>()` without arguments.
169
170 ### DjxWidgetBase<Attrs, Events>
171
172 TODO
173
174 ### Markup (.tsx)
175
176 Add to your `tsconfig.json` the following options
177
178 ```json
179 {
180 "compilerOptions": {
181 "types": ["@implab/djx"],
182 "experimentalDecorators": true,
183 "jsxFactory": "createElement",
184 "jsx": "react",
185 }
186 }
187
188 ```
189
190 Import `createElement` into your `.tsx` file
191
192 ```ts
193 import { createElement } from "@implab/djx/tsx";
194 ```
195
196 You are ready to go!
197
198 TODO
@@ -4,9 +4,21
4 4 declare namespace JSX {
5 5
6 6 interface DjxIntrinsicAttributes {
7 /** alias for className */
7 8 class: string;
9
10 /** specifies the name of the property in the widget where the the
11 * reference to the current object will be stored
12 */
8 13 "data-dojo-attach-point": string;
14
15 /** specifies handlers map for the events */
9 16 "data-dojo-attach-event": string;
17
18 [attr: string]: any;
19 }
20
21 interface DjxIntrinsicElements {
10 22 }
11 23
12 24 type RecursivePartial<T> = T extends string | number | boolean | null | undefined | Function ?
@@ -19,16 +31,22 declare namespace JSX {
19 31 type NotMatchingMemberKeys<T, U> = {
20 32 [K in keyof T]: T[K] extends U ? never : K;
21 33 }[keyof T];
34
35 type ExtractMembers<T, U> = Pick<T, MatchingMemberKeys<T, U>>;
36
37 type ExcludeMembers<T, U> = Pick<T, NotMatchingMemberKeys<T, U>>;
38
22 39 type ElementAttrNames<E> = NotMatchingMemberKeys<E, (...args: any[]) => any>;
23 40
24 41 type ElementAttrType<E, K extends keyof any> = K extends keyof E ? RecursivePartial<E[K]> : string;
25 42
26 type LaxElement<E extends object> = E & { }
43 type LaxElement<E extends object> = ExcludeMembers<Omit<E, "children">, (...args: any[]) => any> & DjxIntrinsicAttributes;
27 44
28 type LegacyElementAttributes<E> = {
29 [attr in ElementAttrNames<E>]?: ElementAttrType<E, attr>;
30 } | Partial<DjxIntrinsicAttributes>;
31 interface IntrinsicElements {
32 [tag: keyof HTMLElementTagNameMap]: LegacyElementAttributes<HTMLElementTagNameMap[tag]>;
45 type LaxIntrinsicElementsMap = {
46 [tag in keyof HTMLElementTagNameMap]: LaxElement<HTMLElementTagNameMap[tag]>
47 } & DjxIntrinsicElements;
48
49 type IntrinsicElements = {
50 [tag in keyof LaxIntrinsicElementsMap]: RecursivePartial<LaxIntrinsicElementsMap[tag]>;
33 51 }
34 52 }
@@ -27,17 +27,12 export class MyWidget extends djbase(Djx
27 27
28 28 render() {
29 29 const Frame = (props: any) => <div>{props.children}</div>;
30 return <div class="" className="" tabIndex={1} style={{ alignContentz: "", border: "" }} >
30 return <div className="myWidget" tabIndex={3} style={{ alignContent: "center", border: "1px solid" }} >
31 31 <h1 data-dojo-attach-point="titleNode"></h1>
32 32 <Frame>
33 33 <span class="up-button" onclick={e => this._onIncClick(e)}>[+]</span>
34 <span class="down-button" onclick={() => this._onDecClick()}>[-]</span>
34 <span class="down-button" onclick={() => this._onDecClick()}>[-]</span>
35 35 </Frame>
36 <table style="pretty">
37 <tr>
38 <td colSpan={2} colspan="3" onclick=""></td>
39 </tr>
40 </table>
41 36 </div>;
42 37 }
43 38
@@ -8,6 +8,6
8 8 "../main/ts",
9 9 "../main/typings"
10 10 ],
11 "types": ["requirejs", "../main/typings/legacy", "dojo-typings"]
11 "types": ["requirejs", "../main/typings", "dojo-typings"]
12 12 }
13 13 } No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now