wallace 0.3.0 → 0.4.0
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/lib/initCalls.js +29 -13
- package/lib/types.d.ts +87 -23
- package/package.json +3 -3
package/lib/initCalls.js
CHANGED
|
@@ -1,16 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Everything in here is used by or modified by the Babel plugin.
|
|
3
|
+
*/
|
|
1
4
|
import { Component } from "./component";
|
|
2
5
|
import { buildComponent, replaceNode } from "./utils";
|
|
3
6
|
import { KeyedRepeater, SequentialRepeater } from "./repeaters";
|
|
7
|
+
|
|
4
8
|
const throwAway = document.createElement("template");
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
|
-
*
|
|
11
|
+
* A utility function that has to be in here because it needs _createConstructor and
|
|
12
|
+
* we'd otherwise get cirular inmports.
|
|
13
|
+
*
|
|
14
|
+
* Calls to this function which provide the 2nd argument:
|
|
15
|
+
*
|
|
16
|
+
* const Foo = extendComponent(Bar, () => <div></div>))
|
|
17
|
+
*
|
|
18
|
+
* Are modified by the Babel plugin to become this:
|
|
19
|
+
*
|
|
20
|
+
* const Foo = defineComponent(,,,,Bar);
|
|
21
|
+
*
|
|
22
|
+
* So it should never be called with 2nd arg in real life.
|
|
8
23
|
*/
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
|
|
24
|
+
export function extendComponent(base, componentDef) {
|
|
25
|
+
// This function call will have been replaced if 2nd arg is a valid component func.
|
|
26
|
+
// and therefor we would not receive it.
|
|
27
|
+
if (componentDef)
|
|
28
|
+
throw new Error("2nd arg to extendComponent must be a JSX arrow function");
|
|
29
|
+
return _createConstructor(base);
|
|
12
30
|
}
|
|
13
31
|
|
|
32
|
+
/*
|
|
33
|
+
Everything after this is used by code generated by the Babel plugin.
|
|
34
|
+
*/
|
|
35
|
+
|
|
14
36
|
export function findElement(rootElement, path) {
|
|
15
37
|
return path.reduce((acc, index) => acc.childNodes[index], rootElement);
|
|
16
38
|
}
|
|
@@ -52,22 +74,15 @@ export function getSequentialRepeater(cls) {
|
|
|
52
74
|
return new SequentialRepeater(cls);
|
|
53
75
|
}
|
|
54
76
|
|
|
55
|
-
export function extendComponent(base, componentDef) {
|
|
56
|
-
// This function call will have been replaced if 2nd arg is a valid component func.
|
|
57
|
-
// and therefor we would not receive it.
|
|
58
|
-
if (componentDef)
|
|
59
|
-
throw new Error("2nd arg to extendComponent must be a JSX arrow function");
|
|
60
|
-
return _createConstructor(base);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
77
|
export function defineComponent(html, watches, queries, buildFunction, inheritFrom) {
|
|
64
78
|
const ComponentDefinition = _createConstructor(inheritFrom || Component);
|
|
65
79
|
const prototype = ComponentDefinition.prototype;
|
|
80
|
+
throwAway.innerHTML = html;
|
|
66
81
|
//Ensure these do not clash with fields on the component itself.
|
|
67
82
|
prototype._w = watches;
|
|
68
83
|
prototype._q = queries;
|
|
69
84
|
prototype._b = buildFunction;
|
|
70
|
-
prototype._n =
|
|
85
|
+
prototype._n = throwAway.content.firstChild;
|
|
71
86
|
return ComponentDefinition;
|
|
72
87
|
}
|
|
73
88
|
|
|
@@ -88,5 +103,6 @@ function _createConstructor(base) {
|
|
|
88
103
|
configurable: true
|
|
89
104
|
}
|
|
90
105
|
});
|
|
106
|
+
ComponentDefinition.prototype.base = Component.prototype;
|
|
91
107
|
return ComponentDefinition;
|
|
92
108
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -98,7 +98,10 @@ render(props, ctrl) {
|
|
|
98
98
|
Updates the DOM. Only called internally by `render`, but you can call it from other
|
|
99
99
|
places.
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
#### Overriding
|
|
102
|
+
|
|
103
|
+
You can override these methods, and add new ones using `methods` directly on the
|
|
104
|
+
component definition:
|
|
102
105
|
|
|
103
106
|
```tsx
|
|
104
107
|
MyComponent.methods({
|
|
@@ -118,7 +121,21 @@ This has the same effect as setting them on the prototype:
|
|
|
118
121
|
MyComponent.prototype.render = function () {};
|
|
119
122
|
```
|
|
120
123
|
|
|
121
|
-
You
|
|
124
|
+
You can use `this.base` to access methods on the base `Component` class:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
MyComponent.methods({
|
|
128
|
+
render(props) {
|
|
129
|
+
this.base.render.call(this, props, ctrl);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Note that `base` is not the same as `super` in classes which access the lowest override.
|
|
135
|
+
|
|
136
|
+
You access the instance as `this` in methods, but cannot use `this` in arrow functions,
|
|
137
|
+
so use `self` from the **xargs** in component functions.
|
|
138
|
+
|
|
122
139
|
|
|
123
140
|
### 1.4 Fields
|
|
124
141
|
|
|
@@ -171,7 +188,7 @@ const TopTasks = (tasks) => (
|
|
|
171
188
|
|
|
172
189
|
const TaskList = (tasks) => (
|
|
173
190
|
<div>
|
|
174
|
-
<Task.repeat
|
|
191
|
+
<Task.repeat items={tasks} />
|
|
175
192
|
</div>
|
|
176
193
|
);
|
|
177
194
|
```
|
|
@@ -245,7 +262,7 @@ const Task = (task) => (<div>{task.name}</div>);
|
|
|
245
262
|
|
|
246
263
|
const TaskList = (_, {ctrl}) => (
|
|
247
264
|
<div>
|
|
248
|
-
<Task.repeat
|
|
265
|
+
<Task.repeat items={ctrl.getTasks()} />
|
|
249
266
|
</div>
|
|
250
267
|
);
|
|
251
268
|
|
|
@@ -330,8 +347,7 @@ const Task: Uses<null> = () => <div>Hello</div>;
|
|
|
330
347
|
|
|
331
348
|
### Props
|
|
332
349
|
|
|
333
|
-
TypeScript will ensure you pass correct props during mounting or nesting
|
|
334
|
-
including repeat, which expects an arry of the type:
|
|
350
|
+
TypeScript will ensure you pass correct props during mounting or nesting:
|
|
335
351
|
|
|
336
352
|
```
|
|
337
353
|
const TaskList: Uses<iTask[]> = (tasks) => (
|
|
@@ -339,7 +355,7 @@ const TaskList: Uses<iTask[]> = (tasks) => (
|
|
|
339
355
|
First task:
|
|
340
356
|
<Task.nest props={tasks[0]} />
|
|
341
357
|
<div>
|
|
342
|
-
<Task.repeat
|
|
358
|
+
<Task.repeat items={tasks.slice(1)} />
|
|
343
359
|
</div>
|
|
344
360
|
</div>
|
|
345
361
|
);
|
|
@@ -475,10 +491,13 @@ declare module "wallace" {
|
|
|
475
491
|
> {
|
|
476
492
|
(
|
|
477
493
|
props: Props,
|
|
478
|
-
|
|
494
|
+
xargs?: {
|
|
479
495
|
ctrl: Controller;
|
|
480
496
|
self: ComponentInstance<Props, Controller, Methods>;
|
|
481
497
|
event: Event;
|
|
498
|
+
ev: Event;
|
|
499
|
+
element: HTMLElement;
|
|
500
|
+
el: HTMLElement;
|
|
482
501
|
}
|
|
483
502
|
): JSX.Element;
|
|
484
503
|
nest?({
|
|
@@ -491,11 +510,11 @@ declare module "wallace" {
|
|
|
491
510
|
hide?: boolean;
|
|
492
511
|
}): JSX.Element;
|
|
493
512
|
repeat?({
|
|
494
|
-
|
|
513
|
+
items,
|
|
495
514
|
show,
|
|
496
515
|
hide
|
|
497
516
|
}: {
|
|
498
|
-
|
|
517
|
+
items: Array<Props>;
|
|
499
518
|
show?: boolean;
|
|
500
519
|
hide?: boolean;
|
|
501
520
|
}): JSX.Element;
|
|
@@ -516,7 +535,7 @@ declare module "wallace" {
|
|
|
516
535
|
};
|
|
517
536
|
|
|
518
537
|
/**
|
|
519
|
-
* A type which
|
|
538
|
+
* A type which must be placed as shown:
|
|
520
539
|
*
|
|
521
540
|
* ```tsx
|
|
522
541
|
* const Task: Uses<iTask> = ({text}) => <div>{text}</div>;
|
|
@@ -544,19 +563,53 @@ declare module "wallace" {
|
|
|
544
563
|
Controller = any,
|
|
545
564
|
Methods extends object = {}
|
|
546
565
|
> = {
|
|
547
|
-
update(): void;
|
|
548
|
-
render(props: Props, ctrl?: Controller): void;
|
|
549
566
|
el: HTMLElement;
|
|
550
567
|
props: Props;
|
|
551
568
|
ctrl: Controller;
|
|
552
|
-
|
|
569
|
+
ref: { [key: string]: HTMLElement };
|
|
570
|
+
base: Component<Props, Controller>;
|
|
571
|
+
} & Component<Props, Controller> &
|
|
572
|
+
Methods;
|
|
553
573
|
|
|
554
574
|
/**
|
|
555
575
|
* The component constructor function (typed as a class, but isn't).
|
|
556
576
|
*/
|
|
557
577
|
export class Component<Props = any, Controller = any> {
|
|
558
|
-
update(): void;
|
|
559
578
|
render(props: Props, ctrl?: Controller): void;
|
|
579
|
+
/**
|
|
580
|
+
* The base render method looks like this:
|
|
581
|
+
*
|
|
582
|
+
* ```
|
|
583
|
+
* render(props?: Props, ctrl?: Controller) {
|
|
584
|
+
* this.props = props;
|
|
585
|
+
* this.ctrl = ctrl;
|
|
586
|
+
* this.update();
|
|
587
|
+
* }
|
|
588
|
+
* ```
|
|
589
|
+
*
|
|
590
|
+
* You can override like so:
|
|
591
|
+
*
|
|
592
|
+
* ```
|
|
593
|
+
* render(props?: Props, ctrl?: Controller) {
|
|
594
|
+
* // do your thing
|
|
595
|
+
* this.base.render.call(this, props, ctrl);
|
|
596
|
+
* }
|
|
597
|
+
* ```
|
|
598
|
+
*/
|
|
599
|
+
render(props?: Props, ctrl?: Controller): void;
|
|
600
|
+
/**
|
|
601
|
+
* Updates the DOM.
|
|
602
|
+
*
|
|
603
|
+
* You can override like so:
|
|
604
|
+
*
|
|
605
|
+
* ```
|
|
606
|
+
* update() {
|
|
607
|
+
* // do your thing
|
|
608
|
+
* this.base.update.call(this);
|
|
609
|
+
* }
|
|
610
|
+
* ```
|
|
611
|
+
*/
|
|
612
|
+
update(): void;
|
|
560
613
|
}
|
|
561
614
|
|
|
562
615
|
/**
|
|
@@ -725,17 +778,28 @@ interface DirectiveAttributes extends AllDomEvents {
|
|
|
725
778
|
*/
|
|
726
779
|
html?: MustBeExpression;
|
|
727
780
|
|
|
728
|
-
/** Wallace
|
|
729
|
-
*
|
|
781
|
+
/** ## Wallace directive: if
|
|
782
|
+
*
|
|
783
|
+
* Excludes this element from the DOM completely if the condition is false,
|
|
784
|
+
* and does not render dynamic elements underneath.
|
|
785
|
+
* When the condition becomes true, the element is reattached.
|
|
786
|
+
*/
|
|
730
787
|
if?: MustBeExpression;
|
|
731
788
|
|
|
789
|
+
/**
|
|
790
|
+
* ## Wallace directive: items
|
|
791
|
+
*
|
|
792
|
+
* Specifies items for repeated component. Must be an array of the props which the
|
|
793
|
+
* nested item accepts.
|
|
794
|
+
*
|
|
795
|
+
*/
|
|
796
|
+
items?: MustBeExpression;
|
|
797
|
+
|
|
732
798
|
/**
|
|
733
799
|
* ## Wallace directive: props
|
|
734
800
|
*
|
|
735
|
-
* Specifies props for a nested
|
|
801
|
+
* Specifies props for a nested component.
|
|
736
802
|
*
|
|
737
|
-
* If it is a repeated component, the props should be an array of whatever type it
|
|
738
|
-
* accepts.
|
|
739
803
|
*/
|
|
740
804
|
props?: MustBeExpression;
|
|
741
805
|
|
|
@@ -810,7 +874,7 @@ declare namespace JSX {
|
|
|
810
874
|
* Nesting syntax:
|
|
811
875
|
* ```
|
|
812
876
|
* <MyComponent.nest props={singleProps} />
|
|
813
|
-
* <MyComponent.repeat
|
|
877
|
+
* <MyComponent.repeat items={arrayOfProps} />
|
|
814
878
|
* ```
|
|
815
879
|
* But note that repeat must not have siblings.
|
|
816
880
|
*
|
|
@@ -822,9 +886,9 @@ declare namespace JSX {
|
|
|
822
886
|
* - `hide` sets an element or component's hidden property.
|
|
823
887
|
* - `html` Set the element's `innnerHTML` property.
|
|
824
888
|
* - `if` excludes an element from the DOM.
|
|
889
|
+
* - `items` set items for repeated component, must be an array of props.
|
|
825
890
|
* - `on[EventName]` creates an event handler (note the code is copied)
|
|
826
|
-
* - `props` specifes props for a nested
|
|
827
|
-
* an array.
|
|
891
|
+
* - `props` specifes props for a nested components.
|
|
828
892
|
* - `ref` saves a reference to an element or nested component.
|
|
829
893
|
* - `show` sets and element or component's hidden property.
|
|
830
894
|
* - `style:xyz` sets a specific style property.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wallace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"author": "Andrew Buchan",
|
|
5
5
|
"description": "The framework that brings you FREEDOM!!",
|
|
6
6
|
"license": "ISC",
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"test": "jest --clearCache && jest"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"babel-plugin-wallace": "^0.
|
|
16
|
+
"babel-plugin-wallace": "^0.4.0",
|
|
17
17
|
"browserify": "^17.0.1"
|
|
18
18
|
},
|
|
19
|
-
"gitHead": "
|
|
19
|
+
"gitHead": "286a00b51777c4b7fed9a778b93e9727ed905e2a"
|
|
20
20
|
}
|