wallace 0.16.0 → 0.17.1
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/component.js +9 -3
- package/lib/router.js +42 -6
- package/lib/types.d.ts +137 -46
- package/package.json +3 -3
package/lib/component.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
const throwAway = document.createElement("template");
|
|
2
2
|
const NO_LOOKUP = "__";
|
|
3
3
|
|
|
4
|
+
const defaultSetFunction = function (props, /* #INCLUDE-IF: allowCtrl */ ctrl) {
|
|
5
|
+
this.props = props;
|
|
6
|
+
/* #INCLUDE-IF: allowCtrl */ this.ctrl = ctrl;
|
|
7
|
+
};
|
|
8
|
+
|
|
4
9
|
const ComponentPrototype = {
|
|
5
10
|
render: function (props, /* #INCLUDE-IF: allowCtrl */ ctrl) {
|
|
6
|
-
this.props
|
|
7
|
-
/* #INCLUDE-IF: allowCtrl */ this.ctrl = ctrl;
|
|
11
|
+
this.set(props, /* #INCLUDE-IF: allowCtrl */ ctrl);
|
|
8
12
|
this.update();
|
|
9
13
|
},
|
|
10
14
|
|
|
@@ -57,7 +61,7 @@ const ComponentPrototype = {
|
|
|
57
61
|
detacher = displayToggle.d;
|
|
58
62
|
if (query !== undefined) {
|
|
59
63
|
lookupTrue = !!lookups[query](props, this);
|
|
60
|
-
shouldBeVisible = displayToggle.r ? lookupTrue :
|
|
64
|
+
shouldBeVisible = displayToggle.r ? !lookupTrue : lookupTrue;
|
|
61
65
|
}
|
|
62
66
|
if (detacher) {
|
|
63
67
|
detacher.apply(element, shouldBeVisible, elements, stash);
|
|
@@ -152,12 +156,14 @@ export const defineComponent = (
|
|
|
152
156
|
watches,
|
|
153
157
|
queries,
|
|
154
158
|
contructor,
|
|
159
|
+
setFunction,
|
|
155
160
|
/* #INCLUDE-IF: allowDismount */ dismountKeys,
|
|
156
161
|
inheritFrom
|
|
157
162
|
) => {
|
|
158
163
|
const ComponentDefinition = initConstructor(contructor, inheritFrom || ComponentBase);
|
|
159
164
|
const proto = ComponentDefinition.prototype;
|
|
160
165
|
throwAway.innerHTML = html;
|
|
166
|
+
proto.set = setFunction || defaultSetFunction;
|
|
161
167
|
proto._w = watches;
|
|
162
168
|
proto._q = queries;
|
|
163
169
|
proto._t = throwAway.content.firstChild;
|
package/lib/router.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
The Router is a component which mounts other components based on
|
|
2
|
+
The Router is a component which mounts other components based on URL hash.
|
|
3
3
|
|
|
4
4
|
It currently expects the route to be made of chunks separated by / which are either
|
|
5
5
|
text or placeholders:
|
|
@@ -24,10 +24,31 @@ export const Router = () => <div></div>;
|
|
|
24
24
|
|
|
25
25
|
Object.assign(Router.prototype, {
|
|
26
26
|
render(props, /* #INCLUDE-IF: allowCtrl */ ctrl) {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
if (wallaceConfig.flags.allowBase) {
|
|
28
|
+
} else {
|
|
29
|
+
throw new Error(
|
|
30
|
+
"Flag `allowBase` must be set to true in the config for this feature."
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (wallaceConfig.flags.allowDismount) {
|
|
34
|
+
} else {
|
|
35
|
+
throw new Error(
|
|
36
|
+
"Flag `allowDismount` must be set to true in the config for this feature."
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
this._alive = true;
|
|
40
|
+
this.error =
|
|
41
|
+
props.error ||
|
|
42
|
+
(error => {
|
|
43
|
+
throw error;
|
|
44
|
+
});
|
|
29
45
|
this.current = null;
|
|
30
|
-
|
|
46
|
+
this.handlers = events.map(e => {
|
|
47
|
+
const handler = () => this.onHashChange();
|
|
48
|
+
window.addEventListener(e, handler);
|
|
49
|
+
return { e, handler };
|
|
50
|
+
});
|
|
51
|
+
|
|
31
52
|
if (props.atts) {
|
|
32
53
|
Object.keys(props.atts).forEach(k => {
|
|
33
54
|
this.el.setAttribute(k, props.atts[k]);
|
|
@@ -49,6 +70,7 @@ Object.assign(Router.prototype, {
|
|
|
49
70
|
routeData,
|
|
50
71
|
/* #INCLUDE-IF: allowCtrl */ this.ctrl
|
|
51
72
|
);
|
|
73
|
+
if (!this._alive) return;
|
|
52
74
|
this.current && this.current.cleanup();
|
|
53
75
|
this.mount(component);
|
|
54
76
|
this.current = route;
|
|
@@ -56,6 +78,7 @@ Object.assign(Router.prototype, {
|
|
|
56
78
|
}
|
|
57
79
|
i++;
|
|
58
80
|
}
|
|
81
|
+
if (!this._alive) return;
|
|
59
82
|
throw new Error(`Router unable to match path "${path}"`);
|
|
60
83
|
} catch (error) {
|
|
61
84
|
this.error(error, this);
|
|
@@ -64,6 +87,19 @@ Object.assign(Router.prototype, {
|
|
|
64
87
|
mount(component) {
|
|
65
88
|
this.el.textContent = "";
|
|
66
89
|
this.el.appendChild(component.el);
|
|
90
|
+
},
|
|
91
|
+
/* #INCLUDE-IF: allowDismount */
|
|
92
|
+
dismount() {
|
|
93
|
+
this._alive = false;
|
|
94
|
+
if (this.current) {
|
|
95
|
+
this.current.cleanup();
|
|
96
|
+
}
|
|
97
|
+
this.base.dismount.call(this);
|
|
98
|
+
if (this._handlers) {
|
|
99
|
+
this._handlers.forEach(({ e, handler }) => {
|
|
100
|
+
window.removeEventListener(e, handler);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
67
103
|
}
|
|
68
104
|
});
|
|
69
105
|
|
|
@@ -108,10 +144,10 @@ Route.prototype = {
|
|
|
108
144
|
return this.component;
|
|
109
145
|
},
|
|
110
146
|
/**
|
|
111
|
-
* Allows user to
|
|
147
|
+
* Allows user to dismount component or perform other cleanup.
|
|
112
148
|
*/
|
|
113
149
|
cleanup() {
|
|
114
|
-
this._cleanup(this);
|
|
150
|
+
this._cleanup(this.component);
|
|
115
151
|
}
|
|
116
152
|
};
|
|
117
153
|
|
package/lib/types.d.ts
CHANGED
|
@@ -346,7 +346,6 @@ So long as the rendered component has all its stubs defined somewhere, it will w
|
|
|
346
346
|
|
|
347
347
|
Notes:
|
|
348
348
|
|
|
349
|
-
- Stubs receive the same props and controller as their containing component.
|
|
350
349
|
- Stubs are separate components, so cannot access methods on the containing component
|
|
351
350
|
through `self` (use the controller for that kind of thing).
|
|
352
351
|
|
|
@@ -657,6 +656,7 @@ declare module "wallace" {
|
|
|
657
656
|
ref: { [key: string]: HTMLElement };
|
|
658
657
|
part: { [key: string]: Part };
|
|
659
658
|
base: Component<Props, Controller>;
|
|
659
|
+
dismount(): void;
|
|
660
660
|
} & Component<Props, Controller> &
|
|
661
661
|
Methods;
|
|
662
662
|
|
|
@@ -795,24 +795,33 @@ declare module "wallace" {
|
|
|
795
795
|
export function route<Props>(
|
|
796
796
|
path: string,
|
|
797
797
|
componentDef: ComponentFunction<Props>,
|
|
798
|
-
converter
|
|
798
|
+
converter?: RouteConverter<Props>,
|
|
799
|
+
cleanup?: RouteCleanup<Props>
|
|
799
800
|
): Route<Props>;
|
|
800
801
|
|
|
801
802
|
type RouteConverter<Props> = (routedata: RouteData) => Props;
|
|
802
|
-
|
|
803
|
-
|
|
803
|
+
type RouteCleanup<Props> = (component: ComponentInstance<Props>) => void;
|
|
804
|
+
|
|
805
|
+
export type Route<Props> = [
|
|
806
|
+
string,
|
|
807
|
+
ComponentFunction<Props>,
|
|
808
|
+
RouteConverter<Props>?,
|
|
809
|
+
RouteCleanup<Props>?
|
|
810
|
+
];
|
|
804
811
|
export type RouterProps = {
|
|
805
|
-
routes: readonly Route<
|
|
806
|
-
atts?: Record<string,
|
|
812
|
+
routes: readonly Route<any>[];
|
|
813
|
+
atts?: Record<string, any>;
|
|
807
814
|
error?: (error: Error, router: Router) => void;
|
|
808
815
|
};
|
|
809
816
|
|
|
810
|
-
export
|
|
811
|
-
static nest?({ props }: { props?: RouterProps }): JSX.Element;
|
|
817
|
+
export type Router = ComponentFunction<RouterProps> & {
|
|
812
818
|
mount(component: Component<any>): void;
|
|
813
|
-
}
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
export const Router: Router;
|
|
814
822
|
}
|
|
815
823
|
|
|
824
|
+
type OptionalExpression<T> = T | boolean;
|
|
816
825
|
type MustBeExpression = Exclude<any, string>;
|
|
817
826
|
|
|
818
827
|
/**
|
|
@@ -841,6 +850,37 @@ interface DirectiveAttributes extends AllDomEvents {
|
|
|
841
850
|
*/
|
|
842
851
|
apply?: MustBeExpression;
|
|
843
852
|
|
|
853
|
+
/**
|
|
854
|
+
* ## Wallace directive: assign
|
|
855
|
+
*
|
|
856
|
+
* Assigns the component instance to a value during `render`, typically on the props
|
|
857
|
+
* or the controller.
|
|
858
|
+
*
|
|
859
|
+
* You can either use an expression:
|
|
860
|
+
*
|
|
861
|
+
* ```
|
|
862
|
+
* const MyComponent = ({ id }, { ctrl }) => (
|
|
863
|
+
* <div assign={ctrl.register[id]}>
|
|
864
|
+
* </div>
|
|
865
|
+
* );
|
|
866
|
+
* ```
|
|
867
|
+
*
|
|
868
|
+
* Or use a qualifier, which is read as being a field on the props:
|
|
869
|
+
*
|
|
870
|
+
* ```
|
|
871
|
+
* const MyComponent = () => (
|
|
872
|
+
* <div assign:c>
|
|
873
|
+
* </div>
|
|
874
|
+
* );
|
|
875
|
+
* ```
|
|
876
|
+
*
|
|
877
|
+
* Be careful not to assign to a watched property which updates this component or a
|
|
878
|
+
* parent, as that will create an infinite loop.
|
|
879
|
+
*
|
|
880
|
+
* May only be used on the root element. Modifies the `set` method.
|
|
881
|
+
*/
|
|
882
|
+
assign?: ComponentInstance;
|
|
883
|
+
|
|
844
884
|
/**
|
|
845
885
|
* ## Wallace directive: bind
|
|
846
886
|
*
|
|
@@ -936,6 +976,50 @@ interface DirectiveAttributes extends AllDomEvents {
|
|
|
936
976
|
*/
|
|
937
977
|
fixed?: string;
|
|
938
978
|
|
|
979
|
+
/**
|
|
980
|
+
* ## Wallace directive: help
|
|
981
|
+
*
|
|
982
|
+
* Does nothing other than show this tooltip.
|
|
983
|
+
*
|
|
984
|
+
* ### Directives:
|
|
985
|
+
*
|
|
986
|
+
* - `apply` runs a callback to modify an element.
|
|
987
|
+
* - `assign` assigns the component instance to a value.
|
|
988
|
+
* - `bind` updates a value when an input is changed.
|
|
989
|
+
* - `class:xyz` defines a set of classes to be toggled.
|
|
990
|
+
* - `css` shorthand for `fixed:class`.
|
|
991
|
+
* - `ctrl` specifies ctrl for nested/repeated components.
|
|
992
|
+
* - `event` changes the event which `bind` reacts to.
|
|
993
|
+
* - `fixed:xyz` sets a attribute from an expression at definition.
|
|
994
|
+
* - `hide` sets an element or component's hidden property.
|
|
995
|
+
* - `html` Set the element's `innnerHTML` property.
|
|
996
|
+
* - `if` excludes an element from the DOM.
|
|
997
|
+
* - `key` specifies a key for repeated components.
|
|
998
|
+
* - `on[EventName]` creates an event handler (note the code is copied).
|
|
999
|
+
* - `part:xyz` saves a reference to part of a component so it can be updated.
|
|
1000
|
+
* - `props` specifies props for stubs, nested or repeated components.
|
|
1001
|
+
* - `ref:xyz` saves a reference to an element or nested component.
|
|
1002
|
+
* - `show` sets and element or component's hidden property.
|
|
1003
|
+
* - `style:xyz` sets a specific style property.
|
|
1004
|
+
* - `toggle:xyz` toggles `xyz` as defined by `class:xyz` on same element, or class
|
|
1005
|
+
* `xyz`.
|
|
1006
|
+
* - `unique` can be set on components which are only used once for better performance.
|
|
1007
|
+
* - `watch` watches the props or the controller.
|
|
1008
|
+
*
|
|
1009
|
+
* See more by hovering on a specific directive.
|
|
1010
|
+
* Qualifiers like `class:danger` break the tool tip. Try `class x:danger`.
|
|
1011
|
+
*
|
|
1012
|
+
* ### Nesting syntax:
|
|
1013
|
+
*
|
|
1014
|
+
* ```
|
|
1015
|
+
* <MyComponent props={singleProps} />
|
|
1016
|
+
* <MyComponent.repeat props={arrayOfProps} />
|
|
1017
|
+
* <MyComponent.repeat props={arrayOfProps} key="id"/>
|
|
1018
|
+
* <MyComponent.repeat props={arrayOfProps} key={(i) => i.id}/>
|
|
1019
|
+
* ```
|
|
1020
|
+
*/
|
|
1021
|
+
help?: boolean;
|
|
1022
|
+
|
|
939
1023
|
/** ## Wallace directive: hide
|
|
940
1024
|
*
|
|
941
1025
|
* Set the element's `hidden` property and if true, does not render dynamic elements
|
|
@@ -1053,14 +1137,57 @@ interface DirectiveAttributes extends AllDomEvents {
|
|
|
1053
1137
|
* ## Wallace directive: unique
|
|
1054
1138
|
*
|
|
1055
1139
|
* Performance optimisation that can be applied to a component which is only used once.
|
|
1140
|
+
*
|
|
1141
|
+
* May only be used on the root element.
|
|
1056
1142
|
*/
|
|
1057
1143
|
unique?: boolean;
|
|
1144
|
+
|
|
1145
|
+
/**
|
|
1146
|
+
* ## Wallace directive: watch
|
|
1147
|
+
*
|
|
1148
|
+
* Wraps the props in a `watch` call which updates the component by overriding the
|
|
1149
|
+
* `set` method:
|
|
1150
|
+
*
|
|
1151
|
+
* ```
|
|
1152
|
+
* function set(props, ctrl) {
|
|
1153
|
+
* this.props = watch(props, () => this.update());
|
|
1154
|
+
* this.ctrl = ctrl;
|
|
1155
|
+
* }
|
|
1156
|
+
* ```
|
|
1157
|
+
*
|
|
1158
|
+
* You can provide a different callback to `watch`:
|
|
1159
|
+
*
|
|
1160
|
+
* ```
|
|
1161
|
+
* const MyComponent = () => (
|
|
1162
|
+
* <div watch={(target, key, value) => foo()}></div>
|
|
1163
|
+
* );
|
|
1164
|
+
* ```
|
|
1165
|
+
*
|
|
1166
|
+
* For more complex use cases, import the `watch` function and use it in an overriden
|
|
1167
|
+
* `render` method.
|
|
1168
|
+
*
|
|
1169
|
+
* May only be used on the root element. Modifies the `set` method.
|
|
1170
|
+
*/
|
|
1171
|
+
watch?: OptionalExpression<CallableFunction>;
|
|
1058
1172
|
}
|
|
1059
1173
|
|
|
1060
1174
|
// This makes this a module, which is needed to declare global, which is needed to make
|
|
1061
1175
|
// LibraryManagedAttributes work.
|
|
1062
1176
|
export {};
|
|
1063
1177
|
|
|
1178
|
+
type NativeIntrinsicElements = {
|
|
1179
|
+
[K in keyof HTMLElementTagNameMap]: DirectiveAttributes & {
|
|
1180
|
+
style?: string;
|
|
1181
|
+
class?: string;
|
|
1182
|
+
[attr: string]: any;
|
|
1183
|
+
};
|
|
1184
|
+
};
|
|
1185
|
+
|
|
1186
|
+
// WARNING - check that your changes here don't break standard html autocomplete
|
|
1187
|
+
// in JSX. The following should autocomplete button and allow style:
|
|
1188
|
+
//
|
|
1189
|
+
// <button style="width:20px" >
|
|
1190
|
+
|
|
1064
1191
|
declare global {
|
|
1065
1192
|
namespace JSX {
|
|
1066
1193
|
// This allows <Foo props={x} if={y} />
|
|
@@ -1069,43 +1196,7 @@ declare global {
|
|
|
1069
1196
|
type LibraryManagedAttributes<C, P> =
|
|
1070
1197
|
C extends ComponentFunction<infer Props, any, any, any> ? Wrapper<Props> : P;
|
|
1071
1198
|
|
|
1072
|
-
interface IntrinsicElements {
|
|
1073
|
-
/**
|
|
1074
|
-
* Nesting syntax:
|
|
1075
|
-
* ```
|
|
1076
|
-
* <MyComponent props={singleProps} />
|
|
1077
|
-
* <MyComponent.repeat props={arrayOfProps} />
|
|
1078
|
-
* <MyComponent.repeat props={arrayOfProps} key="id"/>
|
|
1079
|
-
* <MyComponent.repeat props={arrayOfProps} key={(i) => i.id}/>
|
|
1080
|
-
* ```
|
|
1081
|
-
*
|
|
1082
|
-
* Available Wallace directives:
|
|
1083
|
-
*
|
|
1084
|
-
* - `apply` runs a callback to modify an element.
|
|
1085
|
-
* - `bind` updates a value when an input is changed.
|
|
1086
|
-
* - `class:xyz` defines a set of classes to be toggled.
|
|
1087
|
-
* - `css` shorthand for `fixed:class`.
|
|
1088
|
-
* - `ctrl` specifies ctrl for nested/repeated components.
|
|
1089
|
-
* - `event` changes the event which `bind` reacts to.
|
|
1090
|
-
* - `fixed:xyz` sets a attribute from an expression at definition.
|
|
1091
|
-
* - `hide` sets an element or component's hidden property.
|
|
1092
|
-
* - `html` Set the element's `innnerHTML` property.
|
|
1093
|
-
* - `if` excludes an element from the DOM.
|
|
1094
|
-
* - `key` specifies a key for repeated components.
|
|
1095
|
-
* - `on[EventName]` creates an event handler (note the code is copied).
|
|
1096
|
-
* - `part:xyz` saves a reference to part of a component so it can be updated.
|
|
1097
|
-
* - `props` specifies props for stubs, nested or repeated components.
|
|
1098
|
-
* - `ref:xyz` saves a reference to an element or nested component.
|
|
1099
|
-
* - `show` sets and element or component's hidden property.
|
|
1100
|
-
* - `style:xyz` sets a specific style property.
|
|
1101
|
-
* - `toggle:xyz` toggles `xyz` as defined by `class:xyz` on same element, or class
|
|
1102
|
-
* `xyz`.
|
|
1103
|
-
* - `unique` can be set on components which are only used once for better performance.
|
|
1104
|
-
*
|
|
1105
|
-
* You will get more details by hovering on the directive itself, but unfortunetely
|
|
1106
|
-
* the tool tip won't display when you use a qualifier, like `class:danger`. To see
|
|
1107
|
-
* it you cantemporarily change it to something `class x:danger`.
|
|
1108
|
-
*/
|
|
1199
|
+
interface IntrinsicElements extends NativeIntrinsicElements {
|
|
1109
1200
|
[elemName: string]: DirectiveAttributes & Record<string, any>;
|
|
1110
1201
|
}
|
|
1111
1202
|
interface Element {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wallace",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"author": "Andrew Buchan",
|
|
5
5
|
"description": "An insanely small, fast, intuitive and extendable front-end framework",
|
|
6
6
|
"homepage": "https://wallace.js.org",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"test": "jest --clearCache && jest"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"babel-plugin-wallace": "^0.
|
|
18
|
+
"babel-plugin-wallace": "^0.17.1",
|
|
19
19
|
"browserify": "^17.0.1"
|
|
20
20
|
},
|
|
21
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "c114de400a01385d31891dd6475d8858e15e70e1"
|
|
22
22
|
}
|