cx 26.0.14 → 26.1.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/build/ui/VDOM.d.ts +1 -20
- package/build/ui/VDOM.js +1 -3
- package/build/ui/Widget.d.ts +1 -1
- package/build/ui/Widget.js +0 -5
- package/build/ui/app/startAppLoop.js +2 -10
- package/build/util/Component.js +5 -0
- package/build/util/test/createTestRenderer.d.ts +3 -1
- package/build/util/test/createTestRenderer.js +8 -2
- package/build/widgets/form/Checkbox.d.ts +0 -1
- package/build/widgets/form/Checkbox.js +1 -0
- package/build/widgets/form/ColorField.d.ts +0 -1
- package/build/widgets/form/ColorField.js +2 -2
- package/build/widgets/form/DateTimeField.d.ts +0 -2
- package/build/widgets/form/DateTimeField.js +1 -0
- package/build/widgets/form/DateTimePicker.d.ts +0 -2
- package/build/widgets/form/DateTimePicker.js +1 -0
- package/build/widgets/form/Radio.d.ts +0 -1
- package/build/widgets/form/Slider.js +9 -1
- package/build/widgets/form/Switch.d.ts +0 -1
- package/build/widgets/form/Switch.js +1 -1
- package/build/widgets/form/Wheel.d.ts +0 -1
- package/build/widgets/grid/Grid.d.ts +0 -2
- package/build/widgets/grid/GridCellEditor.js +3 -1
- package/build/widgets/icons/calendar.js +4 -3
- package/build/widgets/icons/check.js +2 -2
- package/build/widgets/icons/clear.js +2 -2
- package/build/widgets/icons/close.js +2 -2
- package/build/widgets/icons/cx.js +2 -2
- package/build/widgets/icons/drop-down.js +2 -2
- package/build/widgets/icons/file.js +2 -2
- package/build/widgets/icons/folder-open.js +2 -2
- package/build/widgets/icons/folder.js +2 -2
- package/build/widgets/icons/forward.js +2 -2
- package/build/widgets/icons/loading.js +2 -2
- package/build/widgets/icons/menu.js +2 -2
- package/build/widgets/icons/pixel-picker.js +2 -2
- package/build/widgets/icons/search.js +2 -2
- package/build/widgets/icons/sort-asc.js +2 -2
- package/build/widgets/icons/square.js +2 -2
- package/build/widgets/overlay/Overlay.d.ts +3 -0
- package/build/widgets/overlay/Overlay.js +3 -2
- package/dist/manifest.js +867 -867
- package/dist/ui.js +4 -18
- package/dist/util.js +4 -0
- package/dist/widgets.js +395 -319
- package/package.json +11 -8
- package/src/charts/Chart.ts +108 -108
- package/src/core.d.ts +182 -182
- package/src/data/Expression.spec.ts +229 -229
- package/src/data/Expression.ts +233 -233
- package/src/data/Grouper.ts +158 -158
- package/src/data/Selector.ts +10 -10
- package/src/data/StringTemplate.spec.ts +132 -132
- package/src/data/StructuredSelector.ts +146 -146
- package/src/data/ZoomIntoPropertyView.spec.ts +64 -64
- package/src/data/comparer.ts +78 -78
- package/src/data/computable.spec.ts +87 -87
- package/src/data/createStructuredSelector.ts +62 -62
- package/src/data/getAccessor.spec.ts +11 -11
- package/src/data/getAccessor.ts +74 -74
- package/src/data/getSelector.spec.ts +43 -43
- package/src/data/getSelector.ts +66 -66
- package/src/data/ops/filter.spec.ts +35 -35
- package/src/data/ops/filter.ts +9 -9
- package/src/data/ops/merge.ts +13 -13
- package/src/data/ops/removeTreeNodes.spec.ts +37 -37
- package/src/data/ops/updateArray.spec.ts +69 -69
- package/src/data/ops/updateArray.ts +31 -31
- package/src/data/test-types.ts +7 -7
- package/src/hooks/invokeCallback.spec.tsx +4 -4
- package/src/hooks/resolveCallback.spec.tsx +4 -4
- package/src/hooks/store.spec.tsx +15 -15
- package/src/hooks/useTrigger.spec.tsx +16 -10
- package/src/hooks/useTrigger.ts +26 -26
- package/src/index.scss +6 -6
- package/src/jsx-runtime.ts +79 -79
- package/src/svg/BoundedObject.ts +101 -101
- package/src/svg/util/Rect.ts +105 -105
- package/src/ui/CSS.ts +87 -87
- package/src/ui/CSSHelper.ts +17 -17
- package/src/ui/ContentResolver.spec.tsx +31 -29
- package/src/ui/Controller.spec.tsx +47 -39
- package/src/ui/Culture.ts +159 -159
- package/src/ui/Cx.spec.tsx +10 -8
- package/src/ui/DataProxy.spec.tsx +18 -18
- package/src/ui/Instance.ts +866 -866
- package/src/ui/IsolatedScope.spec.tsx +16 -9
- package/src/ui/Prop.ts +140 -140
- package/src/ui/PureContainer.spec.tsx +20 -18
- package/src/ui/RenderingContext.ts +99 -99
- package/src/ui/Repeater.spec.tsx +8 -6
- package/src/ui/Rescope.spec.tsx +13 -13
- package/src/ui/Restate.spec.tsx +31 -27
- package/src/ui/StructuredInstanceDataAccessor.ts +32 -32
- package/src/ui/VDOM.ts +1 -34
- package/src/ui/Widget.tsx +0 -7
- package/src/ui/adapter/TreeAdapter.spec.ts +76 -76
- package/src/ui/adapter/TreeAdapter.ts +185 -185
- package/src/ui/app/History.ts +133 -133
- package/src/ui/app/Url.spec.ts +50 -50
- package/src/ui/app/startAppLoop.tsx +5 -9
- package/src/ui/app/startHotAppLoop.ts +41 -41
- package/src/ui/createFunctionalComponent.spec.tsx +20 -18
- package/src/ui/layout/ContentPlaceholder.spec.tsx +46 -34
- package/src/ui/layout/FirstVisibleChildLayout.spec.tsx +31 -19
- package/src/ui/layout/FirstVisibleChildLayout.ts +60 -60
- package/src/ui/selection/PropertySelection.ts +87 -87
- package/src/util/Component.spec.ts +30 -0
- package/src/util/Component.ts +301 -296
- package/src/util/Console.ts +13 -13
- package/src/util/DOM.ts +88 -88
- package/src/util/hasKey.ts +18 -18
- package/src/util/index.ts +55 -55
- package/src/util/isArray.ts +3 -3
- package/src/util/isDefined.ts +3 -3
- package/src/util/isString.ts +3 -3
- package/src/util/test/createTestRenderer.tsx +9 -2
- package/src/widgets/AccessorBindings.spec.tsx +4 -4
- package/src/widgets/DocumentTitle.ts +95 -95
- package/src/widgets/HtmlElement.spec.tsx +6 -6
- package/src/widgets/ReactElementWrapper.spec.tsx +37 -37
- package/src/widgets/autoFocus.ts +9 -9
- package/src/widgets/cx.ts +63 -63
- package/src/widgets/form/Checkbox.tsx +0 -1
- package/src/widgets/form/ColorField.tsx +15 -12
- package/src/widgets/form/DateTimeField.tsx +0 -2
- package/src/widgets/form/DateTimePicker.tsx +0 -2
- package/src/widgets/form/Radio.tsx +0 -1
- package/src/widgets/form/Slider.tsx +12 -4
- package/src/widgets/form/Switch.tsx +2 -3
- package/src/widgets/form/ValidationGroup.spec.tsx +12 -12
- package/src/widgets/form/Wheel.tsx +0 -1
- package/src/widgets/grid/Grid.tsx +0 -1
- package/src/widgets/grid/GridCellEditor.tsx +7 -1
- package/src/widgets/icons/calendar.tsx +20 -15
- package/src/widgets/icons/check.tsx +2 -1
- package/src/widgets/icons/clear.tsx +2 -1
- package/src/widgets/icons/close.tsx +2 -2
- package/src/widgets/icons/cx.tsx +2 -1
- package/src/widgets/icons/drop-down.tsx +2 -1
- package/src/widgets/icons/file.tsx +2 -1
- package/src/widgets/icons/folder-open.tsx +2 -1
- package/src/widgets/icons/folder.tsx +2 -1
- package/src/widgets/icons/forward.tsx +2 -1
- package/src/widgets/icons/loading.tsx +2 -1
- package/src/widgets/icons/menu.tsx +2 -1
- package/src/widgets/icons/pixel-picker.tsx +2 -2
- package/src/widgets/icons/search.tsx +2 -1
- package/src/widgets/icons/sort-asc.tsx +2 -1
- package/src/widgets/icons/square.tsx +2 -1
- package/src/widgets/nav/Route.spec.tsx +2 -2
- package/src/widgets/overlay/Overlay.tsx +5 -1
- package/src/widgets/overlay/captureMouse.ts +195 -195
- package/src/widgets/overlay/createHotPromiseWindowFactory.ts +71 -71
- package/src/widgets/overlay/index.d.ts +11 -11
- package/src/widgets/overlay/tooltip-ops.ts +173 -173
- package/build/data/ArrayElementView.spec.d.ts +0 -1
- package/build/data/ArrayElementView.spec.js +0 -81
- package/build/data/Binding.spec.d.ts +0 -1
- package/build/data/Binding.spec.js +0 -61
- package/build/data/Expression.spec.d.ts +0 -1
- package/build/data/Expression.spec.js +0 -196
- package/build/data/Grouper.spec.d.ts +0 -1
- package/build/data/Grouper.spec.js +0 -48
- package/build/data/Ref.spec.d.ts +0 -1
- package/build/data/Ref.spec.js +0 -72
- package/build/data/Store.spec.d.ts +0 -1
- package/build/data/Store.spec.js +0 -19
- package/build/data/StoreRef.spec.d.ts +0 -1
- package/build/data/StoreRef.spec.js +0 -22
- package/build/data/StringTemplate.spec.d.ts +0 -1
- package/build/data/StringTemplate.spec.js +0 -112
- package/build/data/StructuredSelector.spec.d.ts +0 -1
- package/build/data/StructuredSelector.spec.js +0 -102
- package/build/data/View.spec.d.ts +0 -1
- package/build/data/View.spec.js +0 -44
- package/build/data/ZoomIntoPropertyView.spec.d.ts +0 -1
- package/build/data/ZoomIntoPropertyView.spec.js +0 -54
- package/build/data/comparer.spec.d.ts +0 -1
- package/build/data/comparer.spec.js +0 -50
- package/build/data/computable.spec.d.ts +0 -1
- package/build/data/computable.spec.js +0 -56
- package/build/data/createAccessorModelProxy.spec.d.ts +0 -1
- package/build/data/createAccessorModelProxy.spec.js +0 -30
- package/build/data/createStructuredSelector.spec.d.ts +0 -1
- package/build/data/createStructuredSelector.spec.js +0 -42
- package/build/data/diff/diffs.spec.d.ts +0 -1
- package/build/data/diff/diffs.spec.js +0 -45
- package/build/data/getAccessor.spec.d.ts +0 -1
- package/build/data/getAccessor.spec.js +0 -10
- package/build/data/getSelector.spec.d.ts +0 -1
- package/build/data/getSelector.spec.js +0 -36
- package/build/data/ops/append.spec.d.ts +0 -1
- package/build/data/ops/append.spec.js +0 -24
- package/build/data/ops/filter.spec.d.ts +0 -1
- package/build/data/ops/filter.spec.js +0 -25
- package/build/data/ops/findTreeNode.spec.d.ts +0 -1
- package/build/data/ops/findTreeNode.spec.js +0 -20
- package/build/data/ops/merge.spec.d.ts +0 -1
- package/build/data/ops/merge.spec.js +0 -23
- package/build/data/ops/removeTreeNodes.spec.d.ts +0 -1
- package/build/data/ops/removeTreeNodes.spec.js +0 -35
- package/build/data/ops/updateArray.spec.d.ts +0 -1
- package/build/data/ops/updateArray.spec.js +0 -33
- package/build/data/ops/updateTree.spec.d.ts +0 -1
- package/build/data/ops/updateTree.spec.js +0 -44
- package/build/hooks/invokeCallback.spec.d.ts +0 -1
- package/build/hooks/invokeCallback.spec.js +0 -44
- package/build/hooks/resolveCallback.spec.d.ts +0 -1
- package/build/hooks/resolveCallback.spec.js +0 -35
- package/build/hooks/store.spec.d.ts +0 -1
- package/build/hooks/store.spec.js +0 -48
- package/build/hooks/useTrigger.spec.d.ts +0 -1
- package/build/hooks/useTrigger.spec.js +0 -59
- package/build/ui/Controller.spec.d.ts +0 -1
- package/build/ui/Controller.spec.js +0 -247
- package/build/ui/Cx.spec.d.ts +0 -1
- package/build/ui/Cx.spec.js +0 -153
- package/build/ui/DataProxy.spec.d.ts +0 -1
- package/build/ui/DataProxy.spec.js +0 -208
- package/build/ui/IsolatedScope.spec.d.ts +0 -1
- package/build/ui/IsolatedScope.spec.js +0 -42
- package/build/ui/PureContainer.spec.d.ts +0 -1
- package/build/ui/PureContainer.spec.js +0 -149
- package/build/ui/Repeater.spec.d.ts +0 -1
- package/build/ui/Repeater.spec.js +0 -109
- package/build/ui/Rescope.spec.d.ts +0 -1
- package/build/ui/Rescope.spec.js +0 -134
- package/build/ui/Restate.spec.d.ts +0 -1
- package/build/ui/Restate.spec.js +0 -257
- package/build/ui/adapter/ArrayAdapter.spec.d.ts +0 -1
- package/build/ui/adapter/ArrayAdapter.spec.js +0 -44
- package/build/ui/adapter/TreeAdapter.spec.d.ts +0 -1
- package/build/ui/adapter/TreeAdapter.spec.js +0 -71
- package/build/ui/app/Url.spec.d.ts +0 -1
- package/build/ui/app/Url.spec.js +0 -43
- package/build/ui/createFunctionalComponent.spec.d.ts +0 -1
- package/build/ui/createFunctionalComponent.spec.js +0 -272
- package/build/ui/layout/ContentPlaceholder.spec.d.ts +0 -1
- package/build/ui/layout/ContentPlaceholder.spec.js +0 -333
- package/build/ui/layout/FirstVisibleChildLayout.spec.d.ts +0 -1
- package/build/ui/layout/FirstVisibleChildLayout.spec.js +0 -101
- package/build/util/Format.spec.d.ts +0 -1
- package/build/util/Format.spec.js +0 -58
- package/build/util/TraversalStack.spec.d.ts +0 -1
- package/build/util/TraversalStack.spec.js +0 -43
- package/build/util/date/upperBoundCheck.spec.d.ts +0 -1
- package/build/util/date/upperBoundCheck.spec.js +0 -22
- package/build/util/getSearchQueryPredicate.spec.d.ts +0 -1
- package/build/util/getSearchQueryPredicate.spec.js +0 -33
- package/build/util/isValidIdentifierName.spec.d.ts +0 -1
- package/build/util/isValidIdentifierName.spec.js +0 -28
- package/build/util/routeAppend.spec.d.ts +0 -1
- package/build/util/routeAppend.spec.js +0 -14
- package/build/widgets/AccessorBindings.spec.d.ts +0 -1
- package/build/widgets/AccessorBindings.spec.js +0 -40
- package/build/widgets/HtmlElement.spec.d.ts +0 -1
- package/build/widgets/HtmlElement.spec.js +0 -38
- package/build/widgets/form/ValidationGroup.spec.d.ts +0 -1
- package/build/widgets/form/ValidationGroup.spec.js +0 -62
- package/build/widgets/nav/Route.spec.d.ts +0 -1
- package/build/widgets/nav/Route.spec.js +0 -15
- package/dist/manifest.d.ts +0 -1443
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { Store } from "../data/Store";
|
|
2
|
-
import { createTestRenderer } from "../util/test/createTestRenderer";
|
|
2
|
+
import { createTestRenderer, act } from "../util/test/createTestRenderer";
|
|
3
3
|
import assert from "assert";
|
|
4
4
|
import { IsolatedScope } from "./IsolatedScope";
|
|
5
5
|
import { bind } from "./bind";
|
|
6
6
|
|
|
7
7
|
describe("IsolatedScope", () => {
|
|
8
|
-
it("prevents multiple re-renders", () => {
|
|
8
|
+
it("prevents multiple re-renders", async () => {
|
|
9
9
|
let list: any[] = [];
|
|
10
10
|
let widget = (
|
|
11
11
|
<cx>
|
|
12
12
|
<IsolatedScope
|
|
13
13
|
data={{
|
|
14
|
-
value: { bind:
|
|
14
|
+
value: { bind: "value" },
|
|
15
15
|
}}
|
|
16
16
|
>
|
|
17
|
-
<span
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
<span
|
|
18
|
+
text={bind("value")}
|
|
19
|
+
onExplore={(context, { store }) => {
|
|
20
|
+
list.push(store.get("value"));
|
|
21
|
+
}}
|
|
22
|
+
/>
|
|
20
23
|
</IsolatedScope>
|
|
21
24
|
</cx>
|
|
22
25
|
);
|
|
@@ -27,7 +30,7 @@ describe("IsolatedScope", () => {
|
|
|
27
30
|
},
|
|
28
31
|
});
|
|
29
32
|
|
|
30
|
-
const component = createTestRenderer(store, widget);
|
|
33
|
+
const component = await createTestRenderer(store, widget);
|
|
31
34
|
|
|
32
35
|
let tree = component.toJSON();
|
|
33
36
|
assert.deepEqual(list, ["bad"]);
|
|
@@ -38,12 +41,16 @@ describe("IsolatedScope", () => {
|
|
|
38
41
|
});
|
|
39
42
|
|
|
40
43
|
//component should not re-render if unrelated data changes
|
|
41
|
-
|
|
44
|
+
await act(async () => {
|
|
45
|
+
store.set("dummy", "dummy");
|
|
46
|
+
});
|
|
42
47
|
tree = component.toJSON();
|
|
43
48
|
assert.deepEqual(list, ["bad"]);
|
|
44
49
|
|
|
45
50
|
//component should not re-render if unrelated data changes
|
|
46
|
-
|
|
51
|
+
await act(async () => {
|
|
52
|
+
store.set("value", "good");
|
|
53
|
+
});
|
|
47
54
|
tree = component.toJSON();
|
|
48
55
|
assert.deepEqual(list, ["bad", "good"]);
|
|
49
56
|
assert.deepEqual(tree, {
|
package/src/ui/Prop.ts
CHANGED
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
import { Selector } from "../data/Selector";
|
|
2
|
-
import { AccessorChain } from "../data/createAccessorModelProxy";
|
|
3
|
-
|
|
4
|
-
export type Bind = {
|
|
5
|
-
bind: string;
|
|
6
|
-
defaultValue?: any;
|
|
7
|
-
throttle?: number;
|
|
8
|
-
debounce?: number;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type Tpl = {
|
|
12
|
-
tpl: string;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type Expr = {
|
|
16
|
-
expr: string;
|
|
17
|
-
set?: (value: any, instance?: any) => boolean;
|
|
18
|
-
throttle?: number;
|
|
19
|
-
debounce?: number;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export type Binding = Bind | Tpl | Expr;
|
|
23
|
-
|
|
24
|
-
export type GetSet<T> = {
|
|
25
|
-
get: Selector<T>;
|
|
26
|
-
set?: (value: T, instance?: any) => boolean;
|
|
27
|
-
throttle?: number;
|
|
28
|
-
debounce?: number;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export interface StructuredSelector {
|
|
32
|
-
[prop: string]: Selector<any>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export type Prop<T> = T | Binding | Selector<T> | AccessorChain<T> | GetSet<T>;
|
|
36
|
-
|
|
37
|
-
export type WritableProp<T> = Bind | AccessorChain<T>;
|
|
38
|
-
|
|
39
|
-
export interface DataRecord {
|
|
40
|
-
[prop: string]: any;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface Config {
|
|
44
|
-
[prop: string]: any;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface StructuredProp {
|
|
48
|
-
[prop: string]: Prop<any>;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Utility type that extracts the resolved value type from a Prop<T>.
|
|
53
|
-
* Used to derive the runtime type of structured props.
|
|
54
|
-
*/
|
|
55
|
-
export type ResolveProp<P> =
|
|
56
|
-
P extends Selector<infer T>
|
|
57
|
-
? T
|
|
58
|
-
: P extends AccessorChain<infer T>
|
|
59
|
-
? T
|
|
60
|
-
: P extends GetSet<infer T>
|
|
61
|
-
? T
|
|
62
|
-
: P extends Bind
|
|
63
|
-
? any
|
|
64
|
-
: P extends Tpl
|
|
65
|
-
? string
|
|
66
|
-
: P extends Expr
|
|
67
|
-
? any
|
|
68
|
-
: P;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Utility type that resolves a structured prop object to its runtime value types.
|
|
72
|
-
* Transforms { name: StringProp, count: NumberProp } to { name: string, count: number }
|
|
73
|
-
*/
|
|
74
|
-
export type ResolveStructuredPropType<S> = {
|
|
75
|
-
[K in keyof S]: ResolveProp<S[K]>;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Resolves the runtime value type from either a Prop<T> or a StructuredProp.
|
|
80
|
-
* Use this for generic widgets like ContentResolver and Validator where the
|
|
81
|
-
* input can be either a single prop or a structured object.
|
|
82
|
-
*
|
|
83
|
-
* - For Prop<T> (Selector, AccessorChain, GetSet), resolves to T
|
|
84
|
-
* - For bindings (Bind, Tpl, Expr), resolves to any/string/any
|
|
85
|
-
* - For structured objects, recursively resolves each property via ResolveStructuredProp
|
|
86
|
-
* - For literal values, returns them as-is
|
|
87
|
-
*/
|
|
88
|
-
export type ResolvePropType<P> =
|
|
89
|
-
P extends Selector<infer T>
|
|
90
|
-
? T
|
|
91
|
-
: P extends AccessorChain<infer T>
|
|
92
|
-
? T
|
|
93
|
-
: P extends GetSet<infer T>
|
|
94
|
-
? T
|
|
95
|
-
: P extends Bind
|
|
96
|
-
? any
|
|
97
|
-
: P extends Tpl
|
|
98
|
-
? string
|
|
99
|
-
: P extends Expr
|
|
100
|
-
? any
|
|
101
|
-
: P extends object
|
|
102
|
-
? ResolveStructuredPropType<P>
|
|
103
|
-
: P;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Generic structured prop type that provides type safety for params and their resolved values.
|
|
107
|
-
* Use with ContentResolver and similar widgets to type the onResolve callback params.
|
|
108
|
-
*/
|
|
109
|
-
export type TypedStructuredProp<T extends Record<string, any>> = {
|
|
110
|
-
[K in keyof T]: Prop<T[K]>;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
export type StringProp = Prop<string>;
|
|
114
|
-
export type StyleProp = Prop<string | React.CSSProperties> | StructuredProp;
|
|
115
|
-
export type NumberProp = Prop<number>;
|
|
116
|
-
export type BooleanProp = Prop<boolean>;
|
|
117
|
-
export type ClassProp = Prop<string> | StructuredProp;
|
|
118
|
-
export type RecordsProp = Prop<DataRecord[]>;
|
|
119
|
-
export type SortersProp = Prop<Sorter[]>;
|
|
120
|
-
export type UnknownProp = Prop<unknown>;
|
|
121
|
-
export type ModProp = StringProp | StructuredProp;
|
|
122
|
-
|
|
123
|
-
export type RecordAlias = string | { toString(): string };
|
|
124
|
-
|
|
125
|
-
export type SortDirection = "ASC" | "DESC";
|
|
126
|
-
|
|
127
|
-
export interface Sorter {
|
|
128
|
-
field?: string;
|
|
129
|
-
value?: (record: DataRecord) => any;
|
|
130
|
-
direction: SortDirection;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export interface CollatorOptions {
|
|
134
|
-
localeMatcher?: "lookup" | "best fit";
|
|
135
|
-
usage?: "sort" | "search";
|
|
136
|
-
sensitivity?: "base" | "accent" | "case" | "variant";
|
|
137
|
-
ignorePunctuation?: boolean;
|
|
138
|
-
numeric?: boolean;
|
|
139
|
-
caseFirst?: "upper" | "lower" | "false";
|
|
140
|
-
}
|
|
1
|
+
import { Selector } from "../data/Selector";
|
|
2
|
+
import { AccessorChain } from "../data/createAccessorModelProxy";
|
|
3
|
+
|
|
4
|
+
export type Bind = {
|
|
5
|
+
bind: string;
|
|
6
|
+
defaultValue?: any;
|
|
7
|
+
throttle?: number;
|
|
8
|
+
debounce?: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type Tpl = {
|
|
12
|
+
tpl: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type Expr = {
|
|
16
|
+
expr: string;
|
|
17
|
+
set?: (value: any, instance?: any) => boolean;
|
|
18
|
+
throttle?: number;
|
|
19
|
+
debounce?: number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type Binding = Bind | Tpl | Expr;
|
|
23
|
+
|
|
24
|
+
export type GetSet<T> = {
|
|
25
|
+
get: Selector<T>;
|
|
26
|
+
set?: (value: T, instance?: any) => boolean;
|
|
27
|
+
throttle?: number;
|
|
28
|
+
debounce?: number;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export interface StructuredSelector {
|
|
32
|
+
[prop: string]: Selector<any>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type Prop<T> = T | Binding | Selector<T> | AccessorChain<T> | GetSet<T>;
|
|
36
|
+
|
|
37
|
+
export type WritableProp<T> = Bind | AccessorChain<T>;
|
|
38
|
+
|
|
39
|
+
export interface DataRecord {
|
|
40
|
+
[prop: string]: any;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface Config {
|
|
44
|
+
[prop: string]: any;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface StructuredProp {
|
|
48
|
+
[prop: string]: Prop<any>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Utility type that extracts the resolved value type from a Prop<T>.
|
|
53
|
+
* Used to derive the runtime type of structured props.
|
|
54
|
+
*/
|
|
55
|
+
export type ResolveProp<P> =
|
|
56
|
+
P extends Selector<infer T>
|
|
57
|
+
? T
|
|
58
|
+
: P extends AccessorChain<infer T>
|
|
59
|
+
? T
|
|
60
|
+
: P extends GetSet<infer T>
|
|
61
|
+
? T
|
|
62
|
+
: P extends Bind
|
|
63
|
+
? any
|
|
64
|
+
: P extends Tpl
|
|
65
|
+
? string
|
|
66
|
+
: P extends Expr
|
|
67
|
+
? any
|
|
68
|
+
: P;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Utility type that resolves a structured prop object to its runtime value types.
|
|
72
|
+
* Transforms { name: StringProp, count: NumberProp } to { name: string, count: number }
|
|
73
|
+
*/
|
|
74
|
+
export type ResolveStructuredPropType<S> = {
|
|
75
|
+
[K in keyof S]: ResolveProp<S[K]>;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Resolves the runtime value type from either a Prop<T> or a StructuredProp.
|
|
80
|
+
* Use this for generic widgets like ContentResolver and Validator where the
|
|
81
|
+
* input can be either a single prop or a structured object.
|
|
82
|
+
*
|
|
83
|
+
* - For Prop<T> (Selector, AccessorChain, GetSet), resolves to T
|
|
84
|
+
* - For bindings (Bind, Tpl, Expr), resolves to any/string/any
|
|
85
|
+
* - For structured objects, recursively resolves each property via ResolveStructuredProp
|
|
86
|
+
* - For literal values, returns them as-is
|
|
87
|
+
*/
|
|
88
|
+
export type ResolvePropType<P> =
|
|
89
|
+
P extends Selector<infer T>
|
|
90
|
+
? T
|
|
91
|
+
: P extends AccessorChain<infer T>
|
|
92
|
+
? T
|
|
93
|
+
: P extends GetSet<infer T>
|
|
94
|
+
? T
|
|
95
|
+
: P extends Bind
|
|
96
|
+
? any
|
|
97
|
+
: P extends Tpl
|
|
98
|
+
? string
|
|
99
|
+
: P extends Expr
|
|
100
|
+
? any
|
|
101
|
+
: P extends object
|
|
102
|
+
? ResolveStructuredPropType<P>
|
|
103
|
+
: P;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Generic structured prop type that provides type safety for params and their resolved values.
|
|
107
|
+
* Use with ContentResolver and similar widgets to type the onResolve callback params.
|
|
108
|
+
*/
|
|
109
|
+
export type TypedStructuredProp<T extends Record<string, any>> = {
|
|
110
|
+
[K in keyof T]: Prop<T[K]>;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export type StringProp = Prop<string>;
|
|
114
|
+
export type StyleProp = Prop<string | React.CSSProperties> | StructuredProp;
|
|
115
|
+
export type NumberProp = Prop<number>;
|
|
116
|
+
export type BooleanProp = Prop<boolean>;
|
|
117
|
+
export type ClassProp = Prop<string> | StructuredProp;
|
|
118
|
+
export type RecordsProp = Prop<DataRecord[]>;
|
|
119
|
+
export type SortersProp = Prop<Sorter[]>;
|
|
120
|
+
export type UnknownProp = Prop<unknown>;
|
|
121
|
+
export type ModProp = StringProp | StructuredProp;
|
|
122
|
+
|
|
123
|
+
export type RecordAlias = string | { toString(): string };
|
|
124
|
+
|
|
125
|
+
export type SortDirection = "ASC" | "DESC";
|
|
126
|
+
|
|
127
|
+
export interface Sorter {
|
|
128
|
+
field?: string;
|
|
129
|
+
value?: (record: DataRecord) => any;
|
|
130
|
+
direction: SortDirection;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface CollatorOptions {
|
|
134
|
+
localeMatcher?: "lookup" | "best fit";
|
|
135
|
+
usage?: "sort" | "search";
|
|
136
|
+
sensitivity?: "base" | "accent" | "case" | "variant";
|
|
137
|
+
ignorePunctuation?: boolean;
|
|
138
|
+
numeric?: boolean;
|
|
139
|
+
caseFirst?: "upper" | "lower" | "false";
|
|
140
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Store } from "../data/Store";
|
|
2
2
|
import assert from "assert";
|
|
3
|
-
import { createTestRenderer } from "../util/test/createTestRenderer";
|
|
3
|
+
import { createTestRenderer, act } from "../util/test/createTestRenderer";
|
|
4
4
|
import { bind } from "./bind";
|
|
5
5
|
import { PureContainer } from "./PureContainer";
|
|
6
6
|
|
|
7
7
|
describe("PureContainer", () => {
|
|
8
|
-
it("renders static text children", () => {
|
|
8
|
+
it("renders static text children", async () => {
|
|
9
9
|
let widget = (
|
|
10
10
|
<cx>
|
|
11
11
|
<PureContainer>
|
|
@@ -15,7 +15,7 @@ describe("PureContainer", () => {
|
|
|
15
15
|
);
|
|
16
16
|
|
|
17
17
|
let store = new Store();
|
|
18
|
-
const component = createTestRenderer(store, widget);
|
|
18
|
+
const component = await createTestRenderer(store, widget);
|
|
19
19
|
|
|
20
20
|
let tree = component.toJSON();
|
|
21
21
|
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
@@ -26,7 +26,7 @@ describe("PureContainer", () => {
|
|
|
26
26
|
});
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
it("renders multiple children", () => {
|
|
29
|
+
it("renders multiple children", async () => {
|
|
30
30
|
let widget = (
|
|
31
31
|
<cx>
|
|
32
32
|
<PureContainer>
|
|
@@ -38,7 +38,7 @@ describe("PureContainer", () => {
|
|
|
38
38
|
);
|
|
39
39
|
|
|
40
40
|
let store = new Store();
|
|
41
|
-
const component = createTestRenderer(store, widget);
|
|
41
|
+
const component = await createTestRenderer(store, widget);
|
|
42
42
|
|
|
43
43
|
let tree = component.toJSON();
|
|
44
44
|
assert(Array.isArray(tree), "Expected array of elements");
|
|
@@ -62,7 +62,7 @@ describe("PureContainer", () => {
|
|
|
62
62
|
]);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
it("renders children with data bindings", () => {
|
|
65
|
+
it("renders children with data bindings", async () => {
|
|
66
66
|
let widget = (
|
|
67
67
|
<cx>
|
|
68
68
|
<PureContainer>
|
|
@@ -77,7 +77,7 @@ describe("PureContainer", () => {
|
|
|
77
77
|
},
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
-
const component = createTestRenderer(store, widget);
|
|
80
|
+
const component = await createTestRenderer(store, widget);
|
|
81
81
|
|
|
82
82
|
let tree = component.toJSON();
|
|
83
83
|
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
@@ -88,7 +88,7 @@ describe("PureContainer", () => {
|
|
|
88
88
|
});
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
it("renders nested containers", () => {
|
|
91
|
+
it("renders nested containers", async () => {
|
|
92
92
|
let widget = (
|
|
93
93
|
<cx>
|
|
94
94
|
<PureContainer>
|
|
@@ -102,7 +102,7 @@ describe("PureContainer", () => {
|
|
|
102
102
|
);
|
|
103
103
|
|
|
104
104
|
let store = new Store();
|
|
105
|
-
const component = createTestRenderer(store, widget);
|
|
105
|
+
const component = await createTestRenderer(store, widget);
|
|
106
106
|
|
|
107
107
|
let tree = component.toJSON();
|
|
108
108
|
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
@@ -119,7 +119,7 @@ describe("PureContainer", () => {
|
|
|
119
119
|
});
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
-
it("conditionally renders children based on visible binding", () => {
|
|
122
|
+
it("conditionally renders children based on visible binding", async () => {
|
|
123
123
|
let widget = (
|
|
124
124
|
<cx>
|
|
125
125
|
<PureContainer>
|
|
@@ -135,7 +135,7 @@ describe("PureContainer", () => {
|
|
|
135
135
|
},
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
-
const component = createTestRenderer(store, widget);
|
|
138
|
+
const component = await createTestRenderer(store, widget);
|
|
139
139
|
|
|
140
140
|
let tree = component.toJSON();
|
|
141
141
|
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
@@ -146,7 +146,7 @@ describe("PureContainer", () => {
|
|
|
146
146
|
});
|
|
147
147
|
});
|
|
148
148
|
|
|
149
|
-
it("handles empty children", () => {
|
|
149
|
+
it("handles empty children", async () => {
|
|
150
150
|
let widget = (
|
|
151
151
|
<cx>
|
|
152
152
|
<PureContainer>
|
|
@@ -156,7 +156,7 @@ describe("PureContainer", () => {
|
|
|
156
156
|
);
|
|
157
157
|
|
|
158
158
|
let store = new Store();
|
|
159
|
-
const component = createTestRenderer(store, widget);
|
|
159
|
+
const component = await createTestRenderer(store, widget);
|
|
160
160
|
|
|
161
161
|
let tree = component.toJSON();
|
|
162
162
|
assert(tree && !Array.isArray(tree), "Expected single element");
|
|
@@ -167,7 +167,7 @@ describe("PureContainer", () => {
|
|
|
167
167
|
});
|
|
168
168
|
});
|
|
169
169
|
|
|
170
|
-
it("renders children from items property", () => {
|
|
170
|
+
it("renders children from items property", async () => {
|
|
171
171
|
let widget = (
|
|
172
172
|
<cx>
|
|
173
173
|
<PureContainer items={[<div key="1">Item 1</div>, <div key="2">Item 2</div>]} />
|
|
@@ -175,7 +175,7 @@ describe("PureContainer", () => {
|
|
|
175
175
|
);
|
|
176
176
|
|
|
177
177
|
let store = new Store();
|
|
178
|
-
const component = createTestRenderer(store, widget);
|
|
178
|
+
const component = await createTestRenderer(store, widget);
|
|
179
179
|
|
|
180
180
|
let tree = component.toJSON();
|
|
181
181
|
assert(Array.isArray(tree), "Expected array of elements");
|
|
@@ -192,7 +192,7 @@ describe("PureContainer", () => {
|
|
|
192
192
|
});
|
|
193
193
|
});
|
|
194
194
|
|
|
195
|
-
it("updates children when store data changes", () => {
|
|
195
|
+
it("updates children when store data changes", async () => {
|
|
196
196
|
let widget = (
|
|
197
197
|
<cx>
|
|
198
198
|
<PureContainer>
|
|
@@ -207,7 +207,7 @@ describe("PureContainer", () => {
|
|
|
207
207
|
},
|
|
208
208
|
});
|
|
209
209
|
|
|
210
|
-
const component = createTestRenderer(store, widget);
|
|
210
|
+
const component = await createTestRenderer(store, widget);
|
|
211
211
|
|
|
212
212
|
let tree = component.toJSON();
|
|
213
213
|
assert.deepEqual(tree, {
|
|
@@ -217,7 +217,9 @@ describe("PureContainer", () => {
|
|
|
217
217
|
});
|
|
218
218
|
|
|
219
219
|
// Update the store
|
|
220
|
-
|
|
220
|
+
await act(async () => {
|
|
221
|
+
store.set("count", 5);
|
|
222
|
+
});
|
|
221
223
|
|
|
222
224
|
// Re-render
|
|
223
225
|
tree = component.toJSON();
|